sync: update from private repo (2336949a)
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
oss-sync
2026-09-17 11:29:31 +00:00
parent 28f74c4e37
commit 57702b4f34
2139 changed files with 321270 additions and 17494 deletions
+636
View File
@@ -0,0 +1,636 @@
# Auto Prompter ワークスペース機能 設計方針
作成日: 2026-07-24
対象: MAESTRO(gitea-agent-orchestrator)
位置づけ: `auto-prompter-hook-feasibility-study.md` に対する製品方針の追補
## 1. 結論
Auto Prompterは管理者専用機能に限定せず、ワークスペースを利用する一般ユーザーも利用できる機能として設計する。
初期実装ではルールの適用範囲をワークスペース単位に限定する。ワークスペース編集権限を持つユーザーが設定し、利用権限だけを持つメンバーには、有効なルールと適用結果を表示する。
一般ユーザー向け機能として提供する方針と、安全な段階公開は両立させる。初期提供はテンプレートと決定的条件に限定する。常時適用ルールはstatic preamble合成経路の実装後、自由記述の自然言語条件はshadow評価の品質基準を満たした後に有効化する。
EU AI Act対応を有効にする場合も、Auto Prompter単体で適合を自己宣言しない。適用範囲、Decision Record、human oversight、provenance、保持・完全性は [EU AI Act透明性対応 設計付録](./auto-prompter-eu-ai-act-transparency-design.md) に従い、Compliance Profileとして段階実装する。
内部実装は汎用Hook基盤の上に構築するが、UIでは「Hook」を主語にせず、「Auto Prompter」または「自動ルール」と表示する。
## 2. 設定の配置 (例)
```text
ワークスペース設定
├─ AGENTS
├─ Memory
├─ MCP
├─ ツール権限
└─ Auto Prompter
```
AGENTSやMemoryと同様に、「このワークスペースでエージェントにどう振る舞わせるか」を定める設定として扱う。
設定画面には、次の注意を明示する。
> このルールは、このワークスペースを利用するすべてのメンバーに適用されます。
個人設定、組織設定、Movement設定との多階層な優先順位は初期実装へ含めない。
Auto Prompterには次の2段階のオン・オフを設ける。
- ワークスペース全体のマスタースイッチ
- ルールごとの有効・無効スイッチ
マスタースイッチをオフにした場合、個別ルールの設定値は保持したまま、常時適用ルールと条件付きルールの両方を停止する。監査上は設定変更の事実だけを記録し、無効化中のルール判定や判定モデル呼び出しは行わない。
## 3. 想定ユースケース
### インフラ管理
- コマンドを提示する場合は公式資料を確認する
- 削除や設定変更の前に影響範囲を確認する
- 危険な操作はユーザー承認を求める
### プログラミング学習
- 初心者向けに説明する
- 専門用語には短い補足を付ける
- 完成コードだけでなく考え方も説明する
### 調査
- 日本語で回答する
- 一次情報を優先する
- 推測と確認済み情報を分ける
## 4. 設定UI
設定項目は次の構造を維持する。
```text
ルール名
いつ
何に対して
どのような条件で
何をする
追加する指示
```
「何に対して」は、選択したタイミングで対象が必要な場合だけ表示する。
### 4.1 いつ
初期実装:
- 常に
- ツールを実行する直前
- 作業を完了する直前
将来候補:
- エージェントが動作を開始する前
- LLMを呼び出す前
- ツールを実行した後
- Movementを開始する前
- Movementを完了する前
### 4.2 何に対して
一般設定ではカテゴリ単位で選択する。
- すべてのツール
- コマンド実行
- インターネット検索
- ファイル読み取り
- ファイル変更
- 外部通信
- ブラウザ操作
- SSHや外部マシン操作
初期リリースでAPIとUIが受け付けるカテゴリは、`command_execution`、`internet_search`、`file_read`、`file_write`、`external_communication`、`browser`、`ssh` に限定する。`git` と `data_deletion` は将来の引数・構文分類に備えてPolicy型には保持するが、初期UIには表示せず、APIは保存を拒否する。既存データ等から未対応カテゴリを含むsnapshotが実行時へ到達した場合も、黙って非一致にせずfail-closedとする。
初期分類ではBash系ツールを `command_execution`、MCPツールを `external_communication` とする。Git操作や削除操作を厳密に区別するには、ツール名だけでなくコマンド構文・引数の決定的な解析が必要なため、その分類器を実装してから `git` と `data_deletion` を公開する。
個別ツール指定は詳細設定に置く。
### 4.3 どのような条件で
将来フェーズでは自然言語条件を入力できるようにする。ただし、すべてを小型LLMへ送らない。初期実装では新規入力・編集を提供せず、決定的テンプレートに変換できる条件だけを扱う。
次は決定的に判定する。
- 対象ツールとカテゴリ
- PieceとMovement
- ユーザー権限と承認状態
- 発火回数
- 外部通信の有無
- 既知の危険操作
- ファイル削除や権限変更
- 言語比率
意味判断が必要な候補だけ、小型LLMが登録済みルールIDを三値判定する。
```text
match
no_match
unknown
```
将来、小型LLMを導入する初期段階ではshadow modeとし、発火結果と遅延を測定するだけで制御actionへ使用しない。自然言語条件を使う本番制御は、precision、P95遅延、Judge対象率、承認疲れの基準を満たした後に段階公開する。
初期UIでは自然言語条件の新規作成・編集を提供せず、既存データに含まれる条件付きルールは読み取り専用で表示する。小型LLMによるshadow評価と自然言語条件の編集UIは将来フェーズで追加する。初期提供では決定的テンプレートに変換できる組合せだけ制御actionを有効にし、停止、管理者通知は表示しない。
判定モデルは追加指示、拒否理由、停止理由を自由生成しない。
### 4.4 何をする
- エージェントに登録済みの追加指示を与える
- 今回のツール実行を中止する
- 既存のユーザー承認を求める
- タスク全体を停止する
- 監査ログへ記録する
- 管理者へ通知する
追加指示には既存のmessage injection方式を再利用するが、DBコメント取得処理を直接呼ばない。専用の `InstructionInjector` が同一iterationの全tool resultを記録した後に、統合済みの登録指示をuser messageとして1件だけ追加する。ツール実行前に追加指示を与えた場合、元のbatchは実行せず、全tool callへ合成tool resultを作ってからエージェントへ戻す。
承認UIの配置と `waiting_human` の状態遷移パターンは既存機能を利用する。Policy承認には専用request、専用waitReason、専用CAS decide/resume処理を追加し、既存tool-requestの再開関数へ直接流さない。
Policy承認は既存のtask+tool名権限付与とは別recordへ保存し、task、Piece、Movement、rule ID/version、tool名、正規化引数をfingerprintで固定する。「今回だけ」はrequest IDとnonceを持ち、tool実行直前に `approved → consumed` をCAS更新できた1回だけ許可する。引数が変更された場合や実行失敗後の再試行には、新しい承認を要求する。
### 4.5 Hook pointごとの許可action
| Hook point | 初期実装で許可するaction |
|---|---|
| `always` | 初期実装では設定APIが拒否する。static preamble合成を実装した将来フェーズで `inject_instruction` を許可 |
| `tool.before` | `audit_only`、`inject_instruction`、`deny_current_tool`、`request_approval` |
| `completion.before_accept` | `audit_only`、`inject_instruction`、`deny_current_tool` |
| `tool.after` / `tool.denied` / `runtime.error` | 観測専用。利用者が制御actionを設定しない |
`stop_task` は初期実装の設定APIが拒否する。専用のタスク終端設計を追加した将来フェーズで再検討する。UIのdisabled表示だけに依存せず、設定APIのschema validationでも未対応の組合せを拒否する。初期 `completion.before_accept` では承認待ちとstopを扱わず、必要になった場合は専用のpark/ABORT設計を追加してから許可表を拡張する。
## 5. 常時適用ルールと条件付きルール
以下は将来フェーズの設計である。初期実装はstatic preamble合成経路を持たないため、`always` の新規作成・更新を設定APIで拒否し、保存成功後のsilent no-opを防ぐ。既存データに残る `always` はUIで読み取り専用として表示する。
```text
常時適用ルール
└─ 判定モデルを呼ばず、Job開始時にstatic preambleへ一度だけ合成
条件付きルール
└─ 対象Hookで状態を判定し、成立時だけ登録済みactionを実行
```
「常に日本語で回答する」「常に初心者向けに説明する」などは常時適用ルールとする。将来フェーズでは設定UIを条件付きルールと共通化し、「いつ」で `常に` を選択できるようにする。
Jobのclaim・workspace準備時に有効ルール、rule version、発火上限、常時指示、Judge設定をsnapshotし、Job内では不変とする。常時指示はAGENTSやMemoryと同じ静的preamble側へ安定した順序で合成し、毎iteration、毎Movement、途中user messageとして重複追加しない。設定変更は次のJobから反映する。
AGENTSとの機能重複は残るが、利用者が一つの画面から振る舞いルールを管理できる利点がある。セキュリティ境界、ツール権限、承認要否は自然言語指示へ移さない。
## 6. テンプレート
次のテンプレートを初期提供する。
- 初心者向けに説明する
- 日本語で回答する
- 難しい言葉を避ける
- コマンドには補足を付ける
- 危険なコマンドを確認する
- 外部送信前に承認を求める
- 公式資料を確認する
- Movement外の操作を防ぐ
- 削除操作を監査ログへ記録する
テンプレート選択時には、「いつ」「対象」「条件」「action」「追加指示」「発火上限」「判定方法」の編集可能な初期値を設定する。テンプレートは設定項目を隠すために使わない。
## 7. 権限
### 一般のワークスペース編集者が設定可能
- 追加指示
- 日本語の維持
- 初心者向け説明
- 難しい言葉の回避
- ユーザー承認要求
- 通常の監査記録
### 追加権限が必要
- タスクの強制停止
- 管理者通知
- 監査ログの保存範囲変更
- ワークスペース全体の強制セキュリティルール変更
- 他ユーザーに不利益を与え得る制限
権限やsandboxの本体はHookへ移行せず、独立した既存機能として維持する。Hookはそれらを共通サービスとして呼び出す。
## 8. 透明性
- 全メンバーがAuto Prompter全体のオン・オフ状態を確認できるようにする
- 全メンバーが有効なルール一覧を確認できるようにする
- 無効なルールは一覧から消さず、オフ状態として表示する
- 追加指示、拒否、承認、停止など、行動を変える発火は通知する
- 常時適用ルールは毎回通知せず、設定画面またはセッション開始時に確認可能とする
- 通知にはルール名、対象操作、実施actionを示す
- 判定結果を「不正利用者」などの人格評価へ変換しない
表示例:
> 自動ルール「削除前の確認」が適用されました。今回の操作は実行せず、影響範囲を確認するようエージェントへ指示しました。
## 9. 初期実装の推奨範囲
初期実装は、実現可能性調査のPhase 0~4を順に検証した最初のGA範囲を指す。各Phaseはfeature flagで分離し、未到達Phaseの設定はUIで非表示または無効化する。
### 含める
- ワークスペースごとのルール保存
- ワークスペース編集権限によるCRUD
- ワークスペース全体のマスタースイッチ
- ルールごとの有効・無効の切り替え
- ルール名
- 「いつ」「何に対して」「条件」「action」「追加指示」
- 常時適用ルール
- テンプレート
- ツール実行前Hook
- Complete受理前の最小Hook
- 決定的判定による候補絞り込み
- 小型LLMによる三値判定のshadow評価
- 既存ユーザー承認との接続
- 発火回数と重複発火の制限
- 基本監査ログ
- 発火時のユーザー通知
### 後回し
- 自由記述の自然言語条件による拒否、停止、承認の本番制御
- ユーザー個人による上書き
- 組織、ワークスペース、ユーザーの多階層ルール
- Movement遷移の制御
- 生成ストリーム途中の判定
- Hook同士の複雑な依存関係
- 一般ユーザーによる管理者通知設定
- 自動的な利用者制限
- 大規模なプラグイン基盤
## 10. リスクと対策
### 共有ワークスペースでの好みの衝突
「詳しく説明」と「簡潔に説明」などが競合し得る。初期実装では個人上書きを導入せず、全員へ適用されることを明示し、ルール変更履歴を残す。競合が運用上問題になる場合にだけ階層化を検討する。
### 自然言語条件の不安定性
曖昧な条件、モデル変更、プロンプトインジェクションにより結果が変化する。決定的フィルタを先行させ、モデルには候補IDと三値判定だけを許可する。Web本文やツール引数は非信頼データとして区切る。
### 動作の予測困難化
適用ルールと発火通知を可視化し、監査イベントにrule ID、rule version、判定方法、actionを残す。
### 承認疲れ
発火上限、同一fingerprint抑止、クールダウン、拒否後の再申請制限を設ける。安全上決定的に拒否すべき操作を承認へ流さない。
### 監査イベントの配信・重複排除契約
policy監査のJSONL保存は、決定的な eventId を付けた **best-effort append** とする。exactly-onceおよびat-least-onceは保証・表明しない。再試行や複数runtimeにより同じ eventId の行が複数保存される場合がある。markerファイルや別のdedupeディレクトリは作成せず、既存markerが残っていても参照しない。
ライブ通知は、永続appendに成功したイベントだけを候補とする。JobEventBus がjob単位のbounded first-seen FIFO(初期上限1,024 ID)でfirst-wins重複排除を行い、jobの done で状態を破棄する。append失敗はseenへ登録しないため、後続の成功した再試行を通知できる。REST読取はJSONL内の同一 eventId をfirst-winsで1件へまとめる。同一IDでpayloadが異なる場合も先頭を正本として扱い、将来必要なら機密情報を含まない警告だけを追加する。
### 監査ログのプライバシー
会話全文や生のツール引数を原則保存せず、allowlist形式の要約、マスキング、保持期限、アクセス制御を適用する。
### Hook基盤の複雑化
観測は既存EventLoggerを用いる非同期・fail-open、制御は明示的な同期PolicyGateとして分離する。既存の権限、承認、timeout、retry、Movement遷移をHook内部へ全面移行しない。
## 11. 敵対的レビュー
一般ユーザーへ公開すると、曖昧な自然言語条件、共有メンバー間の好みの衝突、過剰な承認要求、挙動の再現性低下、問い合わせ増加が起きる可能性がある。
特に「常に日本語」「初心者向け」はAGENTSへ固定記述すれば済むため、Auto Prompterへ統合することが必ずしも技術的に優れているわけではない。また、危険操作は自然言語判定より、ツールカテゴリと引数に対する決定的な検査の方が安全である。
したがって一般ユーザー公開を正当化できるのは、次を守る場合に限る。
- 初期提供テンプレートを中心にする
- 常時ルールはJudgeを使わない
- 自然言語条件は安全境界として扱わない
- 既存承認と権限を置き換えない
- 適用範囲と発火結果を可視化する
- PoCで誤検知、見逃し、遅延、問い合わせ量を測る
PoCで自然言語条件のprecisionが低い、P95遅延が許容範囲を超える、承認疲れが顕著、または設定競合の問い合わせが多い場合は、自然言語条件を縮小し、「常時ルール+定型条件+既存承認拡張」へ戻すべきである。
## 12. 最終判断
採用する方針:
- Auto Prompterをワークスペース設定として一般ユーザーへ提供する
- 初期適用範囲はワークスペース共通に限定する
- ワークスペース全体とルール単位の2段階でオン・オフを切り替えられるようにする
- 設定は「いつ」「何に対して」「どのような条件で」「何をする」を維持する
- テンプレートと初期値で設定を支援する
- 常時適用ルールと条件付きルールを内部的に分離する
- 制御はツール実行前Hook、最終確認はComplete前Hookへ限定する
- 承認機構は独立サービスとして維持し、Hookから再利用する
- 観測用Hookと制御用Hookを分離する
延期する方針:
- 個人設定による上書き
- 多階層ルールの優先順位
- Movement遷移制御
- ストリーム途中の介入
- 自動利用者制限
- すべての既存処理のHook化
この方針は、一般ユーザーが求める説明スタイルや言語設定を扱いつつ、既存の承認・権限・Piece/Movementを最大限維持する。Hookは共通基盤、Auto Prompterはその利用機能の一つとして分離する。
## 13. 既存チャット画面への変更
### 13.1 現在の表示構造
現在のチャット画面は次の経路で構成されている。
```text
ChatPane
├─ ChatMessageFeed
│ ├─ ChatMessage
│ ├─ MovementGroupExpanded
│ └─ ChatMessageFeedPanel
└─ ChatComposer
└─ ChatComposerPanel
├─ ToolRequestApproval
└─ PackageRequestApproval
```
実際に使用されているメッセージ一覧は `ChatMessageFeed` である。かつて類似する旧構成が `ChatTimeline.tsx` に残っていたが、`ChatPane` からは利用されておらず、2026-09-07 に削除した(issue #1483)。
### 13.2 流用できるUI
| 用途 | 既存UI | 判断 | 利用方法 |
|---|---|---|---|
| ユーザー承認 | `ToolRequestApproval.tsx` | 構造と配置を流用可能 | チャット入力欄の直上に承認カードを表示し、Approve/Deny、mutation中の無効化、失敗表示、query更新を踏襲する |
| パッケージ承認 | `PackageRequestApproval.tsx` | 設計パターンを流用可能 | 汎用承認カード抽出時の第2の既存利用例とする |
| 入力ロック | `ChatComposer.tsx` / `ChatComposerPanel.tsx` | 流用可能 | `waiting_human` と `waitReason` にAuto Prompter承認待ちを追加し、承認中の再送信を防ぐ |
| 一時通知 | `useToast.ts` / `ToastHost.tsx` / `ToastCard.tsx` | そのまま流用可能 | 画面外のタスクで発火した場合や、軽微な適用完了を通知する。同一event IDで重複を抑止できる |
| 永続通知 | `NotificationBell.tsx` / `NotificationCenterPage.tsx` | 限定的に流用可能 | 承認待ち、強制停止、管理者通知など、後から確認すべきイベントだけを通知Inboxへ送る |
| 監査タイムライン | `ActivityTimeline.tsx` / `ActivityEventCard.tsx` | 表示基盤を流用可能 | policy用event kind、色、タイトル、要約を追加する。生の条件文やtool引数は表示しない |
| 軽量な進行表示 | `ChatMessage.tsx` の `ProgressPill` | 見た目だけ流用可能 | 「ルールを確認中」「追加指示を適用」の短い状態表示に使える |
| 再試行・Movement履歴 | `MovementGroup.tsx` | 原則変更しない | Auto PrompterイベントをMovement完了イベントとして扱わない |
### 13.3 新規作成が必要なUI
#### PolicyActionNotice
Auto Prompterの発火結果をチャット履歴へ永続表示する専用コンポーネントは現状存在しないため、新規作成する。
表示項目:
- ルール名
- 実行したaction
- 対象ツールまたは対象処理の安全な要約
- 「実行しなかった」「追加指示を与えた」「承認待ち」などの結果
- 発火日時
- 必要な場合だけ詳細表示
通常のエージェント発言と誤認しないよう、左右の吹き出しではなく中央のsystem noticeとして表示する。情報、警告、拒否、承認待ちで視覚状態を分けるが、色だけに依存せずラベルとアイコンを付ける。
候補ファイル:
- `ui/src/components/chat/PolicyActionNotice.tsx`
- `ui/src/components/chat/PolicyActionNotice.test.tsx`
#### PolicyApprovalCard
既存の `ToolRequestApproval` は、`ToolRequest` API、tool名、Movement、task単位のgrantへ直接結合している。このままAuto Prompter承認へ流用すると条件分岐が増えるため、Auto Prompter用カードは新規作成するか、共通の表示部品を抽出する。
推奨は次の分離である。
```text
ApprovalRequestCard(新規・表示専用)
├─ ToolRequestApproval(既存API adapter)
├─ PackageRequestApproval(既存API adapter)
└─ PolicyApprovalCard(新規API adapter)
```
`ApprovalRequestCard` はタイトル、理由、安全な操作要約、scope、Approve/Deny、pending/error状態だけを受け取る。API取得、mutation、権限判定、job再開は各adapterに残す。
候補ファイル:
- `ui/src/components/chat/ApprovalRequestCard.tsx`
- `ui/src/components/chat/PolicyApprovalCard.tsx`
- 各コンポーネントのテスト
### 13.4 チャットデータの持たせ方
Auto Prompter発火通知は一時的なtoastだけにしない。再読み込み後も「なぜ操作が止まったか」を追える必要がある。
初期実装では、既存の `progress` commentへ識別可能な構造化payloadを保存し、`ChatMessage.tsx` でparserを追加して `PolicyActionNotice` を描画する案が変更範囲を抑えやすい。
```json
{
"type": "policy_action",
"eventId": "...",
"ruleId": "...",
"ruleName": "削除前の確認",
"action": "inject_instruction",
"outcome": "tool_not_executed",
"targetLabel": "コマンド実行",
"createdAt": "..."
}
```
ただし、監査ログの完全なpayloadをコメントへ保存してはならない。チャット用payloadは表示に必要なallowlist項目だけに限定する。将来policy eventが増える場合は、`CommentKind` に専用kindを追加するか、タスクイベントfeedへ統合する。
### 13.5 表示方針
- 追加指示、拒否、承認、停止はチャット履歴へ必ず表示する
- `audit_only` はチャットへ毎回表示せず、Activityタブだけに記録する
- 常時適用ルールは各LLM呼び出しで表示せず、チャットヘッダーまたはセッション開始時に有効件数を表示する
- 同一event IDはtoast、チャット、通知Inboxで重複生成しない
- 詳細には自然言語条件全文、判定用プロンプト、生のtool引数、機密値を表示しない
- 共有ビューでは内部監査情報を除外し、利用者向け説明だけを表示する
### 13.6 変更候補ファイル
| ファイル | 変更内容 |
|---|---|
| `ui/src/components/chat/ChatMessage.tsx` | `policy_action` payload parserと専用noticeへの分岐 |
| `ui/src/components/chat/ChatMessageFeed.tsx` | 原則そのまま。既存comment feedへ載せる |
| `ui/src/components/chat/ChatComposer.tsx` | policy approval待ちのロック条件を追加 |
| `ui/src/components/chat/ChatComposerPanel.tsx` | `PolicyApprovalCard` を既存承認カードと同じ位置へ追加 |
| `ui/src/components/chat/ToolRequestApproval.tsx` | 表示部分を共通カードへ段階的に抽出 |
| `ui/src/components/chat/PackageRequestApproval.tsx` | 表示部分を共通カードへ段階的に抽出 |
| `ui/src/hooks/useToast.ts` | 原則変更不要。event IDを既存 `id` に渡して重複抑止 |
| `ui/src/components/notifications/*` | 重要イベントを通知Inboxへ載せる場合だけcategoryと表示文言を追加 |
| `ui/src/components/activity/ActivityEventCard.tsx` | policy event kindの色・ラベル追加 |
| `ui/src/lib/utils.ts` | `ActivityEventKind`、label、titleの拡張 |
| `ui/src/api/tasks.ts` | policy approval DTO、取得・決定API、表示payload型 |
| `ui/src/locales/*/chat.json` | notice、承認、エラー、入力ロック文言 |
### 13.7 推奨実装順
1. `PolicyActionNotice` と構造化comment表示を追加する
2. Auto Prompter承認を既存 `waiting_human` 状態へ接続する
3. `PolicyApprovalCard` を既存カードと同じ場所へ追加する
4. 3つの承認カードで重複する表示部分だけ `ApprovalRequestCard` へ抽出する
5. toastを軽微な通知、通知Inboxを要対応・重要イベントに限定して接続する
6. Activityタイムラインへ監査表示を追加する
承認UIを最初から全面的に汎用化するのは避ける。まずPolicy用adapterを追加し、Tool、Package、Policyの3例で共通部分が確定してから表示部品を抽出する方が回帰リスクを抑えられる。
## 14. 機能OFF時の完全後方互換要件
Auto Prompterを無効にしたワークスペースでは、設定UIとDB schemaの存在を除き、エージェントの実行動作を従来と同一に保つ。
### 14.1 二段階スイッチ
```text
auto_prompter.available(サーバー機能フラグ)
└─ auto_prompter.enabled(ワークスペースのマスタースイッチ)
└─ rule.enabled(ルール単位スイッチ)
```
- `available=false`: APIと設定UIを公開せず、実行経路は即時短絡する。
- `available=true, enabled=false`: 設定の閲覧・編集・保持だけを許可し、実行には介入しない。
- `available=true, enabled=true`: 有効なルールだけを評価する。
- マスタースイッチまたはルールをOFFにしても設定内容は削除しない。
### 14.2 OFF時に変更してはならないもの
- LLMへ渡すmessages、tools、tool schema、順序
- system prompt、Movement guidance、dynamic context block
- tool callの引数、順序、並列実行判定
- Workspace Tool Policy、sandbox、MCP、SSH、編集権限
- Tool Request、Package Request、ASKの状態遷移
- Movement遷移、Complete、WAIT_SUBTASKS、再試行、キャンセル
- Conversation、コメント、activity、最終結果
- Push、Webhook、Notification Inboxの通知条件
OFF時にはJudge、ルール取得、発火状態保存、policy監査、policy通知を実行しない。許容する追加処理は、メモリ上の機能フラグを確認して既存経路へ即時returnする処理だけとする。
### 14.3 実装上の制約
- 既存承認サービスを初期実装で全面的に書き換えない。
- `PolicyGate`は未指定またはOFFなら、既存tool dispatcherを直接呼ぶ。
- OFF経路ではtool callやmessagesをclone、normalize、serializeしない。
- feature flag判定のためにtool callごとのDBアクセスを行わない。
- 既存のTool RequestとPackage RequestはAPI adapterと状態管理を維持する。
- UI共通化は表示専用コンポーネントに限定し、mutationとjob再開は既存adapterへ残す。
### 14.4 後方互換テスト
同一fixtureを機能導入前相当と `available=false`、`enabled=false` で実行し、次を比較する。
- LLM requestのmessages/toolsスナップショットが一致
- tool実行履歴、引数、結果、順序が一致
- Movement historyとPiece resultが一致
- job status、waitReason、resumeMovement、askCountが一致
- task commentsと最終出力が一致
- Auto Prompter専用のrule/state DB query、Judge、通知が0回
- 既存テストを期待値変更なしで通過
- OFF時の追加レイテンシを計測し、回帰閾値を超えない
workspace master enabledは既存のworkspace取得またはJob claim snapshotへ同梱してメモリ判定する。ここでいうDB query 0回は、enabled判定後のAuto Prompter専用rule/state queryが発生しないことを指す。
## 15. 現行タスク処理アーキテクチャ
現行コードに基づく全体フローは、共通資料へ分離した。
- [MAESTRO タスク実行アーキテクチャ](./task-execution-architecture.md)
- Auto Prompter固有の挿入位置とOFF時短絡は次節に記載する。
## 16. Auto Prompterの挿入位置とOFF時短絡
```mermaid
flowchart TD
CLAIM[Job claim / workspace準備]
AVAIL{auto_prompter.available}
MASTER{workspace enabled}
SNAPSHOT[Policy Snapshotを作成]
PREAMBLE[常時指示をstatic preambleへ一度だけ合成]
TOOLCALL[LLMがregular / complete / transitionを生成]
LEGACY[既存dispatcherへ直接渡す]
PREFLIGHT[regular callをparse・基本許可判定<br/>control callを分類]
MATCH[regular callを決定的判定]
JUDGESHADOW[三値Judge<br/>初期shadow]
SHADOWAUDIT[shadow結果を監査<br/>制御には不使用]
JUDGEPROD[品質基準通過後の本番Judge<br/>Phase 5以降]
NEEDPRODJUDGE{本番Judgeが必要か}
DECISION{batch decision}
EXECUTE[allow callだけcache / execute]
POLICYRESULTS[Policy保留時<br/>同一assistant内の全tool callへ合成結果]
INJECT[統合した登録指示をuser messageで1件追記]
PARK[Policy approvalを保存してwaiting_human]
STOP[policy reason付きABORT<br/>既存終端処理で子タスクを取消]
EXISTINGFLOW[既存dispatcherのwaiting / terminal / 次iteration処理]
NEXTLLM[次のLLM iteration]
CLAIM --> AVAIL
AVAIL -->|false| TOOLCALL
AVAIL -->|true| MASTER
MASTER -->|false| TOOLCALL
MASTER -->|true| SNAPSHOT
SNAPSHOT --> PREAMBLE
PREAMBLE --> TOOLCALL
TOOLCALL -->|OFF| LEGACY
TOOLCALL -->|ON| PREFLIGHT
PREFLIGHT --> MATCH
MATCH --> NEEDPRODJUDGE
MATCH -->|意味候補・shadow| JUDGESHADOW
JUDGESHADOW --> SHADOWAUDIT
NEEDPRODJUDGE -->|no| DECISION
NEEDPRODJUDGE -->|yes: Phase 5以降・意味候補| JUDGEPROD
JUDGEPROD --> DECISION
DECISION -->|allow / audit_only| EXECUTE
DECISION -->|denyを含む| EXECUTE
DECISION -->|advise / approval / stop| HELD[batch全体を実行しない]
EXECUTE --> EXISTINGFLOW
HELD --> POLICYRESULTS
POLICYRESULTS -->|advise| INJECT
INJECT --> NEXTLLM
POLICYRESULTS -->|approval| PARK
POLICYRESULTS -->|stop| STOP
```
OFF時はSnapshot、preflight、引数正規化、Judge、policy監査を行わず、現在のdispatcherへ直接渡す。ON時はcall内のrule競合を `stop > deny > approval > advise > allow` で解決した後、iteration全体を集約する。異なるcall間では `stop > approval > advise` を全体保留として優先し、denyだけならdeny対象へ合成resultを作り、残りは既存dispatcherへ渡すため、InteractiveBrowse等の途中待機を含む従来の記録・再開挙動を維持する。advise、approval、stopでbatch全体を保留した場合に限り、regularとcontrolを含む同一assistant内の全tool callへ合成resultを作る。stopは新しいJob statusを増やさずhard-terminal abort reason `policy_stopped` 付きの既存ABORTへ変換し、既存終端処理でpending子タスクを取り消して利用者へ通知する。
### 16.1 Complete受理前Hook
```mermaid
flowchart TD
CANDIDATES[complete / transition候補を分類]
WINNER[既存規則でnative winnerを選択]
PENDING{pending子タスク等があるか}
AUTOPARK[既存WAIT_SUBTASKSへauto-park]
ENABLED{Auto Prompter有効か}
CGATE[completion.before_accept<br/>決定的確認のみ]
CDECISION{decision}
RECORD[既存control tool resultsを記録]
RESULT[Movement resultを生成]
RETRY[全control callへError: tool result<br/>登録済み指示を追記]
CANDIDATES --> WINNER
WINNER --> PENDING
PENDING -->|yes| RECORDP[既存control tool resultsを記録]
RECORDP --> AUTOPARK
PENDING -->|no| ENABLED
ENABLED -->|false| RECORD
ENABLED -->|true| CGATE
CGATE --> CDECISION
CDECISION -->|allow / audit_only| RECORD
CDECISION -->|deny / advise| RETRY
RETRY --> NEXTLLM2[次のLLM iteration]
RECORD --> RESULT
```
Complete Hookは、pending子タスクなどによるauto-park判定を通過し、本当に終端可能なCompleteだけに適用する。拒否または追加確認では、providerへ再送できるよう全control callへ `Error:` で始まるtool resultを記録し、既存retry経路と同じmessage順序で再推論する。発火回数はtask+Movement+rule単位でDBへ保存し、resume後も上限を維持する。
### 16.2 Policy状態の寿命
- Job内で不変かつDB永続: snapshot ID、rule version、常時指示、Judge設定。再claim時は現在設定で再構築せず復元する
- task・MovementをまたいでDB保持: 発火回数、承認要求回数、拒否済みfingerprint、承認decision、one-shotのrequest ID・nonce・消費状態
- Policy park中にDB保持: snapshot IDへ紐付くapprovalRequestId、nonce、fingerprintのresume context
- iteration内だけ保持: 候補rule、正規化済み引数、重複排除用の一時cache
- `jobId` は監査相関に使うが操作fingerprintには含めない。one-shotはrequest ID・nonce・未消費状態も一致条件にする
- delegate子エージェントで承認が必要になった場合、初期実装では独立駐車せず親へbubbleするか決定的に拒否する