From b0c91049b13c9c727b29579f51d79ea7d23ae46c Mon Sep 17 00:00:00 2001 From: Hare Date: Wed, 13 May 2026 06:30:45 +0900 Subject: [PATCH] close: complete pod manifest and file ref tickets --- TODO.md | 2 - tickets/file-ref-directory.md | 69 ------------------------ tickets/file-ref-directory.review.md | 25 --------- tickets/pod-cli-manifest-flags.md | 57 -------------------- tickets/pod-cli-manifest-flags.review.md | 23 -------- 5 files changed, 176 deletions(-) delete mode 100644 tickets/file-ref-directory.md delete mode 100644 tickets/file-ref-directory.review.md delete mode 100644 tickets/pod-cli-manifest-flags.md delete mode 100644 tickets/pod-cli-manifest-flags.review.md diff --git a/TODO.md b/TODO.md index 1dab3486..83f3d2a4 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,6 @@ - AI maintainer 用 WorkItem / Thread 抽象 → [tickets/maintainer-work-items.md](tickets/maintainer-work-items.md) - Prompt / Workflow 評価メトリクスと改善 Offer → [tickets/prompt-eval-metrics.md](tickets/prompt-eval-metrics.md) - Permission: allow-all 既定 policy への整理 → [tickets/permission-default-policy.md](tickets/permission-default-policy.md) -- Pod CLI: マニフェスト関連フラグの整理 → [tickets/pod-cli-manifest-flags.md](tickets/pod-cli-manifest-flags.md) - Pod: 空応答ターン (Submit 後 AI 応答ゼロで Pause/Cancel) を自動巻き戻し → [tickets/pod-empty-turn-rollback.md](tickets/pod-empty-turn-rollback.md) - Pod: 任意ターンからの Fork(複数ターン巻き戻しを汎用化) → [tickets/pod-session-fork.md](tickets/pod-session-fork.md) - Pod: 子→親の TurnEnded/Errored callback を親由来ターンのみに絞る → [tickets/pod-parent-turn-callback.md](tickets/pod-parent-turn-callback.md) @@ -21,7 +20,6 @@ - spawn 失敗時に Pod の stderr が TUI に表示されない → [tickets/tui-spawn-error-surface.md](tickets/tui-spawn-error-surface.md) - 巻き戻されたターンの入力テキストを編集領域に復元 → [tickets/tui-empty-turn-restore.md](tickets/tui-empty-turn-restore.md) - セッションコンテキスト長 / ウィンドウ占有率の常時表示 → [tickets/tui-context-usage-indicator.md](tickets/tui-context-usage-indicator.md) -- Submit 時 FileRef でディレクトリを参照したときの挙動 → [tickets/file-ref-directory.md](tickets/file-ref-directory.md) - Prune: 保護境界を turn 数から末尾 token budget に置き換え → [tickets/prune-token-budget.md](tickets/prune-token-budget.md) - メモリ機構 - extract / consolidation 監査ログ → [tickets/memory-audit-log.md](tickets/memory-audit-log.md) diff --git a/tickets/file-ref-directory.md b/tickets/file-ref-directory.md deleted file mode 100644 index 995dfef4..00000000 --- a/tickets/file-ref-directory.md +++ /dev/null @@ -1,69 +0,0 @@ -# Submit 時 FileRef でディレクトリを参照したときの挙動 - -## 背景 - -submit 時に `Segment::FileRef { path }` は `crates/pod/src/fs_view.rs` の -`PodFsView::resolve_file_ref` でファイル本文として読まれ、`[File: ]` system -message に展開される。内部では `ScopedFs::read_bytes` を経由するため、`path` が -ディレクトリだった場合は `ToolsError::IsDirectory` で失敗し、Pod 側は -`AlertLevel::Warn` を出してそのセグメントを丸ごと捨てる -(`crates/pod/src/pod.rs` の `resolve_file_refs`)。 - -ユーザーから見ると `@some-dir` を添付しても LLM 側にはプレースホルダが残る -だけで、ディレクトリ参照という意図が反映されない。TUI completion は -ディレクトリも候補として出すので、実際の挙動とのギャップが大きい。 - -`tickets/file-ref-symlink-diagnostics.md` は symlink が canonicalize 後に -ディレクトリ・scope 外だった場合の診断にフォーカスしており、通常ディレクトリの -FileRef 解決をどう扱うかは扱っていない。 - -## ゴール - -submit 時に `Segment::FileRef` がディレクトリを指している場合の挙動を -仕様として確定し、ユーザーが添付の意図どおりの結果を LLM に届けられる -ようにする。 - -## 要件 - -ディレクトリに対する FileRef の意味論を決め、実装する。少なくとも以下の -論点をチケット内で結論づけ、実装・テスト・ドキュメントを揃える: - -- 採用する挙動: 浅い entry listing を `[Dir: ]` 等の label で返すか、 - 明示的に reject して `read_file` / `glob` の利用を促すか、それ以外か -- listing を返す場合の上限: entry 件数や本文 byte 数を、ファイル本文用の - upload/attachment 上限と同じにするか別途持つか -- 隠しファイル・gitignore・scope 外 entry の扱い -- symlink entry の扱いは `tickets/file-ref-symlink-diagnostics.md` と矛盾 - しないこと(重複する判定は共通化を検討する) -- TUI completion がディレクトリ候補を出す挙動と整合すること(候補に出る - 以上、submit 時に黙って捨てるのは UX として不整合) - -## 完了条件 - -- 通常ディレクトリの FileRef が、`IsDirectory` Warn で黙って捨てられる - 現状の挙動を残していない -- 採用した挙動が `PodFsView` のテストで覆われている -- `Segment::FileRef` のドキュメント / コメントが新仕様に揃っている -- TUI completion とのギャップが解消されている(ディレクトリを候補から - 外すのか、submit でも扱うのか、いずれかに寄せる) - -## 範囲外 - -- 再帰的なディレクトリ走査、glob 展開、`tree` 風の深い表現 -- ディレクトリ内ファイルの自動 read 集約(auto-read / fs view 側の責務) -- symlink 経由のディレクトリ判定の刷新 - (`tickets/file-ref-symlink-diagnostics.md` 側で扱う) -- upload / attachment 上限の manifest 化(`tickets/manifest-output-upload-limits.md`) - -## 参照 - -- `crates/pod/src/fs_view.rs` `resolve_file_ref` / `list_file_completions` -- `crates/pod/src/pod.rs` `resolve_file_refs` -- `crates/tools/src/scoped_fs.rs` `read_bytes` -- `tickets/file-ref-symlink-diagnostics.md` -- `tickets/manifest-output-upload-limits.md` - -## Review -- 状態: Approve -- レビュー詳細: [./file-ref-directory.review.md](./file-ref-directory.review.md) -- 日付: 2026-05-12 diff --git a/tickets/file-ref-directory.review.md b/tickets/file-ref-directory.review.md deleted file mode 100644 index e7c4b784..00000000 --- a/tickets/file-ref-directory.review.md +++ /dev/null @@ -1,25 +0,0 @@ -# Review: Submit 時 FileRef でディレクトリを参照したときの挙動 - -## 前提・要件の確認 -- 通常ディレクトリの FileRef が `IsDirectory` Warn で黙って捨てられないこと: 満たされています。`PodFsView::resolve_file_ref` が symlink を含まない通常ディレクトリを検出し、`[Dir: ]` system message に展開する経路へ分岐しています(`crates/pod/src/fs_view.rs:124-143`, `crates/pod/src/fs_view.rs:240-304`)。Pod 側の alert 文脈も `[File]` / `[Dir]` 両対応に更新されています(`crates/pod/src/pod.rs:1019-1044`)。 -- 採用する挙動の明確化: 満たされています。通常ディレクトリは浅い entry listing として `[Dir: ]` で返す仕様になっており、再帰走査やファイル本文集約には踏み込んでいません(`crates/pod/src/fs_view.rs:114-123`, `crates/pod/src/fs_view.rs:240-304`)。 -- listing 上限: 満たされています。entry 件数は TUI completion と同じ `COMPLETION_LIMIT` を `DIR_FILE_REF_ENTRY_LIMIT` として使い、本文 byte 数は既存の `file_upload.max_bytes` を使う設計です(`crates/pod/src/fs_view.rs:21-25`, `crates/pod/src/fs_view.rs:278-291`, `crates/manifest/src/lib.rs:228-239`)。 -- 隠しファイル・gitignore・scope 外 entry の扱い: 満たされています。hidden / gitignore は特別扱いせず、scope 上 readable な直下 entry のみを返します(`crates/pod/src/fs_view.rs:117-123`, `crates/pod/src/fs_view.rs:249-269`)。テストでも hidden / gitignore を含め、deny された entry を除外する挙動が確認されています(`crates/pod/src/fs_view.rs:456-514`)。 -- symlink entry / symlink directory との整合: 満たされています。解決対象パス自体に symlink が含まれる場合は従来の `ScopedFs::read_bytes` 経路に委ね、通常ディレクトリ listing 内の symlink entry は `@` 付きで表示しています(`crates/pod/src/fs_view.rs:132-146`, `crates/pod/src/fs_view.rs:263-265`, `crates/pod/src/fs_view.rs:549-563`)。 -- TUI completion とのギャップ解消: 満たされています。completion がディレクトリ候補を出す前提を維持し、submit 側でも通常ディレクトリを扱う方向に寄せています。TUI 側コメントもその仕様に更新されています(`crates/tui/src/input.rs:35-37`)。 -- `Segment::FileRef` のドキュメント / コメント更新: 満たされています。Protocol 上の `Segment::FileRef` と flatten の説明が `[Dir: ]` listing に追従しています(`crates/protocol/src/lib.rs:127-130`, `crates/protocol/src/lib.rs:154-159`)。 - -## アーキテクチャ・スコープ -- FileRef 解決は既存の `PodFsView` に集約されており、Pod 本体には alert 化と attachment 組み立て以上の責務を増やしていません。層の置き方は妥当です。 -- TUI completion の挙動変更ではなく、submit 側の意味論を completion に合わせる実装で、チケットの UX ギャップに対して最小限です。 -- directory listing は浅い直下列挙に留まり、範囲外の再帰走査・glob 展開・ファイル本文集約には踏み込んでいません。 -- `ScopedFs::read_bytes` の symlink 診断経路を温存しつつ、通常ディレクトリだけを新仕様にしているため、`file-ref-symlink-diagnostics` 側の関心と衝突していません。 - -## 判断 -Approve — チケットで求められた通常ディレクトリ FileRef の仕様化・実装・テスト・コメント更新が揃っており、Blocking 指摘はありません。 - -## 確認 -- `cargo fmt --check` -- `cargo test -p pod` -- `cargo test -p pod fs_view::tests::resolve_file_ref -- --nocapture` -- `cargo test -p tui input::tests -- --nocapture` diff --git a/tickets/pod-cli-manifest-flags.md b/tickets/pod-cli-manifest-flags.md deleted file mode 100644 index 87018d97..00000000 --- a/tickets/pod-cli-manifest-flags.md +++ /dev/null @@ -1,57 +0,0 @@ -# Pod CLI: マニフェスト関連フラグの整理 - -## 背景 - -現状の `pod` CLI は `--user-manifest` / `--project` / `--overlay` の 3 つでカスケードを制御している(`crates/pod/src/main.rs`)。実運用で 2 つ足りない / 1 つ過剰: - -- **`--user-manifest` フラグが過剰**: 個人マシンの user 設定は本来「一度設定して忘れる」性質のもので、毎回 CLI で渡し直す動機が薄い。XDG / `~/.config/insomnia/manifest.toml` の自動探索 + 環境変数による上書きがあれば足りる -- **環境変数連携が無い**: 「user 設定を別の場所に置きたい人」が手段を持たない -- **単一ファイル起動 mode が無い**: 「カスケードを一切回さず、このマニフェスト 1 枚だけで起動したい」という用途(再現性確保、CI、検証目的等)がカバーされていない。`--overlay` は cascade の最上位レイヤとして追加されるだけで、user / project 層は依然として読み込まれる - -`--project` は workspace の起点を上書きする一般的なフラグなので(manifest 探索だけでなく将来の prompts ディレクトリ等にも効く)、そのまま残す。`--overlay` も意味的に「cascade の最上位レイヤを差し込む」で正しいのでそのまま。 - -## 要件 - -### `--user-manifest` の削除と env への置換 - -`--user-manifest ` フラグは削除し、代わりに `INSOMNIA_USER_MANIFEST` 環境変数で user manifest のパスを上書きできるようにする。 - -- env 未指定: 既存の XDG 自動探索(`manifest::user_manifest_path()`) -- env 指定: そのパスを user manifest として読む(ファイル不在はエラー、`with_user_manifest` 相当) -- env が空文字列なら未指定扱い - -`pod/src/main.rs` から `user_manifest` フィールドを除き、`build_factory` 内の分岐も env 読み取りに置き換える。 - -### `--manifest ` の新設 - -カスケードを一切回さず、指定ファイル 1 枚だけを manifest として読み込んで Pod を起動する mode。 - -- `--project` / `--overlay` / `INSOMNIA_USER_MANIFEST` のいずれとも **併用不可**(clap の `conflicts_with` + 環境変数の事前チェック) -- 内部的には `PodFactory` の cascade 経路を通さず、`PodManifest::from_toml`(既存)の直接ルートで構築する -- prompt loader 等 cascade 経由で組まれるものは、単一ファイル mode 用に最小構成で組み直す - -### 既存挙動の保持 - -- `--project` / `--overlay`: 変更なし -- `--adopt` / `--callback`: 変更なし(spawn 子 Pod 用、本フラグ群とは独立) -- 引数なしで `pod` を叩くと従来通り XDG → walk-up → 起動 - -## 範囲外 - -- `--no-user-manifest` / `--no-project-manifest` のような per-layer 無効化フラグ。`--manifest` で「全層無効化して 1 枚だけ」のケースはカバー出来るので、「user 層だけ無視して project 層は活かす」のような細粒度の需要が出てから別途 -- `INSOMNIA_PROJECT_ROOT` 等、`--project` 側の env 連携(`--project` 自体の責務見直しと一緒に検討すべき領域なので、本チケットでは触らない) -- TUI spawn UI(`tickets/tui-pod-spawn-ui.md`)の挙動変更。spawn UI が組む overlay 経路は本チケット完了後も互換のまま動く - -## 完了条件 - -- `--user-manifest` フラグが pod CLI から消えている -- `INSOMNIA_USER_MANIFEST= pod` で user manifest のパスを上書きして起動できる -- `pod --manifest ` が単一ファイル mode で起動し、user / project / overlay 層は読まれない -- `--manifest` を `--project` / `--overlay` と併用しようとすると clap が拒否する -- `INSOMNIA_USER_MANIFEST` がセットされた状態で `--manifest` を使おうとするとエラーになる -- 既存の `pod --overlay ` 起動(`start_pod.local.fish` 経由)が引き続き動く - -## Review -- 状態: Approve with follow-up -- レビュー詳細: [./pod-cli-manifest-flags.review.md](./pod-cli-manifest-flags.review.md) -- 日付: 2026-05-12 diff --git a/tickets/pod-cli-manifest-flags.review.md b/tickets/pod-cli-manifest-flags.review.md deleted file mode 100644 index 2de668fd..00000000 --- a/tickets/pod-cli-manifest-flags.review.md +++ /dev/null @@ -1,23 +0,0 @@ -# Review: Pod CLI: マニフェスト関連フラグの整理 - -## 前提・要件の確認 -- `--user-manifest ` の削除: 満たされている。`Cli` から `user_manifest` フィールドは消え、代わりに `manifest` / `project` / `overlay` が定義されている(`crates/pod/src/main.rs:17-32`)。`--user-manifest` が clap 上 unknown argument になるテストも追加されている(`crates/pod/src/main.rs:279-283`)。 -- `INSOMNIA_USER_MANIFEST` による user manifest override: 満たされている。`resolve_manifest` が `std::env::var_os(USER_MANIFEST_ENV)` を読み、非空の場合のみ `PathBuf` に変換して `with_user_manifest` 経路へ渡している(`crates/pod/src/main.rs:59-91`, `crates/pod/src/main.rs:102-115`)。明示 path は既存の `with_user_manifest` により missing file が error になる(`crates/pod/src/factory.rs:123-131`)。override のテストもある(`crates/pod/src/main.rs:332-349`)。 -- env 空文字列は未指定扱い: 満たされている。`OsString::is_empty()` の場合 `None` に落としている(`crates/pod/src/main.rs:84-91`)。`--manifest` との併用でも空 env は許可されるテストがある(`crates/pod/src/main.rs:317-330`)。 -- `--manifest ` の単一ファイル mode: 満たされている。`--manifest` 指定時は factory/cascade 経路へ進まず `load_single_manifest` に return し、`PodManifest::from_toml` と `PromptLoader::builtins_only()` で構築している(`crates/pod/src/main.rs:69-75`, `crates/pod/src/main.rs:94-99`)。 -- `--manifest` と `--project` / `--overlay` の併用不可: 満たされている。clap の `conflicts_with_all = ["project", "overlay"]` が付いており(`crates/pod/src/main.rs:18-21`)、conflict テストもある(`crates/pod/src/main.rs:285-301`)。 -- `--manifest` と `INSOMNIA_USER_MANIFEST` の併用不可: 満たされている。非空 env がある場合は `load_single_manifest` 前に error を返す(`crates/pod/src/main.rs:67-75`)。テストもある(`crates/pod/src/main.rs:303-315`)。 -- 既存の `--project` / `--overlay` / `--adopt` / `--callback` 挙動保持: 満たされている。cascade mode 側では従来通り project 探索と overlay 適用を行い(`crates/pod/src/main.rs:117-130`)、Pod 生成側の adopt/callback/session 分岐は flag 整理の外側で維持されている(`crates/pod/src/main.rs:173-204`)。 -- `pod --overlay ` 起動の互換: 満たされている。CLI 上 `--overlay` は残り、`build_factory_with_user_manifest_path` で従来通り `with_overlay_toml` に渡される(`crates/pod/src/main.rs:29-32`, `crates/pod/src/main.rs:126-130`)。手元の `start_pod.local.fish` は `--overlay` のみを使っており、削除された `--user-manifest` には依存していない(`/home/hare/Projects/insomnia/start_pod.local.fish:5`)。 - -## アーキテクチャ・スコープ -- 変更は `crates/pod/src/main.rs` の CLI entrypoint に閉じており、manifest cascade 本体や `PodFactory` の責務を拡張していない。`--manifest` は ticket 指定通り `PodManifest::from_toml` の直接経路で、cascade mode は既存 factory を使い続けるため、層境界は保たれている。 -- 単一ファイル mode の prompt loader は `PromptLoader::builtins_only()` として最小構成で組まれており、user / workspace prompt layer や pack file の自動探索を持ち込んでいない(`crates/pod/src/main.rs:94-99`)。 -- 追加依存や crate 構成変更はなく、ticket scope に対して過剰な実装は見当たらない。 - -## 指摘事項 -### Non-blocking / Follow-up -- `docs/pod-factory.md` の CLI 説明が旧仕様のまま残っている — `--user-manifest` を掲載し、`--manifest` と `INSOMNIA_USER_MANIFEST` を説明していない(`docs/pod-factory.md:300-312`)。ticket の完了条件ではないため blocking にはしないが、利用者向けドキュメントとして追随更新した方がよい。 - -## 判断 -Approve with follow-up — ticket の完了条件は満たされており blocking はないが、既存ドキュメントに旧 CLI フラグが残っているため follow-up として扱う。