close: complete pod manifest and file ref tickets

This commit is contained in:
Keisuke Hirata 2026-05-13 06:30:45 +09:00
parent 418451ebf8
commit b0c91049b1
No known key found for this signature in database
5 changed files with 0 additions and 176 deletions

View File

@ -4,7 +4,6 @@
- AI maintainer 用 WorkItem / Thread 抽象 → [tickets/maintainer-work-items.md](tickets/maintainer-work-items.md) - 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) - 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) - 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: 空応答ターン (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: 任意ターンからの 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) - 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) - 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-empty-turn-restore.md](tickets/tui-empty-turn-restore.md)
- セッションコンテキスト長 / ウィンドウ占有率の常時表示 → [tickets/tui-context-usage-indicator.md](tickets/tui-context-usage-indicator.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) - 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) - extract / consolidation 監査ログ → [tickets/memory-audit-log.md](tickets/memory-audit-log.md)

View File

@ -1,69 +0,0 @@
# Submit 時 FileRef でディレクトリを参照したときの挙動
## 背景
submit 時に `Segment::FileRef { path }``crates/pod/src/fs_view.rs`
`PodFsView::resolve_file_ref` でファイル本文として読まれ、`[File: <path>]` 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: <path>]` 等の 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

View File

@ -1,25 +0,0 @@
# Review: Submit 時 FileRef でディレクトリを参照したときの挙動
## 前提・要件の確認
- 通常ディレクトリの FileRef が `IsDirectory` Warn で黙って捨てられないこと: 満たされています。`PodFsView::resolve_file_ref` が symlink を含まない通常ディレクトリを検出し、`[Dir: <path>]` 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: <path>]` で返す仕様になっており、再帰走査やファイル本文集約には踏み込んでいません(`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: <path>]` 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`

View File

@ -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 <PATH>` フラグは削除し、代わりに `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 <PATH>` の新設
カスケードを一切回さず、指定ファイル 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=<path> pod` で user manifest のパスを上書きして起動できる
- `pod --manifest <path>` が単一ファイル mode で起動し、user / project / overlay 層は読まれない
- `--manifest``--project` / `--overlay` と併用しようとすると clap が拒否する
- `INSOMNIA_USER_MANIFEST` がセットされた状態で `--manifest` を使おうとするとエラーになる
- 既存の `pod --overlay <toml>` 起動(`start_pod.local.fish` 経由)が引き続き動く
## Review
- 状態: Approve with follow-up
- レビュー詳細: [./pod-cli-manifest-flags.review.md](./pod-cli-manifest-flags.review.md)
- 日付: 2026-05-12

View File

@ -1,23 +0,0 @@
# Review: Pod CLI: マニフェスト関連フラグの整理
## 前提・要件の確認
- `--user-manifest <PATH>` の削除: 満たされている。`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 <PATH>` の単一ファイル 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 <toml>` 起動の互換: 満たされている。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 として扱う。