Compare commits
3 Commits
ec8a4582b4
...
787abf4f7d
| Author | SHA1 | Date | |
|---|---|---|---|
| 787abf4f7d | |||
| 2109ed6403 | |||
| 3d42c64238 |
|
|
@ -24,11 +24,12 @@ insomnia は環境再現・コンテナ管理・VCS 統合などを自身の責
|
||||||
|
|
||||||
## Pod
|
## Pod
|
||||||
|
|
||||||
独立したエージェントの実行単位。llm-worker の Worker をラップし、マニフェストによる宣言的構成とディレクトリスコープを加える。
|
独立したエージェントの実行単位。llm-worker の Worker をラップし、マニフェストによる宣言的構成、ディレクトリスコープ、Pod 名に紐づく永続状態を加える。
|
||||||
|
|
||||||
- 1 Pod = 1 プロセス = 1 セッション
|
- 1 live Pod process は 1 Pod name/current state を所有する
|
||||||
- マニフェスト(TOML)から完結構築できる
|
- 会話の永続化は `session-store` の `session_id` / `segment_id` ログ、Pod 名の current state は `pod-store` metadata が担う
|
||||||
- scope で書き込み可能なパスを制限(読み取りは自由)
|
- マニフェストまたは profile から完結構築できる
|
||||||
|
- scope で読み取り・書き込み可能なパスを制限する
|
||||||
- 独立した socket サーバーを持ち、Client (TUI / GUI) が接続して操作する
|
- 独立した socket サーバーを持ち、Client (TUI / GUI) が接続して操作する
|
||||||
|
|
||||||
### 実行ループ
|
### 実行ループ
|
||||||
|
|
@ -50,19 +51,28 @@ Client → Method::Run { input }
|
||||||
|
|
||||||
### コンテキスト管理
|
### コンテキスト管理
|
||||||
|
|
||||||
- **Prune**: 古い tool result の content を除去(summary は残す)。`pre_llm_request` で毎回判定
|
- **Prune**: 古い tool result の content を除去(summary は残す)。LLM request context だけを加工し、永続 history 本体は変更しない
|
||||||
- **Compact**: 履歴全体を要約して圧縮。`input_tokens` が閾値を超えたとき、`PreRequestAction::Yield` で Worker を一旦中断し、Pod 側で要約 → 新セッションとして再開
|
- **Compact**: 履歴 prefix を要約し、同じ `session_id` 配下の新 `segment_id` へ rotate する。`SegmentStart.compacted_from` が元 segment を参照し、Pod metadata の active pointer は新 segment を指す
|
||||||
- サーキットブレーカー: compact が3回連続失敗したら無効化
|
- サーキットブレーカー: compact が3回連続失敗したら無効化
|
||||||
|
|
||||||
## Protocol
|
## Protocol
|
||||||
|
|
||||||
Pod の制御・監視に使う JSONL ベースのメッセージプロトコル。トランスポートに依存しない。
|
Pod の制御・監視に使う JSONL ベースのメッセージプロトコル。トランスポートに依存しない。正確な wire enum は `crates/protocol/src/lib.rs::{Method, Event}` を正とし、この節はカテゴリの目次として扱う。
|
||||||
|
|
||||||
- **Method** (Client → Pod): `Run` / `Notify` / `Resume` / `Cancel` / `Shutdown` / `GetHistory`
|
- **Client → Pod (`Method`)**
|
||||||
- **Event** (Pod → Client, broadcast): `TurnStart` / `TurnEnd` / `TextDelta` / `ToolCallStart` / `ToolCallArgsDelta` / `ToolCallDone` / `ToolResult` / `Usage` / `RunEnd` / `Error` / `History` / `Notification` / `Shutdown`
|
- turn 制御: `Run`, `Resume`, `Cancel`, `Pause`, `Shutdown`
|
||||||
- リクエストとレスポンスの紐付けはしない。Pod の状態遷移(イベント)を見れば何が起きているか分かる
|
- context/session 制御: `Compact`, `ListRewindTargets`, `RewindTo`
|
||||||
- イベントは全リスナーに broadcast
|
- typed injection / child lifecycle: `Notify`, `PodEvent`
|
||||||
- 操作の競合は先勝ち(run 中に別の run → AlreadyRunning エラー)
|
- client 補助: `ListCompletions`
|
||||||
|
- Pod visibility / attach: `ListVisiblePods`, `InspectPod`, `AttachOrRestorePod`
|
||||||
|
- **Pod → Client (`Event`)**
|
||||||
|
- accepted input / history seed: `Snapshot`, `UserMessage`, `SystemItem`, `SegmentRotated`
|
||||||
|
- generation stream: `TurnStart`, `TurnEnd`, `LlmCallStart`, `LlmCallEnd`, retry/continuation events, `Text*`, `Thinking*`, `ToolCall*`, `ToolResult`, `Usage`, `RunEnd`
|
||||||
|
- control replies: completions, rewind, visible Pod / inspect / attach results
|
||||||
|
- operational status: `Status`, `Alert`, `MemoryWorker`, `Compact*`, `Error`, `Shutdown`
|
||||||
|
- リクエストとレスポンスの紐付けを一般化した RPC にはしない。多くの状態は broadcast event と Pod status で観測する
|
||||||
|
- 一部の reply(例: completions)は要求 socket にだけ返る。broadcast event と request-local reply の違いは enum variant のコメントを正とする
|
||||||
|
- 操作の競合は先勝ち(run 中に別の run → `AlreadyRunning` エラー)
|
||||||
|
|
||||||
## マニフェストとファクトリ
|
## マニフェストとファクトリ
|
||||||
|
|
||||||
|
|
@ -116,23 +126,28 @@ Pod が操作できるファイルパスの制御。
|
||||||
- `allow` ルールで読み取り・書き込みを許可、`deny` ルールで制限
|
- `allow` ルールで読み取り・書き込みを許可、`deny` ルールで制限
|
||||||
- effective permission = allow - deny
|
- effective permission = allow - deny
|
||||||
- `recursive = false` で直下のみに制限可能(summary に `[non-recursive]` マーカー)
|
- `recursive = false` で直下のみに制限可能(summary に `[non-recursive]` マーカー)
|
||||||
- scope 排他: Pod 間の write 衝突は scope lock file (`$XDG_RUNTIME_DIR/insomnia/scope.lock`) で検出。scope 分譲(spawn 時に譲渡、終了時に返却)の記録にも使う
|
- scope 排他: Pod 間の write 衝突は runtime registry / scope lock で検出する。child Pod へ委譲した write scope は親の effective scope から delegated-out deny として差し引かれ、child 停止・prune 時に reclaim される
|
||||||
|
|
||||||
## セッション永続化
|
## セッション永続化
|
||||||
|
|
||||||
- append-only JSONL ログ。1 エントリ = 1 行
|
- `session-store` は append-only JSONL segment log。1 `LogEntry` = 1 行
|
||||||
- SHA-256 チェーンでエントリの整合性を保証
|
- `SessionId` は論理会話の fork-tree root、`SegmentId` はその中の現在の書き込み先 segment
|
||||||
- ログ再生で Worker の状態を完全復元(スナップショット不要)
|
- fresh conversation だけが新 `SessionId` を作る。compact / fork は同じ `SessionId` 配下に新 `SegmentId` を作り、`SegmentStart.{compacted_from,forked_from}: SegmentOrigin` で出自を持つ
|
||||||
- Compact 時に新セッションを開始し、旧セッションへのリンクを保持
|
- segment log の先頭は `LogEntry::SegmentStart`。以降に `Invoke`, `UserInput`, `AssistantItem`, `ToolResult`, `SystemItem`, `TurnEnd`, `RunCompleted` / `RunErrored`, `ConfigChanged`, `LlmUsage`, `Extension` などを append する
|
||||||
|
- replay は segment log から Worker state を再構成する。lineage は entry hash ではなく `SegmentOrigin.at_turn_index` と segment id で参照する
|
||||||
|
- Pod 名の durable current state(active pointer、resolved manifest snapshot、spawned child delegation/reclaim)は `pod-store` metadata が担う。socket path や runtime mirror は liveness authority ではない
|
||||||
|
|
||||||
## 組み込みツール
|
## 組み込みツール
|
||||||
|
|
||||||
| ツール | 概要 |
|
正確な callable set と description は ToolRegistry / manifest permission / scope / profile に依存する。高レベルには以下のカテゴリを持つ。
|
||||||
| ------ | ------------------------------------------ |
|
|
||||||
| Read | ファイル内容の読み取り |
|
|
||||||
| Write | ファイルの新規作成・上書き |
|
|
||||||
| Edit | 既存ファイルの部分編集(事前 Read が必要) |
|
|
||||||
| Glob | ファイル名パターンマッチ |
|
|
||||||
| Grep | ファイル内容の正規表現検索 |
|
|
||||||
|
|
||||||
すべて scope の permission チェックを経由。`ScopedFs` が書き込み制限を、`Tracker` がセッション内のコンテンツハッシュ追跡を行う。
|
| カテゴリ | 例 | 概要 |
|
||||||
|
|---|---|---|
|
||||||
|
| File / shell | `Read`, `Write`, `Edit`, `Glob`, `Grep`, `Bash` | workspace ファイル操作と shell 実行。file tools は `ScopedFs` と read-before-edit tracker を通る。`Bash` は permission policy と出力退避で制御する |
|
||||||
|
| Task | `TaskCreate`, `TaskUpdate`, `TaskList`, `TaskGet` | セッション内の短期 task 状態管理 |
|
||||||
|
| Memory / Knowledge | `MemoryQuery`, `MemoryRead`, `MemoryWrite`, `MemoryEdit`, `MemoryDelete`, `KnowledgeQuery` | manifest の memory 設定が有効な時に登録される durable memory / knowledge 操作 |
|
||||||
|
| Pod orchestration | `SpawnPod`, `SendToPod`, `ReadPodOutput`, `StopPod`, `ListPods` | child Pod の起動・通信・停止・一覧 |
|
||||||
|
| Visible Pod state | `ListVisiblePods`, `InspectPod`, `AttachOrRestorePod` | durable Pod state と visibility に基づく Pod inspection / attach / restore |
|
||||||
|
| Web | `WebSearch`, `WebFetch` | manifest/env で明示設定された provider 経由の bounded web access |
|
||||||
|
|
||||||
|
すべての tool call は manifest tool permission と scope/policy のチェックを通る。ファイル write scope、Pod delegation、memory layout、web provider 設定はそれぞれ別の authority を持ち、UI 表示だけで権限を広げない。
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ CompactInterceptor (pre_llm_request) ← safety net
|
||||||
→ Worker が WorkerResult::Yielded で正常終了
|
→ Worker が WorkerResult::Yielded で正常終了
|
||||||
↓
|
↓
|
||||||
Pod::handle_worker_result
|
Pod::handle_worker_result
|
||||||
→ persist_turn(旧セッションに記録)
|
→ turn 結果を現在 segment log に記録
|
||||||
→ compact() → resume()
|
→ compact() で同じ session_id 内の新 segment へ rotate → resume()
|
||||||
|
|
||||||
[ターンの合間 — 次の Pod::run 冒頭]
|
[ターンの合間 — 次の Pod::run 冒頭]
|
||||||
Pod::try_pre_run_compact ← proactive
|
Pod::try_pre_run_compact ← proactive
|
||||||
|
|
@ -97,21 +97,29 @@ PreRequestAction::Cancel → WorkerError::Aborted → エラー
|
||||||
|
|
||||||
- **サーキットブレーカー**: 3回連続 compact 失敗で無効化 (`CompactState::disabled`)
|
- **サーキットブレーカー**: 3回連続 compact 失敗で無効化 (`CompactState::disabled`)
|
||||||
- **Thrash 検出**: compact 直後に再び閾値超過 → `PodError::CompactThrash`
|
- **Thrash 検出**: compact 直後に再び閾値超過 → `PodError::CompactThrash`
|
||||||
- **Yield 前の永続化**: `persist_turn` を compact の前に実行。失敗しても旧セッションにデータが残る
|
- **Yield 前後の永続化**: Worker が `Yielded` で抜けた turn は現在 segment log に記録してから compact する。compact が失敗しても元 segment の状態は残る
|
||||||
|
|
||||||
### セッション管理
|
### セッション管理
|
||||||
|
|
||||||
compact は fork と同じ構造。旧セッションを保全し、新 SessionId で圧縮後のセッションを開始。
|
compact は「新 SessionId を作る」操作ではなく、同じ `session_id` 配下で active `segment_id` を切り替える操作。
|
||||||
|
|
||||||
```
|
```
|
||||||
旧セッション (abc-123):
|
session_id = abc-123
|
||||||
[...entries...] → Outcome::Yielded (interrupted=true) ← そのまま残る
|
|
||||||
|
|
||||||
新セッション (def-456):
|
segment old:
|
||||||
[SessionStart { compacted_from: (abc-123, entryN.hash), history: [要約 + 直近] }] → ...
|
SegmentStart { origin: fresh/fork/... }
|
||||||
|
[...entries...]
|
||||||
|
RunCompleted { result: Yielded }
|
||||||
|
|
||||||
|
segment new:
|
||||||
|
SegmentStart { compacted_from: SegmentOrigin { segment_id: old, at_turn_index: N } }
|
||||||
|
[system prompt]
|
||||||
|
[system: 構造化要約]
|
||||||
|
[system: retained tail / auto-read / references]
|
||||||
|
...以後の turn を append
|
||||||
```
|
```
|
||||||
|
|
||||||
`SessionStart` に `forked_from` / `compacted_from` フィールドで出自を追跡可能。
|
`SegmentStart.compacted_from` / `forked_from` が lineage を追跡する。Pod 名からの resume は `pod-store` metadata の active pointer が現在の `(session_id, segment_id)` を指し、conversation/history の replay は `session-store` の segment log から行う。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -220,7 +228,7 @@ write_summary(text) — 構造化要約を出力/上書き
|
||||||
- `final_reserve_tokens` を割った後は `write_summary` 以外の探索 tool call に synthetic error を返し、最終 summary の余白を守る
|
- `final_reserve_tokens` を割った後は `write_summary` 以外の探索 tool call に synthetic error を返し、最終 summary の余白を守る
|
||||||
- `worker_context_max_tokens` 超過は最後の hard stop
|
- `worker_context_max_tokens` 超過は最後の hard stop
|
||||||
5. ターン終了時に write_summary 未呼び出し or read_required 空(かつファイル操作履歴がある場合)→ 追加プロンプトで促す
|
5. ターン終了時に write_summary 未呼び出し or read_required 空(かつファイル操作履歴がある場合)→ 追加プロンプトで促す
|
||||||
6. `summary_max_tokens` と `result_context_max_tokens` で compact 結果を検証してから新 session を作る
|
6. `summary_max_tokens` と `result_context_max_tokens` で compact 結果を検証してから新 segment を作り、Pod metadata の active pointer を更新する
|
||||||
|
|
||||||
### 構造化要約の要件
|
### 構造化要約の要件
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,372 +1,210 @@
|
||||||
# AI maintainer 運用設計
|
# AI Maintainer Workflow 設計
|
||||||
|
|
||||||
## 位置づけ
|
|
||||||
|
|
||||||
この文書は、insomnia を単なる Coding Agent ではなく、開発プロジェクトを継続的に運用する AI maintainer として使うための上位設計である。
|
|
||||||
|
|
||||||
`/auto-maintain` はこの設計の最初の実行形であり、TODO / tickets から小さな実装作業を選んで実装・レビューを orchestration する Workflow に留まる。本設計はその一段上で、設計相談、ticket 整理、実装委譲、レビュー、運用課題の記録、改善提案までを一つの maintainer loop として扱う。
|
|
||||||
|
|
||||||
ただし、これは unattended 自動開発ではない。最終判断、危険な権限拡大、push、未合意の要件変更は人間に戻す。
|
|
||||||
|
|
||||||
また、このフレームワークの対象はプロジェクトの新規立ち上げ・設計ではなく、ある程度タスクの関心対象が分化し、機能追加・課題対応をイテレーションするフェーズにあるプロジェクトである。
|
|
||||||
|
|
||||||
## 目的
|
## 目的
|
||||||
|
|
||||||
AI maintainer の目的は、コードを書くことそのものではなく、開発状態を前に進めることである。
|
AI maintainer は、insomnia リポジトリの開発を継続的に進めるための orchestration role である。単発の `/auto-maintain` より広く、設計相談、work item 整理、実装委譲、レビュー、運用課題の記録、改善提案を一つの maintainer loop として扱う。
|
||||||
|
|
||||||
具体的には以下を担う。
|
`/auto-maintain` はこの設計の限定実行形であり、`tickets.sh` / `work-items/` から小さな実装作業を選んで実装・レビューを orchestration する Workflow に留まる。
|
||||||
|
|
||||||
- TODO / tickets / docs / git history から現在の開発状態を把握する
|
## 正本と権限境界
|
||||||
- 要件が十分に固まった作業を実装可能な単位へ落とす
|
|
||||||
- 設計判断が必要な作業を実装前に人間へ戻す
|
|
||||||
- 実装 Pod / reviewer Pod / 親 Pod 自身を使い分ける
|
|
||||||
- 実装結果を ticket の完了条件に照らして review する
|
|
||||||
- merge / ticket lifecycle / TODO 整理の順序と branch placement を守る
|
|
||||||
- 作業中に見つかった運用上の障壁を `docs/report/` に残す
|
|
||||||
- 繰り返し発生する作業を Workflow / Knowledge / ticket 候補として提案する
|
|
||||||
|
|
||||||
## 役割モデル
|
現在の作業管理の正本は `tickets.sh` と `work-items/` である。古い `TODO.md` / legacy `tickets/` directory を前提にした運用は superseded。
|
||||||
|
|
||||||
### Human maintainer
|
- work item の作成・コメント・レビュー・状態変更・完了は原則 `./tickets.sh` 経由で行う
|
||||||
|
- `work-items/{open,pending,closed}/<id>/item.md` は要件・受け入れ条件の正本
|
||||||
|
- `thread.md` は計画・判断・レビュー・実装報告の時系列 thread
|
||||||
|
- `resolution.md` は close 時の完了記録
|
||||||
|
- 時系列と状態遷移の最終根拠は git history
|
||||||
|
- `docs/report/` は観測・所感・改善候補の記録であり、最新仕様の authority ではない
|
||||||
|
- `.insomnia/memory` は個人/生成 state であり、project record の正本ではない
|
||||||
|
|
||||||
人間は設計上の最終責任者である。
|
AI maintainer は project record を勝手に膨らませない。明確な実装単位は work item 化し、小粒な所見は `KNOWN_ISSUES.md`、ドッグフーディング上の障壁やツール問題は `docs/report/` に記録する。
|
||||||
|
|
||||||
|
## Role model
|
||||||
|
|
||||||
|
### Maintainer Pod
|
||||||
|
|
||||||
|
人間と対話する親 Pod。設計判断、作業選定、scope 委譲、レビュー統括、merge / close の判断を担う。
|
||||||
|
|
||||||
主な責務:
|
主な責務:
|
||||||
|
|
||||||
- プロダクト方針、設計方針、優先順位の決定
|
- `work-items/`, `KNOWN_ISSUES.md`, `docs/`, git history, worktree 状態を読んで現在地を把握する
|
||||||
- AI が提示した選択肢の採否
|
- 作業可能な work item と設計相談が必要な work item を分ける
|
||||||
- scope / permission / history persistence など安全モデルに関わる判断
|
- child worktree / child Pod に実装を委譲する
|
||||||
- push や外部公開に関わる判断
|
- 実装結果を work item の背景・要件・受け入れ条件に照らして review する
|
||||||
- AI maintainer の運用方針そのものの変更承認
|
- review / close / merge の branch placement を守る
|
||||||
|
- 人間に判断が必要な境界で止まる
|
||||||
|
|
||||||
### AI maintainer / orchestrator
|
Maintainer Pod は「便利だから」project record を書き換えない。新規 work item 作成、既存 work item の大幅変更、close、merge、commit などは、ユーザー指示または会話上の合意に基づいて行う。
|
||||||
|
|
||||||
親 Pod が担う役割。コードを書くこともできるが、主な責務は制御面である。
|
|
||||||
|
|
||||||
主な責務:
|
|
||||||
|
|
||||||
- 状態把握: `TODO.md`, `tickets/`, `docs/`, git history, worktree 状態を読む
|
|
||||||
- 作業選定: 実装可能な ticket と設計相談が必要な ticket を分ける
|
|
||||||
// ↑ について、設計相談も含めてOrchestrator-Coder間で行わせて良いのでは
|
|
||||||
- 計画: 作業範囲、検証方法、child worktree / Pod scope を決める
|
|
||||||
- 委譲: 実装 Pod / reviewer Pod を spawn し、必要最小 scope を渡す
|
|
||||||
- 監督: Pod 出力、worktree diff、test 結果を確認する
|
|
||||||
- レビュー: ticket の背景・要件・完了条件に対して実装を確認する
|
|
||||||
- lifecycle: review artifact、ticket 完了、TODO 更新、merge の branch placement を守る
|
|
||||||
- 報告: 完了内容、検証結果、未解決事項、次の人間判断をまとめる
|
|
||||||
|
|
||||||
### Implementation Pod
|
### Implementation Pod
|
||||||
|
|
||||||
狭い write scope を持つ作業者である。実装 Pod は ticket と worktree を渡され、その範囲で実装・検証・報告を行う。
|
狭い write scope を持つ作業者。対象 worktree と work item を渡され、その範囲で実装・検証・報告を行う。
|
||||||
|
|
||||||
禁止事項:
|
|
||||||
|
|
||||||
- `/auto-maintain` など上位 Workflow を実行しない
|
|
||||||
- ticket / TODO / review artifact / docs/report を勝手に編集しない
|
|
||||||
- git commit / merge / push をしない
|
|
||||||
- scope / permission / history persistence を勝手に再設計しない
|
|
||||||
|
|
||||||
### Reviewer Pod
|
|
||||||
|
|
||||||
原則 read-only の検証者である。実装 Pod とは分けるのが望ましいが、小さい作業や scope 衝突がある場合は親 Pod が review してよい。
|
|
||||||
|
|
||||||
主な確認項目:
|
|
||||||
|
|
||||||
- ticket の要件を満たしているか
|
|
||||||
- 既存設計を歪めていないか
|
|
||||||
- 不要な抽象化や過剰実装がないか
|
|
||||||
- test / build の結果が妥当か
|
|
||||||
- ticket lifecycle 上、どの branch に review / completion commit を置くべきか
|
|
||||||
|
|
||||||
## 状態と成果物
|
|
||||||
|
|
||||||
AI maintainer は、状態を会話内だけに閉じ込めない。継続的な運用に必要な情報は、用途ごとに既存のファイルへ残す。
|
|
||||||
|
|
||||||
### `TODO.md`
|
|
||||||
|
|
||||||
未完了 ticket の一覧。1 ticket = 1 行。作業選定の入口であり、完了したら feature branch 側で該当行を削除する。
|
|
||||||
|
|
||||||
AI maintainer は TODO と ticket の不整合を見つけた場合、勝手に ticket を作成・削除せず、人間に報告する。
|
|
||||||
|
|
||||||
### `tickets/`
|
|
||||||
|
|
||||||
実装可能な要件単位。作業の完了条件は ticket が基準になる。
|
|
||||||
|
|
||||||
AI maintainer は ticket を読むだけでなく、git history 上の作成・更新・削除も参照して前提を把握する。
|
|
||||||
|
|
||||||
ただし、`tickets/` は長い設計相談、実装 Pod の報告、review 指摘、修正依頼、lease、artifact を thread として扱うには弱い。長期的には WorkItem / Thread 抽象を導入し、ticket は WorkItem の linked artifact または backend view として扱う。
|
|
||||||
|
|
||||||
### WorkItem / Thread
|
|
||||||
|
|
||||||
AI maintainer の上位運用単位。`tickets/` より広く、design / feature / refactor / ops / investigation を含む project coordination record として扱う。
|
|
||||||
|
|
||||||
WorkItem は Git に依存しない domain model として定義し、初期 backend は repo-managed な `work-items/` または `issues/` directory にできるようにする。正本として残すのは description、acceptance criteria、discussion thread、decision、review、status history、linked branch / worktree / commit、durable artifact metadata である。
|
|
||||||
|
|
||||||
`.insomnia` に WorkItem 正本は置かない。`.insomnia/maintainer/` は Pod run、lease cache、polling cursor、temporary inbox、local-only trial log など runtime coordination state の置き場とする。
|
|
||||||
|
|
||||||
将来 network 越し workspace / remote maintainer hub を導入する場合も、AI maintainer は file path ではなく `WorkItemStore` / `LeaseStore` 相当の interface を通す。remote backend は後回しにするが、初期 file backend の時点で Git 前提の API に固定しない。
|
|
||||||
|
|
||||||
### `tickets/*.review.md`
|
|
||||||
|
|
||||||
review の判断根拠。review artifact は対象 feature branch 側に commit する。`develop` の first-parent に review / completion commit を直接置かない。
|
|
||||||
|
|
||||||
### `docs/plan/`
|
|
||||||
|
|
||||||
長期設計、概念設計、運用設計を置く。実装 ticket より上位の合意形成に使う。
|
|
||||||
|
|
||||||
本ファイルは `/auto-maintain` 単体ではなく、AI maintainer 全体の設計を置く場所である。
|
|
||||||
|
|
||||||
### `docs/report/`
|
|
||||||
|
|
||||||
実際の運用で発生した障壁や改善案を残す。明確な力不足、tool 問題、workflow 問題、ユーザーからの指示があった場合に作る。
|
|
||||||
|
|
||||||
report は愚痴ではなく、後から改善 ticket / Workflow 改訂 / Knowledge 化へつなげる観測記録である。
|
|
||||||
|
|
||||||
### `.insomnia/workflow/`
|
|
||||||
|
|
||||||
実行可能な手順。Workflow は人間が書く、または AI が提案して人間が承認する。AI が勝手に自律生成しない。
|
|
||||||
|
|
||||||
### memory / Knowledge
|
|
||||||
|
|
||||||
作業中の判断や設計を再利用可能な知識として扱う。ただし、turn を跨ぐ根拠を history に残さず context だけへ差し込むことは禁止する。
|
|
||||||
|
|
||||||
## 権限モード
|
|
||||||
|
|
||||||
AI maintainer の運用は、作業ごとに権限モードを明示する。
|
|
||||||
|
|
||||||
### Mode 0: Consultation
|
|
||||||
|
|
||||||
設計相談・方針整理のみ。ファイル編集しない。
|
|
||||||
|
|
||||||
使う場面:
|
|
||||||
|
|
||||||
- 要件が曖昧
|
|
||||||
- 複数の設計方針が自然に導ける
|
|
||||||
- ticket 化する前に合意したい
|
|
||||||
|
|
||||||
### Mode 1: Documentation / ticket maintenance
|
|
||||||
|
|
||||||
`docs/`, `tickets/`, `TODO.md` など制御面だけを編集する。実装コードは触らない。
|
|
||||||
|
|
||||||
使う場面:
|
|
||||||
|
|
||||||
- 設計文書作成
|
|
||||||
- ticket の詳細化
|
|
||||||
- report 作成
|
|
||||||
- TODO と ticket の整合確認
|
|
||||||
|
|
||||||
注意点:
|
|
||||||
|
|
||||||
- 新 ticket 作成や既存 ticket の大幅変更は、人間の合意後に行う
|
|
||||||
- 完了削除は対象 feature branch 側で行う
|
|
||||||
|
|
||||||
### Mode 2: Delegated implementation
|
|
||||||
|
|
||||||
child worktree を作り、実装 Pod に狭い write scope を渡して実装させる。親 Pod は orchestration と review を行う。
|
|
||||||
|
|
||||||
使う場面:
|
|
||||||
|
|
||||||
- 要件と完了条件が明確
|
|
||||||
- 影響範囲が限定されている
|
|
||||||
- test / build で確認可能
|
|
||||||
|
|
||||||
### Mode 3: Maintainer execution with explicit git authority
|
|
||||||
|
|
||||||
人間が明示的に許可した場合に、親 Pod が commit / merge / ticket 完了削除まで行う。
|
|
||||||
|
|
||||||
使う場面:
|
|
||||||
|
|
||||||
- 「レビューして問題なければマージして」など、明示的な実行指示がある
|
|
||||||
- 実装 branch / review / ticket lifecycle の配置が明確
|
|
||||||
|
|
||||||
制約:
|
制約:
|
||||||
|
|
||||||
- push は行わない
|
- 指定 scope 外を編集しない
|
||||||
- unrelated dirty changes を commit に混ぜない
|
- `.insomnia` や main workspace の control-plane record を勝手に編集しない
|
||||||
- review / completion commit は feature branch 側に置く
|
- work item / review / close は maintainer の責務として扱う
|
||||||
- `develop` first-parent には merge commit だけが載る形を目標にする
|
- 実装報告には変更点、検証、未解決点を含める
|
||||||
|
|
||||||
## 基本 loop
|
### Reviewer Pod
|
||||||
|
|
||||||
AI maintainer の基本 loop は以下である。
|
原則 read-only。実装 diff と対象 work item を読み、妥当性を確認する。
|
||||||
|
|
||||||
1. 状態把握
|
見るべき点:
|
||||||
- `git status --short --branch`
|
|
||||||
- `TODO.md`
|
|
||||||
- 対象 ticket
|
|
||||||
- 関連 docs / report
|
|
||||||
- 既存 review artifact
|
|
||||||
|
|
||||||
2. 分類
|
- work item の要件・受け入れ条件を満たしているか
|
||||||
- 実装可能
|
- 設計を歪めていないか
|
||||||
- 設計相談が必要
|
- 不必要な後方互換性や局所最適な変更を作っていないか
|
||||||
- ticket 整理が必要
|
- テストが適切か
|
||||||
- 運用上の問題として report すべき
|
- ドキュメント / work item / known issue の更新が必要か
|
||||||
|
|
||||||
3. 方針提示または実行
|
## Workflow modes
|
||||||
- 設計判断が必要なら、人間に質問する
|
|
||||||
- 実装可能なら、worktree / Pod / scope / test 方針を決める
|
|
||||||
|
|
||||||
4. 実装
|
### Mode 0: Design consultation
|
||||||
- 原則 child worktree
|
|
||||||
- 実装 Pod に任せるか、親 Pod が直接行うかを選ぶ
|
|
||||||
- `.insomnia` は child worktree から除外する
|
|
||||||
|
|
||||||
5. 検証
|
設計や方針を相談するだけの mode。コードや work item は編集しない。
|
||||||
- focused test
|
|
||||||
- 必要なら broader test
|
|
||||||
- `git diff --check`
|
|
||||||
- `cargo fmt --check` は既存 unrelated 差分を区別して扱う
|
|
||||||
|
|
||||||
6. Review
|
使う場面:
|
||||||
- ticket の背景・要件・完了条件に照らす
|
|
||||||
- 過剰実装や設計歪みを見る
|
|
||||||
- 必要なら修正依頼
|
|
||||||
|
|
||||||
7. Lifecycle
|
- 要件がまだ曖昧
|
||||||
- implementation commit
|
- work item 化する前に合意したい
|
||||||
- review commit
|
- 複数案の設計判断が必要
|
||||||
- ticket / review / TODO completion commit
|
|
||||||
- develop への merge
|
|
||||||
- first-parent 確認
|
|
||||||
|
|
||||||
8. 報告
|
### Mode 1: Project record maintenance
|
||||||
- 実装概要
|
|
||||||
- 変更ファイル
|
|
||||||
- test 結果
|
|
||||||
- review 判断
|
|
||||||
- 未解決事項
|
|
||||||
- 残った dirty changes
|
|
||||||
|
|
||||||
## エスカレーション基準
|
`work-items/`, `KNOWN_ISSUES.md`, `docs/`, `docs/report/` など control-plane record だけを編集する。実装コードは触らない。
|
||||||
|
|
||||||
以下では AI maintainer は実装を止め、人間に戻す。
|
例:
|
||||||
|
|
||||||
- ticket の要件から複数の設計方針が自然に導ける
|
- work item の作成・詳細化
|
||||||
- 長期構造、crate boundary、protocol、permission、scope、history persistence に触れる
|
- review / implementation report / resolution の追記
|
||||||
- prompt context 加工原則に関わる
|
- stale docs の修正
|
||||||
- 新 ticket の作成、既存 ticket の大幅変更、ticket 完了削除について合意がない
|
- known issue の追加・削除
|
||||||
- git commit / merge / push などの書き込み権限が明示されていない
|
|
||||||
- test 不能、再現不能、または作業範囲外の不具合に遭遇した
|
|
||||||
- child worktree に `.insomnia` が出てしまった
|
|
||||||
- SpawnedPod の完了状態が不明で、worktree 状態からも安全に判断できない
|
|
||||||
|
|
||||||
## Orchestration の制約
|
新規 work item 作成や大幅変更は、人間の合意後に行う。
|
||||||
|
|
||||||
### SpawnedPod の完了は自動検知しない
|
### Mode 2: Implementation orchestration
|
||||||
|
|
||||||
現状、親 Pod は SpawnedPod の完了を push 通知として自動検知しない。完了確認は以下で行う。
|
Maintainer Pod が child worktree と implementation Pod を作り、実装と review を回す。親は scoped delegation と project record authority を保持する。
|
||||||
|
|
||||||
- `ReadPodOutput` による polling
|
基本手順:
|
||||||
- Pod が出した完了報告
|
|
||||||
- `stopped` 状態
|
|
||||||
- worktree の `git status` / `git diff`
|
|
||||||
- build / test 結果
|
|
||||||
|
|
||||||
そのため、AI maintainer は「Pod が何も言わないが実は完了している」ケースと「Pod が止まっているが失敗した」ケースを区別するため、Pod 出力だけでなく worktree 状態を確認する。
|
1. 対象 work item を main workspace で作成・詳細化し commit する
|
||||||
|
2. orchestrator が child worktree を作る
|
||||||
|
3. implementation Pod に対象 worktree と task を渡す
|
||||||
|
4. implementation Pod が実装・検証・報告する
|
||||||
|
5. reviewer Pod が diff と work item を読む
|
||||||
|
6. 必要なら修正を戻す
|
||||||
|
7. maintainer が merge-ready dossier を作る
|
||||||
|
|
||||||
### Scope は所有権として扱う
|
### Mode 3: Maintainer-managed completion
|
||||||
|
|
||||||
実装 Pod に write scope を渡している間、親 Pod は同じ path を編集しない。review artifact や ticket lifecycle を書く前に、必要なら `StopPod` して scope を回収する。
|
人間が明示的に許可した場合に、親 Pod が commit / merge / close まで行う。
|
||||||
|
|
||||||
### main workspace は制御面
|
条件:
|
||||||
|
|
||||||
main workspace は orchestration / docs / ticket lifecycle / merge のための場所である。実装差分は原則 child worktree に隔離する。
|
- 対象 work item が明確
|
||||||
|
- scope と worktree が分離されている
|
||||||
|
- review 結果が approve または残件が明示されている
|
||||||
|
- validation が通っている
|
||||||
|
- close / merge してよいというユーザー指示または会話上の合意がある
|
||||||
|
|
||||||
## Git / ticket lifecycle
|
push はしない。破壊的 git 操作は明示指示なしに行わない。
|
||||||
|
|
||||||
feature branch の ticket lifecycle は以下の形を正とする。
|
## Work item lifecycle
|
||||||
|
|
||||||
```text
|
### 作成
|
||||||
* merge: <topic> # develop
|
|
||||||
|\
|
```
|
||||||
| * docs(tickets): complete <topic>
|
./tickets.sh create --title "..." [--slug slug] [--kind task] [--priority P2] [--label a,b]
|
||||||
| * review: <topic>
|
|
||||||
| * feat/fix/refactor: <topic> # feature branch
|
|
||||||
|/
|
|
||||||
* previous develop
|
|
||||||
```
|
```
|
||||||
|
|
||||||
重要な検査:
|
作成後、必要なら `item.md` を詳細化し、背景・要件・受け入れ条件を明確にする。worktree を使う場合は、対象 work item を作成・詳細化して commit してから branch/worktree を切る。
|
||||||
|
|
||||||
- review / completion commit は feature branch 側にある
|
### コメント / 計画 / 判断
|
||||||
- `develop` first-parent に review / completion commit が直接載っていない
|
|
||||||
- unrelated dirty changes が staged / committed されていない
|
|
||||||
- ticket / review / TODO cleanup は merge 前に feature branch 側で完了している
|
|
||||||
|
|
||||||
## `/auto-maintain` との関係
|
```
|
||||||
|
./tickets.sh comment <id-or-slug> --role plan --file path
|
||||||
|
./tickets.sh comment <id-or-slug> --role decision --file path
|
||||||
|
./tickets.sh comment <id-or-slug> --role implementation_report --file path
|
||||||
|
```
|
||||||
|
|
||||||
`/auto-maintain` は、この設計の Mode 2 を安全側に制限した Workflow である。
|
thread は後から読まれる project record なので、実装ログをだらだら貼るより、判断理由・検証結果・残件を簡潔に残す。
|
||||||
|
|
||||||
現在の `/auto-maintain` は以下に留める。
|
### レビュー
|
||||||
|
|
||||||
- TODO / tickets を読む
|
```
|
||||||
- 将来的には WorkItemStore を入口にして、ticket は linked artifact または backend view として扱う
|
./tickets.sh review <id-or-slug> --approve --file path
|
||||||
- 低リスク ticket を選ぶ
|
./tickets.sh review <id-or-slug> --request-changes --file path
|
||||||
- worktree / implementation Pod / reviewer を orchestration する
|
```
|
||||||
- 完了候補を報告する
|
|
||||||
- 原則として commit / merge / ticket 完了削除は人間に戻す
|
|
||||||
|
|
||||||
一方、この文書が扱う AI maintainer は、ユーザーが明示的に許可した場合に Mode 3 として commit / merge / ticket lifecycle まで実行できる。ただし push はしない。
|
レビューは diff の確認だけではない。work item の前提・要件・受け入れ条件が実装で満たされているか、コードベースを歪めていないかを確認する。
|
||||||
|
|
||||||
## 今後必要な機能
|
### 完了
|
||||||
|
|
||||||
この設計を安定運用するには、以下が必要になる。
|
```
|
||||||
|
./tickets.sh close <id-or-slug> --resolution "..."
|
||||||
|
```
|
||||||
|
|
||||||
### WorkItemStore / LeaseStore
|
close は `work-items/closed/` へ移動し、`resolution.md` と thread entry を残す。close commit には resolution と関連 project record 更新を含める。
|
||||||
|
|
||||||
`tickets/` file を直接読むだけでなく、AI maintainer が WorkItem / Thread / Event / Artifact を扱うための store interface。初期実装は repo-managed file backend でよいが、network 越し workspace / remote maintainer hub へ差し替えられるよう、Git 操作や path layout を上位 Workflow に漏らさない。
|
## Branch / worktree placement
|
||||||
|
|
||||||
Lease は thread の正本とは分け、`.insomnia/maintainer/` または local DB に置く runtime coordination state として扱う。remote hub を導入する場合は LeaseStore だけを先に集権化できる設計にする。
|
main workspace は orchestration / docs / work item lifecycle / merge の control plane。実装差分は原則 child worktree に隔離する。
|
||||||
|
|
||||||
|
```
|
||||||
|
main/develop workspace:
|
||||||
|
work item 作成・詳細化 commit
|
||||||
|
child worktree 作成
|
||||||
|
|
||||||
|
child worktree feature branch:
|
||||||
|
implementation commit(s)
|
||||||
|
validation
|
||||||
|
|
||||||
|
main/develop workspace:
|
||||||
|
reviewer Pod に read-only 依頼
|
||||||
|
merge / close / cleanup commit
|
||||||
|
```
|
||||||
|
|
||||||
|
child Pod に write scope を渡している間、親 Pod は同じ path を編集しない。必要なら `StopPod` で scope を回収してから project record を更新する。
|
||||||
|
|
||||||
|
## Human approval boundaries
|
||||||
|
|
||||||
|
AI maintainer は以下で人間に戻す。
|
||||||
|
|
||||||
|
- 要件から複数の設計方針が自然に導ける
|
||||||
|
- public API / protocol / manifest / durable data format を変える
|
||||||
|
- 大規模 rename / directory 移動 / repository-wide format を伴う
|
||||||
|
- work item の作成・大幅変更・close について合意がない
|
||||||
|
- reviewer が request-changes しており、修正方針が自明でない
|
||||||
|
- validation が失敗し、原因が対象変更か既存問題か不明
|
||||||
|
- destructive git operation や push が必要
|
||||||
|
|
||||||
|
## Reports / Knowledge / Memory
|
||||||
|
|
||||||
|
- `docs/report/`: ドッグフーディングで感じた障壁、改善案、ツール問題の記録。明確な作業単位になったら work item 化する
|
||||||
|
- `.insomnia/knowledge`: curated project knowledge。正本ではなく補助 context
|
||||||
|
- `.insomnia/memory`: generated/personal state。project record の代替にしない
|
||||||
|
- `KNOWN_ISSUES.md`: ticket 化するほどではないが、次に近所を触る時に拾いたい小粒所見
|
||||||
|
|
||||||
|
## Future extension points
|
||||||
|
|
||||||
|
### WorkItemStore API
|
||||||
|
|
||||||
|
現在は `tickets.sh` + repo-managed `work-items/` を正本とする。将来、remote maintainer hub や issue tracker へ差し替えるなら、WorkItem / Thread / Event / Artifact を扱う store interface を追加し、Git/path layout を上位 workflow に漏らさない形にする。
|
||||||
|
|
||||||
### Maintainer doctor
|
### Maintainer doctor
|
||||||
|
|
||||||
merge 前 / ticket 完了前に以下を検査するコマンド。
|
merge 前 / close 前に以下を検査する command。
|
||||||
|
|
||||||
- current branch
|
- 対象 work item が存在する
|
||||||
- feature branch と develop の merge base
|
- acceptance criteria と implementation report が対応している
|
||||||
- review / completion commit の branch placement
|
- review status が明示されている
|
||||||
- unrelated staged changes
|
- validation log がある
|
||||||
- ticket / TODO の整合
|
- work item lifecycle と branch placement が矛盾していない
|
||||||
- child worktree に `.insomnia` が含まれていないこと
|
|
||||||
|
|
||||||
### Pod completion tracking
|
### Multi-maintainer coordination
|
||||||
|
|
||||||
SpawnedPod の状態を polling ではなく、親 Pod が扱いやすいイベントとして観測できる仕組み。
|
複数 maintainer Pod が同じ repository を扱う場合は、work item / branch / scope の lease が必要。現状は人間と git history が最終調停者。
|
||||||
|
|
||||||
必要な情報:
|
|
||||||
|
|
||||||
- running / completed / failed / stopped
|
|
||||||
- 最終 assistant output
|
|
||||||
- 最終 tool result
|
|
||||||
- worktree path
|
|
||||||
- delegated scope
|
|
||||||
|
|
||||||
### Operation inbox / trial log
|
|
||||||
|
|
||||||
maintainer が見つけた改善候補、試走結果、未整理の気づきを一時的に集める場所。恒久的な ticket にする前の buffer として使う。
|
|
||||||
|
|
||||||
### Profile / role manifest
|
|
||||||
|
|
||||||
Orchestrator / Coder / Reviewer / Researcher で model・prompt・scope 既定値を分けるための manifest profile。人間が用途ごとに起動時設定を切り替えられるようにする。
|
|
||||||
|
|
||||||
### Workflow quality evaluation
|
|
||||||
|
|
||||||
Workflow 本文が実際に subagent に渡された時、どこで裁量補完が発生し、どこが曖昧だったかを構造化して report する仕組み。
|
|
||||||
|
|
||||||
## 非目標
|
|
||||||
|
|
||||||
当面やらないこと:
|
|
||||||
|
|
||||||
- 常駐 scheduler による unattended 開発
|
|
||||||
- AI による push
|
|
||||||
- AI による無承認の ticket 新規作成 / 大幅変更
|
|
||||||
- AI による Workflow 自律生成
|
|
||||||
- scope owner handoff の暗黙化
|
|
||||||
- history に残らない情報を context へ差し込む運用
|
|
||||||
|
|
||||||
## 現時点の方針
|
|
||||||
|
|
||||||
AI maintainer は「コードを書く agent」ではなく、「プロジェクト状態を読み、必要な作業単位へ分解し、適切な worker に委譲し、結果を検証し、履歴に残す agent」として扱う。
|
|
||||||
|
|
||||||
`/auto-maintain` はその最小実行単位であり、今後はこの文書を上位設計として、Workflow 本文・doctor・profile・Pod completion tracking を段階的に足していく。
|
|
||||||
|
|
|
||||||
|
|
@ -1,235 +1,28 @@
|
||||||
# 永続化データ構造の設計・実装プラン
|
# LLM 履歴永続化 plan(superseded)
|
||||||
|
|
||||||
## Context
|
> Status: superseded / historical note.
|
||||||
|
>
|
||||||
|
> この文書は、`session-store` / segment log / Pod metadata 分離が入る前の検討メモ。現在の実装仕様として読まないこと。現行仕様は `docs/architecture.md` の「セッション永続化」と `crates/session-store` / `crates/pod-store` / `crates/pod` を正とする。
|
||||||
|
|
||||||
INSOMNIA の `llm-worker` クレートは現在すべてのセッション状態をインメモリで保持しており、
|
## 現在の要点
|
||||||
プロセス終了時に会話履歴やターン状態が失われる。
|
|
||||||
Coding Agent として Pause/Resume・Fork をまたいだセッション継続を実現するため、
|
|
||||||
永続化レイヤーを追加する。
|
|
||||||
|
|
||||||
**設計方針**: Codex CLI / Claude Code と同様の **JSONL append-only ログ** 方式を採用。
|
- 会話・worker replay の authority は `session-store` の append-only JSONL segment log。
|
||||||
セッションログを replay することで Worker 状態を完全に復元する。
|
- fresh conversation は新しい `SessionId` を作る。
|
||||||
Pause/正常終了で永続化データの構造に差異を設けない。
|
- compact / fork / rewind は同じ `SessionId` 配下の `SegmentId` を切り替える。
|
||||||
理由: Worker の状態は Pause 時も正常終了時も同じ形(`history: Vec<Item>` + `turn_count` + `request_config`)であり、
|
- segment 出自は `LogEntry::SegmentStart` 内の `SegmentOrigin`(`compacted_from` / `forked_from`)で表す。
|
||||||
APIレスポンスのデータ構造上、両者に本質的な違いがない。
|
- Pod 名からの current state は `pod-store` metadata が持つ。
|
||||||
`resume()` は「ユーザー入力を追加せず `run_turn_loop()` に再入する」だけなので、
|
- active `(SessionId, SegmentId)` pointer
|
||||||
復元に必要なのは history の中身であり、前回の終了理由ではない。
|
- `resolved_manifest_snapshot`
|
||||||
`RunOutcome` の `Finished`/`Paused` 区分は監査・デバッグ用メタデータであり、replay ロジックの分岐には使わない。
|
- spawned child delegation / reclaim state
|
||||||
|
- runtime socket path / registry mirror は live/derived state であり、conversation history や Pod-name current state の durable authority ではない。
|
||||||
|
|
||||||
**命名規約**:
|
## Superseded な旧前提
|
||||||
- **SessionLog / LogEntry** — 状態復元用の構造化された記録(永続化の本体)
|
|
||||||
- **EventTrace / TraceEntry** — デバッグ用の生ストリームイベント全録(オプション)
|
|
||||||
|
|
||||||
## クレート構成
|
この旧 plan は以下の前提を含んでいたため、現在の仕様とは一致しない。
|
||||||
|
|
||||||
永続化は `llm-worker` とは別クレートに分離する。
|
- session を単一ファイル・単一系列として扱う前提。
|
||||||
`llm-worker` は永続化を一切知らず、Session ラッパーが外から Worker を包む。
|
- compact/fork で新 SessionId を作る前提。
|
||||||
|
- entry hash を replay lineage の主参照にする前提。
|
||||||
|
- Pod 名 current state と conversation log authority を分離しない前提。
|
||||||
|
|
||||||
```
|
履歴としては有用だが、実装時の根拠には使わない。新しい変更を検討する場合は、まず current code と work item を読むこと。
|
||||||
crates/
|
|
||||||
llm-worker/ ← 既存(LLM クライアント + Worker、変更なし以外は最小限)
|
|
||||||
llm-worker-macros/ ← 既存(変更なし)
|
|
||||||
llm-worker-persistence/ ← 新規クレート
|
|
||||||
Cargo.toml
|
|
||||||
src/
|
|
||||||
lib.rs -- モジュールルート・re-exports・SessionId 型エイリアス
|
|
||||||
session_log.rs -- LogEntry enum(JSONL 1行 = 1エントリ)
|
|
||||||
event_trace.rs -- TraceEntry(デバッグ用生イベント記録)
|
|
||||||
store.rs -- Store trait(バックエンド抽象)
|
|
||||||
fs_store.rs -- JSONL ファイルシステム実装
|
|
||||||
session.rs -- Session<C, St> ラッパー + replay/restore
|
|
||||||
insomnia/ ← 将来のトップレベルアプリ
|
|
||||||
|
|
||||||
docs/persistence.md -- 設計ドキュメント(このプランの清書版)
|
|
||||||
```
|
|
||||||
|
|
||||||
依存グラフ:
|
|
||||||
```
|
|
||||||
llm-worker-persistence → llm-worker → llm-worker-macros
|
|
||||||
insomnia (将来) → llm-worker-persistence, llm-worker
|
|
||||||
```
|
|
||||||
|
|
||||||
### llm-worker-persistence/Cargo.toml 依存
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
llm-worker = { path = "../llm-worker" }
|
|
||||||
serde = { version = "1", features = ["derive"] }
|
|
||||||
serde_json = "1"
|
|
||||||
tokio = { version = "1", features = ["fs", "io-util"] }
|
|
||||||
uuid = { version = "1", features = ["v7", "serde"] }
|
|
||||||
thiserror = "2"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 既存コードへの変更(llm-worker 側)
|
|
||||||
|
|
||||||
### 1. `RequestConfig` に Serialize/Deserialize 追加
|
|
||||||
- **ファイル**: `crates/llm-worker/src/llm_client/types.rs:504`
|
|
||||||
- `#[derive(Debug, Clone, Default)]` → `#[derive(Debug, Clone, Default, Serialize, Deserialize)]`
|
|
||||||
|
|
||||||
### 2. Worker に復元用セッター追加
|
|
||||||
- **ファイル**: `crates/llm-worker/src/worker.rs`
|
|
||||||
- `impl<C: LlmClient> Worker<C, Mutable>` ブロックに追加:
|
|
||||||
- `pub fn set_turn_count(&mut self, count: usize)`
|
|
||||||
- `pub fn set_last_run_interrupted(&mut self, interrupted: bool)`
|
|
||||||
|
|
||||||
### 3. ワークスペース Cargo.toml にメンバー追加
|
|
||||||
- **ファイル**: `Cargo.toml`(ワークスペースルート)
|
|
||||||
- `members` に `"crates/llm-worker-persistence"` を追加
|
|
||||||
|
|
||||||
## 新規コード: データ型
|
|
||||||
|
|
||||||
### LogEntry(session_log.rs)
|
|
||||||
|
|
||||||
状態復元に必要な構造化記録。JSONL 1行 = 1エントリ。
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
|
||||||
pub enum LogEntry {
|
|
||||||
// セッション開始(ログ先頭、fork 時は history にシード状態を含む)
|
|
||||||
SessionStart {
|
|
||||||
ts: u64,
|
|
||||||
system_prompt: Option<String>,
|
|
||||||
config: RequestConfig,
|
|
||||||
history: Vec<Item>,
|
|
||||||
},
|
|
||||||
|
|
||||||
// ユーザー入力(worker.rs:229 に対応)
|
|
||||||
UserInput { ts: u64, item: Item },
|
|
||||||
|
|
||||||
// アシスタント応答(worker.rs:1040-1041 に対応)
|
|
||||||
AssistantItem { ts: u64, item: Item },
|
|
||||||
|
|
||||||
// ツール実行結果(worker.rs:897-900, 1072-1076 に対応)
|
|
||||||
ToolResult { ts: u64, item: Item },
|
|
||||||
|
|
||||||
// typed system injection
|
|
||||||
SystemItem { ts: u64, item: SystemItem },
|
|
||||||
|
|
||||||
// ターン境界
|
|
||||||
TurnEnd { ts: u64, turn_count: usize },
|
|
||||||
|
|
||||||
// KV キャッシュロック/アンロック
|
|
||||||
CacheLocked { ts: u64, locked_prefix_len: usize },
|
|
||||||
CacheUnlocked { ts: u64 },
|
|
||||||
|
|
||||||
// run/resume の終了結果
|
|
||||||
RunOutcome { ts: u64, outcome: Outcome, interrupted: bool },
|
|
||||||
|
|
||||||
// RequestConfig 変更
|
|
||||||
ConfigChanged { ts: u64, config: RequestConfig },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum Outcome { Finished, Paused, Error { message: String } }
|
|
||||||
```
|
|
||||||
|
|
||||||
**Replay ロジック**: 全エントリ種別を走査し、`AssistantItem` / `ToolResult` / `SystemItem` / `UserInput` → history に append、
|
|
||||||
`TurnEnd` → turn_count 更新、`CacheLocked` → locked_prefix_len 設定。
|
|
||||||
|
|
||||||
### TraceEntry(event_trace.rs)
|
|
||||||
|
|
||||||
デバッグ用の生ストリームイベント全録。デフォルト OFF。
|
|
||||||
セッションログとは別ファイル `{session_id}.trace.jsonl` に記録。
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct TraceEntry {
|
|
||||||
pub ts: u64,
|
|
||||||
pub turn: usize,
|
|
||||||
pub event: Event,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
replay 対象外。状態復元には使わない。
|
|
||||||
|
|
||||||
### SessionId
|
|
||||||
|
|
||||||
`uuid` クレートの UUID v7 をそのまま使用。型エイリアスのみ。
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub type SessionId = uuid::Uuid;
|
|
||||||
|
|
||||||
pub fn new_session_id() -> SessionId {
|
|
||||||
uuid::Uuid::now_v7()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
UUID v7 はタイムスタンプ埋め込みで辞書順 = 時系列順。独自フォーマット不要。
|
|
||||||
|
|
||||||
### Store trait(store.rs)
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub trait Store: Send + Sync {
|
|
||||||
fn append(&self, id: SessionId, entry: &LogEntry) -> impl Future<Output = Result<(), StoreError>> + Send;
|
|
||||||
fn read_all(&self, id: SessionId) -> impl Future<Output = Result<Vec<LogEntry>, StoreError>> + Send;
|
|
||||||
fn list_sessions(&self) -> impl Future<Output = Result<Vec<SessionId>, StoreError>> + Send;
|
|
||||||
fn create_session(&self, id: SessionId, entries: &[LogEntry]) -> impl Future<Output = Result<(), StoreError>> + Send;
|
|
||||||
fn exists(&self, id: SessionId) -> impl Future<Output = Result<bool, StoreError>> + Send;
|
|
||||||
|
|
||||||
// EventTrace 用(デバッグモード時のみ使用)
|
|
||||||
fn append_trace(&self, id: SessionId, entry: &TraceEntry) -> impl Future<Output = Result<(), StoreError>> + Send;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
RPITIT (Rust 1.75+) 使用。`async_trait` 不要。
|
|
||||||
|
|
||||||
### FsStore(fs_store.rs)
|
|
||||||
|
|
||||||
ファイル配置:
|
|
||||||
- セッションログ: `{root}/{session_id}.jsonl`
|
|
||||||
- イベントトレース: `{root}/{session_id}.trace.jsonl`
|
|
||||||
|
|
||||||
append モードで書き込み。SQLite インデックスなし。
|
|
||||||
|
|
||||||
### Session ラッパー(session.rs)
|
|
||||||
|
|
||||||
Worker を直接変更せず、**外部ラッパー** として実装:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub struct Session<C: LlmClient, St: Store> {
|
|
||||||
pub worker: Worker<C, Mutable>, // pub で直接アクセス可能
|
|
||||||
store: St,
|
|
||||||
session_id: SessionId,
|
|
||||||
config: SessionConfig,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `Session::new()` → SessionStart を append
|
|
||||||
- `Session::run()` → Worker::run() の前後で history.len() を比較、差分をログ記録
|
|
||||||
- `Session::resume()` → 同上
|
|
||||||
- `Session::fork()` → 現在の history をシードにした新 SessionStart を書き込み
|
|
||||||
- `Session::fork_at(store, source_id, entry_idx)` → 任意地点から分岐
|
|
||||||
|
|
||||||
**復元**: `restore_session(client, store, session_id)` → read_all → replay_entries → Worker 再構築
|
|
||||||
|
|
||||||
### EventTrace 記録(デバッグモード)
|
|
||||||
|
|
||||||
`SessionConfig::record_event_trace: bool`(デフォルト `false`)が `true` の場合、
|
|
||||||
Session が Worker に `OnStreamChunk` Hook を登録。
|
|
||||||
Hook 内で `TraceEntry` を `{session_id}.trace.jsonl` に append。
|
|
||||||
セッションログとは完全に分離。
|
|
||||||
|
|
||||||
## 実装順序
|
|
||||||
|
|
||||||
1. `RequestConfig` に Serialize/Deserialize 追加(llm-worker 側)
|
|
||||||
2. Worker に `set_turn_count` / `set_last_run_interrupted` 追加(llm-worker 側)
|
|
||||||
3. `crates/llm-worker-persistence/` クレート作成(Cargo.toml + ワークスペース登録)
|
|
||||||
4. `session_log.rs` 作成(LogEntry + Outcome + replay_entries)
|
|
||||||
5. `event_trace.rs` 作成(TraceEntry)
|
|
||||||
6. `store.rs` 作成(Store trait + StoreError)
|
|
||||||
7. `fs_store.rs` 作成(JSONL ファイルシステム実装)
|
|
||||||
8. `session.rs` 作成(Session ラッパー + restore_session)
|
|
||||||
9. `lib.rs` 作成(re-exports・SessionId 型エイリアス・new_session_id)
|
|
||||||
10. テスト作成(replay round-trip, FsStore 読み書き, Session::run ログ記録)
|
|
||||||
11. `docs/persistence.md` 設計ドキュメント作成
|
|
||||||
|
|
||||||
## 検証方法
|
|
||||||
|
|
||||||
1. **ユニットテスト**: `replay_entries` に手動構築した LogEntry 列を渡し、復元状態を検証
|
|
||||||
2. **統合テスト**: MockLlmClient + FsStore で Session::run → restore_session → history 一致を確認
|
|
||||||
3. **Fork テスト**: fork → 新セッションの history が fork 時点と一致することを確認
|
|
||||||
4. **cargo test**: 既存テストが壊れていないことを確認
|
|
||||||
5. **cargo clippy / cargo check**: 警告なし
|
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,33 @@
|
||||||
# AI maintainer 用 WorkItem / Thread 抽象メモ
|
# AI maintainer 用 WorkItem / Thread 抽象メモ
|
||||||
|
|
||||||
## 位置づけ
|
> Status: mostly implemented / historical design memo.
|
||||||
|
>
|
||||||
|
> この文書は `tickets.sh` + `work-items/` MVP の前に書かれた設計メモ。現在の運用上の正本は `AGENTS.md` の Work item / Ticket 運用と、実際の `tickets.sh` / `work-items/{open,pending,closed}`。古い `TODO.md` / `tickets/` 前提は superseded。
|
||||||
|
|
||||||
AI maintainer が単なる coding agent ではなく、作業の発見・分解・実装委譲・review・完了判断まで扱うには、現在の `TODO.md` / `tickets/*.md` だけでは足りない。必要なのは、個々の file path ではなく「作業単位」と「その会話・判断・成果物」を扱う抽象である。
|
## 現在実現済みの部分
|
||||||
|
|
||||||
このメモは実装 ticket ではなく、将来こういうものが必要になるという設計メモとして置く。具体的な最初の実装は `tickets.sh` / `work-items/` の MVP で試す。
|
- WorkItem 相当: `work-items/{open,pending,closed}/<id>/item.md`
|
||||||
|
- Thread 相当: `thread.md`
|
||||||
|
- Event 相当: `tickets.sh comment/review/status/close` が append する thread entry
|
||||||
|
- Artifact 相当: `artifacts/` directory
|
||||||
|
- Resolution 相当: close 時の `resolution.md`
|
||||||
|
- ID: timestamp + slug 形式
|
||||||
|
- Doctor: `./tickets.sh doctor`
|
||||||
|
|
||||||
## 必要になりそうな概念
|
`work-items/` は repo-managed な project coordination record であり、`.insomnia/memory` はその代替ではない。
|
||||||
|
|
||||||
- WorkItem
|
## 現在も残る設計余地
|
||||||
- 作業単位。title / status / kind / priority / labels / acceptance criteria / links を持つ。
|
|
||||||
- Thread
|
|
||||||
- WorkItem に紐づく append-only な会話・判断・review・実装報告の流れ。
|
|
||||||
- Event
|
|
||||||
- comment / plan / decision / implementation_report / review / status_change など。
|
|
||||||
- Artifact
|
|
||||||
- review log、test log、設計メモ、branch / commit / worktree への link など。
|
|
||||||
- Lease / Run
|
|
||||||
- どの Pod / agent がどの worktree / scope で作業中かを表す runtime coordination 情報。
|
|
||||||
|
|
||||||
## 配置の分担
|
- Rust crate / Store interface としての WorkItemStore
|
||||||
|
- LeaseStore / Run tracking / maintainer inbox
|
||||||
|
- remote maintainer hub / GitHub Issues などへの backend 差し替え
|
||||||
|
- TUI 統合
|
||||||
|
|
||||||
repo-managed な project-visible 領域には、作業の正本として人間が読める coordination data を置く。
|
これらは必要になった時点で改めて work item 化する。
|
||||||
|
|
||||||
```text
|
## 現在の運用参照
|
||||||
repo/
|
|
||||||
work-items/ # WorkItem / Thread / Artifact
|
|
||||||
tickets/ # 当面の既存 ticket。将来 WorkItem view に寄せる候補
|
|
||||||
docs/ # plan / report
|
|
||||||
```
|
|
||||||
|
|
||||||
`.insomnia` は local runtime state として扱い、project coordination の正本にはしない。
|
- `AGENTS.md` — Work item / Ticket の運用ルール
|
||||||
|
- `tickets.sh` — 実際の操作コマンド
|
||||||
```text
|
- `work-items/` — 現在の project-visible coordination data
|
||||||
.insomnia/
|
- `docs/plan/ai-maintainer.md` — AI maintainer workflow の現行設計
|
||||||
memory/
|
|
||||||
workflow/
|
|
||||||
maintainer/
|
|
||||||
leases/
|
|
||||||
runs/
|
|
||||||
inbox/
|
|
||||||
```
|
|
||||||
|
|
||||||
## ID と backend の考え方
|
|
||||||
|
|
||||||
WorkItem ID は中央 `SEQUENCE` にしない。複数 branch / worktree / Pod が同時に作業を作ると conflict しやすいため、timestamp + slug などの衝突しにくい ID にする。
|
|
||||||
|
|
||||||
```text
|
|
||||||
YYYYMMDD-HHMMSS-<slug>
|
|
||||||
YYYYMMDD-HHMMSS-<short-rand>-<slug>
|
|
||||||
```
|
|
||||||
|
|
||||||
backend は最初は repo 内 file backend でよいが、抽象としては Git directory 固定にしない。将来、remote maintainer hub や GitHub Issues などへ移る可能性を潰さない。
|
|
||||||
|
|
||||||
## 移行イメージ
|
|
||||||
|
|
||||||
1. 既存の `TODO.md` / `tickets/` 運用は維持する。
|
|
||||||
2. `tickets.sh` MVP で `work-items/` の file backend と thread 操作を試す。
|
|
||||||
3. 既存 `TODO.md` / `tickets/` を手動で `work-items/` に寄せ、`doctor` が通る状態にする。
|
|
||||||
4. その運用が安定したら、`TODO.md` を generated view にするか、廃止するかを判断する。
|
|
||||||
5. 必要になった段階で Rust crate / Store interface / LeaseStore / remote backend を検討する。
|
|
||||||
|
|
||||||
## 当面やらないこと
|
|
||||||
|
|
||||||
- remote maintainer hub の実装。
|
|
||||||
- SQLite / index / search daemon の導入。
|
|
||||||
- Pod lifecycle / completion tracking の完全実装。
|
|
||||||
- LeaseStore の本格実装。
|
|
||||||
- TUI 統合。
|
|
||||||
|
|
||||||
## 参照
|
|
||||||
|
|
||||||
- `tickets/tickets-sh-workitem-thread-mvp.md`
|
|
||||||
- `docs/plan/ai-maintainer.md`
|
|
||||||
- `tickets/auto-maintain-workflow.md`
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ Available tools: {{ tools | join(", ") }}
|
||||||
|
|
||||||
### タイミング
|
### タイミング
|
||||||
|
|
||||||
1. `Pod::from_manifest` 時点: テンプレート文字列を `SystemPromptTemplate::parse` で **構文検査のみ** 行い、`Pod.system_prompt_template: Option<SystemPromptTemplate>` に保持する。この時点で Worker 側の system_prompt は `None`、session log もまだ書かれない (`head_hash: None`)。
|
1. `Pod::from_manifest` 時点: テンプレート文字列を `SystemPromptTemplate::parse` で **構文検査のみ** 行い、`Pod.system_prompt_template: Option<SystemPromptTemplate>` に保持する。この時点で Worker 側の system_prompt は `None`、segment log の head もまだ作られない。
|
||||||
|
|
||||||
2. `Pod::run` / `Pod::resume` 初回呼び出し冒頭 (`ensure_system_prompt_materialized`):
|
2. `Pod::run` / `Pod::resume` 初回呼び出し冒頭 (`ensure_system_prompt_materialized`):
|
||||||
1. `worker.tool_server_handle().flush_pending()` で pending な tool factory を materialize して tool 名を確定させる
|
1. `worker.tool_server_handle().flush_pending()` で pending な tool factory を materialize して tool 名を確定させる
|
||||||
|
|
@ -54,12 +54,12 @@ Available tools: {{ tools | join(", ") }}
|
||||||
3. `template.render(ctx)` で文字列化して `worker.set_system_prompt(rendered)` を呼ぶ
|
3. `template.render(ctx)` で文字列化して `worker.set_system_prompt(rendered)` を呼ぶ
|
||||||
4. `Pod.system_prompt_template = None` (`Option::take()` で構造的に1回性を保証)
|
4. `Pod.system_prompt_template = None` (`Option::take()` で構造的に1回性を保証)
|
||||||
|
|
||||||
3. その直後の `ensure_session_head` が `head_hash` を見て初回なら `create_session_with_id` を呼び、materialize 後の system_prompt を **SessionStart ログエントリに焼き付ける**。
|
3. その直後の `ensure_segment_head` が現在 segment の entry count を見て初回なら `SegmentStart` を append し、materialize 後の system_prompt を segment log に焼き付ける。
|
||||||
|
|
||||||
### 1回性の保証
|
### 1回性の保証
|
||||||
|
|
||||||
- `Pod.system_prompt_template` は `Option<SystemPromptTemplate>` で、materialize 時に `take()` する。2 ターン目以降はフィールドが `None` なので `ensure_system_prompt_materialized` は早期 return し、再 render は発生しない。
|
- `Pod.system_prompt_template` は `Option<SystemPromptTemplate>` で、materialize 時に `take()` する。2 ターン目以降はフィールドが `None` なので `ensure_system_prompt_materialized` は早期 return し、再 render は発生しない。
|
||||||
- compact は Worker の system_prompt フィールドを触らない (pod.rs の `compact` は `w.get_system_prompt()` を読み取って新セッションに引き継ぐだけ)。そのため compact 前後で同じ文字列が流れ続ける。
|
- compact は Worker の system_prompt フィールドを触らない (pod.rs の `compact` は `w.get_system_prompt()` を読み取って新 segment に引き継ぐだけ)。そのため compact 前後で同じ文字列が流れ続ける。
|
||||||
- 統合テスト `compact_preserves_system_prompt` が実装で直接検証している。
|
- 統合テスト `compact_preserves_system_prompt` が実装で直接検証している。
|
||||||
|
|
||||||
### 責務分離
|
### 責務分離
|
||||||
|
|
@ -79,7 +79,7 @@ Available tools: {{ tools | join(", ") }}
|
||||||
## 関連ファイル
|
## 関連ファイル
|
||||||
|
|
||||||
- `crates/pod/src/system_prompt.rs` — `SystemPromptTemplate` / `SystemPromptContext` / `SystemPromptError`
|
- `crates/pod/src/system_prompt.rs` — `SystemPromptTemplate` / `SystemPromptContext` / `SystemPromptError`
|
||||||
- `crates/pod/src/pod.rs` — `Pod.system_prompt_template` フィールド、`ensure_system_prompt_materialized`、`ensure_session_head` の初回 append ロジック
|
- `crates/pod/src/pod.rs` — `Pod.system_prompt_template` フィールド、`ensure_system_prompt_materialized`、`ensure_segment_head` の初回 append ロジック
|
||||||
- `crates/manifest/src/scope.rs` — `Scope::summary` / `readable_paths` / `writable_paths`
|
- `crates/manifest/src/scope.rs` — `Scope::summary` / `readable_paths` / `writable_paths`
|
||||||
- `crates/session-store/src/session.rs` — `create_session_with_id` (事前生成 ID で SessionStart を書くための entry point)
|
- `crates/session-store/src/segment_log.rs` — `LogEntry::SegmentStart` / segment replay entries
|
||||||
- `crates/llm-worker/src/tool_server.rs` — `ToolServerHandle::flush_pending` (pub)
|
- `crates/llm-worker/src/tool_server.rs` — `ToolServerHandle::flush_pending` (pub)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# TUI キーバインド
|
# TUI キーバインド
|
||||||
|
|
||||||
`crates/tui` の対話画面で効くキー一覧。`main.rs:handle_key` を単一情報源とし、このドキュメントは人間向けの目次。
|
`crates/tui` の対話画面で効くキー一覧。`crates/tui/src/main.rs:handle_key` を単一情報源とし、このドキュメントは人間向けの目次。
|
||||||
|
|
||||||
## 入力編集
|
## 入力編集
|
||||||
|
|
||||||
|
|
@ -11,9 +11,10 @@
|
||||||
| `Backspace` | カーソル直前を削除(ペーストプレースホルダは 1 回で全削除) |
|
| `Backspace` | カーソル直前を削除(ペーストプレースホルダは 1 回で全削除) |
|
||||||
| `Delete` | カーソル直後を削除(同上) |
|
| `Delete` | カーソル直後を削除(同上) |
|
||||||
| `Left` / `Right` | カーソル移動 |
|
| `Left` / `Right` | カーソル移動 |
|
||||||
| `Up` / `Down` | 論理行単位の上下移動(桁位置を保持) |
|
| `Up` / `Down` | 通常は論理行単位の上下移動。入力欄の先頭/末尾では送信済み composer history を browse |
|
||||||
| `Home` / `End` | 現在行の行頭 / 行末へ |
|
| `Home` / `End` | 現在行の行頭 / 行末へ |
|
||||||
| `Alt-Enter` | 改行を挿入(Input を複数行化) |
|
| `Alt-Enter` | 改行を挿入(Input を複数行化) |
|
||||||
|
| `Esc` | completion popup があれば閉じる |
|
||||||
|
|
||||||
### ペーストプレースホルダ
|
### ペーストプレースホルダ
|
||||||
|
|
||||||
|
|
@ -23,13 +24,34 @@
|
||||||
カーソルはプレースホルダ内部には入れず、`Backspace` / `Delete` 1 回で
|
カーソルはプレースホルダ内部には入れず、`Backspace` / `Delete` 1 回で
|
||||||
プレースホルダ全体が消える。`#N` の通し番号は TUI プロセス起動中で連番。
|
プレースホルダ全体が消える。`#N` の通し番号は TUI プロセス起動中で連番。
|
||||||
|
|
||||||
|
### Completion
|
||||||
|
|
||||||
|
`@` file ref / `#` knowledge ref / `/` workflow invocation などは completion popup を開く。
|
||||||
|
|
||||||
|
| キー | 動作 |
|
||||||
|
|---|---|
|
||||||
|
| `Up` / `Down` | completion 候補を移動 |
|
||||||
|
| `Tab` | 選択候補をテキストとして適用 |
|
||||||
|
| `Enter` | committable な候補は chip 化して空白を追加。directory などはテキスト適用して drill-in |
|
||||||
|
| `Esc` | popup を閉じる |
|
||||||
|
| 空白文字 | exact match なら chip 化してから空白を挿入 |
|
||||||
|
|
||||||
## 送信(Enter)
|
## 送信(Enter)
|
||||||
|
|
||||||
| 状態 | 入力あり | 入力空 |
|
| 状態 | 入力あり | 入力空 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Idle | `Method::Run` で新ターン開始 | no-op |
|
| Idle | `Method::Run` で新ターン開始 | no-op |
|
||||||
| Paused | `Method::Run`(前ターンは割り込み終了として扱い、新ターンとして開始) | `Method::Resume`(前ターンの続きを再開) |
|
| Paused | `Method::Run`(前ターンは割り込み終了として扱い、新ターンとして開始) | `Method::Resume`(前ターンの続きを再開) |
|
||||||
| Running | 入力は TUI 側でバッファのみ、送信はしない | 同左 |
|
| Running | 入力は TUI 側 queue に積まれ、現在 turn の終了後に自動送信 | no-op |
|
||||||
|
|
||||||
|
### Running 中の queue
|
||||||
|
|
||||||
|
Running 中に入力ありで Enter すると、現在の provider stream には割り込まず、typed input segments を TUI-local queue に積む。`RunResult::Finished` / `LimitReached` 後に先頭の queued input が次の `Method::Run` として自動送信される。`Paused` / `RolledBack` では自動送信しない。
|
||||||
|
|
||||||
|
| キー | 動作 |
|
||||||
|
|---|---|
|
||||||
|
| `Alt-Q` | queue 先頭を composer に戻す(composer が空の時のみ) |
|
||||||
|
| `Alt-C` | queued input を全消去 |
|
||||||
|
|
||||||
### Paused からの挙動
|
### Paused からの挙動
|
||||||
|
|
||||||
|
|
@ -42,16 +64,32 @@ Paused 中に Enter すると、入力の有無で 2 通り:
|
||||||
3. 入力を新しい user メッセージとして append
|
3. 入力を新しい user メッセージとして append
|
||||||
4. ターン開始
|
4. ターン開始
|
||||||
|
|
||||||
|
## Command mode
|
||||||
|
|
||||||
|
composer が空の通常入力で `:` を押すと command mode に入る。command mode 中は composer が command line として扱われる。
|
||||||
|
|
||||||
|
| キー | 動作 |
|
||||||
|
|---|---|
|
||||||
|
| `Enter` | command を実行 |
|
||||||
|
| `Esc` | command mode を終了 |
|
||||||
|
| `Backspace` | 文字を削除。空なら command mode を終了 |
|
||||||
|
| `Ctrl-U` | command input をクリア |
|
||||||
|
| `Tab` | command completion を適用 |
|
||||||
|
| `Up` / `Down` | command completion 候補があれば移動、なければカーソル上下 |
|
||||||
|
|
||||||
|
主な command は `:help`, `:noop`, `:compact`, `:rewind` / `:rollback`。`:compact` は idle 時だけ即時 compaction を要求し、`:rewind` / `:rollback` は rewind target picker を開く。
|
||||||
|
|
||||||
## 履歴ビューのナビゲーション
|
## 履歴ビューのナビゲーション
|
||||||
|
|
||||||
履歴ビューは全画面 TUI の上段にあり、TUI 内部で全ブロックを state として
|
履歴ビューは全画面 TUI の上段にあり、TUI 内部で全ブロックを state として
|
||||||
保持してスクロール可能。スクロールバック(端末側の履歴)ではなく TUI の
|
保持してスクロール可能。スクロールバック(端末側の履歴)ではなく TUI の
|
||||||
自前バッファを動かす点に注意。
|
自前バッファを動かす点に注意。
|
||||||
|
|
||||||
| キー | 動作 |
|
| キー / 操作 | 動作 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `Shift-Up` / `Shift-Down` | 1 論理行スクロール |
|
| `Shift-Up` / `Shift-Down` | 1 論理行スクロール |
|
||||||
| `PageUp` / `PageDown` | 1 ページスクロール(`area_height - 1` 行) |
|
| mouse wheel | 数行単位でスクロール |
|
||||||
|
| `PageUp` / `PageDown` | 1 ページスクロール(task pane が開いている時は task pane をスクロール) |
|
||||||
| `Ctrl-[` / `Ctrl-]` | 前 / 次のターン先頭へジャンプ |
|
| `Ctrl-[` / `Ctrl-]` | 前 / 次のターン先頭へジャンプ |
|
||||||
| `Ctrl-Home` | 履歴の先頭へ |
|
| `Ctrl-Home` | 履歴の先頭へ |
|
||||||
| `Ctrl-End` | 履歴の末尾へ(末尾追従モードを再開) |
|
| `Ctrl-End` | 履歴の末尾へ(末尾追従モードを再開) |
|
||||||
|
|
@ -69,7 +107,7 @@ Paused 中に Enter すると、入力の有無で 2 通り:
|
||||||
合わせる。多数のツール呼び出しが挟まった長いターンでも前後ターンの先頭に
|
合わせる。多数のツール呼び出しが挟まった長いターンでも前後ターンの先頭に
|
||||||
1 発で戻れる。末尾ターンから `Ctrl-]` を押すと末尾追従に復帰する。
|
1 発で戻れる。末尾ターンから `Ctrl-]` を押すと末尾追従に復帰する。
|
||||||
|
|
||||||
## 表示モード
|
## 表示モード / 補助 pane
|
||||||
|
|
||||||
履歴各ブロックの密度を 3 段階で切り替える。現在のモードはステータスバー
|
履歴各ブロックの密度を 3 段階で切り替える。現在のモードはステータスバー
|
||||||
右端に `[mode]` として表示される。
|
右端に `[mode]` として表示される。
|
||||||
|
|
@ -77,12 +115,11 @@ Paused 中に Enter すると、入力の有無で 2 通り:
|
||||||
| キー | 動作 |
|
| キー | 動作 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `Ctrl-O` | `detail` → `normal` → `overview` → `detail` の順に循環 |
|
| `Ctrl-O` | `detail` → `normal` → `overview` → `detail` の順に循環 |
|
||||||
|
| `Ctrl-T` | task pane を開閉 |
|
||||||
|
|
||||||
- **detail**: 全ブロック完全表示。ツールブロックは結果本体も全量
|
- **detail**: 全ブロック完全表示。ツールブロックは結果本体も全量
|
||||||
- **normal**: 完了ブロックは概ね 5–6 行に圧縮、実行中のツールブロックは
|
- **normal**: 完了ブロックは概ね 5–6 行に圧縮、実行中のツールブロックは detail と同じ扱い
|
||||||
detail と同じ扱い
|
- **overview**: 各ブロック 1 行に畳む(ツールブロックは `ToolResult.summary` 1 行、長文 AssistantText は先頭 1 行 + 省略記)
|
||||||
- **overview**: 各ブロック 1 行に畳む(ツールブロックは
|
|
||||||
`ToolResult.summary` 1 行、長文 AssistantText は先頭 1 行 + 省略記)
|
|
||||||
|
|
||||||
モード切替は全体に一括適用。個別ブロックの開閉は持たない。
|
モード切替は全体に一括適用。個別ブロックの開閉は持たない。
|
||||||
|
|
||||||
|
|
@ -90,9 +127,10 @@ Paused 中に Enter すると、入力の有無で 2 通り:
|
||||||
|
|
||||||
| キー | Running 中 | Idle / Paused |
|
| キー | Running 中 | Idle / Paused |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `Ctrl-X` | `Method::Cancel`(進行中ターンを破棄 → Idle) | `Method::Shutdown`(Pod を終了) |
|
| `Ctrl-X` | queued input を消去して `Method::Cancel`(進行中ターンを破棄 → Idle) | `Method::Shutdown`(Pod を終了) |
|
||||||
| `Ctrl-C` | `Method::Pause`(進行中ターンを中断 → Paused) | 1 回目 warn、3 秒以内の 2 回目で TUI 終了(Pod は残る) |
|
| `Ctrl-C` | `Method::Pause`(進行中ターンを中断 → Paused) | 1 回目 warn、3 秒以内の 2 回目で TUI 終了(Pod は残る) |
|
||||||
| `Ctrl-D` | TUI 終了(Pod は残る、Pause しない) | TUI 終了(Pod は残る) |
|
| `Ctrl-D` | TUI 終了(Pod は残る、Pause しない) | TUI 終了(Pod は残る) |
|
||||||
|
| `Ctrl-R` | rewind picker 要求は拒否される | rewind target picker を開く |
|
||||||
|
|
||||||
### Cancel と Pause の違い
|
### Cancel と Pause の違い
|
||||||
|
|
||||||
|
|
@ -101,9 +139,21 @@ Paused 中に Enter すると、入力の有無で 2 通り:
|
||||||
|
|
||||||
Running 中に割り込みたい場合、ほとんどのケースで `Ctrl-C`(Pause)が自然。Ctrl-X(Cancel)は明示的に破棄したい時(LLM が暴走した時など)用。Pod を終了したい場合は、先に Running ではない状態(Idle / Paused)にしてから `Ctrl-X` で Shutdown する。
|
Running 中に割り込みたい場合、ほとんどのケースで `Ctrl-C`(Pause)が自然。Ctrl-X(Cancel)は明示的に破棄したい時(LLM が暴走した時など)用。Pod を終了したい場合は、先に Running ではない状態(Idle / Paused)にしてから `Ctrl-X` で Shutdown する。
|
||||||
|
|
||||||
|
### Rewind picker
|
||||||
|
|
||||||
|
`Ctrl-R` または `:rewind` / `:rollback` で Pod に `Method::ListRewindTargets` を送り、main area に rewind target picker を開く。picker 中の操作は以下。
|
||||||
|
|
||||||
|
| キー | 動作 |
|
||||||
|
|---|---|
|
||||||
|
| `Up` / `Down` | target を移動 |
|
||||||
|
| `Enter` | 選択 target へ `Method::RewindTo`。復元された user input は composer に戻る |
|
||||||
|
| `Esc` | picker を閉じる |
|
||||||
|
|
||||||
|
Running 中の rewind request は拒否される。Paused 中は picker を開けるが、実際の apply は idle で composer が空の時だけ行う。
|
||||||
|
|
||||||
### Ctrl-C と Ctrl-D の終了 UX
|
### Ctrl-C と Ctrl-D の終了 UX
|
||||||
|
|
||||||
- Ctrl-X Running 中: `Method::Cancel`。終了したい場合は、明示的にターンを止めて Idle に戻してからもう一度 `Ctrl-X`
|
- Ctrl-X Running 中: queued input を消去して `Method::Cancel`。終了したい場合は、明示的にターンを止めて Idle に戻してからもう一度 `Ctrl-X`
|
||||||
- Ctrl-X Idle / Paused: `Method::Shutdown` を送って Pod を終了
|
- Ctrl-X Idle / Paused: `Method::Shutdown` を送って Pod を終了
|
||||||
- Ctrl-C Running 中: 1 回目で即 Pause(破壊的ではない)
|
- Ctrl-C Running 中: 1 回目で即 Pause(破壊的ではない)
|
||||||
- Ctrl-C Idle / Paused: 1 回目で warn メッセージ、3 秒以内の 2 回目で TUI 終了(Pod は残る)
|
- Ctrl-C Idle / Paused: 1 回目で warn メッセージ、3 秒以内の 2 回目で TUI 終了(Pod は残る)
|
||||||
|
|
@ -115,10 +165,7 @@ TUI のダイアログから Pod を起動する経路では、起動した Pod
|
||||||
|
|
||||||
## 履歴メモ
|
## 履歴メモ
|
||||||
|
|
||||||
- かつて存在した `Ctrl-R`(Resume 専用)は、空 Enter での Resume に統合されたため廃止
|
- `Ctrl-R` はかつて Resume 専用だったが、空 Enter での Resume に統合された。現在の `Ctrl-R` は rewind picker の導線
|
||||||
- かつて存在した `Esc`(TUI 終了)は、`Ctrl-C` の 2 連打 UX に統合されたため廃止
|
- かつて存在した `Esc`(TUI 終了)は、`Ctrl-C` の 2 連打 UX に統合されたため廃止。現在の `Esc` は popup / picker / command mode のキャンセル用途
|
||||||
- かつて `Ctrl-D` は Pod に `Method::Shutdown` を送っていたが、TUI だけを抜けるデタッチ操作に変更された
|
- かつて `Ctrl-D` は Pod に `Method::Shutdown` を送っていたが、TUI だけを抜けるデタッチ操作に変更された
|
||||||
- 旧 inline viewport 時代は履歴スクロールを端末側スクロールバックに
|
- 旧 inline viewport 時代は履歴スクロールを端末側スクロールバックに任せていたため TUI 内のスクロールキーは存在しなかった。全画面 alt screen への移行で `Shift-Up/Down` ほかのナビゲーションキーが追加された
|
||||||
任せていたため TUI 内のスクロールキーは存在しなかった。全画面 alt screen
|
|
||||||
への移行(`tickets/tui-fullscreen-overhaul.md`)で `Shift-Up/Down` ほか
|
|
||||||
のナビゲーションキーが追加された
|
|
||||||
|
|
|
||||||
46
work-items/closed/20260530-062852-refresh-stale-docs/item.md
Normal file
46
work-items/closed/20260530-062852-refresh-stale-docs/item.md
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
id: 20260530-062852-refresh-stale-docs
|
||||||
|
slug: refresh-stale-docs
|
||||||
|
title: Docs: refresh stale architecture and operation docs
|
||||||
|
status: closed
|
||||||
|
kind: task
|
||||||
|
priority: P2
|
||||||
|
labels: [docs, maintenance]
|
||||||
|
created_at: 2026-05-30T06:28:52Z
|
||||||
|
updated_at: 2026-05-30T06:39:41Z
|
||||||
|
assignee: null
|
||||||
|
legacy_ticket: null
|
||||||
|
---
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
Read-only docs audit Pod `docs-stale-audit-20260530` reported that several high-level docs still describe older protocol/session/tool/TUI behavior. The stale content is concentrated in architecture, compaction, TUI keybindings, and older plan documents.
|
||||||
|
|
||||||
|
The current authoritative sources are the code, `work-items/`, `KNOWN_ISSUES.md`, `AGENTS.md`, and git history. `docs/report/` remains historical observations, not current spec authority.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
Update or clearly demote stale docs so readers do not mistake old plans for current behavior:
|
||||||
|
|
||||||
|
- `docs/architecture.md`
|
||||||
|
- Refresh Protocol Method/Event overview.
|
||||||
|
- Refresh session persistence description for current `session_id` / `segment_id` / `SegmentOrigin` / Pod metadata split.
|
||||||
|
- Refresh built-in tools description beyond only file tools.
|
||||||
|
- Clarify the coarse `1 Pod = 1 process = 1 session` statement after Pod metadata / session / segment separation.
|
||||||
|
- `docs/compaction.md`
|
||||||
|
- Refresh compact/session/segment descriptions to match current session-store and segment semantics.
|
||||||
|
- `docs/tui-keybindings.md`
|
||||||
|
- Refresh `Ctrl-R` behavior and current command/queue/completion controls.
|
||||||
|
- `docs/plan/llm_presistence.md`
|
||||||
|
- Mark as superseded/archival or replace with current-session persistence pointers.
|
||||||
|
- `docs/plan/ai-maintainer.md`
|
||||||
|
- Replace old `TODO.md` / `tickets/` authority language with current `tickets.sh` + `work-items/` operation.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- High-priority stale claims from the docs audit are either corrected or explicitly marked historical/superseded.
|
||||||
|
- Updated docs consistently describe current Pod metadata vs session-store vs runtime registry responsibilities at a high level.
|
||||||
|
- Updated docs do not claim `TODO.md` / legacy `tickets/` are the active work-item authority.
|
||||||
|
- Updated docs do not claim `Ctrl-R` is removed; TUI keybindings reflect current behavior sufficiently for users.
|
||||||
|
- No generated report/history document is rewritten as if it were current spec authority.
|
||||||
|
- `./tickets.sh doctor` and `git diff --check` pass.
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
docs stale audit の高優先指摘を反映し、architecture / compaction / TUI keybindings / system-prompt-template / plan docs を現行の protocol・session-store/pod-store・work-items 運用に合わせて更新した。旧 llm persistence / maintainer work item plan は superseded/historical と明示。検証は ./tickets.sh doctor と git diff --check。
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
<!-- event: create author: tickets.sh at: 2026-05-30T06:28:52Z -->
|
||||||
|
|
||||||
|
## Created
|
||||||
|
|
||||||
|
Created by tickets.sh create.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- event: plan author: hare at: 2026-05-30T06:29:24Z -->
|
||||||
|
|
||||||
|
## Plan
|
||||||
|
|
||||||
|
Implementation plan:
|
||||||
|
|
||||||
|
1. Read the current target docs and authoritative code/type definitions.
|
||||||
|
2. Update high-level docs in-place, keeping edits scoped to stale claims rather than broad prose rewrites.
|
||||||
|
3. Mark superseded plan docs clearly when replacing them would be larger than useful.
|
||||||
|
4. Validate with `./tickets.sh doctor` and `git diff --check`.
|
||||||
|
5. Review the resulting diff against the audit findings before closing.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- event: implementation_report author: hare at: 2026-05-30T06:39:11Z -->
|
||||||
|
|
||||||
|
## Implementation report
|
||||||
|
|
||||||
|
Implementation report:
|
||||||
|
|
||||||
|
- Refreshed `docs/architecture.md` for current protocol categories, session-store vs pod-store responsibilities, profile/manifest input, scope delegation, and current built-in tool categories.
|
||||||
|
- Updated `docs/compaction.md` to describe same-session segment rotation and `SegmentStart.compacted_from` instead of the old new-SessionId model.
|
||||||
|
- Rewrote `docs/tui-keybindings.md` around current command mode, queued input behavior, completion, task pane, and `Ctrl-R` rewind picker behavior.
|
||||||
|
- Marked `docs/plan/llm_presistence.md` as superseded and replaced old implementation details with current-session persistence pointers.
|
||||||
|
- Refreshed `docs/plan/ai-maintainer.md` and `docs/plan/maintainer-work-items.md` so current `tickets.sh` + `work-items/` authority replaces old `TODO.md` / legacy `tickets/` assumptions.
|
||||||
|
- Updated `docs/system-prompt-template.md` for current segment log naming (`ensure_segment_head`, `SegmentStart`) while fixing nearby stale session terminology.
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
|
||||||
|
- `./tickets.sh doctor`
|
||||||
|
- `git diff --check`
|
||||||
|
- grep sweep for the high-priority stale phrases from the audit; remaining hits are historical reports/ref docs or explicit superseded notes.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- event: close author: hare at: 2026-05-30T06:39:41Z status: closed -->
|
||||||
|
|
||||||
|
## Closed
|
||||||
|
|
||||||
|
docs stale audit の高優先指摘を反映し、architecture / compaction / TUI keybindings / system-prompt-template / plan docs を現行の protocol・session-store/pod-store・work-items 運用に合わせて更新した。旧 llm persistence / maintainer work item plan は superseded/historical と明示。検証は ./tickets.sh doctor と git diff --check。
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
Loading…
Reference in New Issue
Block a user