# テスト妥当性レビュー: yoi - 評価: 混在 ## 確認範囲 `/home/hare/Projects/yoi/crates/yoi` 配下の `yoi` crate を確認した: - `crates/yoi/Cargo.toml` - `crates/yoi/src/main.rs` - `crates/yoi/src/ticket_cli.rs` - `crates/yoi/src/objective_cli.rs` - `crates/yoi/src/memory_lint.rs` - `crates/yoi/src/session_cli.rs` この crate はプロダクトのバイナリ境界である。責務はトップレベル CLI の parse/dispatch、TUI/panel 起動選択、`yoi pod` 委譲、`yoi ticket ...`、`yoi memory lint`、`yoi session analyze`、および objective-record CLI の処理である。深いドメイン挙動の大半は他 crate(`ticket`、`memory`、`session-analytics`、`tui`、`pod`)に委譲されている。 この crate には 48 個の unit test があり、独立した integration test ファイルはない。 ## 現在のテストがよくカバーしていること - `main.rs` のトップレベル引数 parsing は、重要な routing 判断をカバーしている: - positional Pod name vs `--pod` - `pod` runtime subcommand の pass-through - `ticket`、`session`、`memory lint`、`panel`、`keys`、`setup-model` - `--profile` の互換性制約 - `--resume` / Pod-name の衝突 - Pod identity を伴う明示的な `--session` - `--multi` が launch alias として受理されないこと - `ticket_cli.rs` には `TempDir` を使った比較的強い in-process CLI test がある: - `init` scaffold 作成と非上書き挙動 - `create`、`list`、`show`、`comment`、`review`、`state`、`close`、`doctor` - configured backend root - relation add/list/show rendering - list bounding と title truncation - 曖昧な body source と review result の拒否 - `state closed` が専用の `close` command を要求すること - `memory_lint.rs` は主要な CLI 固有 invariants をカバーしている: - option parsing と usage error - 意図した memory/Knowledge record path だけが lint されること - invalid record が lint failure になること - `--warnings-as-errors` が status を変えること - JSON output が parse 可能で、期待される counts を含むこと - `objective_cli.rs` は基本的な record lifecycle をカバーしている: - create/list/show - 生成される opaque record id の形 - linked Ticket validation - linked-ticket state に対する doctor success/failure - `session_cli.rs` は以下をカバーしている: - `analyze --json` parsing - 最小 JSONL fixture からの output が valid JSON であること - 初期 non-JSON output mode の拒否 ## 不足 / 疑問のあるテスト - 現在の `yoi` crate test suite は pass しない。`cargo test -p yoi` は `ticket_cli::tests::ticket_cli_init_writes_explicit_ticket_config_scaffold` で決定的に失敗する。 - 失敗している assertion は、scaffold role profiles に `profile = "builtin:default"` が含まれることを期待している。 - 現在の `ticket::config::ticket_config_scaffold()` は、`role.default_profile()` 経由で `builtin:intake`、`builtin:orchestrator`、`builtin:coder`、`builtin:reviewer` のような role-specific builtin profiles を出力する。 - 対応する `ticket` crate の scaffold test は pass しているため、これは scaffold generation 自体が壊れている証拠というより、`yoi` boundary test 内の stale duplicate assertion に見える。 - 影響: この suite は現在、この crate に対する有効な green regression signal になっていない。 - `ticket_cli_init_writes_explicit_ticket_config_scaffold` は copied scaffold text に密結合しすぎている。`yoi` crate は、おそらく `yoi ticket init` がファイルを書き、そのファイルが期待される semantic config として parse できることを assert すべきであり、正確な role default は主に `ticket` crate tests の責務である。 - installed binary behavior に対する subprocess-level test がない。in-process test は有用で速いが、以下を検証していない: - `main` からの実際の exit code - parse/runtime error における stderr formatting - real binary 経由の stdout behavior - `std::env::current_dir()` を呼ぶ command の current-directory behavior - packaging/runtime resource の影響 - トップレベル parser coverage は良いが、hand-written parser としては完全ではない。欠けている、または薄い case には以下がある: - 引数なしの default spawn mode - `--workspace=...`、`--pod=...`、`--socket=...`、`--profile=...`、`--session=...` - 重複した positional Pod names - Pod name なしの `--socket` - `--session` と併用した `--socket` - `--session` と併用した `--resume` - `panel` の malformed argument cases - `ticket_cli.rs` は良い happy-path lifecycle をカバーしているが、多くの CLI error と file-boundary case がまだない: - ほとんどの flag に対する required value 欠落 - invalid `--state`、`--limit`、`--role`、relation kind - `--message`/`--file` 欠落 - 読めない `--file` - comment/review/close に対する `--file` bodies - invalid configured backend provider/root config - malformed Ticket records に対する doctor failure rendering - `objective_cli.rs` は自身の Markdown records を書き、validate するため、test surface は現在より強くあるべきである。欠けている case には以下がある: - missing/invalid frontmatter - invalid state - required section headings の欠落 - duplicate linked tickets warning - `show` における path traversal / invalid id rejection - paused/done/archived/all に対する list filtering - `memory_lint.rs` には妥当な focused tests があるが、decisions と Knowledge records を明示的にはカバーしておらず、symlink/directory の特殊性、読めない file、summary fragments を超えた stdout human-output details もカバーしていない。 - `session_cli.rs` は意図的に薄いが、ほとんどは最小 fixture を通じて delegated analytics output shape を検証している。より広い analytics correctness は `session-analytics` に属する。`yoi` crate には、unknown subcommands/options と duplicate path handling の test がまだない。 ## 追加提案 - まず失敗している scaffold test を修正する。以下のどちらかを推奨する: - `builtin:default` ではなく `role.default_profile()` を assert するように更新する、または - `yoi` test を semantic にする: `ticket init` を実行し、生成された config を `TicketConfig::from_toml` / `load_workspace` で parse し、各 fixed role が launch config を持つことを assert する。正確な scaffold-string coverage は `crates/ticket` に残す。 - 完全な E2E design の前でも、binary boundary に対するごく小さい subprocess smoke suite を追加する: - `yoi --help` が 0 で exit し、core commands を出力する - unknown top-level arg が non-zero で exit し、`try yoi --help` hint を書く - temp cwd で `yoi ticket init` が 0 で exit し、`.yoi/ticket.config.toml` を作る - `yoi memory lint --workspace --json` が適切に 0/1 で exit する - `yoi session analyze --json` が 0 で exit し、JSON を出力する - トップレベル edge cases に対して、特に `--flag=value` forms と invalid combinations の table-driven parser tests を追加する。これは安価で、既存の unit-test style に合っている。 - `ticket_cli` parsing と body-file handling に対する CLI 固有の negative tests を追加する: - missing `--title` - invalid list state / limit - missing body source - unreadable `--file` - invalid relation kind - invalid comment role - malformed persisted records 周辺の objective CLI tests を強化する。この code は validation を別 crate にすべて委譲するのではなく、自身で storage format を所有しているためである。 - domain-deep tests は owning crates に置き続ける。`yoi` では、CLI mapping、filesystem boundary behavior、output/status contract、delegated crates との integration に focus する。 ## 実行したコマンド - `cargo test -p yoi` - Result: failed. - Summary: 47 passed, 1 failed. - Failure: `ticket_cli::tests::ticket_cli_init_writes_explicit_ticket_config_scaffold` - Failure reason: assertion が generated role config に `profile = "builtin:default"` が含まれることを期待していた。 - `cargo test -p yoi ticket_cli::tests::ticket_cli_init_writes_explicit_ticket_config_scaffold -- --exact` - Result: failed. - 失敗する test が deterministic かつ isolated であることを確認した。 - `cargo test -p ticket config::tests::scaffold_config_includes_backend_and_all_fixed_roles -- --exact` - Result: passed. - これは、owning `ticket` crate の scaffold test は現行であり、`yoi` test に stale duplicate expectation があるという解釈を支持する。 - `cargo test -p yoi -- --list` - Result: 48 tests, 0 benchmarks を listed。