ClaudeMods
☰
ZH-TW
● 0 人在線上 · 瀏覽 0 次
贊助提交作品
GitHub 儲存庫 · 發布者 ccdwyer

proof-decay

Claude Code 外掛,追蹤後續編輯後哪些 test、typecheck、lint 和 build 結果仍然有效,並阻止聲稱檢查通過但實際已過期的 commit message。

已翻譯

關於這個 mod

Proof Decay 會記錄 agent 執行的每次 test、typecheck、lint 和 build,之後只要後續編輯碰到它涵蓋的內容,就立即將結果標記為過期。它在提示列上方顯示 proof board,在每回合結束和 commit 前為 working tree 建立指紋,並使用 Oathkeeper 拒絕這類 commit:commit message 聲稱檢查通過,但這些檢查實際上已過期、失敗或缺少。可辨識的命令包括 npm/yarn/pnpm/bun test/lint/typecheck/build、jest、vitest、mocha、playwright、pytest、tsc、vue-tsc、mypy、pyright、eslint、ruff、biome、go test/vet/build、cargo test/check/clippy/build、swift test/build、xcodebuild test/build、gradle test/build,以及 make test/lint。透過 /plugin marketplace add ccdwyer/claude-mods 和 /plugin install proof-decay@ccdwyer-mods 安裝。它完全在本機執行,不會透過網路傳送任何內容,也不會收集 telemetry。

安裝

請先查看作者 README,確認 marketplace 與外掛名稱;指令可能隨儲存庫結構而變動。

claude plugin marketplace add ccdwyer/proof-decay
claude plugin install proof-decay
原文 / README

Proof Decay

Proof Decay demo

Tests and tsc pass, so the board reads ✓ tests fresh · ✓ types fresh. One edit later both go ⚠ stale (1 edit), and a commit claiming "All tests pass" is refused by Oathkeeper. MP4

| Fresh | Stale | Refused | |---|---|---| | fresh | stale | refused |

A Claude Code mod that tracks which verification results are still true.

"Tests passed" stops meaning anything once the code changes. Proof Decay records every test, typecheck, lint and build run the agent makes, then marks the result stale as soon as a later edit touches what it covered.

  • Proof board above the prompt, for example ✓ tests fresh · ⚠ types stale (3 edits) · ✗ lint failed. It shows the repo you're in.
  • What counts. Only a lone check, an && chain that succeeded, or the last command of a newline/; script is recorded, because those are the only cases where the one exit status the call has can be pinned to the check. npm test; true, npm test || …, pipes, subshells and $(…) never produce a pass, and anything inside quotes is never treated as a command. A check whose outcome can't be read (npm test || true, $(npm test), a failed chain) casts doubt on the earlier pass instead. Interrupted or backgrounded runs are skipped.
  • Scope. Only a bare whole-project run (npm test, pytest, go test ./..., tsc -p tsconfig.json) counts as a project result. Some runs are scoped or filtered instead. That includes runs from below the repo root (or from a nested package.json), runs that name files or a directory, script variants (test:unit), workspace or package flags, plain cargo test at a workspace root, and name filters (-t, -kfoo, --lib, -only-testing). They still show on the board, but they never back a claim. A failed scoped run also casts doubt on the project pass.
  • Staleness. Results go stale on any edit in the repo, including edits made by the agent's own shell commands. At the end of each turn, and before every commit, each repo's working tree is fingerprinted: the path and content id of every tracked and untracked file that isn't ignored. HEAD and the index are left out, so committing the tested tree doesn't make it stale, while putting an edit back makes the result fresh again. That catches changes no hook saw, such as your editor, a formatter or a script. A run whose files changed while it was running is not trusted.
  • Oathkeeper. The commit message is read from -m, heredocs and -F files, and git -C is supported. If it claims checks passed ("all tests pass", "typecheck is clean", "CI is green"), but the matching whole-project run in that repo is stale, failed or missing, the commit is refused. Hedged lines ("should pass", "tests pass when…", "not all tests pass") are ignored. A claimed commit has to run as its own command, not chained after other commands. git add before it in the same call is fine. It's also refused if it would commit less than what was tested: unstaged changes, untracked files the tests saw (even with -a), or pathspec, --only and --patch commits. bash -c '…' wrappers are looked inside. After popd, cd ~ or cd -, the target repo can't be pinned, so claims are refused. If a message can't be read in advance (a $VAR, an editor, --amend --no-edit when history can't be read), the commit only goes through while every check in the repo is fresh. Every other commit goes through, with a note to the model listing what wasn't re-verified.
  • /proofs lists every recorded run with its age, scope, repo and any reason for doubt. /proofs clear forgets them all. Results last for the whole session, across prompts.

Recognised commands include npm/yarn/pnpm/bun test/lint/typecheck/build scripts, jest, vitest, mocha, playwright test, pytest, tsc, vue-tsc, mypy, pyright, eslint, ruff, biome, go test/vet/build, cargo test/check/clippy/build, swift test/build, xcodebuild test/build, gradle test/build, and make test/make lint.

Install

/plugin marketplace add ccdwyer/claude-mods
/plugin install proof-decay@ccdwyer-mods
/reload-plugins

Develop

claude plugin validate .
claude plugin test .

What it hooks

Events this mod hooks, as claude plugin validate reads the module:

  • session.start
  • command.run{command=proofs}
  • tool.call{tool=Bash}
  • tool.call
  • turn.complete
  • ui.render{component=AbovePrompt}

Engine calls it makes: $.clock.now, $.command.register, $.fs.read (via demote, judgeCommit), $.fs.stat (via exists), $.process.run (via fingerprint, judgeCommit, rootOf), $.session.cwd, $.state.get, $.state.set, $.ui.resolve.

A tool.call hook sits in the middle of every tool call: it can see the call, refuse it, or add context to its result. This mod uses that only for the behaviour described above.

Privacy

It runs entirely on your machine. It sends nothing over the network. It runs git locally to fingerprint the working tree.

The mod collects no analytics or telemetry, and its author receives no data from it.

Full policy: PRIVACY.md.

License

MIT

更多類似作品