Magic Moment

AI RUN / EVIDENCE TRACE

AIエージェントは、なぜ「完了」を誤認したか

34 runs、5 successes。生成物、Git、deploy、productionが別々の状態を指したとき、AIは簡単にfalse DONEを返す。

CEOコラムAI・業務変革村尾 祐弥約19分
AI RUN / EVIDENCE TRACEINCIDENT-DRIVEN DESIGN
RUNS34
SUCCESS5
BASELINE15%
REQUESTBASE A
GITRESULT B
DEPLOY REPORTREVISION B
PRODUCTIONSERVING A
FALSE DONEREPORT ≠ PRODUCTION
01 / STATEONE RUN ID
02 / EVIDENCEEXACT REVISION
03 / STOPNO PROOF, NO DONE

Read the English edition →

34回走らせて、成功は5回でした。15%です。

その日、AIは「deploy済み」と報告しました。productionは古いrevisionのままでした。

問題は、AIが嘘をついたことではありません。生成物、Git、deploy、productionが一致しなくても、自己申告だけで「Done」へ昇格できる設計だったことです。

4月には、夜通し動くagent pipelineが28回反復しました。testは通り、大きなPull Request(PR)もできました。その裏で、detached HEAD、更新されないGitHub diff、壊れたlocal state、失敗したcleanupが連鎖し、最後にはfalse completion reportまで出しました。

僕は法学部出身の非エンジニアCEOです。だからcodeの巧さより先に、「契約、請求、資金繰りという業務結果が本当に変わったか」を見ました。その視点が、build successとproduction successは別物だと教えました。

この記事は成功談ではありません。AI workerの実行速度が人間の検証速度を超えたとき、何が壊れたのか。失敗のたびに、完了条件をcode generationから、revision、deploy evidence、production readbackへ動かした記録です。

先に、この記事が証明しないこと
AIによって開発生産性、品質、顧客価値、費用対効果が改善したとは証明できません。新しいpipelineが旧pipelineより成功しているとも言えません。同じ分母を持つ現在のrun ledgerがないからです。本稿が示すのは、特定時点の活動metadata、当時記録された障害、障害後に導入したcontrol、そして今も残る穴です。

82秒mergeは、速度ではなく警報だった

調査の起点は大きな数字でした。

固定snapshotには8,048 commitsがあります。固定cutoffまでのPRは1,362本。そのうちmm-yuya名義は1,261本で、cutoff時点でmerge済みだった1,205本のcreated-to-merge中央値は1.37分でした。910本、つまり75.5%が2分以内です。

AUTONOMOUS DEV5 / 34

2026-03-26時点の旧script。成功率15%。

MERGED BY CUTOFF1,205

共有account名義。review主体を証明しない。

MERGE P501.37m

p10 0.36分、p90 7.49分、p99 469.47分。

≤ 2 MINUTES910

分母1,205。高速reviewの証拠ではない。

OPEN / UNMERGED56

cutoff時点。merge latencyからはright-censored。

IDENTITYCOLLAPSED

人間、worker、承認主体を同じaccountから分離できない。

commit数もPR数も、生産性ではありません。特に中央値82秒のPRは、通常のreview unitとして機能していたとは考えにくい。

mm-yuyaは僕個人の作業量を示す名札ではなく、人間と複数のAI workerが共有した入口でした。当時は便利でしたが、監査上は失敗です。

  • どのworkerとmodelがdiffを作ったのか
  • 誰がPRを作り、誰が承認したのか
  • どのcredential scopeで動いたのか
  • result SHAとdeploy revisionは一致したのか

Git metadataだけでは答えられません。大量のactivityが見えた一方で、provenanceは消えていました。

失敗1:それらしい答えを、事実より先に作った

2026年2月、AIが作った経営分析に、実データで裏づけられていない経済性が混ざりました。文章は整っていました。論理も一見通っていました。だから危険でした。

僕たちは、その文書を磨かずに削除しました。先に実データを取り直し、根拠が揃わない判断を止めるgateを追加しました。

壊れていた仮定は、次です。

model outputがcoherentなら、判断材料として使える。

実際には、coherenceはevidenceではありません。ここでDoneの境界を「生成完了」から「採用したauthorityで裏づけられた」へ移しました。

失敗2:正しいcodeが、間違った経営判断を実装した

資金繰りの計算で、年払い契約を月次cash flowへどう配賦するかを決める前に、AIが計算logicを変更しました。

構文は正しい。buildもできる。しかし、契約上の意味が決まっていない。変更は直後にrevertしました。

この失敗を、抽象語ではなくdecision contractへ落とすと、こうなります。

FieldEvidence / rule
Decision年払い契約を月次cash flowへどう配賦するか
Authoritysigned contractとbilling schedule
InvariantACVとMRRを同じcash inflowへ二重計上しない
Stop condition契約期間または請求日が欠損している
Human approvalFinance owner
Executable evidencefixtureとreconciliation test
Production readback月次合計と請求総額が一致する

