---
title: "開発"
description: "テスト、フォーマット、Lint、ビルドの手順。"
---

## 前提

Rust stable を使用します。`Cargo.toml` の `rust-version` は 1.88 で、
`rust-toolchain.toml` により `rustfmt` と `clippy` も自動で有効になります。

## Rust の検証

リポジトリのルートで、次のコマンドを実行します。

```sh
cargo check --locked
cargo test --locked
cargo fmt --all -- --check
cargo clippy --all-targets --locked -- -D warnings
cargo build --release --locked
```

`makers`（cargo-make）を使う場合は、対応するタスクを実行できます。

```sh
makers check
makers test
makers fmt-check
makers clippy
makers build
```

macOS arm64 で `ld: library not found for -liconv` が発生する場合は、`makers` の cargo
ラッパーが Apple Clang と Xcode SDK を設定して対応します。

## 実装の責務と拡張時の確認点

- `app` は CLI 引数から実行環境を組み立て、結果の出力と履歴記録を調整します。
  モデルへの要求・ツール呼び出しは `engine`、workflow の制御構造は `workflow` が担当します。
  `app/workflow_run.rs` はトップレベルの進捗・再開・チェックポイント・実行期限を管理します。
- `engine/context.rs` の `AppServices` は設定に依存するレジストリ・キャッシュを共有し、
  `RunContext` は実行ごとの変数・使用量・ポリシー・キャンセル元を保持します。
  共有サービスの終了は最上位の所有者が行い、個々の実行コンテキストから終了させません。
  `config::Endpoint` は認証情報の取得方法を選ぶだけで、シークレット取得コマンドは
  実際の要求時に `SecretResolver` が非同期で実行します。
- ワークフローは `workflow/parse.rs` が YAML を読み込み、ステップの種類キー・フィールドの
  組み合わせ・id の重複・スキーマ参照・jq/テンプレートの構文・`break`/`stop`/`ask`/`write`
  の配置をすべて検証してから、`workflow/model.rs` の `Step`/`StepKind` へ変換します。
  実行（`workflow/exec.rs`）・dry-run・graph・lint はこの検証済みの型だけを受け取ります。
  構文を変更する場合は `schemas/workflow.json` も更新し、パーサーと Schema の整合性テストを
  追加します。
- `workflow/exec.rs` はステップ間の値を `serde_json::Value` のまま扱い、テキストが必要な
  境界（ユーザーメッセージ・標準入力・書き出し・最終出力）でだけ `template::to_text` で
  文字列にします。jq とテンプレートは `jq::Globals`（`$steps`/`$inputs`/`$loop`）という
  同じ文脈を共有します。
- `engine::ToolLoop` はモデルとの会話履歴、ツール集合、ラウンド上限、ツール実行を管理します。
  ストリームの有無にかかわらず同じ状態管理を使います。
- `engine/stream.rs` はストリームの集約と表示を扱います。出力先を `AsyncWrite` として
  渡せるため、標準出力の差し替えや実 API を使わずに reasoning、ツール呼び出し、キャンセルを
  検証できます。
- `frontmatter::parse` は agent・skill の文書構造、`async_cache::AsyncCache` は
  同じキーの読み込み共有とキャンセル、`registry` は一覧表示を担当します。
  各ファイルの内容の検証やパス解決は agent・skill 側に残します。
- `error::Interrupted` はキャンセルと実行期限超過を表します。中断を返すときはこの型を
  エラーチェーンに保持してください。終了コードはエラーの型から決まり、ファイル名や
  エラーメッセージに含まれる単語には依存しません。
- `lint` はファイル・設定の検査結果を `LintRun` に集め、テキスト・JSON・GitHub 向けに
  表示します。検査項目を追加する際は、表示形式ごとに検査処理を追加せず、共通の解析結果に
  追加します。
- `storage::write_atomic` は cache・cassette・checkpoint の保存を担当します。
  各書き込みが専用の一時ファイルを作り、完成後に同じディレクトリ内で rename します。
  同時に保存しても途中の内容を公開せず、一時ファイルの後始末も共通処理が行います。
  `fsync` による電源断時の永続性保証は行いません。
- `process::run_process` はコマンドとシークレット取得で共通のプロセス実行基盤です。
  出力上限、キャンセル、期限、子プロセスの回収と読み書きタスクの後始末を一か所で管理します。
- `cancellation` は `CancellationToken`/`AtomicBool` それぞれの「キャンセル済みか」チェックと、
  キャンセルが配線されていない呼び出し元向けの never-cancelled sentinel (`none()`/`NEVER_SET`)
  を提供します。`file_walk::DirWalker` は `lait lint`/`lait test` のディレクトリ再帰探索
  (決定的な順序・symlink 非追従・ドット始まりエントリの除外・重複排除) を共有し、
  `sync_cache::SyncCache` は `template`/`jq` のコンパイル結果キャッシュ (ロック・poison 復帰
  込み) を共有します。`report::note`/`warn` は `note:`/`warning:` 接頭辞付きの標準エラー出力を
  一箇所に集約します。`app::load_config`/`build_run_context` は `lait chat`/`prompt run`/
  `agent run` が共有するエントリポイントの定型セットアップ (Ctrl-C ハンドラの登録、設定読込、
  キャッシュポリシー解決、`RunContext` 構築) です。
- workflow の出力は正規化したパスと、実際に開いた通常ファイルの二段階でロックします。
  `file_lock::ExclusiveLease` を切り詰め前に取得し、書き込み完了まで保持することで、
  別名のハードリンクも直列化します。Unix のファイルロックは advisory であり、
  同じロックを使わない外部プログラムの書き込みまでは防止しません。

統合テストは `tests/support::test_command` を使い、実ユーザーのグローバル設定と履歴から
隔離します。履歴を複数コマンド間で共有するテストでは、一時ディレクトリを用意して
`XDG_DATA_HOME` を明示的に上書きします。並行処理の変更では、成功時だけでなく、待機中の
キャンセル・初期化失敗後の再試行・保存失敗時の後始末も検証してください。

## ドキュメントサイト

日本語ドキュメントの正本は `docs/usage/ja/` です。文書を変更したら、サイト側の生成コピーを
同期してから型チェックを実行します。

```sh
cd website
pnpm sync-docs
pnpm types:check
```

`pnpm build` は同期と Blume のチェック・リンク検証・ビルドをまとめて実行します。

GitHub Actions でも Rust の検証と `pnpm build` を実行します。
