Refactor Receipt — act101 Agent Skill
Emit durable refactor receipts — content-addressed JSON artifacts proving a refactor was verified. Delegates to the shipped gate machinery (act gate --receipts / MCP gate with receipts:true) rather than re-running verification ops manually.
refactor-receipt
Emit durable refactor receipts — content-addressed JSON files stored in
.act/receipts/ that record the full verification evidence for each changed
function. The receipt machinery is built into act gate; this skill describes
how to drive it, where the files live, what validity means, and how to read one.
Honesty caveat (read first)
A receipt is evidence, not proof of equivalence. The modeled_kinds field
records what the grammar can actually judge; every dimension the grammar cannot
judge is reported as unknown:… in the contract field, never silently treated
as preserved. Per-grammar degradation is real — some languages cover fewer
dimensions. When citing a receipt, always quote modeled_kinds for any
unknown dimension; omitting it misrepresents the receipt's confidence.
Rename receipts always record contract: "unknown:rename" because names differ
by construction; that is not a verification gap, it is the correct honest answer.
Tier
Engineer. The gate tool (which writes receipts) requires the Engineer tier.
The receipt: true parameter on the four refactor tools also requires Engineer;
it is silently ignored in preview mode.
Emitting receipts
Whole changed set — act gate --receipts
Run after a refactor session to verify and record every changed function in one pass:
act gate --receipts
MCP equivalent:
gate(receipts=true)
The gate discovers changed functions from the git diff (working tree vs HEAD by
default, or vs base_ref when supplied), runs the full verification pipeline
per function, and writes one <id>.json receipt to .act/receipts/ per
verified function. The overall verdict (MERGE / REVIEW / BLOCK / UNKNOWN) is
returned; receipt writing does not change the verdict rules — those live in the
gate engine.
Single refactor op — receipt: true
The four refactor tools (rename, extract_function, move_symbol, inline)
accept receipt: true to write a receipt immediately after applying the change.
CLI usage (dev builds, --features dev-cli):
act refactor --receipt rename --file src/lib.ts --old-name foo --new-name bar
MCP equivalent (pass receipt=true as a parameter):
rename(file=…, old_name=…, new_name=…, receipt=true)
On success the result carries receipt.id. On failure it carries
receipt_error. In preview mode (preview: true) the field is ignored and no
receipt is written.
Where receipts live
All receipts are stored flat in .act/receipts/<id>.json at the workspace
root. The <id> is the first 16 hex characters of
sha256("<file>\0<symbol>\0<before_hash>\0<after_hash>") — a content-addressed
key that encodes the exact before/after state.
Validity — content-addressed, never stale
Receipt consumption is always on when .act/receipts/ exists: before using
a cached result the engine recomputes before_hash and after_hash from the
live span text and confirms they match the stored values. A mismatch means the
code changed since verification ran — the receipt is discarded and the function
is re-verified from scratch. There is no "stale pass": a hash mismatch is always
a re-verify signal.
Receipts with an unrecognised schema_version are also silently skipped and
treated as re-verify signals.
Reading a receipt
Each receipt is a JSON file with these fields:
| Field | What it means |
|---|---|
verdict |
MERGE / REVIEW / BLOCK / UNKNOWN — the gate's top-line decision |
contract |
"preserved" / "broken:<dims>" / "unknown:<dims>" |
diff_semantics |
Array of hunk classifications: format, signature, behavior |
effects_added / effects_removed |
Side-effect delta |
dropped_cleanup |
true if a cleanup effect was removed |
impacted_tests |
Test files whose call graph reaches the changed function |
modeled_kinds |
Bitmask of what the grammar could judge — cite this for any unknown dimension |
before_hash / after_hash |
"sha256:<hex>" of the function's span text at verification time |
id |
Content-addressed key (see above) |
tool_version / timestamp |
Provenance |
When citing a receipt in a review or audit:
- Quote the
verdictandcontractfields. - For any
unknown:…orbroken:…contract, quotemodeled_kindsand name the unmodeled dimension — do not present anunknowndimension as preserved. - The verdict decision rules live in the gate engine (
full_descriptionof thegatecatalog entry); do not re-derive them here.