SpecRunnerDocs
ドキュメント安全性と保証
SAFETY MODEL

安全性と保証

SpecRunnerがコードでenforceする保証、fail-closedの境界、trust model、意図的な例外を分けて説明します。

このページの内容

Guarantee Set G1の適用範囲

安全性は「止める場所」まで含めて読みます。fail-closedは自動却下ではなく、判定材料が足りないときに人間へ戻す設計です。escalationを無人で自動承認しません。

G1は2026-07-13制定の保証集合です。「何を保証するか」と「どの実装がenforceするか」を対にし、機構が存在しない主張は含めません。

boundaryassumptionmeaning
対象profilestandard / fastPRを生成するrunのG1保証
対象外profiledesign-onlyverification・review・conformance・PR生成を通らない
入力request.mdはtrusted input作者が内容を管理する前提
repositorycommit historyを信頼git log / diffがagent promptへ入る
最終判断人間がPRをreview・mergesolo useで作者とreviewerが同一でも省略しない

コードでenforceされる6つの保証

G1-1Verdictは機械導出

review agentはfindingsだけを返し、CLIがseverityとresolutionからverdictを導出します。

G1-2Findingの参照を検証

verdictに影響するcritical・high・decision-neededのfile:lineが実在しなければescalationへ倒します。

G1-3Gateはskip不能

standardとfastはverification・code-review・conformanceを迂回する遷移を持ちません。

G1-4収束ループは予算有界

reviewer / fixer loopはmaxIterationsを持ち、枯渇時は人間へescalationします。

G1-5Credentialはseamに封じ込める

subprocess envのsecret除去、出力mask、host-token束縛をarchitecture testで継続検査します。

G1-6受け入れ基準を照合

PR作成前のconformanceがrequest.mdと実装を照合し、approved以外では先へ進みません。

保証の追加・削除・意味変更ではG1の版号を上げます。file pathの更新や表現修正だけでは版号を変えません。

判定不能を安全側へ倒す

すべてを同じ方法で停止させるのではなく、失われる保証に応じてescalation、over-activation、verification fail、merge blockを使い分けます。

conditionresultprotected property
findingのfile:lineが存在しないescalation不正な根拠でapprovedを成立させない
scopeのchanged filesを導出できないUNKNOWN finding + escalation評価不能を無言で通さない
reviewerのpaths条件を評価できないreviewerを起動skipせずover-activationする
coverage対象fileがlcovに存在しないverification fail未loadをpass扱いしない
protectedPaths有効時にPR file listがtruncatedauto-merge block不完全な一覧でmerge判断しない
integrity-aware load / foldがjournal破損・counter逆行を検出JOURNAL_CORRUPTED該当経路の更新を停止。全entry pointの一律保証ではない

escalationでは人間が判断します。 「失敗したから無条件に拒否」ではありません。事実を表示し、修正・リスク受容・中止を操作者が選ぶための停止点です。

Journalを一次情報として復旧する

  1. 01
    append

    events.jsonlへ1行1recordで追記

  2. 02
    fold

    step、history、interruption、lineageを再構成

  3. 03
    project

    state.jsonを再構築可能なprojectionとして扱う

  4. 04
    resume

    journalにinterruptionがあればresumePointをmaterialize

journal状態扱い
末尾のpartial write最後の不完全な1行をdropし、直前のcommit済みrecordまでfold
中間行のinvalid JSON / non-objectfold時にcorruptionとして記録。integrity-aware load / persist経路は停止
fold件数がstate counterより減少fold時にcounter reversalとして停止
running processが消失staleを検出し、awaiting-resumeへreconcile

適用範囲。 catalog discoveryとpersist fast pathは一律fail-closedではありません。slug一覧はcorruption metadataを捨てる経路があり、new eventがないpersistはfoldを省く場合があります。運用ではdoctorを明示ゲートにし、失敗中はresumeしません。

journalから確認できる証跡は監査と証跡、再開ゲートは再開と状態照合、証拠保全を含む復旧操作はトラブル対応を参照してください。

Main checkoutへの逃避書き込みを検出する

local worktree modeのagent step前後で、main checkoutの監視対象をsnapshotし、content hashの差分を比較します。driftを検出するとcommitへ進まずawaiting-resumeで停止します。

  • 対象
    監視対象

    pipeline.fast.forbiddenSurfaces + .specrunner/**

  • 種別
    検出種別

    created / modified / deleted

  • 検出後
    検出後

    自動revertせず、人間が変更の帰属を判断

  • 再開
    再開

    再開runbookの全ゲート通過後

backstopの範囲。 これは全面的なfail-closed保証ではありません。snapshotのgit / fs errorはnullとして検査をskipします。managed・no-worktree、CLI step、監視対象外pathも対象外です。防止層を補う限定的な検出backstopです。

信頼境界を越えて使わない

TRUSTEDrequest.md

作者が管理し、agentへ渡してよい内容だけを記述します。

TRUSTEDcommit history

git loggit diffがpromptへ入るため、履歴も入力です。

ATTENDEDPR review / merge

Pipeline完走後も人間が差分とchecksを確認してmergeします。

GitHub Issueによる無人運用は推奨しません。 Issue本文を外部の未信頼入力として取り込む運用は、このtrust modelの外です。Issue連携を使う場合もtrusted author、承認label、人間のescalation対応とPR reviewを省略しません。

保証に含めないもの

design-onlyにもG1が適用される

適用されません。design-onlyはverification、code-review、conformance、PR生成を通らないため、PRを産むrun向けのG1対象外です。

agentがmain checkoutへ絶対に書けない

断言しません。local adapterの防止層と限定的なdrift detection backstopがあり、監視範囲と実行modeに既知のgapがあります。

0.xでもstate・config形式が固定される

固定されません。minor releaseでbreaking changeがあり得ます。migrationとchangelogを確認して更新します。

Pipeline完走がmerge承認を意味する

意味しません。awaiting-archiveは人間のmerge判断を待つ状態です。

運用者が最後に確認すること

  1. 1
    実行前

    doctor、request内容、repository履歴の信頼性を確認。

  2. 2
    停止時

    escalation reason、finding、drift path、journal integrityを確認。

  3. 3
    PR時

    差分、受け入れ基準、checks、protected pathを人間が確認。

  4. 4
    完了時

    merge前にarchive commandで記録し、merge後にStatus: archivedとcleanupを確認。

terminal
npx specrunner doctor
# archive前にslugの非終端jobが意図した1件だけか確認
npx specrunner job ls --all --json
npx specrunner job show <job-id>
npx specrunner job archive --with-merge <slug>
# cleanup後はslugで表示し、出力されたJob IDを固定値と照合
npx specrunner job show <slug>

同じslugの非終端jobが複数ある、または一覧のJob IDが固定値と違う場合はarchiveしません。

参照ソース 13