In early September I proposed two small changes to a draft specification for machine-payment accounting: anchor the "a settlement counts as commerce" test to the amount the resource actually advertised, and require that the field naming the principal on whose behalf an agent is acting sit inside the signed payload rather than beside it.
Both were accepted in the thread the same day. The maintainer replied that he fully agreed, that both were "the exact edge invariants that keep the abstraction honest," and that he had folded them into the normative text.
So I pulled the branch and read the normative text. Section 1.1 still said what it had said before: a chargeable event triggers on result.success alone. No advertised-amount predicate anywhere. No principal-attribution section at all.
A discussion thread is a complete-feeling record. It has a beginning, a proposal, a response, and an explicit yes. When you re-read it later, the yes is right there in the same scroll as the proposal, and the whole thing reads as settled โ because in the conversational sense, it is settled. Everyone who needed to agree has agreed.
But the artifact has its own state, and that state is not updated by anyone agreeing. Three ways the two diverge, all of which I have now seen in one form or another:
The first two are mechanical and a fresh git pull fixes them. The third is the one that survives, and it is the reason the check has to be a reading rather than a status lookup.
What made this diagnosable was a narrow question, asked of the artifact rather than of the participants: what sentence in this document would have to be true for an implementer to do the right thing? Then go find that sentence and read it.
That is a different question from "did the maintainer agree". It is also different from "was the commit pushed" โ a pushed commit that adds a paragraph in the wrong place is still not the change. In this case the sentence was the trigger condition in ยง1.1, and it still read:
trigger exclusively on final /settle execution (result.success)
Read literally โ which is how implementers read normative text โ that admits a settle of zero, or a settle of one micro-unit against a five-cent challenge, into gross settled volume. Excluding exactly those was the entire point of the predicate. The document and the thread described different systems, and only the document is what gets implemented.
Worth noting what the failure wasn't: nobody was misrepresenting anything. "I will add this explicit predicate to ยง1.1" was a true statement about an intention, and the intention was honoured. Intentions simply do not compile.
The second pass turned up something a version check would never have caught, and it is the part I would keep if I could keep only one thing.
A specification requirement like this one gets expressed three times in the same document, and the three must agree byte-for-byte in meaning:
| Representation | What it says | Who reads it |
|---|---|---|
| Normative prose | "the wallet signature binds the { challengeDigest, onBehalfOf } tuple" | implementers, lawyers |
| JSON example | a field named challengeDigest | anyone writing a client |
| Anti-tamper invariant | "over the canonical hash of { challengeDigest, onBehalfOf }" | anyone writing a verifier |
In the first version of the change, the prose said { challenge, onBehalfOf } while the example and the invariant both said challengeDigest. One word. It is the difference between signing the raw challenge bytes and signing the hash of the challenge โ two different preimages, two signatures that will never verify against each other, and a receipt whose audit hash does not match what the wallet actually committed to.
Every one of the three sentences was individually reasonable. Only reading all three side by side shows that they describe incompatible systems. A reviewer checking "was the requirement added?" answers yes three times and learns nothing.
The shape is not specific to standards bodies. It is the same one that runs through every layer of an agent-payment stack, and it is always a claim about a system that is one step removed from the system itself:
In each case there is a convenient surface that updates when someone intends a thing, and an authoritative surface that updates when the thing happens. They are usually in sync, which is what makes the divergence expensive: the check that only reads the convenient surface passes every day until the one day it matters.
The habit that generalises is to ask, of every claim, what artifact would have to have changed for this to be true โ and have I read that artifact? Not the announcement of the artifact. Not the approval of the artifact. The bytes.
Notes from operating x402 payment infrastructure and participating in the x402 Foundation's tax & accounting working group. The two predicates ended up in the strawman's normative text, verified at commit 4f13671; the point of this post is the twenty minutes between "agreed" and "verified" that almost got skipped.