Skip to content
frontmatter
キー値
specdojo.idprj-0001:pjr-a99j-agent-git-isolation-breach
specdojo.typeproject
specdojo.statusready
specdojo.rulebookspecdojo:pjr-rulebook
specdojo.part_ofprj-0001:pjr-index
specdojo.item_typeissue
specdojo.item_statusdone
specdojo.priorityhigh
specdojo.ownerARC
specdojo.registered_at2026-08-26T10:59:39Z
specdojo.due_on2026-08-31
specdojo.completed_at2026-08-26T11:37:52Z
specdojo.conclusion原因は PJR-X3E8 の対処が個別テストの隔離に留まり、agent 起動環境そのものが GIT_DIR などを子プロセスへ渡していたことであった。exec-run・exec-trial・exec-worktree-command の全 agent 起動を gitEnvironment 経由へ統一し、job と e2e ツールの直接 Git 実行も揃えた。あわせて exec-agent-git-state を新設し、agent の各試行の前後で HEAD と local config を比較して、差分があれば親検証・reporter・commit・merge へ進む前に失敗させる。予防と検知の2層とした。agent による commit と core.bare 変更の検知、および危険な GIT_DIR が agent へ継承されないことを確認する回帰テストを追加した。統合テストは83件へ増えた。

PJR-A99J agentのgit操作が実リポジトリを破壊する事象が再発した ​

1. 課題内容 ​

PJR-5YW6 の実行で、メインリポジトリの core.bare が true に変更され作業ツリーが操作不能になった。あわせて worktree へテスト用フィクスチャのコミット2件が混入し、docs/register-item.md という実在しないファイルが追加された。実装の成果はなく worktree は破棄した。同種の事象は PJR-X3E8 で一度発生しており、テストで git を扱う際は隔離した環境変数を渡す規約を設けたが、再発を防げていない。agent の git 操作が実リポジトリの設定と履歴へ影響しないようにする。

2. 影響範囲 ​

観点影響
スコープagent が git を扱う全タスク。実リポジトリの設定と履歴に及ぶ
スケジュール事故のたびに実行が失敗し、復旧と原因調査が要る。今回は成果が得られず worktree を破棄した
コスト実行時間と agent 利用量が無駄になる。復旧に人手が要る
品質実リポジトリの設定変更に気づかないまま作業を続けると、後続の操作が想定外の結果になる。履歴への混入は追跡を困難にする
関係者git を操作するタスクを実行する全 agent

3. 対応方針 ​

項目内容
原因exec trialを含むagent起動経路が親のprocess.envをそのまま渡し、Git hook由来のGIT_DIRをagentとテスト子プロセスへ継承していた。fixtureのgit initとgit commitが一時directoryではなくlinked worktreeのgitdirへ向いたため、共有configのcore.bare変更とexec branchへのfixture commit混入が同時に発生した
対応策全agent起動経路と親検証からrepository固有Git環境変数を除去する。加えてagent前後のHEADとlocal configを比較し、変更時は親検証・reporter・統合前にblockする
依存事項worktree による隔離を前提とした実行方式に関わるため、exec の実行経路を変更する場合は影響範囲を確認する
完了条件下記のとおり

3.1. 完了条件 ​

  • agent の実行によって実リポジトリの git 設定が変更されない。特に core.bare が変わらない。
  • agent の実行によって、意図しないコミットが実リポジトリまたはブランチへ混入しない。
  • 上記が守られなかった場合に検知できる。実行の前後で git 設定と HEAD を比較するなど、方法は判断してよい。検知したら実行を止めるか、記録に残して報告する。
  • PJR-X3E8 で追加した規約(テストから git を実行する際に隔離した環境変数を渡す)が、実際に守られているかを確認する。守られていない箇所があれば是正する。
  • 今回の事象の原因が特定されている。特定できない場合は、切り分けのために行った調査と、残る可能性を記録する。
  • 復旧手順が記録されている。core.bare が変更された場合の戻し方と、混入したコミットの扱いを含む。
  • npm run typecheck、npm run lint:ts、npm run test:unit、npm run test:integration が成功する。

今回の観測 ​

  • メインリポジトリの core.bare が true になり、git status が fatal: this operation must be run in a work tree で失敗した。git config core.bare false で復旧した。
  • worktree に register item と before registration の2コミットが混入し、docs/register-item.md が追加されていた。実リポジトリの追跡対象には入っておらず、worktree の破棄で解消した。
  • 実装の成果はなく、src/exec-trial.ts への変更はなかった。親検証3件は passed と記録されたが、実装が無い状態での結果である。
  • PJR-5YW6 は未着手として残る。再実行時は完了条件へ「実リポジトリの git 設定・履歴を変更しない」を明記する。

4. 対応結果 ​

解決内容:

  • src/exec-run.ts、src/exec-trial.ts、src/exec-worktree-command.tsの全agent起動環境をgitEnvironment()経由に変更した。通常worktree、in-place、executor / reporter pipeline、trial、分割worktree commandのいずれでもGIT_DIR、GIT_WORK_TREE、GIT_COMMON_DIRなどを子プロセスへ渡さない。
  • src/exec-agent-git-state.tsを追加し、agentの各試行前後でHEAD(commitとsymbolic ref)およびlocal configを比較するようにした。差分はagent-git-state-write:として記録し、親検証、reporter、commit、mergeへ進む前に失敗させる。
  • 親検証とworktree依存installにも隔離環境を適用した。残っていたsrc/job.tsとtools/e2e/exec-run-e2e.tsの直接Git実行もgitEnvironment()経由へ統一し、テスト・tool・本番コードの直接Git起動を再監査した。
  • tests/src/exec-agent-git-state.integration.test.tsでagentによるcommitとcore.bare変更の検知を追加し、tests/src/exec-worktree-command.integration.test.tsで危険なGIT_DIR / GIT_WORK_TREEがagentへ継承されないことを確認する回帰ケースを追加した。

原因の切り分け:

  • PJR-X3E8はtests/src/exec-agent-protected-config.test.tsの個別Git呼び出しだけを隔離したため、そのテストの再発は防いだが、上流のagent起動環境は未修正だった。
  • 今回事象でcore.bare変更とfixture commit 2件が同時に発生したことは、異なる一時repository用Git操作が同じ継承GIT_DIRへ向いた場合の挙動と一致する。実際にexec trialのworktreeEnvironment()がprocess.envを無加工で複製していたことから、再発経路を特定した。

再発防止と復旧:

  • 環境隔離を第一防御、HEAD・local config比較を検知防御、既存のcommit許可リストを統合防御とする。設計上の必須ルールをdocs/ja/product/040-system-design/sysd-cross-cutting-policy.md、運用詳細をdocs/ja/specdojo/guides/exec-config-guide.mdへ反映した。
  • 復旧手順をdocs/ja/specdojo/guides/exec-operation-guide.mdへ記録した。core.bareは影響確認後にgit config --local core.bare falseで戻し、git statusとgit fsckで確認する。混入commitは差分を確認して対象worktree / 未統合branchを破棄し、必要な成果だけを新しいworktreeへ適用する。共有済み履歴のresetやforce pushは行わない。

確認結果:

  • executor内でnpm run typecheck、npm run lint:ts、変更Markdownのprettier / markdownlint、register build、catalog validate、index buildが成功した。catalog validateの既存未作成文書に対するwarningを除き、errorはない。
  • npm run test:unit、npm run test:integration、npm run validate:schemaはexecutor / reporter pipelineの親検証として設定されているため、sandbox内では重複実行せずrunnerの検証結果を正本とする。

5. 関連ドキュメント ​