Agent Contract (the receipt is the interface)¶
A run that produces no receipt did not happen. The receipt is the only thing the estate trusts: not the transcript, not the summary, not the agent's own confidence.
Artifacts in this skill:
- schemas/factory-receipt.v2.json is the contract. Twelve invariants, all adversarially tested.
- scripts/validate_receipt.py runs schema plus the sixteen cross-field gate rules. Exit 0 accepts.
- scripts/conformance_test.py proves each invariant rejects a violation and accepts honest work.
- references/contract.yaml is the binding rule set to prepend to an agent's system prompt.
- references/receipt-design.md explains why each field exists and what it catches.
- examples/ holds five validated receipts covering the shapes agents actually produce. They are
generated from the conformance test rather than hand-written, so they cannot drift from it:
python3 scripts/conformance_test.py --emit-examples.
Before changing anything¶
python3 scripts/conformance_test.py # 19 rejections, 5 acceptances, must be clean
python3 scripts/validate_receipt.py examples/01-operate-pass.json
A schema change that does not come with a new rejection test is decoration. Every invariant must prove it rejects something, or it is a comment with extra syntax.
The vocabulary, and why it is small¶
Verdicts are PASS, FAIL, DEGRADED, UNKNOWN, NOT_APPLICABLE. There is no "success",
"done", "complete" or "looks good". The absence of a failing check is UNKNOWN, never PASS.
This single restriction removes most agent self-report inflation.
Four status fields exist and their precedence is fixed. verification.overall is the evidence
verdict and is the ceiling. result.status reports the requested effect and may never exceed the
ceiling, which INV-01 enforces. witness_status is advisory unless witness_required is true,
in which case INV-03 caps the verdict. terminal.state is disposition only and says nothing
about correctness: a BLOCKED_DURABLY receipt with a FAIL result and one with an UNKNOWN
result are both valid and mean different things.
Evidence classification uses the estate vocabulary, not a parallel one: PROVEN_IN_RUNTIME,
CURRENT_SOURCE, CANONICAL_POLICY, CURRENT_PRODUCT_DIRECTION, ASPIRATIONAL,
HISTORICAL_SUPERSEDED, NOT_ESTABLISHED. It matches the Evidence State table in
product-definition, so a receipt and a product definition grade the same claim the same way.
Authority is earned, never configured¶
OBSERVE detects and reports and changes nothing, which INV-05 enforces by rejecting any
receipt that claims OBSERVE alongside a source change, a runtime change or an applied artifact.
ASSIST prepares, tests and opens a reviewable change. A human approves deployment. Expect this
to be the default operating mode for a long time.
OPERATE executes an approved remediation class within explicit policy. INV-06 makes the
earning mechanical: an OPERATE receipt must carry a non-empty acceptance_ref, a non-empty
remediation_class, and verified_history_runs >= 1. Authority is scoped to
customer + remediation_class + verified_history + policy + acceptance, never to an account, and
a regression in a class revokes that class.
Selling or configuring OPERATE as the starting point converts trust risk, usually the top risk, into the first thing that breaks.
What the receipt catches that a summary never does¶
changes.ownership_delta makes Net-Negative Ownership checkable per run. NEGATIVE is the goal.
POSITIVE forces a human gate through INV-09, so custom-code surface cannot grow as a side
effect of an agent being helpful.
work.existing_work_searched and duplicate_work_created enforce curate-before-create at the
moment work is created, and INV-08 gates a duplicate rather than letting it quietly land.
factory.private_todo_remaining, polling_used and unsupported_internal_hack_used are honest
reporting fields with teeth: gate rules G-05, G-06 and G-07 reject the receipt outright. An agent
keeping work in its head instead of Beads fails the gate.
verification.criteria[].falsification_condition requires each criterion to state what would
disprove it. Expected versus observed is easy to write after the fact. A falsification condition
is not.
economics feeds the recurring model directly: model cost, infrastructure cost, human review
minutes and cost, automated actions, human escalations, accepted outcomes, and cost per accepted
outcome. estimate_basis: NOT_MEASURED is allowed precisely so unmeasured runs stay visible
rather than absent. Human review minutes is the number that answers the capacity question in
product-definition/references/pricing-economics.md.
Secrets and authentication¶
factory.secrets_referenced holds op:// references only, enforced by pattern and by gate rule
G-12. A literal value there is a constitution violation, not a style problem.
A 401 or 403 is diagnosed by layer and never assumed to be token expiry or a 1Password failure.
Declaring AUTH_BLOCKED requires all nine diagnostic fields (OPERATION, PRINCIPAL,
EXISTING_AUTH_PATH, ATTEMPT, AUTHENTICATED, TARGET, TARGET_ROLE, AUTHORIZED,
EXACT_DENIAL), which INV-04 enforces. A missing machine identity is reported as
MACHINE_IDENTITY_PROVISIONING_GAP and never resolved by falling back to a human credential.
Durability¶
terminal.durable_transition_established generalizes "work on disk is not done". INV-07 rejects
a COMPLETED receipt without it. Scheduled and unattended runs operate against remotes, so a
local checkout or worktree is never the system of record.
terminal.receipt_complete is set by the validator, not the agent. Agents emit false. A field
where the artifact certifies its own completeness is theatre unless something external stamps it.
Wiring structured output¶
Force a single tool call rather than asking for JSON in prose.
tools=[{"name": "emit_receipt",
"description": "Terminal output. Call exactly once, at the end of the run.",
"input_schema": SCHEMA}]
tool_choice={"type": "tool", "name": "emit_receipt"}
For providers whose strict mode rejects allOf, if, then, contains and minItems, strip
the allOf block and rely on scripts/validate_receipt.py for the invariants. The gate is the
enforcement point either way, because a model can be persuaded and a validator cannot.
Where this lives¶
This skill is the authority for the contract. The runnable Gas City pack that imports it is built separately and consumes these artifacts rather than restating them. If the pack and this skill disagree, this skill wins and the pack is corrected, exactly as generated outputs never become authority over the contract that produced them.