「判断を外部化する」とは、AIへ美しい説明を渡すことではありません。authority、invariant、例外、停止条件、test、production predicateを、workerが検査できる形にすることです。

ただし、僕たちがこれを全runで機械強制できているとは、まだ証明できていません。

失敗3:deploy scriptが終わり、productionは変わらなかった

3月26日の誤報では、deploy scriptは成功しました。しかし、scriptが送ったlocal diskと、意図したcommitと、実際にserveされているrevisionを結ぶ証拠がありませんでした。

worker result     = commit B
deploy report     = success
expected revision = B
production        = revision A

この状態で、pipelineはDoneを返しました。

scriptのexit codeは、production stateではありません。必要だったのは、少なくとも次のchainでした。

result SHA
  -> landed SHA
  -> build provenance
  -> deployed revision
  -> serving revision
  -> production predicate

どこか一つが欠けたら、前へ進めない。health checkが200でも、意図した業務結果が返らなければVERIFIEDにしない。

失敗4:local fileをstate machineにした

4月のNight Shiftは、CEOが寝ているあいだにagentが実装とreviewを繰り返し、朝に一つのPRを届ける仕組みでした。

28回反復できたことは、自律性の証明ではありません。誤りも28回増幅できます。

NIGHT SHIFT FAILURE TREEFALSE COMPLETION
01

detached HEADでworkerの修正をpushできない。

02

push failureを致命的に扱わず、GitHub diffが古いまま残る。

03

reviewerが古いdiffを繰り返し読み、local iteration fileだけが進む。

04

ghost filesが反復数を誤認させ、安全上限を発火させる。

05

cleanupとrollbackの失敗を検知せず、完了報告を出す。

branch、GitHub diff、local counter、cleanup statusが別々のstateを持ち、authoritative sourceがありませんでした。人間の途中介入もtransition外で起きていました。

問題はagentの知能ではなく、distributed stateとfailure semanticsです。

Doneを、証拠付きの状態遷移に変える

障害後、僕たちは依頼をcontext.mdtask.mdmetadata.yamlへ分け、実装workerと判定ownerの役割を分けました。

しかし、fileを増やすだけでは同じ失敗を繰り返します。必要なのは、一つのrun_idへ証拠を結ぶことです。

ACCEPTED
  -> WORKER_EXITED
  -> LANDING_READY
  -> LANDED
  -> DEPLOYED
  -> VERIFIED | FAILED | ROLLED_BACK

各transitionには、最低限の証拠があります。

WORKER → LANDINGRESULT IDENTITY

base_sharesult_sha、clean tree、write scope、test evidence。

LANDING → DEPLOYREVISION IDENTITY

landed SHA、build provenance、deployed revisionが同じresultを指す。

DEPLOY → VERIFIEDPRODUCTION PREDICATE

serving revisionと、期待した業務結果のreadback。証拠欠落時は前進しない。

公開starter kitには、次の最小contractを入れました。

{
  "schema_version": "1.0",
  "run_id": "run-demo-001",
  "base_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "goal": "Change one bounded behavior",
  "write_scope": ["src/**", "tests/**"],
  "deny_scope": [".github/**", "infrastructure/production/**"],
  "acceptance": [{"name": "unit", "command": "python3 -m unittest"}],
  "timeout_seconds": 600,
  "production_readback": {"predicate": "response.status == 200"}
}

verify_run.pyは、reportをcontractのschema、run ID、base SHA、write/deny scope、acceptance command、production predicateへ結びます。dirty tree、scope外のchanged path、未実行・別commandのtest、result SHAとlanded SHAの不一致、deploy revisionの不一致、別predicateやreadback欠損を見つけると、後のstateを主張しません。

重要な限界があります。このverifierは、報告者が嘘をついていないことを証明しません。hard gateにするには、test、build、deploy、readbackのattestationをworkerとは別の主体が取得し、bot自身が変更できないremote controlで強制する必要があります。

現在のcontrolは、まだ破れる

2026年7月15日に固定した観測では、GitHub上のrequired CIとrequired reviewはなく、rulesetもdisabledでした。local pre-commit gateと明示deploy/readbackはありますが、local hookは迂回できます。

ControlLocalRemote enforcementBypassEvidence
Contract / scopeyesnopossibletask artifacts
Tests / static gatesyesno--no-verifylocal logs
Independent reviewconventionnopossibleincomplete
Landing identitymanual checknopossiblecommit SHA
Deploy identityexplicit deploypartialoperator dependentrevision
Production readbackscript / manualno universal gatepossibleprobe output

「証拠がなければ止まれ」は、まだsystem invariantではありません。運用契約です。

共有human identityも残るriskです。必要なのは、workerごとのGitHub Appまたはbot identity、短命credential、run IDとcommitのbinding、作成主体とlanding authorityの分離、signed build/deploy provenanceです。

