The audit record
Every task that reaches Done leaves one file in .zones/audit/. It is written by the machine at close, not composed afterwards by whoever remembers the week, and it is the artifact you hand a skeptic.
The unit is the task, and that is the whole distinction. Durable provenance for agent-written code already exists and is good — there are tools that record, per line, which model wrote it and from what prompt, surviving rebase and squash. That answers who typed this character. This record answers a governance question instead: for one unit of work, what did it declare it would touch, what did it actually touch, who approved the difference, and what was overridden and why. Same repository, different question — and a per-line log cannot answer this one no matter how complete it is.
What it contains
Section titled “What it contains”The frontmatter is the machine-readable half:
task: CC-39owner: paulo@commitcycle.combranch: task/CC-39-approve-and-close-is-offered-by-the-consquality_gate: regression suitezones_declared: []zones_touched: []declaration_matches: trueexceptions: 2blocks: 0mutations_observed: 0evidence: - type: capture location: .zones/evidence/CC-39/verification.mddiff: files: 13 base: HEAD~1 head: d8a07c8aclosed: 2026-08-04closed_by: agentzones_declared against zones_touched is the line that matters: it is the difference between what the task said it would do and what the diff shows it did. declaration_matches is that comparison, computed.
A fourth line appears only when it has something to say. If the work hit a wall mid-task, asked for a zone and an owner approved it, that approval amends the declaration — and the record splits the two, so you can tell a task that scoped a risky area up front from one that was let into it by a person:
zones_declared: [web:write]zones_amended: [schema:write]zones_touched: [web, schema]declaration_matches: truedeclaration_matches is measured against both together, because both are what the closing gate was checked against. The approval itself — who answered, when, for how long, and what the agent offered to do instead — is in the Access asked for table further down.
The body carries what was asked, what it was explicitly not allowed to do, how anyone would know it worked, the logged exceptions, and the file-by-file diff.
Logged exceptions
Section titled “Logged exceptions”An exception is not a failure. It is something the close noticed and refused to swallow silently — recorded with an owner and a date, so it is a question someone can answer later rather than a detail nobody was told:
2026-08-04 — at close, 12 changed file(s) are in no zone:
.zones/tasks/CC-39.md,AGENTS.md,apps/dashboard/package.jsonand 9 more. Should any be protected?cycle protect <glob> --zone <id>if yes,cycle dismiss <glob>to stop being asked.
Most repos have a long tail of paths nobody has decided about. Asking once, at close, when the evidence is in front of you, is cheaper than asking at declaration time when it is hypothetical.
The gap it admits
Section titled “The gap it admits”The most useful entry any of these records carries is the one about what could not be seen:
2026-08-04 — at close, Nothing observed this work: 12 changed file(s) and no mutation events at all. That is what a hand-edited task looks like — but it is also what a task run with the hook switched off looks like, and from here they are the same.
CC cannot tell those two apart from the record alone. A task edited by a human at their keyboard and a task run with Layer 2 uninstalled produce the same silence.
This is the same finding that makes Layer 3 necessary — a hook is fail-open unless something outside the laptop checks — and it is why closes have been refused on this repository twice rather than overridden. A record that quietly rounded that silence up to “verified” would be worth less than no record.