What the critique found
The btw.media article, published against revision 04, reproduced two Merkle roots for the same five-step "get BTC price" workflow. The live workflow page built leaves as SHA-256 over the UTF-8 bytes of seq:receipt_hash, producing root a4b2fcb4684cec481e4ece889ed15c7d9e47e58d9ba4fb02ea354c0cb2ca44c4. Revision 04 required leaves as SHA-256 over the UTF-8 bytes of each step's receipt_id, producing root 7c4817ca249edfeae259b98abf63ed38a31d9dbeebf5ee23139410a7a7f63b37. Same parent rule, same odd-node duplication, different leaves, different trees. Both calculations were reproducible. Neither was malformed.
Beyond the divergence, the review made four further points: revision 04 first called the construction recommended and then made it a MUST; the 43-vector conformance corpus tested no workflow root at all, so a perfect score said nothing about this boundary; the word "verified" bundles at least six separate facts (step integrity, manifest binding, leaf semantics, root compatibility, witnessing, external effect) and a root cannot upgrade provenance or turn invocation into delivery; and a traveling root needs a "construction passport" recording which rule built it, with a careful migration path that never silently recomputes old roots.
Thank you for the review. It is the kind of reading that makes a draft better, and revision 12 is measurably better for it.
Claim by claim: what revision 12 changed
Two roots for one workflow
Section 8.1 now states a single normative construction: "An implementation MUST use the construction specified above. The alternative-construction permission from earlier revisions is removed." The leaf is SHA-256 over the UTF-8 bytes of the step's receipt_id string; parents pair raw 32-byte digests; an odd level duplicates the last digest; the final digest is lowercase hex.
Section 8 goes further. Its worked example replays the exact workflow the review examined (workflow 42a3c2cf-2cdd-5b8a-aced-016e5a2fb634, "get BTC price", five steps) and publishes merkle_root 7c4817ca249edfeae259b98abf63ed38a31d9dbeebf5ee23139410a7a7f63b37: byte-identical to the review's draft-construction root. The draft states this value recomputes from the five step receipt_id values with the Section 8.1 construction and that the live record at the workflow's verify URL carries it. Spec, reference implementation, and the review's own arithmetic now converge on one root.
The RECOMMENDED/MUST contradiction in Section 8.1
Fixed. The revision 12 abstract names the fix explicitly, and Section 8.1 now speaks with one voice: MUST, no contradiction, no alternative-construction permission.
The underspecified leaf contract
The review listed what a verifier must know: what becomes a leaf, how the input is encoded, how children combine, what happens to an odd child, and how the final value is represented. Section 8.1 now pins every one of these. Two edge cases the review's contract implied are spelled out: with a single step, the leaf digest is the merkle_root (no pairing occurs), and an empty steps array MUST be rejected by a verifier. As a backstop, "a verifier that cannot determine the construction MUST NOT report the Merkle root as confirmed."
The odd-duplication collision class
With last-duplication on odd levels, the step lists [r1, r2, r3, r4, r5] and [r1, r2, r3, r4, r5, r5] recompute to the identical root, so root comparison alone cannot distinguish them. Section 8.2 now requires verifiers to confirm that no two steps carry the same receipt_id value and to reject the receipt if they do. The draft states the rationale plainly: the rule is structural, not cosmetic, and it closes this collision class at the verification layer.
"Verified" must name its object; a root upgrades nothing
Section 8.2 now requires verifiers to "report only what the stored observations support": a passing Merkle root confirms the step sequence is intact as recorded, and "the workflow receipt does not upgrade the provenance of its steps." New Section 8.4 states the truncation honest limit: a rebuilt root over a shorter step list still verifies, so the root check alone MUST NOT be presented as truncation-proof. Section 10 adds that a verified anchor proves the digest existed at the anchor time and "does not upgrade the receipt's provenance class." The review's six facts stay separate in the text: step integrity, manifest binding, leaf semantics, root compatibility, witnessing, and external effect are each checked by their own rule.
The construction passport
Section 8.1 now requires implementations to document the leaf encoding, hash function, tree structure, and output encoding alongside the receipt so an independent verifier can recompute the root from the steps array alone, and forbids reporting a root as confirmed when the construction cannot be determined. That answers the substance: a root that cannot name its construction is not a confirmed root.
What is not yet specified is the compact machine-readable passport the review sketches (a leaf-construction identifier, schema versions, anchor scope, the vector version that tested the construction, and a policy version on the acceptance decision itself). The documentation requirement is normative; the passport format remains a design proposal. Open.
Migration must not silently recompute old roots
Section 9 now states the stability rule the review asked for: once published, the record at a URL MUST NOT be altered, and corrections are published as new receipts that reference the superseded id rather than rewriting history at the original URL.
What is not yet specified is the explicit labeled-transition procedure the review recommends (preserving the original commitment, publishing a versioned successor, and calculating both roots with clear labels during transition). The anti-rewrite rule is normative; the transition procedure remains guidance. Open.
A workflow-root test vector
The review's sharpest process point stood when this page was published: the conformance corpus carried no vector that exercised the Section 8 Merkle construction, so a perfect score said nothing about this boundary. Revision 12 grew the corpus to 45 vectors, and none of them froze leaf inputs, leaf digests, intermediate levels, odd-node duplication, or the final root value for a workflow.
That gap has since closed. The corpus now ships nine dedicated Merkle vectors (the canonical five-step workflow, the byte-exact worked example, odd-node duplication, ordering sensitivity, the single-leaf and one-step cases, the empty-steps rejection, the duplicate-receipt-id collision, and rejection of the legacy construction), exercised by both reference runners as part of the current 99-vector, 102-check corpus. A perfect score now says something about this boundary.
What remains open, in one list
- A workflow-root conformance vector: closed since publication. The corpus now carries nine Merkle vectors covering leaf inputs, leaf digests, intermediate levels, odd-node duplication, and the final lowercase root, run by both reference implementations.
- A machine-readable construction passport: a compact identifier for the leaf construction and the acceptance policy version, so a root carries its own rule instead of relying on adjacent documentation.
- A specified migration procedure with labeled dual roots for transitions, so no deployment ever silently recomputes a published root.
These are tracked as specification work, not as disagreements. The review was right that an honest verifier reports the split until implementations, fixtures, and deployed surfaces converge. On the central split, the two-roots problem, they now converge.
Status: an Internet-Draft, improved by review
Review is the process working
AER-1 is an IETF Internet-Draft (draft-zambo-aer1), currently at revision 23. It is a working document, not a finalized standard, and independent technical review is exactly how working documents get better. The btw.media reading caught a real divergence between text and deployment, named the missing contract precisely, and proposed concrete remedies. Revision 12 adopted the substance of those remedies, and the first of the three remaining items, the workflow-root vector, has since landed in the corpus. The passport and migration items above are the remainder, stated here so the next review can check them too.