Network Working Group T. Oga Internet-Draft The HORIZONs Co., Ltd. Intended status: Informational 17 October 2026 Expires: 20 April 2027 MUSUBI Settlement: Recomputing Whether an Agent Acted Within a Signed Grant draft-oga-musubi-settlement-00 Abstract MUSUBI settlement is a deterministic function that takes a contract signed by two parties, a set of signed records of what an agent did under that contract, and a view of Bitcoin block headers, and computes whether the recorded acts stayed within the grant the contract gives. Anyone holding the same bytes can recompute the result without trusting the party that produced it. This document specifies one well defined part of that function, settle core v0, precisely enough that a second implementation can be written from the text and the published test vectors alone. Settlement is not runtime enforcement and is not a judgement of liability. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 20 April 2027. Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Oga Expires 20 April 2027 [Page 1] Internet-Draft MUSUBI Settlement October 2026 Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. What Settlement Is . . . . . . . . . . . . . . . . . . . 4 1.2. Why a Second Implementation Needs a Text . . . . . . . . 4 1.3. What Settlement Is Not . . . . . . . . . . . . . . . . . 5 1.4. Scope of Core v0 . . . . . . . . . . . . . . . . . . . . 5 2. Conventions and Terminology . . . . . . . . . . . . . . . . . 5 2.1. Requirements Language . . . . . . . . . . . . . . . . . . 6 2.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 6 3. Inputs, Outputs and the Shape of the Computation . . . . . . 7 3.1. Inputs . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.2. Reading JSON . . . . . . . . . . . . . . . . . . . . . . 7 3.3. The Computation in One Paragraph . . . . . . . . . . . . 8 3.4. Output . . . . . . . . . . . . . . . . . . . . . . . . . 8 4. Canonical Form, Digests and Signatures . . . . . . . . . . . 8 4.1. Canonical JSON (musubi-canonical-v0) . . . . . . . . . . 8 4.2. Base64 and Keys . . . . . . . . . . . . . . . . . . . . . 9 4.3. The Digests . . . . . . . . . . . . . . . . . . . . . . . 9 4.4. Ed25519 Verification . . . . . . . . . . . . . . . . . . 10 5. The Contract . . . . . . . . . . . . . . . . . . . . . . . . 10 5.1. The Contract Door (Contract Verification) . . . . . . . . 10 5.2. Settleable Terms . . . . . . . . . . . . . . . . . . . . 13 5.3. Strict Terms . . . . . . . . . . . . . . . . . . . . . . 14 6. The Header View . . . . . . . . . . . . . . . . . . . . . . . 15 6.1. Verifying the View . . . . . . . . . . . . . . . . . . . 16 6.2. Compact Target Decoding . . . . . . . . . . . . . . . . . 17 7. Records Before Their Anchors . . . . . . . . . . . . . . . . 17 7.1. Strict Records and Triage . . . . . . . . . . . . . . . . 17 7.2. Binding . . . . . . . . . . . . . . . . . . . . . . . . . 20 7.3. Size Limit . . . . . . . . . . . . . . . . . . . . . . . 20 7.4. Identical Bytes . . . . . . . . . . . . . . . . . . . . . 21 7.5. Several Copies of One Signed Body . . . . . . . . . . . . 21 7.6. Authentication . . . . . . . . . . . . . . . . . . . . . 21 7.7. Conformance . . . . . . . . . . . . . . . . . . . . . . . 22 8. Anchors . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 8.1. What an Anchor Is . . . . . . . . . . . . . . . . . . . . 23 8.2. Height . . . . . . . . . . . . . . . . . . . . . . . . . 23 8.3. Order of the Checks . . . . . . . . . . . . . . . . . . . 23 8.4. Height and Block . . . . . . . . . . . . . . . . . . . . 24 8.5. The Proof . . . . . . . . . . . . . . . . . . . . . . . . 24 8.6. The Batch Leg Rule . . . . . . . . . . . . . . . . . . . 25 Oga Expires 20 April 2027 [Page 2] Internet-Draft MUSUBI Settlement October 2026 9. The Event Set and Finality . . . . . . . . . . . . . . . . . 26 9.1. Order . . . . . . . . . . . . . . . . . . . . . . . . . . 26 9.2. Kinds . . . . . . . . . . . . . . . . . . . . . . . . . . 27 9.3. Same Block . . . . . . . . . . . . . . . . . . . . . . . 27 9.4. Horizon . . . . . . . . . . . . . . . . . . . . . . . . . 27 9.5. Status . . . . . . . . . . . . . . . . . . . . . . . . . 27 10. Output . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 10.1. Core Fields . . . . . . . . . . . . . . . . . . . . . . 27 10.2. Dispositions . . . . . . . . . . . . . . . . . . . . . . 29 10.3. Bond Outcome . . . . . . . . . . . . . . . . . . . . . . 30 10.4. Informative Fields . . . . . . . . . . . . . . . . . . . 30 11. Grant Evaluation . . . . . . . . . . . . . . . . . . . . . . 30 11.1. Revocation . . . . . . . . . . . . . . . . . . . . . . . 30 11.2. Expiry . . . . . . . . . . . . . . . . . . . . . . . . . 31 11.3. Actions and Delegation . . . . . . . . . . . . . . . . . 31 11.4. Conditional Actions and Approvals . . . . . . . . . . . 31 11.5. Forged Approvals . . . . . . . . . . . . . . . . . . . . 33 12. NENRIN Checks . . . . . . . . . . . . . . . . . . . . . . . . 33 12.1. Cross Check . . . . . . . . . . . . . . . . . . . . . . 33 12.2. Required Evidence . . . . . . . . . . . . . . . . . . . 33 13. Verdict . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 14. Written Behaviour and Changes from Earlier Settle Versions . 34 14.1. Written Behaviour . . . . . . . . . . . . . . . . . . . 34 14.2. Changes in Settle v1.16 . . . . . . . . . . . . . . . . 36 15. Test Vectors . . . . . . . . . . . . . . . . . . . . . . . . 38 15.1. Contents . . . . . . . . . . . . . . . . . . . . . . . . 39 15.2. The Core-Field Projection . . . . . . . . . . . . . . . 40 15.3. Reporting a Disagreement . . . . . . . . . . . . . . . . 40 16. Implementation Status . . . . . . . . . . . . . . . . . . . . 41 16.1. Reference Implementation . . . . . . . . . . . . . . . . 42 16.2. Independent Implementations . . . . . . . . . . . . . . 44 17. Security Considerations . . . . . . . . . . . . . . . . . . . 44 17.1. Unsigned Parts of a Record . . . . . . . . . . . . . . . 44 17.2. Signature Malleability and Strict Ed25519 . . . . . . . 45 17.3. Number and Canonicalization Divergence . . . . . . . . . 46 17.4. Reorganizations Deeper Than the Finality Depth . . . . . 46 17.5. What the Verdict Does Not Establish . . . . . . . . . . 47 18. Privacy Considerations . . . . . . . . . . . . . . . . . . . 48 19. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 48 20. References . . . . . . . . . . . . . . . . . . . . . . . . . 48 20.1. Normative References . . . . . . . . . . . . . . . . . . 48 20.2. Informative References . . . . . . . . . . . . . . . . . 49 Appendix A. Codes . . . . . . . . . . . . . . . . . . . . . . . 50 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 51 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 51 1. Introduction Oga Expires 20 April 2027 [Page 3] Internet-Draft MUSUBI Settlement October 2026 1.1. What Settlement Is A principal and a contractor sign a contract. The contract carries a grant: the actions the contractor is authorized to take, the actions it is prohibited from taking, the actions that need a separate approval from the principal, the parties to whom work may be delegated, an expiry height and a revocation policy. While the contractor (or a witness named in the grant) works, it signs records of what it did, and each record is committed to the Bitcoin block chain [BITCOIN] through an anchor. Later, anyone who holds the contract, the records and a view of the relevant block headers can settle: walk the records in the order the block chain gives them, compare each act with the grant, and produce a verdict, a status and a bond outcome. The record schema names carry the prefix "a2a" because the format was designed for agents that interact over the Agent2Agent (A2A) protocol [A2A]. Settlement reads no A2A message and does not depend on A2A. 1.2. Why a Second Implementation Needs a Text Until this document, the MUSUBI settle function was defined only by Python code (settle_v1.py to settle_v1_16.py, each layer importing the ones below it) [MUSUBI-REF]. A function that only one program can compute is a tool, not a protocol. This document states one well defined part of it, settle core v0, in plain language. A stranger should be able to write a second implementation from this text and the vectors alone, without reading the reference. The text was written from the reference code, not from intent. Writing it against settle_v1_10.py found places where the code accepted input a careful second implementation would read differently, and one place where a record nobody signed could change the verdict (items N1 to N11 of [MUSUBI-NOTES]). settle_v1_16.py was written to close them, and this document describes it. Section 14 lists what changed. Where the reference still does something surprising, this document says so and marks it WRITTEN BEHAVIOUR. Written behaviour is still normative for core v0: a second implementation that differs on it will disagree with the vectors. This document is an adaptation of [MUSUBI-SETTLE-CORE] into the Internet-Draft format. Where the two differ in meaning, that is an error in this document. Oga Expires 20 April 2027 [Page 4] Internet-Draft MUSUBI Settlement October 2026 1.3. What Settlement Is Not Settlement is not runtime enforcement. It never stops an agent from acting; it reads records after the fact and says whether the recorded acts were within the grant. Settlement is not a judgement of liability or fault, and it does not make the contract a legal contract. The verdict is a function anyone can recompute from the same bytes. Section 17.5 lists what the verdict does not establish. 1.4. Scope of Core v0 Settle core v0 is exactly what the reference computes when the contract carries none of the following: * requirements.spine (the spine gate, settle v1.8), * requirements.convergence (drawn measurers, settle v1.9), * grant.approval_policy.approvers (pinned approvers, settle v1.10), * grant.limits (which forces requirements.admission), * requirements.admission (settle v1.11 to v1.14 read it; the admissions input is passed through unchanged). It is computed in binding mode "strict" over exactly one header view. Out of scope, and not defined here: * choosing between several header views (fork choice by work above the checkpoint), * binding mode "legacy" (records bound by contract_id only), * fetching anything. Settle core v0 never touches the network. Every key it uses is inside the contract. If a contract carries any of the keys above, this document does not define the result. An implementation MUST NOT claim core v0 conformance for such an input. 2. Conventions and Terminology Oga Expires 20 April 2027 [Page 5] Internet-Draft MUSUBI Settlement October 2026 2.1. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. Most rules in this document are stated in the indicative ("is", "gives", "adds"). They are normative all the same: they determine the core fields (Section 10.1) that a second implementation MUST reproduce exactly. 2.2. Terminology contract: A JSON object with schema a2a-contract-v0, signed by a principal and a contractor, that carries the grant. principal, contractor: The two parties to a contract, identified by their role and holding the Ed25519 [RFC8032] keys pinned in the contract. witness: A key named in grant.witnesses that may sign execution records. record: An execution (a2a-execution-v0), a revocation (a2a-revocation-v0) or a revocation acknowledgement (a2a-revocation-ack-v0). header view: A list of raw 80 byte Bitcoin block headers [BITCOIN-HEADERS] with their heights. walk: A NENRIN walk record [NENRIN-VERIFIER] cited by an execution through nenrin_ref. the reference: settle_v1_16.py and the files it imports, at the versions listed in Section 16 [MUSUBI-REF]. WRITTEN BEHAVIOUR: A behaviour of the reference that may surprise a reader, kept because the vectors pin it, or would. integer: A JSON value written as an integer token: no fraction, no exponent. true and false are never integers. The following notation is used for byte strings. A string in double quotes, such as "a2a-contract-v0\n", denotes the ASCII bytes between the quotes, where \n stands for one line feed (0x0A). When A and B are byte strings, A + B is their concatenation. sha256(x) is SHA-256 Oga Expires 20 April 2027 [Page 6] Internet-Draft MUSUBI Settlement October 2026 [FIPS180-4] of the bytes x. Byte ranges such as "bytes 4 to 36" are zero-based and exclude the upper bound, so they name the 32 bytes at offsets 4 through 35. "Lowercase hex" means the characters 0 to 9 and a to f, two per byte. 3. Inputs, Outputs and the Shape of the Computation 3.1. Inputs 1. contract: one JSON object (schema a2a-contract-v0). 2. events: a list of JSON values. Each is meant to be a record: an execution (a2a-execution-v0), a revocation (a2a-revocation-v0) or a revocation acknowledgement (a2a-revocation-ack-v0). Anything else is ignored. Order carries no meaning. 3. view: one JSON object {"headers": [{"height": H, "hex": "<160 lowercase hex>"}, ...]}, raw 80 byte Bitcoin block headers. Other keys are ignored. 4. nenrin_records: optional list of JSON values (walk records cited by executions). Absent and empty mean the same thing. A value that is not a list is treated as absent. 5. parent: optional, the parent contract, needed only when contract.parent_contract is present (Section 5.3). If contract is not an object, the settlement is underspecified with the single reason contract_not_verified. If events is not a list, it is underspecified with input_not_settleable. Nothing else is computed in either case. Keys are not a separate input. The principal's and contractor's Ed25519 public keys are parties[i].public_key_ed25519_b64 inside the contract, and witness keys are grant.witnesses[i].public_key_ed25519_b64. key_url is never fetched. Checking that the key served at key_url equals the pinned key is outside settle core. 3.2. Reading JSON Inputs are parsed as JSON [RFC8259] with one extra rule: an object with a duplicate key is an error and no settlement is produced. Text nested deeper than 512 levels of [ or { (counted outside strings) is also an error. Oga Expires 20 April 2027 [Page 7] Internet-Draft MUSUBI Settlement October 2026 Numbers MUST be integers within plus or minus (2^53 - 1). The contract is checked for this in Section 5.1, records in Section 7.1, the view in Section 6.1 and walks in Section 12. A JSON value with a non-integer number is not "strict" in the sense of Section 7.1. A JSON value is an "integer" in this document only if it is written as an integer token: no fraction, no exponent. true and false are never integers. These rules are close to, but not the same as, I-JSON [RFC7493]. 3.3. The Computation in One Paragraph Compute contract_sha256 (Section 4.3) and bind records by it (Section 7.2). Triage every bound record (Section 7.1): records not strictly signed by a party are rejected or set aside here, and no later step sees them. Check the contract's terms (Section 5) and verify the header view (Section 6). Every problem found so far is collected; none of them stops the other checks in this paragraph. If a problem was found in Section 5.1, Section 5.2 or rules 1 to 8 of Section 6.1, no record is examined further. Otherwise: collapse copies of one signed body (Section 7.5), check conformance (Section 7.7), check anchors (Section 8). Records that pass are the event set, ordered by anchor height then record sha256 (Section 9). Walk the event set against the grant (Section 11), add the NENRIN checks (Section 12), and decide the verdict (Section 13), status (Section 9.5) and bond outcome (Section 10.3). The checks of Section 5.3, rule 9 of Section 6.1, Section 7.1 (a record that fails closed), Section 8.4 (below the lower bound) and Section 12 (a cited walk) are collected in the same way and make the settlement underspecified; they never stop the computation of the event set. 3.4. Output The output is one JSON object. Section 10 lists the core fields a second implementation MUST reproduce exactly. Everything else the reference writes is informative. 4. Canonical Form, Digests and Signatures 4.1. Canonical JSON (musubi-canonical-v0) canonical(v) is the UTF-8 [RFC3629] encoding of this text: 1. Objects: keys sorted by Unicode code point, at every level. Written {"k":v,...} with no whitespace. 2. Arrays: [a,b,...] with no whitespace. Oga Expires 20 April 2027 [Page 8] Internet-Draft MUSUBI Settlement October 2026 3. Strings: written between ". Escape only " as \", \ as \\, and U+0000 to U+001F. Of those, U+0008 is \b, U+000C is \f, U+000A is \n, U+000D is \r, U+0009 is \t, and the rest are \u00xx with lowercase hex. Every other character is written as itself, including U+007F, U+2028, U+2029 and all non-ASCII. A lone surrogate code unit (U+D800 to U+DFFF not part of a valid pair) is written \udxxx with lowercase hex. 4. Integers: decimal, - only for negatives, no leading zeros, no fraction, no exponent. 5. true, false, null as literals. The reference ships fixed inputs for this rule (musubi-v0/ canonical_vectors.json) and a Node twin (canonical_v0.mjs) [MUSUBI-REF]. This form is not the JSON Canonicalization Scheme [RFC8785]. Among other differences, RFC 8785 sorts keys by UTF-16 code units, which gives a different order for keys with characters above U+FFFF, and serializes non-integer numbers, which this form never writes. 4.2. Base64 and Keys Base64 is standard base64 (Section 4 of [RFC4648]) with padding, and MUST be canonical: decoding then re-encoding gives the same text. A public key is 32 bytes after decoding, a signature 64 bytes. Any other length, any non-canonical text, or any non-string is "unusable". A public key is also unusable if it is not the canonical encoding of a point on edwards25519, if it is the identity point, or if the point is not in the prime order subgroup (small order or mixed order points). 4.3. The Digests +=================+================================================+ | name | definition | +=================+================================================+ | contract | "a2a-contract-v0\n" + canonical(contract | | signing bytes | without its "signatures" key) | +-----------------+------------------------------------------------+ | contract_sha256 | lowercase hex sha256 of the contract signing | | | bytes | +-----------------+------------------------------------------------+ | record_sha256 | lowercase hex sha256 of canonical(record), the | | | whole record including anchor and signatures | Oga Expires 20 April 2027 [Page 9] Internet-Draft MUSUBI Settlement October 2026 +-----------------+------------------------------------------------+ | body digest | sha256 of canonical(record without its | | | "anchor" key). It includes signatures. | | | Anchor proofs start from these 32 bytes | +-----------------+------------------------------------------------+ | record signing | context + canonical(record without | | bytes | "signatures" and without "anchor"). Context | | | is "a2a-execution-v0\n", "a2a-revocation-v0\n" | | | or "a2a-revocation-ack-v0\n" by the record's | | | schema | +-----------------+------------------------------------------------+ Table 1: Digests contract_sha256 is the identity of the terms. It does not change when a signature is added. A record is bound to a contract only by it (Section 7.2). 4.4. Ed25519 Verification verify(pub_b64, sig_b64, message) returns one of: true, false, unusable. It returns unusable when the key or signature fails Section 4.2. Otherwise it is Ed25519 verification ([RFC8032]) of the 64 byte signature over the message bytes. The reference uses the Python cryptography package (OpenSSL). See item N9 of [MUSUBI-NOTES] on libraries that differ for adversarial signatures. A 64 byte signature is "strict" when its last 32 bytes, read as a little-endian integer S, are below the group order L = 2^252 + 27742317777372353535851937790883648493, and its first 32 bytes R pass the public key test of Section 4.2 (a canonical encoding of a point of prime order, not the identity). "Strictly verifies" means the signature is strict and verify returned true. Libraries that disagree on lax signatures all agree on strict ones. Everywhere below, "verifies" means verify returned true. False and unusable are both "does not verify", except in the contract door (Section 5.1), which names them differently. 5. The Contract 5.1. The Contract Door (Contract Verification) The contract is accepted only if every check below passes. Any failure gives the single underspecified reason contract_not_verified (Section 5.2 is then skipped). The reference reports a list of refusal codes alongside; those codes are informative. Only contract_not_verified is core. Oga Expires 20 April 2027 [Page 10] Internet-Draft MUSUBI Settlement October 2026 1. schema is "a2a-contract-v0". 2. contract_id and nonce are each 32 lowercase hex characters. 3. parties is a list of exactly two objects whose role values are exactly one "principal" and one "contractor". 4. Each party's domain normalizes to a bare hostname: lowercase, outer spaces and one or more trailing dots removed, no /, @, : or space, at least two labels, each label matching ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$. The two normalized domains differ. 5. Each party's key_url is an https:// URL. (Whether its host is under the domain is a finding, not a refusal.) 6. Each party's public_key_ed25519_b64 decodes as canonical base64 to 32 bytes. (The point check of Section 4.2 is applied later, when signatures are verified.) 7. task is an object with a non-empty string purpose. task.payload_digest, when present and not null, is 64 lowercase hex. 8. grant is an object. Its keys are only: authorized_actions, prohibited_actions, conditional, delegation, data_access, max_hops, privacy, revocation, finality, witnesses, expiry_height, ordering, approval_policy, limits. Any other key refuses the contract. 9. grant.authorized_actions and grant.prohibited_actions are both lists of non-empty strings, and no action is in both. 10. Typed grant keys, each checked only when present and not null: * data_access: list of non-empty strings. * max_hops, expiry_height: integer >= 0. * delegation: object whose only key is allowed, a list of non- empty strings. * conditional: list of objects, each with a non-empty string action; actions unique; requires, when present, a string. Oga Expires 20 April 2027 [Page 11] Internet-Draft MUSUBI Settlement October 2026 * finality: object with keys only from depth, max_target_bits. depth, when present, integer >= 1. max_target_bits, when present, 8 lowercase hex that decodes (Section 6.2) to a positive target. * witnesses: list of objects, each with a non-empty string name and a public_key_ed25519_b64 that decodes to 32 bytes. * privacy: non-empty string. * ordering: object whose only key is same_height, a string or null. * approval_policy: object with keys only from allow_unscoped (boolean) and approvers (out of scope, Section 1.4). * revocation: an object whose effective_at is "anchor" or "delivery_ack", with keys only from effective_at, ack_window; ack_window, when present, integer >= 1. 11. No number anywhere in the contract (signatures included) is a non-integer, NaN, an infinity, or an integer outside plus or minus (2^53 - 1). 12. Every object key anywhere in the contract is printable ASCII (U+0020 to U+007E). 13. establishes is a non-empty list. No string in it matches, case- insensitively, any of the patterns listed after this list. 14. does_not_establish is a non-empty list. Lowercased, its strings together contain: one of runtime or enforce; one of judge, liability or fault; deviat; and legal. Each of the four groups must be hit by at least one string. 15. signatures is a list. For each object in it: its domain normalizes (rule 4) to a party's normalized domain, or the contract is refused. Its signature is verified (Section 4.4) with that party's key over the contract signing bytes. False or unusable refuses the contract, even if the same party also has a good signature (WRITTEN BEHAVIOUR). alg is not read. 16. Each party has at least one signature that verifies. The patterns of rule 13, one per line, are: Oga Expires 20 April 2027 [Page 12] Internet-Draft MUSUBI Settlement October 2026 \bperformed\b \bdeliver(ed|y)\b \bmoney (moved|was sent)\b \bfunds? (moved|were sent|were transferred)\b \bpaid\b(?!\s+for\s+(this|the)\s+record) \bpayment (was|has been) (made|completed|settled|received)\b \bcontract\b \bbinding\b \bguarantee \bescrow\b \bcustody\b \bsolvent\b \blawful\b \bfair\b \bcertified\b Figure 1: Patterns refused in establishes Not read by the door, and not read anywhere in core v0: expiry (a wall clock), agreed_at, requirements.recovery, selection_provenance, liability_boundary, settlement. lower_bound is not checked here; Section 6 checks it. requirements.evidence is read in Section 12, bond and parent_contract in Section 5.3. 5.2. Settleable Terms Only when Section 5.1 accepts, each of these adds the underspecified reason shown: +============================+====================================+ | condition | reason | +============================+====================================+ | grant.authorized_actions | authorized_actions_missing | | is not a list | | +----------------------------+------------------------------------+ | an action name in | grant_action_name_invalid | | authorized_actions, | | | prohibited_actions or | | | conditional[].action does | | | not match | | | ^[a-z][a-z0-9_.:-]{0,63}$ | | | (see Section 14 and item | | | N1 of [MUSUBI-NOTES]) | | +----------------------------+------------------------------------+ | more than 32 witnesses | too_many_witnesses | +----------------------------+------------------------------------+ | a witness key does not | witness_key_invalid | | decode to 32 bytes | | Oga Expires 20 April 2027 [Page 13] Internet-Draft MUSUBI Settlement October 2026 +----------------------------+------------------------------------+ | two witnesses share a | key_conflict | | name, or any two of | | | {principal key, contractor | | | key, each witness key} | | | decode to the same 32 | | | bytes | | +----------------------------+------------------------------------+ | grant.ordering.same_height | tie_policy_refused | | is present and is neither | | | null nor "conservative" | | +----------------------------+------------------------------------+ | grant.revocation is an | revocation_policy_not_recomputable | | object and effective_at is | | | not "anchor" or | | | "delivery_ack" | | +----------------------------+------------------------------------+ | effective_at is | ack_window_missing | | "delivery_ack" and | | | ack_window is not an | | | integer >= 1 | | +----------------------------+------------------------------------+ | grant.finality.depth is | finality_policy_missing | | not an integer >= 1 | | | (including a missing | | | finality or depth) | | +----------------------------+------------------------------------+ | grant.expiry_height is | bad_expiry_height | | present, not null, and not | | | an integer >= 0 | | +----------------------------+------------------------------------+ | allow_unscoped in | unscoped_approvals_refused | | grant.approval_policy is | | | truthy | | +----------------------------+------------------------------------+ Table 2: Settleable terms An empty authorized_actions list means nothing is authorized. It is not an error. 5.3. Strict Terms Whether or not Section 5.1 accepts, each of these adds the underspecified reason shown: Oga Expires 20 April 2027 [Page 14] Internet-Draft MUSUBI Settlement October 2026 +=================================+===============================+ | condition | reason | +=================================+===============================+ | a signatures[].signature | contract_signature_not_strict | | decodes to 64 bytes and is not | | | strict (Section 4.4) | | +---------------------------------+-------------------------------+ | bond is present and not null, | bond_malformed | | and is not an object whose | | | amount is an integer from 1 to | | | 2^53 - 1 (true is not an | | | integer) | | +---------------------------------+-------------------------------+ | parent_contract is present and | parent_not_supplied | | not null, and no parent was | | | supplied | | +---------------------------------+-------------------------------+ | parent_contract is present and | parent_narrowing_failed | | not null, and the parent is not | | | an object, or does not pass | | | Section 5.1 on its own, or the | | | contract does not pass | | | Section 5.1 with the parent | | | supplied (the reference's door | | | then also checks that | | | parent_contract.contract_id | | | equals the parent's contract_id | | | and that the child's grant is a | | | subset of the parent's: | | | contract_v0.grant_subset) | | +---------------------------------+-------------------------------+ Table 3: Strict terms These checks do not stop the walk; the event set and dispositions are still computed (Section 3.3). The vectors show the subset rule with one widening (an added authorized action). A full statement of grant_subset is left to a later version of this document; until then, the reference's grant_subset (in contract_v0.py beside the reference [MUSUBI-REF]) is normative. 6. The Header View Oga Expires 20 April 2027 [Page 15] Internet-Draft MUSUBI Settlement October 2026 6.1. Verifying the View The view is checked under two contract terms: the difficulty floor grant.finality.max_target_bits and the checkpoint lower_bound (height, hash). Any failure below gives the underspecified reason chain_view_rejected. The view is checked even when Section 5 already failed. 1. grant.finality.max_target_bits is 8 lowercase hex and decodes (Section 6.2) to a target, the floor. 2. lower_bound is an object with an integer height and a 64 lowercase hex hash. 3. view.headers is a non-empty list. 4. Each header is an object with an integer height >= 0 and a hex of 160 lowercase hex characters, optionally followed by one line feed (WRITTEN BEHAVIOUR of the lower layers; rule 9 below then refuses the line feed under its own reason). 5. Heights are consecutive in list order: each is the previous plus one. 6. From the second header on, bytes 4 to 36 of the header, reversed, as hex, equal the previous header's hash. 7. The header's own nBits (bytes 72 to 76, little-endian unsigned 32 bit) decode to a target; that target is not above the floor; the header hash read as a big-endian 256 bit number is not above that target. 8. The view holds a header at lower_bound.height whose hash equals lower_bound.hash. The header hash is sha256(sha256(80 raw bytes)), byte-reversed, as lowercase hex (the usual display order). The merkle root used by anchors (Section 8.5) is bytes 36 to 68 of the raw header, not reversed. The tip is the height of the last header. The view may start below the checkpoint. The first header's previous-hash field is not checked. Consensus rules beyond these (retargeting, timestamps, transactions) are not checked. Oga Expires 20 April 2027 [Page 16] Internet-Draft MUSUBI Settlement October 2026 9. Separately, every header is an object with an integer height and a hex of exactly 160 lowercase hex characters, and every string, key and number in the view is strict (first paragraph of Section 7.1). If not, the reason view_not_strict is added. A header in upper case therefore gives both chain_view_rejected and view_not_strict; one that ends in a line feed gives only view_not_strict. Rule 9 does not stop the walk. If the view verifies but holds more than 200000 headers, the reason is input_too_large instead, and no record is examined. 6.2. Compact Target Decoding For a 32 bit value bits: exp = bits >> 24, mant = bits & 0x007fffff. If bits & 0x00800000 is set, or mant is 0, there is no target (invalid). Otherwise the target is mant << (8 * (exp - 3)) when exp >= 3, else mant >> (8 * (3 - exp)). 7. Records Before Their Anchors 7.1. Strict Records and Triage A JSON value is strict when, at every depth up to 512 levels: every string and every object key is free of U+0000 to U+001F and U+007F; every key is ASCII; every number is an integer within plus or minus (2^53 - 1). A value nested deeper is not strict. A record's parts: * the body: the record without signatures and anchor. This is what its signers signed (Section 4.3, record signing bytes). * the anchor: anchor. Nobody signed it. * the signatures list: signatures. Nobody signed it either. The body is not strict when the body as a value is not strict, or (when present) nenrin_ref is neither null nor 64 lowercase hex, or contract_ref.contract_sha256 or contract_ref.payload_digest is present and not 64 lowercase hex, or, for an execution: performed_actions or delegated_to is present and not a list of strings; approvals is present and not a list of objects; or an approval's sig_b64 (or signature) decodes to 64 bytes and is not strict (Section 4.4). Oga Expires 20 April 2027 [Page 17] Internet-Draft MUSUBI Settlement October 2026 The anchor is not strict when it is present and: it is not strict as a value; or its block_hash is present and not exactly 64 lowercase hex; or a proof operation's hex is present and is not exactly pairs of lowercase hex digits (the empty string is allowed). A record is strictly signed when one entry of signatures has a role its schema allows (Section 7.6), a signature that strictly verifies (Section 4.4) with the matching key over the record signing bytes, and is itself a strict value. First, a record of one of the three schemas whose record_sha256 cannot be computed at all (for example an integer too long to write out) is set aside with reason record_not_strict. The others are bound (Section 7.2). Each bound record is then triaged, in this order: Oga Expires 20 April 2027 [Page 18] Internet-Draft MUSUBI Settlement October 2026 +==================================+=============================+ | condition | result | +==================================+=============================+ | not strictly signed, body not | set aside, | | strict | record_not_strict | +----------------------------------+-----------------------------+ | not strictly signed, but a | set aside, | | signature verifies under | signature_not_strict | | Section 4.4 alone (lax) | | +----------------------------------+-----------------------------+ | not strictly signed otherwise | rejected (disposition | | | rejected) | +----------------------------------+-----------------------------+ | strictly signed, body not strict | the record is a party's own | | | statement: underspecified | | | reason record_not_strict | +----------------------------------+-----------------------------+ | strictly signed, anchor not | set aside, | | strict, and another bound record | anchor_not_strict | | with the same record signing | | | bytes is kept by this table and | | | anchors validly (Section 7.5) | | +----------------------------------+-----------------------------+ | strictly signed, anchor not | underspecified reason | | strict, otherwise | anchor_not_strict | +----------------------------------+-----------------------------+ | a revocation, and | set aside, | | grant.revocation is not an | revocation_not_provided_for | | object | (the contract cannot be | | | revoked) | +----------------------------------+-----------------------------+ | otherwise | kept | +----------------------------------+-----------------------------+ Table 4: Triage Set aside and rejected records are never examined again: no collapse (Section 7.5), size limit (Section 7.3), conformance check, anchor check or NENRIN check sees them. They are listed with their disposition (Section 10.2). Problems in the signatures list of a strictly signed record (an extra entry that does not verify or is not strict) are ignored. A third party holding copies of genuine records can change their anchors and signature lists but not their bodies. The table is arranged so that such copies are set aside or rejected whenever the genuine record is in the input. Oga Expires 20 April 2027 [Page 19] Internet-Draft MUSUBI Settlement October 2026 7.2. Binding Let cid = contract.contract_id, pdg = contract.task.payload_digest (it may be absent), csha = contract_sha256. Walk events in the given order. Skip anything that is not an object, or whose schema is not one of the three record schemas. Skip a record whose record_sha256 was already seen (identical bytes are one record). Then, with ref = contract_ref if it is an object, else empty: +==================================+======================+ | condition, in this order | class | +==================================+======================+ | ref.contract_sha256 absent or | unbound (not settled | | null, and ref.contract_id == cid | in strict mode) | +----------------------------------+----------------------+ | ref.contract_sha256 absent or | not ours: dropped | | null otherwise | silently | +----------------------------------+----------------------+ | ref.contract_sha256 is not 64 | inconsistent | | lowercase hex | | +----------------------------------+----------------------+ | ref.contract_sha256 != csha | foreign | +----------------------------------+----------------------+ | ref.contract_id != cid | inconsistent | +----------------------------------+----------------------+ | pdg is present and not null, and | inconsistent | | ref.payload_digest != pdg | | +----------------------------------+----------------------+ | otherwise | bound | +----------------------------------+----------------------+ Table 5: Binding Only bound records go further. Foreign, inconsistent and unbound records are listed (Section 10) and never settled. Binding runs even when Section 5 or Section 6 failed; its classes are then still reported. Binding is by contract_sha256 alone, so a record made under earlier terms with the same contract_id is foreign and is never triaged (Section 7.1). 7.3. Size Limit If more than 10000 records are kept by Section 7.1, the reason input_too_large is added and no record is examined further. Oga Expires 20 April 2027 [Page 20] Internet-Draft MUSUBI Settlement October 2026 7.4. Identical Bytes Two inputs with the same record_sha256 are one record. Supplying a record twice changes nothing. 7.5. Several Copies of One Signed Body The same signed body can reach the input more than once: anchored twice (two calendars, two batches), or with another signatures list. These copies differ only in their unsigned parts. Group the records kept by Section 7.1 by their record signing bytes (Section 4.3). In a group with more than one distinct record_sha256: * A copy "anchors validly" if: its anchor.height is an integer >= 0 that the view holds; anchor.block_hash equals the view's hash at that height; the proof (Section 8.5) reaches that block's merkle root; and the batch leg rule (Section 8.6) accepts it. * If at least one copy anchors validly, keep the one with the smallest (height, record_sha256) and drop the others. Dropped copies are listed (disposition duplicate_dropped). * If none does, keep them all. Each is then examined on its own. This is done when rules 1 to 8 of Section 6.1 passed, whether or not Section 5 did. Note that "anchors validly" does not compare the height with the checkpoint (see item N7 of [MUSUBI-NOTES]). 7.6. Authentication Authentication is part of Section 7.1: only strictly signed records are kept. The roles and keys are: Oga Expires 20 April 2027 [Page 21] Internet-Draft MUSUBI Settlement October 2026 +=======================+=======================+===================+ | schema | signer it needs | key | +=======================+=======================+===================+ | a2a-execution-v0 | a signature with | the contractor's | | | role "contractor", | party key, or the | | | or with role | key of the grant | | | "witness" and a | witness with that | | | witness_name | exact name | +-----------------------+-----------------------+-------------------+ | a2a-revocation-v0 | role "principal" | the principal's | | | | party key | +-----------------------+-----------------------+-------------------+ | a2a-revocation-ack-v0 | role "contractor" | the contractor's | | | | party key | +-----------------------+-----------------------+-------------------+ Table 6: Signers by schema signatures must be a non-empty list. Each entry is an object with role, sig_b64 and, for a witness, witness_name. An entry with another role, or one that does not strictly verify, is skipped. Then, for a kept revocation: if its revoked_by field is not "principal", it is ignored (disposition ignored), even though the principal signed it. 7.7. Conformance Allowed top-level fields: * execution: schema, contract_ref, performed_actions, approvals, delegated_to, nenrin_ref, outcomes, anchor, signatures, * revocation: schema, contract_ref, revoked_by, anchor, signatures, * acknowledgement: schema, contract_ref, revocation_sha256, acked_by, anchor, signatures. A record has a conformance problem if: * it has a field outside its list, * (execution) performed_actions is not a list of strings, * (execution) outcomes is present, not null, and not an object; or one of its keys is not in performed_actions; or one of its values is not "ok", "error", "timeout" or "partial", Oga Expires 20 April 2027 [Page 22] Internet-Draft MUSUBI Settlement October 2026 * (execution) it lists more than 256 performed actions, * (execution) a performed action, or the action of an approval that is an object, does not match ^[a-z][a-z0-9_.:-]{0,63}$. An approval object with no action counts as not matching. (A name ending in a line feed never gets here: its body is not strict, Section 7.1.) If an execution with a problem has a contractor signature that verifies, it is a charge: the deviation nonconforming_record is added, and the record continues to Section 8. Its acts are still judged. Any other record with a problem is rejected (disposition rejected). The computation is then repeated without the rejected records, until no new record is rejected, so no check reads a rejected record. The types of approvals, delegated_to, nenrin_ref and contract_ref are checked in Section 7.1. 8. Anchors 8.1. What an Anchor Is An anchor says where a record's body was committed to Bitcoin: "anchor": {"height": H, "block_hash": "<64 hex>", "proof": [op, ...]} The anchor is not signed. Anyone holding a record can change it. The checks below decide whether the claim holds against the verified view. 8.2. Height The height of a record is anchor.height when anchor is an object and height is an integer >= 0. Otherwise the record has no height. 8.3. Order of the Checks For each record that passed Section 7, apply Section 8.4, Section 8.5 and Section 8.6 in this order. The first failure decides what happens to the record. Every record that reaches this section is strictly signed by a party (Section 7.1). Oga Expires 20 April 2027 [Page 23] Internet-Draft MUSUBI Settlement October 2026 8.4. Height and Block +======================+=======================================+ | condition, in this | result | | order | | +======================+=======================================+ | no height | underspecified reason | | (Section 8.2), or | anchor_incomplete | | anchor.block_hash is | | | not 64 lowercase hex | | +----------------------+---------------------------------------+ | height < | underspecified reason | | lower_bound.height | anchor_below_lower_bound. The body | | | names this contract, and the contract | | | names the checkpoint's block hash, so | | | no honest anchor can be below it | +----------------------+---------------------------------------+ | height > tip, or the | underspecified reason | | view holds no header | anchor_beyond_observed_chain | | at that height | | +----------------------+---------------------------------------+ | anchor.block_hash != | disposition orphaned: excluded, no | | the view's hash at | reason added, but its height counts | | that height | for finality (Section 9.5) | +----------------------+---------------------------------------+ Table 7: Height and block 8.5. The Proof anchor.proof must be a non-empty list of at most 512 operations. Start with the 32 byte body digest (Section 4.3) as the current bytes, and apply each operation: Oga Expires 20 April 2027 [Page 24] Internet-Draft MUSUBI Settlement October 2026 +===================+==============================+ | op | effect | +===================+==============================+ | {"op": "sha256"} | current = sha256(current) | +-------------------+------------------------------+ | {"op": "hexlify"} | current = the ASCII bytes of | | | the lowercase hex of current | +-------------------+------------------------------+ | {"op": "append", | current = current + bytes(X) | | "hex": X} | | +-------------------+------------------------------+ | {"op": "prepend", | current = bytes(X) + current | | "hex": X} | | +-------------------+------------------------------+ Table 8: Proof operations X is a string of pairs of lowercase hex digits (the empty string is allowed) of at most 4096 bytes, and bytes(X) is the byte string that X encodes. (An operand with anything else, a line feed included, never gets here: the anchor is not strict, Section 7.1.) Any other op, a missing or malformed operand, a non-object entry, or current bytes longer than 65536 at any step, fails the proof. The proof holds if the final bytes equal the merkle root of the header at the record's height (Section 6.1). If it fails: underspecified reason anchor_proof_invalid. The operation set resembles a subset of the operations used by OpenTimestamps [OPENTIMESTAMPS]; only the operations above are defined here. 8.6. The Batch Leg Rule A ledger lists records by their hex sha inside a batch, and stamps the batch. A proof can pass through such a batch with hexlify. A hex digest that merely appears somewhere in stamped bytes is not a listing. So: 1. If no op in the proof is hexlify, the rule accepts. 2. If any hexlify is not the first op, or there is more than one, refuse (hexlify_not_leading). Oga Expires 20 April 2027 [Page 25] Internet-Draft MUSUBI Settlement October 2026 3. Rebuild the batch: walk the ops after the first one, up to the first sha256. Each must be append or prepend, else refuse (batch_leg_malformed). If there is no sha256, refuse (batch_leg_malformed). The batch is (all prepend operands, the later one in front) + the ASCII lowercase hex of the body digest + (all append operands, in order). 4. The batch bytes must be UTF-8 text that parses as strict JSON (Section 3.2) into an object whose schema is one of nenrin-agreement-batch-v1 (typed), nenrin-witness-batch-v1, nenrin-trace-pin-batch-v0. Else refuse (batch_not_json or batch_schema_unknown). 5. records is a list of objects (else batch_schema_unknown). If count is present it equals the length of records (else batch_count_mismatch). 6. Exactly one records[i] has sha equal to the hex digest. None: record_not_listed_in_batch. More: record_listed_twice. 7. For a typed batch: the record's schema maps to a kind (a2a-execution-v0 to execution; revocations and acknowledgements have no kind, so they are refused with record_kind_unknown, WRITTEN BEHAVIOUR). records[i].kind equals that kind (else record_kind_mismatch). If records[i].schema is present it equals the record's schema (else record_schema_mismatch). 8. The string value of records[i].sha must be written in the raw text as the 64 hex characters themselves, with no escapes (else refuse, code internal), and its first character must sit at byte offset equal to the total length of the prepend operands (else refuse, batch_leg_splice_not_at_listing). If the rule refuses: underspecified reason anchor_batch_leg_refused. The refusal code is informative detail. If all of Section 8.4 to Section 8.6 pass, the record is accepted (disposition accepted). 9. The Event Set and Finality 9.1. Order The event set is the accepted records sorted by (height, record_sha256 as a lowercase hex string). Arrival order plays no part. Oga Expires 20 April 2027 [Page 26] Internet-Draft MUSUBI Settlement October 2026 9.2. Kinds Each event has a kind: execution, revocation or revocation_ack, by schema. 9.3. Same Block Two records in the same block are not ordered by their bytes for any rule that matters. Section 11 says how same-block cases are decided. The order of Section 9.1 only fixes the listing and the order in which single use approvals are consumed (Section 11.4). 9.4. Horizon With tip T and grant.finality.depth k, the finality horizon is T - k + 1. 9.5. Status * If the verdict is underspecified: undetermined. * Otherwise final if every accepted record's height and every orphaned record's height is at or below the horizon; else provisional. With no accepted and no orphaned record, the status is final. Foreign, rejected, ignored and set aside records do not affect status. 10. Output 10.1. Core Fields A second implementation MUST reproduce these exactly. They are what the vectors' expected.json files hold. Oga Expires 20 April 2027 [Page 27] Internet-Draft MUSUBI Settlement October 2026 +========================+=======================================+ | field | value | +========================+=======================================+ | contract_sha256 | Section 4.3, always computed, even | | | for a contract the door refuses | +------------------------+---------------------------------------+ | verdict | within_grant, deviation, | | | nothing_to_settle or underspecified | | | (Section 13) | +------------------------+---------------------------------------+ | status | final, provisional or undetermined | | | (Section 9.5) | +------------------------+---------------------------------------+ | bond_outcome | Section 10.3 | +------------------------+---------------------------------------+ | deviation_codes | the sorted set of deviation codes | | | (Appendix A). Empty when the verdict | | | is not deviation | +------------------------+---------------------------------------+ | underspecified_reasons | the sorted set of underspecified | | | reasons (Appendix A). Empty unless | | | the verdict is underspecified | +------------------------+---------------------------------------+ | event_set | the list of Section 9.1, each item | | | {"kind", "sha256", "height"} with | | | sha256 the record_sha256. Empty when | | | the walk did not run. A reason from | | | Section 5.3, rule 9 of Section 6.1, | | | Section 7.1, Section 8.4 (below the | | | lower bound) or Section 12 (a cited | | | walk) does not empty it | +------------------------+---------------------------------------+ | dispositions | an object mapping record_sha256 to | | | one code, for every record the | | | computation classified (Section 10.2) | +------------------------+---------------------------------------+ Table 9: Core fields deviation_codes and underspecified_reasons are sets. The reference may list a code more than once (one per action); that multiplicity is informative. Oga Expires 20 April 2027 [Page 28] Internet-Draft MUSUBI Settlement October 2026 10.2. Dispositions +===============================+=============================+ | code | meaning | +===============================+=============================+ | foreign, inconsistent, | Section 7.2 | | unbound | | +-------------------------------+-----------------------------+ | record_not_strict, | Section 7.1, set aside, or | | signature_not_strict, | (for record_not_strict and | | anchor_not_strict, | anchor_not_strict) failing | | revocation_not_provided_for | closed with the same reason | | | added to the settlement | +-------------------------------+-----------------------------+ | duplicate_dropped | Section 7.5 | +-------------------------------+-----------------------------+ | rejected | Section 7.1 or Section 7.7 | +-------------------------------+-----------------------------+ | ignored | Section 7.6, a revocation | | | whose revoked_by is not | | | "principal" | +-------------------------------+-----------------------------+ | anchor_incomplete, | Section 8.4 to Section 8.6, | | anchor_beyond_observed_chain, | with the same reason added | | anchor_proof_invalid, | to the settlement | | anchor_batch_leg_refused | | +-------------------------------+-----------------------------+ | anchor_below_lower_bound | Section 8.4, with the same | | | reason added | +-------------------------------+-----------------------------+ | orphaned | Section 8.4 | +-------------------------------+-----------------------------+ | accepted | in the event set | +-------------------------------+-----------------------------+ Table 10: Dispositions A bound record that the computation never examined (because Section 5, Section 6 or Section 7.3 failed) has no disposition. A record that is not ours (Section 7.2, dropped silently) has no disposition. A record set aside because it cannot be digested has no record_sha256 and so no disposition; it is counted in the informative v1_16.refused. Every record has at most one disposition. Oga Expires 20 April 2027 [Page 29] Internet-Draft MUSUBI Settlement October 2026 10.3. Bond Outcome If contract.bond is absent or null: n/a. A bond of any other form than an object with a positive integer amount makes the settlement underspecified (Section 5.3) and the outcome is then undetermined when the value is one the lower layers read as a bond (an object with a truthy amount), else n/a. For a well formed bond: undetermined if the verdict is underspecified; else pending_finality if the status is provisional; else held for within_grant and nothing_to_settle, and forfeited for deviation. 10.4. Informative Fields Everything else the reference writes is informative: schema, settled_under, v1_16, signed_body_collapse, contract_id, binding_mode, bound_by_label_only, ordering_rule, approval_rule, anchor_rule, view_rules, chain_tip, finality_horizon, pinned_blocks, revocations, approvals, binding, orphaned, predates_contract, ignored, rejected, duplicate_anchorings, establishes, does_not_establish, spine_gate, convergence_gate, approval_gate, signatures, the full underspecified and deviations objects (heights, why texts, details), and their order. The informative fields are useful when comparing implementations. They are not part of conformance. 11. Grant Evaluation The walk runs over the event set (Section 9.1) only. Let g = contract.grant. 11.1. Revocation For each accepted revocation at height h, its effective height E is: * effective_at "anchor": E = h. * effective_at "delivery_ack": E = the smallest of h + ack_window and the heights of every accepted acknowledgement whose revocation_sha256 names this revocation. An acknowledgement names a revocation if its revocation_sha256 equals the lowercase hex body digest of the revocation, or the record_sha256 of any bound copy of that revocation (any anchoring, counted before Section 7.5 drops copies). An acknowledgement anchored before its revocation makes E earlier than h (WRITTEN BEHAVIOUR, see item N5 of [MUSUBI-NOTES]). Oga Expires 20 April 2027 [Page 30] Internet-Draft MUSUBI Settlement October 2026 Sort the revocations by (E, record_sha256). An execution at height h is revoked if some revocation has E <= h. Authority ends at block E inclusive: an act in the same block as an anchor-mode revocation is revoked. For a revoked execution, every string in performed_actions gives the deviation revoked, and nothing else in that record is judged (no expiry, prohibited, conditional, unauthorized or delegation check, and no approval nonce is consumed). If the grant has no revocation object, a revocation never gets here: it is set aside in Section 7.1 (revocation_not_provided_for). 11.2. Expiry If g.expiry_height is present and not null, every string action of an execution with height h > expiry_height gives after_expiry. This does not stop the other checks for that action: an expired prohibited action gives both after_expiry and prohibited. An execution at exactly expiry_height is not expired. 11.3. Actions and Delegation For each accepted, unrevoked execution, for each string a in performed_actions, in order, after Section 11.2: 1. If a is in g.prohibited_actions: deviation prohibited. Next action. 2. Else if a is the action of some g.conditional entry: apply Section 11.4. Next action. (A conditional action does not need to be in authorized_actions.) 3. Else if a is not in g.authorized_actions: deviation unauthorized. Every entry of performed_actions and delegated_to is a string here (Section 7.1). Comparison is exact string equality. There is no case folding or Unicode normalization. Then, for each entry d of delegated_to not in g.delegation.allowed (empty when absent): deviation delegation. An outcome (outcomes) never excuses an act. An attempt that errored is judged like one that succeeded. 11.4. Conditional Actions and Approvals Every approval carried by an accepted execution (revoked or not) is classified. With pk the principal's key and csha this contract's contract_sha256: Oga Expires 20 April 2027 [Page 31] Internet-Draft MUSUBI Settlement October 2026 1. Not an object, or no principal key: forged (Section 11.5). 2. If valid_until_height is an integer >= 0, nonce is a string of 32 lowercase hex characters (a nonce with a line feed never gets here, Section 7.1), single_use is a boolean, and contract_sha256 is 64 lowercase hex: compute the v2 approval bytes shown after this list. If sig_b64 verifies over them with pk: counted when its contract_sha256 equals csha, else other_terms. 3. Otherwise, if sig_b64 verifies with pk over either older form, it is label_bound: * the v1 approval bytes, with contract_id and payload_digest from the contract, only when the field checks of step 2 other than contract_sha256 hold, or * the v0 approval bytes. 4. Otherwise forged. The three forms of approval bytes are: v2: "a2a-approval-v2\n" + canonical({ "contract_sha256": , "action": , "valid_until_height": .., "nonce": .., "single_use": ..}) v1: "a2a-approval-v1\n" + canonical({ "contract_id", "payload_digest", "action", "valid_until_height", "nonce", "single_use"}) v0: "a2a-approval-v0\n" + canonical({ "contract_id", "payload_digest", "action"}) Figure 2: Approval signing bytes A missing field is canonicalized as null. The approval's by field is not read. label_bound and other_terms approvals are listed (informative) and never count. They are not deviations. A conditional action a in an execution at height h with record sha s is approved if some counted approval, taken in event set order (records by Section 9.1, approvals in list order within a record), satisfies all of: * its action equals a, Oga Expires 20 April 2027 [Page 32] Internet-Draft MUSUBI Settlement October 2026 * it is carried by the same record s, or by a record at a height strictly below h (a record in the same block does not count), * h <= its valid_until_height, * if its single_use is true, its nonce has not been consumed yet. The first approval that satisfies all four is used. If it is single use, its nonce is consumed. The set of consumed nonces is shared across all actions and all executions (see item N5 of [MUSUBI-NOTES]). If no approval satisfies all four: deviation conditional. The value of requires in the conditional entry is not read: every conditional action needs a counted approval. 11.5. Forged Approvals Every approval classified forged adds the deviation forged_approval, whatever its action, whether or not the action was needed. 12. NENRIN Checks 12.1. Cross Check Only when nenrin_records is a non-empty list. A walk that is not strict (first paragraph of Section 7.1) is left out. Index every other object in it by its record_sha256 (Section 4.3). For each execution kept by Section 7.1 and not rejected by Section 7.7, left after Section 7.5 (once per record_sha256), look up the walk whose record_sha256 equals the execution's nenrin_ref. If found, and the walk's context is an object whose contract_sha256 is present, not null, and not equal to csha: deviation evidence_names_other_contract. If an execution's nenrin_ref names a walk that was left out for not being strict: underspecified reason walk_not_strict. The contractor chose what to cite, and leaving the walk out silently could hide a deviation. Records that were rejected or set aside are never checked here (item N2 of [MUSUBI-NOTES]). 12.2. Required Evidence When requirements.evidence is "nenrin_required", each accepted execution whose nenrin_ref is not 64 lowercase hex gives the deviation evidence_missing. This is applied after Section 13 found within_grant or deviation. 13. Verdict Oga Expires 20 April 2027 [Page 33] Internet-Draft MUSUBI Settlement October 2026 * underspecified if any underspecified reason was found (Section 5, Section 6, Section 7.1, Section 7.3, Section 8, Section 12). Then deviations is empty and status is undetermined. * Else deviation if any deviation was found (Section 7.7, Section 11, Section 12). * Else nothing_to_settle if the event set is empty: no record was read, so nothing was found within the grant or outside it. Status is as Section 9.5 gives it (final with no orphaned record). * Else within_grant. within_grant covers only the accepted records. One strictly signed record whose anchor fails Section 8.4 (first, second or third row), Section 8.5 or Section 8.6 makes the whole settlement underspecified. A record that is not strictly signed never does. 14. Written Behaviour and Changes from Earlier Settle Versions 14.1. Written Behaviour These are what the reference still does. They are normative for core v0 because the vectors pin them, or would. Oga Expires 20 April 2027 [Page 34] Internet-Draft MUSUBI Settlement October 2026 +============================+====================================+ | item | vector | +============================+====================================+ | An extra bad signature | none | | from a party refuses the | | | contract even when that | | | party also signed | | | correctly | | +----------------------------+------------------------------------+ | Revocations and | none | | acknowledgements cannot | | | pass a typed batch leg (no | | | kind) | | +----------------------------+------------------------------------+ | An acknowledgement | none | | anchored before its | | | revocation ends authority | | | at the acknowledgement's | | | height | | +----------------------------+------------------------------------+ | An orphaned record is | real_p31_anchor_names_other_height | | excluded without making | | | the settlement | | | underspecified, yet its | | | claimed height still | | | counts for status | | +----------------------------+------------------------------------+ | A header ending in a line | synth_view_header_trailing_newline | | feed passes rules 1 to 8 | | | of Section 6.1 and is | | | refused only by rule 9 | | | (view_not_strict); one in | | | upper case is refused by | | | both | | +----------------------------+------------------------------------+ | A party-signed record that | none | | names this contract_sha256 | | | with another contract_id | | | or payload_digest is | | | inconsistent (Section 7.2) | | | and is never triaged, so a | | | deviation it shows is not | | | read | | +----------------------------+------------------------------------+ Table 11: Written behaviour Oga Expires 20 April 2027 [Page 35] Internet-Draft MUSUBI Settlement October 2026 14.2. Changes in Settle v1.16 Each item below was written behaviour of settle v1.10 to v1.15; [MUSUBI-NOTES] has the details under the item numbers given. +======+================================+===========================+ | item | before | now | +======+================================+===========================+ | N2 | The NENRIN cross check | only records strictly | | | read every bound | signed and not rejected | | | execution, also rejected | are read by any check | | | and unsigned ones: anyone | | | | could add a charge and | | | | forfeit a bond | | +------+--------------------------------+---------------------------+ | N1 | A trailing line feed | strict forms | | | passed in block_hash, | (Section 7.1, rule 9 of | | | proof operands, headers, | Section 6.1) | | | action names and approval | | | | nonces | | +------+--------------------------------+---------------------------+ | N3, | delegated_to and approvals | Section 7.1 | | N6 | were not type checked; an | | | | object in delegated_to | | | | stopped the reference | | +------+--------------------------------+---------------------------+ | N4 | Floats and unsafe integers | Section 7.1, rule 9 of | | | in records, views and | Section 6.1, Section 12.1 | | | walks were accepted | | +------+--------------------------------+---------------------------+ | N6 | A revocation against a | set aside | | | grant with no revocation | | | | block stopped the | | | | reference | | +------+--------------------------------+---------------------------+ | N8 | The bond test used | bond_malformed | | | truthiness, so [] was no | | | | bond in Python and a bond | | | | in JavaScript | | +------+--------------------------------+---------------------------+ | N9 | Signatures were checked by | strict signatures | | | OpenSSL alone | (Section 4.4) | +------+--------------------------------+---------------------------+ | N10 | A copy with a junk | copies of one signed body | | | signatures entry was a | collapse (Section 7.5) | | | second body that blocked | | | | the verdict (fixed in | | | | v1.15) | | Oga Expires 20 April 2027 [Page 36] Internet-Draft MUSUBI Settlement October 2026 +------+--------------------------------+---------------------------+ | N11 | An anchor below the | anchor_below_lower_bound; | | | checkpoint was dropped | Section 5.3; | | | without a word; | Section 12.2; | | | parent_contract and | nothing_to_settle | | | requirements.evidence were | | | | never read; an empty event | | | | set was within_grant | | +------+--------------------------------+---------------------------+ Table 12: Changes in settle v1.16 The vectors that pin each change are: Oga Expires 20 April 2027 [Page 37] Internet-Draft MUSUBI Settlement October 2026 +======+======================================================+ | item | vectors | +======+======================================================+ | N2 | synth_nenrin_check_reads_rejected_record, | | | synth_unsigned_copies_anchored_first | +------+------------------------------------------------------+ | N1 | real_p31_proof_operand_trailing_newline, | | | real_p31_proof_operand_trailing_newline_beside_good, | | | real_p31_block_hash_trailing_newline, | | | synth_action_name_trailing_newline, | | | synth_approval_nonce_trailing_newline, | | | synth_view_header_trailing_newline | +------+------------------------------------------------------+ | N3, | synth_delegated_to_object | | N6 | | +------+------------------------------------------------------+ | N4 | synth_float_in_signed_body, | | | synth_unsafe_integer_in_signed_body, | | | synth_unsigned_float_beside_good, | | | synth_cited_walk_not_strict | +------+------------------------------------------------------+ | N6 | synth_revocation_irrevocable_grant | +------+------------------------------------------------------+ | N8 | synth_bond_empty_list, synth_bond_amount_string | +------+------------------------------------------------------+ | N9 | synth_signature_s_plus_l, | | | synth_strict_signature_beside_malleated, | | | real_p31_contract_bad_principal_signature | +------+------------------------------------------------------+ | N10 | real_p31_copy_with_junk_signature_entry | +------+------------------------------------------------------+ | N11 | real_p31_anchor_below_checkpoint, | | | synth_parent_not_supplied, | | | synth_parent_supplied_narrows, synth_parent_widened, | | | synth_nenrin_required_without_ref, | | | synth_nothing_to_settle | +------+------------------------------------------------------+ Table 13: Vectors for the changes in settle v1.16 15. Test Vectors Oga Expires 20 April 2027 [Page 38] Internet-Draft MUSUBI Settlement October 2026 15.1. Contents The vectors are published beside the source text of this document at commit 4100d52a [MUSUBI-VECTORS], in the folder settle-core-v0/ vectors/ under https://github.com/ogasurfproject-jpg/horizon- shield/tree/4100d52a/workers/hs-ledger/nenrin/musubi-v0/settle-core- v0. They are not reproduced here. There are 76 vectors: 22 real and 54 synthetic. Their expected verdicts are within_grant for 23, deviation for 19, nothing_to_settle for 8 and underspecified for 26. The folder holds one subfolder per vector: * contract.json, view.json, events/eNN.json (the events, in any order), nenrin/nNN.json when the vector supplies walks, parent.json when it supplies a parent contract, * expected.json: the core fields (Section 10.1). The index vectors/vectors.json lists, for each vector, its id, its family (real or synthetic), the section of the source text it tests, a description, the expected verdict, status and code sets, and the sha256 of each of its files. It also lists the four synthetic public keys. Real vectors use the real records, contracts and Bitcoin headers of two settled engagements, with one change each (the record bodies cannot change without breaking the real Bitcoin anchors). real_p31_baseline is the first MUSUBI contract settled with no party from the project that publishes the reference (agent-passport.org and kuangmi-bit.github.io, Bitcoin block 970480), with its 359 header view. Synthetic vectors use keys named synthetic-principal, synthetic- contractor, synthetic-witness and synthetic-stranger, derived from fixed seeds, and a synthetic header chain at regtest difficulty (max_target_bits 207fffff, checkpoint height 800001). The public keys are: Oga Expires 20 April 2027 [Page 39] Internet-Draft MUSUBI Settlement October 2026 +====================+============================================+ |name |public_key_ed25519_b64 | +====================+============================================+ |synthetic-principal |rrXBDf5mF249t6wdmMvKtkcBXZmVVfcfYFBBjIpSttE=| +--------------------+--------------------------------------------+ |synthetic-contractor|hl3xmxz86HFYXTczn/5HZw4Jkb3i0nL7iig/2GXZrcs=| +--------------------+--------------------------------------------+ |synthetic-witness |gMKIYPPIjG6r9mt8ybr3dIGGm6LYxkngSym9ltvHNtY=| +--------------------+--------------------------------------------+ |synthetic-stranger |YmzNu/v6K9wUOtcmnssHABVLBDuLBqMcZnM0NL+32rU=| +--------------------+--------------------------------------------+ Table 14: Synthetic keys gen_vectors.py regenerates every vector from the two real inputs and the reference; it is deterministic. run_reference.py runs the reference over every vector and checks every file hash and every core field. 15.2. The Core-Field Projection expected.json holds exactly the eight core fields of Section 10.1 and nothing else. The reference's full settlement object is projected onto them as follows: * contract_sha256, verdict, status and bond_outcome are copied. * deviation_codes and underspecified_reasons are the sorted sets of the codes in the reference's deviations and underspecified lists. Repetitions are removed. * event_set keeps, for each accepted record in the order of Section 9.1, only kind, sha256 and height. * dispositions is one object from record_sha256 to one disposition code (Section 10.2), with keys sorted. A record that would receive two different codes is an error of the projection. An implementation conforms on a vector when its eight core fields are equal to expected.json as JSON values. The informative fields (Section 10.4) are not compared. 15.3. Reporting a Disagreement A disagreement is valuable. It means either the text, the reference or the implementation is wrong, and only a comparison finds out which. Oga Expires 20 April 2027 [Page 40] Internet-Draft MUSUBI Settlement October 2026 1. Run the implementation over the vectors. For each vector, compare its core fields (Section 10.1) with expected.json. 2. Run python3 run_reference.py from the folder holding the source text, to confirm the reference still gives the expected values on the same machine. 3. For each vector with a disagreement, write down: the vector id; the core field; the expected value and the implementation's; the section of this document followed; and, if possible, the step where the computation first diverged (for example "conformance: the name was treated as nonconforming"). 4. Say whether the vector is listed in Section 14. If it is, say whether the behaviour should change. 5. For a disagreement on an input that is not a vector, attach the input files (contract, events, view, walks) so the reference can be run on them. 6. Open an issue on the repository that publishes the source text (at the time of writing github.com/ogasurfproject-jpg/horizon- shield) titled settle core v0 disagreement: , with the above. An implementer should not change an implementation to match a vector believed to be wrong without saying so. A silent match hides a defect. A reported disagreement is resolved by changing this text, the reference, or the vector, and the change is recorded with a new version of this document. 16. Implementation Status Note to the RFC Editor: please remove this section before publication. This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in [RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. Please note that the listing of any individual implementation here does not imply endorsement by the IETF. Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features. Readers are advised to note that other implementations may exist. Oga Expires 20 April 2027 [Page 41] Internet-Draft MUSUBI Settlement October 2026 According to [RFC7942], "this will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature. It is up to the individual working groups to use this information as they see fit". 16.1. Reference Implementation Organization: The HORIZONs Co., Ltd. Implementation: settle_v1_16.py (output schema a2a-settlement-v1.16) and the modules it imports, at commit 4100d52a [MUSUBI-REF]. It is called as a library, settle_v1_16.settle_v1_16(contract, events, view, parent=..., nenrin_records=...). Its command line (--settle, --event, --view, --nenrin, --parent) first checks each view's strict form and runs fork choice, and for a view that does not pass prints why and writes no settlement. The vectors use the library. Description: The implementation from which this document was written. It covers all of settle core v0 and the gates outside its scope (Section 1.4). Maturity: Reference. Its behaviour defines the expected values of the vectors. Coverage: All of settle core v0. The canonical form (Section 4.1) is also implemented in JavaScript (canonical_v0.mjs), which covers only that section. Licensing: MIT. Implementation experience: run_reference.py reports "76/76 vectors agree with the reference" with Python 3.13.16 and the Python package cryptography 50.0.1. Contact: Toshikatsu Oga, thehorizon.nnovation@icloud.com Last updated: 2026-10-17 The reference, as run for the vectors, consists of these files (first 16 hex digits of each file's sha256): Oga Expires 20 April 2027 [Page 42] Internet-Draft MUSUBI Settlement October 2026 +========================+==================+ | file | sha256 prefix | +========================+==================+ | settle_v1.py | 0e51350331c8931c | +------------------------+------------------+ | settle_v1_1.py | a2391a5db199bcda | +------------------------+------------------+ | settle_v1_2.py | 6c674fd54a1a5c89 | +------------------------+------------------+ | settle_v1_3.py | 17119bbc7802647f | +------------------------+------------------+ | settle_v1_4.py | ef3779d05fc98e40 | +------------------------+------------------+ | settle_v1_5.py | f9b313566713cdc4 | +------------------------+------------------+ | settle_v1_6.py | 6752a748ed7b6e3b | +------------------------+------------------+ | settle_v1_7.py | 878a3a3697775d3a | +------------------------+------------------+ | settle_v1_8.py | fe61f67c1593c776 | +------------------------+------------------+ | settle_v1_9.py | 7a84302be1ec38a1 | +------------------------+------------------+ | settle_v1_10.py | 34beeebaa1397059 | +------------------------+------------------+ | settle_v1_11.py | fb03687cbacd2713 | +------------------------+------------------+ | settle_v1_12.py | 40a8fbb82a8e7680 | +------------------------+------------------+ | settle_v1_13.py | eb02b3a6544b1bf1 | +------------------------+------------------+ | settle_v1_14.py | 7d0704fa060adafd | +------------------------+------------------+ | settle_v1_15.py | a2be5de8ba60656e | +------------------------+------------------+ | settle_v1_16.py | ec332ecb387e9b56 | +------------------------+------------------+ | admission_verify_v0.py | aa889e542ff40e25 | +------------------------+------------------+ | agreement_verify.py | 72990326ac4a0a65 | +------------------------+------------------+ | anchor_compose.py | a661f673c05dbe6e | +------------------------+------------------+ | approval_v3.py | e8dde985dbe6fbf4 | +------------------------+------------------+ | clause_eval_v0.py | fee48c3a66c28fe1 | +------------------------+------------------+ | contract_v0.py | 211a568783705e11 | Oga Expires 20 April 2027 [Page 43] Internet-Draft MUSUBI Settlement October 2026 +------------------------+------------------+ | convergence_v0.py | 65a267380fa623f5 | +------------------------+------------------+ | corroboration_v0.py | 62ae1d6c27a92228 | +------------------------+------------------+ | independence_v0.py | 50964883c27896de | +------------------------+------------------+ | recovery_verify.py | e9bc9c11dd7d9aef | +------------------------+------------------+ | spine_verify.py | ad2076d49be6763e | +------------------------+------------------+ | terms_v0.py | 6532d5c6160a3974 | +------------------------+------------------+ Table 15: Reference files 16.2. Independent Implementations No independent implementation of settle core v0 exists at the time of writing. An open call for one, with the procedure of Section 15.3, is at [ISSUE-49]. 17. Security Considerations 17.1. Unsigned Parts of a Record A record has three parts (Section 7.1): the body, which its signer signed, and the anchor and the signatures list, which nobody signed. A third party that holds copies of genuine records, the contract and the walks can therefore change anchors and signature lists at will, but cannot change a body without the signer's key. The rules are arranged around this: * A copy whose signatures list holds no strict, verifying entry from an allowed role is never examined: it is set aside or rejected in Section 7.1, and no later step (collapse, size limit, conformance, anchors, NENRIN checks) sees it. An unsigned record cannot add a charge or forfeit a bond. * A copy that keeps the genuine signature but adds junk entries to signatures has the same record signing bytes as the genuine record. Junk entries are ignored, and copies of one signed body are collapsed (Section 7.5), keeping the copy that anchors validly at the smallest (height, record_sha256). Oga Expires 20 April 2027 [Page 44] Internet-Draft MUSUBI Settlement October 2026 * A copy with an anchor that is not strict is set aside when a validly anchored copy of the same body is present. A copy whose anchor is strict but wrong is dropped by the collapse when a validly anchored copy is present. * Binding is by contract_sha256 alone (Section 7.2): a record made under earlier terms with the same contract_id is foreign and is never triaged. What remains is a liveness property, not a safety one. When the genuine copy is not in the input, a copy with an incomplete or wrong anchor from a strictly signed record makes the whole settlement underspecified (Section 13); a party can delay a verdict in the same way by handing the settler such a record. A copy whose block_hash was edited to disagree with the view at a held height is orphaned and excluded without an underspecified reason (Section 14.1); a settler that has only such a copy does not see the act. Settlers that collect records from more than one source reduce both risks. underspecified must not be read as a statement that the terms are bad. The record_sha256 covers the unsigned parts, so it identifies a copy, not an act. The record signing bytes identify the act. 17.2. Signature Malleability and Strict Ed25519 Ed25519 implementations differ on adversarial signatures: a non- canonical S (for example S + L), a small order or mixed order R or public key, and cofactored versus cofactorless verification equations [EDDSA-TAMING]. Honest signatures verify everywhere. Settle core v0 counts a signature only when it is strict (Section 4.4): S, read as a little-endian integer, is below L, and R and the public key are canonical encodings of points of prime order that are not the identity. With all points in the prime order subgroup and S below L, the libraries that disagree on lax signatures agree. A lax signature that a library accepts is not ignored silently: the record is set aside as signature_not_strict, and a contract signature that is not strict makes the settlement underspecified (contract_signature_not_strict). Anyone can turn a genuine signature into a lax one (S + L) without a key; that changes the record_sha256 but not the body, and the genuine copy, if present, still settles (vectors synth_signature_s_plus_l and synth_strict_signature_beside_malleated). Oga Expires 20 April 2027 [Page 45] Internet-Draft MUSUBI Settlement October 2026 Item N9 of [MUSUBI-NOTES] records that the behaviour of the reference's OpenSSL on published Ed25519 edge cases was not tested beyond the strictness rule. The strictness rule is what conformance depends on. 17.3. Number and Canonicalization Divergence Settlement depends on byte-exact digests computed by different runtimes. JSON readers differ: some accept the tokens NaN and Infinity, some read 970480.0 as a float and others as the integer 970480, integers above 2^53 are exact in some and rounded in others, duplicate keys are resolved differently, and key order by code point differs from order by UTF-16 code unit above U+FFFF. A pattern ending in $ in some regular expression engines also accepts a trailing line feed, and some hex decoders skip whitespace. The rules of Section 3.2, Section 4.1 and Section 7.1 remove these differences for the values that matter: only integers within plus or minus (2^53 - 1) are strict, keys in the contract and in strict values are ASCII, fixed forms such as hex digests are matched whole, and a value that is not strict is set aside or makes the settlement underspecified instead of being read two ways. An implementer has to parse numbers to an exact integer representation, match fixed forms against the whole string, and refuse whitespace in hex. Some divergence remains possible outside strict values. The record_sha256 of a record that is set aside, foreign or unbound is still reported in dispositions, and its canonical form can depend on the runtime for values that are not strict. A record whose record_sha256 "cannot be computed at all" is set aside without a disposition; in the reference this happens, for example, for an integer too long for the Python runtime to write out, and another runtime may reach that limit at a different length. Item N4 of [MUSUBI-NOTES] also records that JSON batches reached through a proof (Section 8.6) are parsed as the lower layers of the reference parse them. 17.4. Reorganizations Deeper Than the Finality Depth Settle core v0 takes one header view as given. It checks linkage, proof of work against each header's own nBits, the grant's difficulty floor and the signed checkpoint, and nothing else of Bitcoin consensus. It does not establish that the view is the heaviest chain. A status of final means that every accepted and orphaned record is at least grant.finality.depth blocks below the tip of the view; a reorganization deeper than that depth can still change a final settlement. Choosing between several views (fork choice) is out of scope (Section 1.4). The difficulty floor and the checkpoint Oga Expires 20 April 2027 [Page 46] Internet-Draft MUSUBI Settlement October 2026 limit what a party can forge cheaply, but a view supplied by an adversary with enough work is accepted. 17.5. What the Verdict Does Not Establish * That any record is true. A signature proves which key signed, not that the act happened as described. * That no key was stolen. A stolen key signs validly. Key rotation and compromise are outside settle. * That acts nobody recorded did not happen. within_grant covers the accepted records only. * That a foreign, unbound, inconsistent, rejected, orphaned or predated record is false. Only that it was not settled here. * Full Bitcoin consensus validity. Only linkage, proof of work against each header's own nBits, the grant's difficulty floor and the signed checkpoint are checked. * That the view is the heaviest chain. Core v0 takes one view as given. A reorganization deeper than the finality depth can change a final settlement. * That the key at a party's key_url is the key in the contract. Settle never fetches. * That the walk cited by nenrin_ref is correct. Section 12 only compares the contract it names. * That anyone judged liability or fault, or that this is a legal contract. The verdict is a function anyone can recompute from the same bytes. * That the parts out of scope (Section 1.4) hold. A contract that relies on the spine gate, convergence, pinned approvers or limits must be settled by a settler that reads them. * That settle layers before v1.16 agree. They do not on the vectors listed in Section 14; on every other vector settle_v1_15.py gives the same core fields. * That a record set aside or rejected is false. Only that it was not strictly signed, or not readable strictly, so it was not settled here. Oga Expires 20 April 2027 [Page 47] Internet-Draft MUSUBI Settlement October 2026 18. Privacy Considerations A contract names both parties by domain and pins their public keys, and records carry action names, delegation targets, payload digests and references to walks. Anyone who is given these bytes can settle, so anyone who is given them learns who contracted with whom and what the agent did. Anchoring commits only a digest to the Bitcoin block chain, but the commitment is public and permanent, and publishing a record later links it to a block and so to a time. Parties should treat the inputs of a settlement as disclosed to every settler they hand them to. Settlement itself fetches nothing (Section 1.4), so computing it reveals nothing to a network observer. 19. IANA Considerations This document has no IANA actions. 20. References 20.1. Normative References [FIPS180-4] National Institute of Standards and Technology, "Secure Hash Standard (SHS)", FIPS PUB 180-4, DOI 10.6028/NIST.FIPS.180-4, August 2015, . [MUSUBI-REF] Oga, T., "MUSUBI reference settler: settle_v1_16.py and the modules it imports", 17 October 2026, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, . [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, . Oga Expires 20 April 2027 [Page 48] Internet-Draft MUSUBI Settlement October 2026 [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, January 2017, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, . 20.2. Informative References [A2A] A2A Project, "Agent2Agent (A2A) Protocol Specification", . [BITCOIN] Nakamoto, S., "Bitcoin: A Peer-to-Peer Electronic Cash System", 2008, . [BITCOIN-HEADERS] Bitcoin Project, "Bitcoin Developer Reference: Block Headers", . [EDDSA-TAMING] Chalkias, K., Garillot, F., and V. Nikolaenko, "Taming the many EdDSAs", DOI 10.1007/978-3-030-64357-7_4, 2020, . [ISSUE-49] The HORIZONs Co., Ltd., "horizon-shield issue 49: call for an independent implementation of settle core v0", October 2026, . [MUSUBI-NOTES] Oga, T., "Notes on settle core v0 (NOTES.md)", 17 October 2026, . [MUSUBI-SETTLE-CORE] Oga, T., "MUSUBI settle core v0 (SETTLE_CORE_v0.md)", 17 October 2026, . Oga Expires 20 April 2027 [Page 49] Internet-Draft MUSUBI Settlement October 2026 [MUSUBI-VECTORS] Oga, T., "MUSUBI settle core v0 test vectors", 17 October 2026, . [NENRIN-VERIFIER] Oga, T., "NENRIN provenance verifier: normative procedure (VERIFIER.md), interoperability vectors and reference verifiers", DOI 10.5281/zenodo.23136978, 4 October 2026, . [OPENTIMESTAMPS] OpenTimestamps, "OpenTimestamps", . [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, DOI 10.17487/RFC7493, March 2015, . [RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, July 2016, . [RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785, June 2020, . Appendix A. Codes Underspecified reasons in core v0: contract_not_verified, input_not_settleable, contract_signature_not_strict, bond_malformed, parent_not_supplied, parent_narrowing_failed, view_not_strict, record_not_strict, anchor_not_strict, anchor_below_lower_bound, walk_not_strict, authorized_actions_missing, grant_action_name_invalid, too_many_witnesses, witness_key_invalid, key_conflict, tie_policy_refused, revocation_policy_not_recomputable, ack_window_missing, finality_policy_missing, bad_expiry_height, unscoped_approvals_refused, chain_view_rejected, input_too_large, anchor_incomplete, anchor_beyond_observed_chain, anchor_proof_invalid, anchor_batch_leg_refused. Deviation codes in core v0: revoked, after_expiry, prohibited, conditional, unauthorized, delegation, forged_approval, nonconforming_record, evidence_names_other_contract, evidence_missing. Oga Expires 20 April 2027 [Page 50] Internet-Draft MUSUBI Settlement October 2026 Verdicts: within_grant, deviation, nothing_to_settle, underspecified. Dispositions: Section 10.2. Acknowledgements The parties behind agent-passport.org and kuangmi-bit.github.io published the contract, the anchored record and the header view of the first MUSUBI contract settled with no party from the project that publishes the reference; the real vectors are built from them. Two independent adversarial reviews of the reference found defects that this document now describes as closed. Author's Address Toshikatsu Oga The HORIZONs Co., Ltd. Japan Email: thehorizon.nnovation@icloud.com Oga Expires 20 April 2027 [Page 51]