さらに、扱うdomainには契約、請求、給与、税、資金繰りがあります。agent identityだけでなく、least privilege、secretと個人情報の隔離、model providerへの送信境界、destructive actionの承認、監査logが必要です。本稿のactivity数字は、その安全性を証明しません。

まだ測れていないもの

新しいpipelineの成功率

3月26日の15%は、旧autonomous-devの34起動/5成功です。その後、実行単位が変わりました。同じ分母を持つrun ledgerがないため、「15%から改善した」とは書けません。

今後の分母は、acceptedされた全runで固定します。各runに、次を残す必要があります。

run_id / contract_sha
base_sha / result_sha
worker identity / model / provider / version
accepted / landed / deployed / verified timestamps
failure stage / stop reason / retry count
human takeover minutes
tokens / actual cost
production predicate / rollback revision

一つの成功率より、stage conversion、p50/p95 latency、human takeover率、rollback率、escaped defect率を見た方が有用です。

費用対効果

repository単位のAI costも算出できません。定額契約、API課金、creditが混在し、run IDとbilling、CEO・engineerの介入時間が結ばれていないからです。

数字を推測で埋めれば、2月に削除した「根拠のない経済性」をもう一度作ることになります。

顧客outcome

production readbackは、意図したrevisionとtransactionが動くことを示せます。顧客との関係性や経済成果まで、deploy直後に証明するものではありません。software deliveryとcustomer outcomeは、別の時間軸とmeasurementが必要です。

集計logicとstarter kitを監査する

public repositoryの読者は、private source dataそのものを独立再現できません。できることは三段階に分かれます。

  1. 公開読者:synthetic testでcutoff、identity分類、zero-merge、option-like ref、false DONEの計算logicを検査する。
  2. 認可された読者:固定Git snapshotと、SHA-256で固定したredacted PR metadataから記事値を再計算する。
  3. 独立第三者:private sourceがないため、8,048 commitsや個別incidentの原資料までは検証できない。

以前の集計scriptには、cutoffより後にmergeされたPRをlatencyへ取り込み得るlook-ahead bugがありました。公開前監査で見つけ、createdAt <= cutoffかつmergedAt <= cutoffへ修正しました。optionに見えるGit ref、shallow repository、Git replace objectもfail-closedにし、mergeが0件ならmedianをnullにします。

scriptとstarter kitはMIT Licenseです。READMEの最初の1画面でlocal gateを試せます。agent loopへの最小組み込み例、GitHub Actionsのremote check例、gate自体をworkerから守るCODEOWNERS例も同梱しました。

ただし、workflow sampleを置いただけではremote enforcementになりません。workerがworkflow、verifier、contract、branch rule、credentialを変更できるなら迂回できます。改善するのはまずclaim protocolです。workerの「Done」だけではstateを進めず、矛盾した証拠をnon-zero exitで止めます。生産性、品質、顧客outcomeが改善したという主張ではありません。

自分のrepositoryへ持ち込み、壊して、抜け道を報告してください。成功例より、gateが拒否すべきcounterexampleの方が役に立ちます。

結論:controlを追加した。改善したとは、まだ言わない

大量のAI-assisted activityを発生させた結果、Git identity、PR review、deployment truth、state managementが壊れました。

僕たちはcontract、scope、test evidence、revision binding、production readbackを追加しました。しかし、それが全runで強制され、成功率、品質、顧客価値、ROIを改善した証拠はまだありません。remote enforcementと同じ分母のrun ledgerも未完成です。

これが現在地です。

AI coding agentの問題を、modelの賢さだけで解こうとすると、また同じ場所へ戻ります。agentが速くなるほど、必要なのは多くの生成ではなく、各state transitionで「何を見たら前へ進めるか」を決めることです。

そして、その証拠がなければ、Doneとは呼ばない。


集計方法・出典・境界

  • Git snapshot:3e14d2bb1123357f05fbf7dbceae5eb25568b76f、8,048 commits
  • GitHub PR cutoff:2026-07-14 18:29 JST、1,362 PRs
  • fixed redacted PR input SHA-256:a7e45878ab0e5eb20e0d5fe1c561676b352c889ab358c7abdb1787678865f01d
  • merge latency denominator:cutoffまでに作成・merge済みのmm-yuya名義1,205 PRs
  • 旧autonomous-dev baseline:2026-03-26の当時記録、34 runs/5 successes
  • Night Shift incident:2026-04-10の当時記録
  • enforcement observation:GitHub settings/APIとrepository configurationを2026-07-15に固定観測

Git author/PR authorはaccount attributionであり、keyboard入力者、実装者、reviewer、承認者を証明しません。Git月次はauthor timestampをJSTへ変換した分布です。incidentは当時記録から選んだ事例であり、failure全体の頻度分布ではありません。

#AI coding agent#Postmortem#Software delivery#Agent provenance

自分のAI coding pipelineで試す

contract、worker report、revision、production readbackを一つのrun IDへ結ぶ、標準ライブラリだけのstarter kitです。
Starter kitを開く