AI codingでGitだけでは分からなかった7つの問題を、小さなtoolにした
AI codingでは、Gitだけを見ていても答えが出ない問題がある。
- この未commitの変更は、どの依頼から来た?
- このregression testは、本当にfixを検出している?
- 消したsourceは、running processに残っていない?
- 同じcommitなのに、なぜ片方の環境だけ失敗する?
- git diffはcleanなのに、途中でfile操作がなかった?
- このJS artifactは、どのcommit付近のsourceから来た?
- GitHub Actionsのworkflowが呼ぶscriptは、package.jsonに実在する?
直近でこの7つを、それぞれ小さなtoolとして試した。どれも大きなframeworkではなく、ひとつの疑問に答えるためだけのCLIで、性質もばらばらだ。このページでは、7本をまとめて一覧できるようにする。
7本の一覧
| 困りごと | Tool | できること | できないこと |
|---|---|---|---|
| dirty treeに複数の依頼の変更が混ざった | wipwho | agent logを根拠に依頼単位でpatchへ分割、unresolvedを残す | 誰が書いたかの証明ではない。attributionは推定 |
| regression testが本当にbugを検出しているか分からない | Timewitness | 現在のtestをfix前worldでも実行し、Before FAIL / After PASSを確認 | fix全体の正しさやtest coverageの証明ではない |
| sourceを上書き・削除してしまった | Ember | まだ動いているNode processからV8 Inspector経由で残存sourceを回収 | live process+sourceがretainされていることが前提。完全復元は保証しない |
| 同じcommitなのに環境によって挙動が違う | Worldbisect | env・ignored file・小さなcache差をpredicateで試しながら1-minimal集合まで絞り込む | root causeやglobal minimumの証明ではない |
| git diffはcleanなのに、途中のfile操作が心配 | Afterimage | 残存NTFS USN Journalをsession時間窓とworking directoryへ絞って調べる | actorの証明でも content復元でもない。retentionに依存する |
| JS artifactが、どのcommitのsourceから来たか分からない | sourcemap-lineage | sourcemapのsourcesContentをGit historyと照合し、source一致commitをgroupで提示する | build provenanceの証明ではない。同一sourceのcommitは区別できない |
| GitHub Actionsが対象package.jsonに存在しないnpm/pnpm/yarn scriptを呼ぶ | workflow-script-audit | workflow commandと実際にresolveされるpackage.jsonのscriptsを静的に照合する | workflow全体の正しさやCI成功を保証しない。dynamic expressionやunresolved workspaceは推測しない |
Timewitness
問題: AIがfixとregression testを同時に書くと、現在のtreeでtestがPASSしていても、それは「fix前ならFAILしていた」ことの証拠にはならない。
できること: 現在のtestを実際に「fix前」のworldへ持ち込んで実行し、Before FAIL / After PASSを確認する。dirty treeのまま、commitやstashをせずに扱える。
できないこと: fix全体の正しさやtest coverageの十分性を証明するものではない。
Blog: AIが書いたregression test、本当にbugを検出している? Timewitnessでfix前後を確かめる
GitHub: https://github.com/iwadjp/timewitness
wipwho
問題: Claude CodeとCodexを並行して使っていると、あるいはそこへ手動editが混ざると、dirty treeに複数の依頼の変更がまとめて積み上がる。
できること: agent logを根拠に、依頼単位のpatchへ分割する。判定できない変更はunresolvedのまま残し、reconstruction hashで再構成結果を確認できる。
できないこと: 著者を証明するものではない。attributionはagent logに基づく推定であり、完全な帰属を保証しない。
Blog: Claude CodeとCodexの変更が混ざった。未commitのdirty treeを依頼ごとに分けるwipwho
GitHub: https://github.com/iwadjp/wipwho
Ember
問題: 編集中のfileを誤って上書き、あるいはgit checkoutやgit restoreで意図せず元に戻してしまった。ただしそのsourceを読み込んでいたNode processは、まだ動いている場合がある。
できること: V8 InspectorのDebugger.getScriptSourceを使い、まだ動いているprocessに残っているsourceを回収する。
できないこと: live processかつsourceがretainされていることが前提で、完全な復元を保証しない。activationは明示的なopt-inが必要。
Blog: Node.jsのsourceを上書き・削除してしまった。まだ動いているprocessから取り戻せるか確かめるEmber
GitHub: https://github.com/iwadjp/ember
Worldbisect
問題: 同じGit commitなのに、GOOD worldとBAD worldで挙動が違う。git diffは何も返さない。
できること: 環境変数・ignored file・小さなcache差などをpredicateで実際に試しながら削減し、observedな1-minimal集合を探す。
できないこと: root causeの証明でも、global minimumの証明でもない。
Blog: Git diffはcleanなのにNode.jsが失敗する。同じcommitの環境差分を絞り込むWorldbisect
GitHub: https://github.com/iwadjp/worldbisect
Afterimage
問題: git diffはcleanでも、agent runの途中でcreate・delete・renameなどのfile操作がなかったとは限らない。
できること: 残存しているNTFS USN Journalを、session時間窓とworking directoryへ絞って調べる。
できないこと: 誰が行ったかの証明ではなく、content復元でもない。保持期間(retention)に依存する。
Blog: Git diffはclean。でもagent run中のfile操作は消えていないかもしれない。AfterimageでNTFS履歴を調べる
GitHub: https://github.com/iwadjp/afterimage
sourcemap-lineage
問題: npmで公開されているJS artifactのsourcemapには、しばしばsourcesContentとしてビルド前のsource全文が残っている。しかしそれだけでは、どのGit commitのsourceかは分からない。
できること: sourcesContentを手元にcloneしたGit historyと照合し、blobが一致するcommitをgroupとして提示する。同一source内容のcommitを無理に1個へ絞り込まない。
できないこと: build provenanceの証明ではない。artifactが実際にどのmachine・環境でbuildされたかは示さない。同一sourceのcommitは区別できない。
Blog: sourcemapのsourcesContentは、どのcommitのsourceか特定できるか。Git historyと照合するsourcemap-lineage
GitHub: https://github.com/iwadjp/sourcemap-lineage
workflow-script-audit
問題: GitHub Actionsのworkflowが呼んでいるnpm/pnpm/yarnのscriptが、対象のpackage.jsonに実在するとは限らない。誰かがscript名を変更・削除して、workflow側の更新を忘れても、workflow YAML単体のlintでは見つからない。
できること: workflowが呼ぶscript名を抽出し、実際にresolveされるpackage.jsonのscriptsと静的に照合する。workspaceのfilter/working-directoryも解決する。
できないこと: workflow全体の正しさやCI成功を保証しない。dynamic expressionやunresolved workspaceの値は推測しない。
Blog: GitHub Actionsにpnpm run fooと書いてあっても、package.jsonにfooがあるとは限らない。workflow-script-auditで静的に照合する
GitHub: https://github.com/iwadjp/workflow-script-audit
どれを使う?
| 状況 | 使うtool |
|---|---|
| dirty treeに複数の依頼の変更が混ざった | wipwho |
| そのtestが本当にbugを捕まえているか分からない | Timewitness |
| 消したJSが、まだ動いているNode processに残っているかもしれない | Ember |
| 同じcommitなのに片方の環境だけ失敗する | Worldbisect |
| final diffには残らないfile操作を調べたい | Afterimage |
| JS artifactが、どのcommitのsourceから来たか調べたい | sourcemap-lineage |
| GitHub Actionsのworkflowが存在しないscriptを呼んでいないか調べたい | workflow-script-audit |
共通して分かったこと
- 最終状態(git diff・git status)だけでは、途中の情報が消えていることがある。
- Gitが追跡していない別の残留情報(agent log、running processのメモリ、環境差、USN Journal)を使うと、後から調べられる場合がある。
- 「証明」と「推定」は分けて出す必要がある。attributionやroot causeは、多くの場合厳密な証明ではなく推定にとどまる。
- UNKNOWN・AMBIGUOUS・INCONCLUSIVEのような判定を残す方が、誤った断定より安全。
- 事前にinstrumentationを仕込んでいなくても、残っている証拠で後から調べられる場合がある。