PJR-3S8Q 実行コマンドを定義する設定ファイルは agent の書き込み範囲に含めない
1. 背景
親 runner の parent_validations は固定 argv(npm run test:integration)で起動するが、実行される内容は package.json の script 本体である。lefthook.yml のコマンドも commit 時に親コンテキストで実行される。したがって edit agent にこれらの書き込みを許すと、設定できるのは ID だけで任意の command や引数を注入できないという exec-defaults の設計前提が無効になり、サンドボックス外での任意コード実行につながる。PJR-CMYX の対応中に一度 allow へ追加したが取り消し、agent は変更が必要な場合に result へ申し送りとして記録し、人間または orchestrator が適用する運用とする。
2. 検討した選択肢
| 選択肢 | 内容 | 利点 | 懸念 |
|---|---|---|---|
| A | 実行コマンドを定義する設定ファイルを agent の書き込み範囲から除外し、必要な変更は result の申し送りとして人間または orchestrator が適用する | 親コンテキストで実行されるコマンドの改変経路を塞げる。既存の parent_validations の設計前提を維持できる | 設定変更を伴うタスクは agent 単独で完結せず、追加の手作業が発生する |
| B | 対象ファイルを allow に追加し、agent が直接編集できるようにする | 設定変更を含むタスクが 1 回の run で完結する | agent が script や hook の本体を書き換えることで、サンドボックス外の親 runner に任意コマンドを実行させられる |
| C | 追加は許すが、commit 対象の許可リストで当該ファイルの変更を弾く | 編集の利便性を残しつつ commit は防げる | 実行は commit 前の検証段階でも起こるため、書き換え自体が有効化される経路を塞げない |
3. 決定内容
選択肢 A を採択する。package.json、lefthook.yml、.specdojo/exec-defaults.yaml、.specdojo/claude/settings.*.json、commitlint 設定、CI 設定など、親コンテキストで実行されるコマンドを定義するファイルは、agent の書き込み許可範囲に含めない。agent はこれらの変更が必要になった場合、変更内容と理由を result の申し送りへ記録して終了し、人間または orchestrator が適用する。
4. 採択理由
- 親検証は
src/exec-parent-validation.tsの固定レジストリからnpm run test:integrationを固定 argv で起動するが、実行される内容はpackage.jsonの script 本体である。agent が script を書き換えられる場合、固定 argv であることは防御にならない。 .specdojo/exec-defaults.yamlには「設定できるのは ID だけで、agent の evidence や設定ファイルから任意の command / 引数を注入することはできない」と設計意図が明記されており、書き込み許可の追加はこの前提を無効化する。lefthook.ymlのコマンドは commit 時に親コンテキストで実行されるため、同じ種類のリスクを持つ。- PJR-CMYX では executor が両ファイルへの書き込みを拒否されたが、orchestrator が申し送りに従って適用することで機能面の欠落は生じなかった。運用として成立することが実例で確認できている。
5. 承認
| 項目 | 内容 |
|---|---|
| 決定者 | PO |
| 決定日 | 2026-08-21 |
| 承認方式 | commit |
| 証跡 | 本個票を追加した commit(docs(register): add PJR-3S8Q) |
- 承認方式は
commitまたはPRを記載する。PRの場合は証跡に PR URL と merge SHA を本文テキストで記載する。 - 不可逆・高リスク・framework schema 破壊的変更に該当する決定は
PR方式で承認する。
6. 影響範囲とフォローアップ
| 項目 | 内容 |
|---|---|
| 影響範囲 | edit / review 両モードの agent 権限設定と、設定ファイルの変更を含むタスクの進め方。provider ごとに sandbox の方式が異なり、claude は allow リスト、codex は workspace-write のため、決定は文章だけでは全 provider に効かない |
| 必要な対応 | 対象ファイルの一覧を agent 権限設定の運用ドキュメントへ明記する。設定変更が必要なタスクでは、申し送りと人手適用を前提に計画する。provider に依存しない実効的な強制手段を用意する |
| 追跡先 | PJR-CMYX の対応結果に記録済み。権限設定の実体は .specdojo/claude/settings.edit.json。強制手段は PJR-Y3KP で追跡する |
本決定の後、PJR-0DA8 の実行で違反事例が発生した。codex-expert-executor が .specdojo/claude/settings.report.json を直接作成し、register 実行の commit 対象が除外方式であるためコミットと merge まで通過した。生成された内容は意図した最小権限と一致していたため成果物としては受け入れたが、決定が provider の sandbox 方式に依存して守られないことが実例で確認された。実効的な強制手段は PJR-Y3KP で対応する。
6.1. 追記: 2026-09-27 の edit 権限の見直し
PJR-E8FY・PJR-QJAD・PJR-HG98 の実行で、claude の edit executor が packages/docs-site/.vitepress/・tools/grade/・README.md へ書き込めずに止まった。このうち QJAD では、executor が Bash 経由で tools/grade/run-per-document.sh を書き換えており、allow リストをすり抜ける経路が使われた。
最初は Edit(tools/**) と Edit(packages/**) を加える案を出した。しかし、次のファイルは git hook から親コンテキストで実行されるため、本決定の対象にあたる。git hook は worktree 間で共有されるので、runner が worktree で commit するときにも動く。
| ファイル | 実行される契機 |
|---|---|
packages/docs-lint/bin/specdojo-docs-lint.js | pre-commit(runner の worktree commit を含む) |
tools/build-if-stale.mjs | post-checkout / post-merge |
tools/protect-main-push.mjs | pre-push |
tools/install-lefthook.mjs | npm install の prepare |
そこで、hook や script の定義から呼ばれないパスだけを加えることにし、利用者が commit b52ac1c7 で .specdojo/claude/settings.edit.json に反映した。
| 追加した許可 | 理由 |
|---|---|
Edit(tools/grade/**) | grade のスクリプト。hook からは呼ばれない。routine から実行される点は既存の Edit(src/**) と同じ扱い |
Edit(packages/docs-site/.vitepress/**) | サイトの設定と表示部品。docs:build の実行時に読まれる点は Edit(src/**) と同じ扱い。packages/docs-site/package.json は対象外 |
Edit(README.md) | 文書で、実行されない |
packages/docs-lint/、tools/ 直下の hook の入口、各 package.json は、引き続き書き込み範囲に含めない。
途中で、許可をリポジトリ共通の .claude/settings.json に加える commit を一度作ったが、push 前に取り消した。共通設定はオーケストレーターと review / report の executor にも効くため、役割別の --settings で書き込み範囲を分ける設計が崩れる。edit の許可は settings.edit.json にだけ置く。
7. 関連ドキュメント
- 契機となった課題: PJR-CMYX exec 実行が古い dist ビルドを使い設定済み parent_validations が実行されない
- 設計意図の記載箇所:
.specdojo/exec-defaults.yamlのpipeline.parent_validations - 実装箇所:
src/exec-parent-validation.tsの固定レジストリ、lefthook.yml - 権限設定の実体:
.specdojo/claude/settings.edit.json