Anthropic's AI-Native SDLC Playbook makes intent.md, spec.md and plan.md, committed to git, your audit trail. Nothing in it checks that the trail is intact. Edit the intent after the spec is signed off and the record quietly lies about what was approved. We wired a 130-line hash-chain checker as a blocking hook, so editing an approved upstream artifact snaps the chain before a pull request can open.
What the playbook says
Anthropic published the AI-Native SDLC Playbook in August. Its one good line is code is no longer the bottleneck, your process is, and its fix is to push agents into every stage of the lifecycle, not just the build step. Each stage ends by writing one file to version control and the next stage begins by reading it:
intent.md → spec.md → plan.md → diff + tests → PR + review
The playbook's own words: "Together, the intent, the spec, the plan, the diff and the review findings are the audit trail." A human signs off at each gate. The originator approves the intent, the product owner approves the spec, the engineer accepts the plan.
The gap
Nothing checks the chain is intact. The artifacts are just markdown files in a repo. Nothing stops someone editing intent.md after the spec was signed off, or reshaping the spec after the engineer accepted the plan. When that happens the audit trail does not break, it lies: it now shows an intent that never produced the spec sitting next to it. Hooks are deterministic and skills are advisory, and on this particular link the playbook has neither. Three of the handoffs it describes are approvals with no check that the thing approved is still the thing in the file.
What we built
One file, chain_check.py, no dependencies. Each downstream
artifact records, in its front matter, the SHA-256 of its parent's body as it
stood when it was signed off:
---
stage: spec
parent: intent.md
parent_sha256: 8f3a...c1
---
Sealing, which stamps those hashes, is the sign-off action a human runs. After that the checker recomputes each parent's hash and fails loudly if any link no longer matches. Here is the whole thing working: build a chain, sign it off, then edit the approved intent and try to commit.
$ python3 chain_check.py --dir intent
[ok ] intent.md
[ok ] spec.md (parent: intent.md)
[ok ] plan.md (parent: spec.md)
chain intact
$ # someone edits the signed-off intent.md, then tries to commit
[ok ] intent.md
[SNAP] spec.md (parent: intent.md) ← parent 'intent.md' changed since sign-off (sealed 2bc5c651846d, now 046b1df37fe1)
[ok ] plan.md (parent: spec.md)
CHAIN BROKEN: an approved artifact changed after sign-off
The exit code is non-zero, so the pre-commit hook and CI block it. To fix it
you review the change and run --seal again, and that reseal is
the human-in-the-loop gate the playbook asks for, now made enforceable instead
of assumed. The included .claude/settings.json shows it wired as
a Claude Code PreToolUse hook that runs before any commit or push.
Why it matters
An audit trail you cannot verify is documentation, not evidence. The whole pitch of the artifact chain is that a regulator, a security reviewer or a teammate six months later can read the intent, the spec and the plan and trust they describe the same change. That trust is only worth anything if the files are tamper-evident. The moment an upstream artifact can be edited after sign-off without leaving a mark, the chain proves nothing. This makes the cheapest possible version of that guarantee: a content hash per link, checked by a hook. It is the difference between saying the artifacts are the audit trail and having something that fails the build when they stop being one.
What's still off
This proves an artifact was not changed after sign-off. It does not prove who signed off, or that the reviewer was a human rather than an agent rubber-stamping its own work. For identity you need the seal to live inside a commit signed by the reviewer, and then the git history and these hashes together give you the full trail. We built the deterministic half; the identity half is your version control's job, and we have not wired that end to end. The checker also only covers the markdown stages, intent through plan. Extending the same idea to the diff and the review findings is obvious and unbuilt.
What's now in the stack
chain_check.py: verifies and seals an intent → spec → plan chain, ~130 lines, no dependencies.- Templates for
intent.md,spec.mdandplan.mdmatching the playbook's structure. - A sample
.claude/settings.jsonhook that blocks a commit on a broken chain. test_chain_check.py: six cases, including the tamper-snaps-the-chain path, all passing.- The whole kit on GitHub. Drop it into your own repo and point the hook at your artifacts.