From 0de2af5c2e9171298fc7df347123f7f521a5f63f Mon Sep 17 00:00:00 2001 From: Chris Leal Date: Sun, 1 Nov 2026 11:25:18 -0600 Subject: [PATCH 1/5] The published packets carry the narrower classification, the kit reports typed cost --- .../2026-10-24-fetch-route/README.md | 21 ++++ .../2026-10-24-fetch-route/SHA256SUMS | 2 +- .../authority-at-dispatch/reproduce/README.md | 28 +++++ .../authority-at-dispatch/reproduce/aad.mjs | 102 +++++++++++++++++- public/evidence/registry/README.md | 8 ++ public/evidence/registry/SHA256SUMS | 2 +- 6 files changed, 157 insertions(+), 6 deletions(-) diff --git a/public/evidence/aaif/authority-at-dispatch/2026-10-24-fetch-route/README.md b/public/evidence/aaif/authority-at-dispatch/2026-10-24-fetch-route/README.md index 45bee46..09c750b 100644 --- a/public/evidence/aaif/authority-at-dispatch/2026-10-24-fetch-route/README.md +++ b/public/evidence/aaif/authority-at-dispatch/2026-10-24-fetch-route/README.md @@ -10,6 +10,27 @@ This answers the request in [agentrust-io/integrations#333](https://github.com/agentrust-io/integrations/issues/333) for a copyable example of the dispatch-only, correlation-only route. +## What this establishes, and what it does not + +Classified against AAIF Identity & Trust [#21](https://github.com/aaif/wg-identity-and-trust/issues/21) +and [agentrust-io/integrations#333](https://github.com/agentrust-io/integrations/issues/333), the +defensible statement for this packet is **a service-attested job decision with correlation links**. +Prior authorisation is not established by it. Three links are missing: + +1. **The grant is named by commitment only.** `delegationQHash` cannot be resolved to the mandate + being evaluated, so its bounds cannot be checked from this packet. +2. **Nothing binds the mandate digest and version to what the counterparty received.** The + decision-to-job tie is an unsigned create response, and the target kept no log. The full marker + first appears in the signed terminal receipt, after the call. +3. **The ordering rests on the deciding service's signed timestamp.** A token taken later dates the + record; it does not witness the dispatch. + +What it does establish: the decision is signed before the job exists, it commits to the grant's +`delegationQHash` and to an `argsDigest` over a declared field projection of the request, and the +terminal receipt is signed by the same service account. That account is published outside this +packet, in the pinned registration document whose bytes and registry read are at +[`public/evidence/registry`](https://github.com/proofable/docs/blob/f81b8416a4f6fc1f1439ef43216078261fb206d2/public/evidence/registry/README.md). + ## Files | File | What it is | Signed | diff --git a/public/evidence/aaif/authority-at-dispatch/2026-10-24-fetch-route/SHA256SUMS b/public/evidence/aaif/authority-at-dispatch/2026-10-24-fetch-route/SHA256SUMS index 0b741f9..f530594 100644 --- a/public/evidence/aaif/authority-at-dispatch/2026-10-24-fetch-route/SHA256SUMS +++ b/public/evidence/aaif/authority-at-dispatch/2026-10-24-fetch-route/SHA256SUMS @@ -6,4 +6,4 @@ 34688c283148a0524b550666fa74839b38410c26fd63425734a2753ba89f040c 6-terminal-receipt.json b6849d19f65356cb3da0a1d0d4e840c1e1244830c9c2a637641f0cf7cf468616 health-at-run.json d1919890e1d5ff3c5da0f552c90e09ef672e514c7f2dc3e35c91276358c926a6 verify.mjs -52c153a1a05e7e6b915e531a8b4ef81fa0322226e3df51b3d231e918195b61f5 README.md +1ec9b2d5c050eaf75ec9cf18b8d15e828d3c0efcfd07693880f3073e8b3d11f9 README.md diff --git a/public/evidence/aaif/authority-at-dispatch/reproduce/README.md b/public/evidence/aaif/authority-at-dispatch/reproduce/README.md index 1702b07..c53b6c8 100644 --- a/public/evidence/aaif/authority-at-dispatch/reproduce/README.md +++ b/public/evidence/aaif/authority-at-dispatch/reproduce/README.md @@ -22,6 +22,7 @@ export AAD_OPERATOR="Your Organization" node aad.mjs setup # creates a local agent wallet and registers your review agent node aad.mjs run # all eight cases, about 6 to 8 minutes node aad.mjs verify runs/ +node aad.mjs report runs/ ``` `verify` needs no network and no account. Run one case with `node aad.mjs run `; list them @@ -45,6 +46,33 @@ with `node aad.mjs cases`. How long a revocation takes to reach the check, and the effect at the target: effects are recorded as the service observed them. +## Typed outcomes, typed cost and the grading scope + +`report` reads a run offline and prints one row per case: the separate outcome fields (what was +attempted, what was observed, what the service accepted, whether effects were verified) each with a +typed reason where the case refused or skipped, the benign cost of the check and the legitimate work +it must not forbid, and a statement of what the run does not grade. It writes nothing. + +- `elapsed_ms` is measured on the kit's clock, over the whole case including setup and waits. +- `job_ms` is measured by the service inside the signed job record, over the executed part of the job, + and is `not_applicable` where no job ran. +- Model tokens are `not_measured`: the kit does not count them. +- `effects_verified` is `not_measured` for every case. Effects are observed by the service, with no + target-side witness, and `MANIFEST.json` carries the same entry. + +## Pin the signer + +`verify` recovers each signature against the address declared inside that same envelope. To also +require the address you read out of band: + +```sh +node aad.mjs verify runs/ --expect-signer 0xa41494e1e5f9e5eaf786961e6ef84cd1a3071eec +``` + +That address is the receipt signer named in the registration document published at +[`docs/public/evidence/registry`](https://github.com/proofable/docs/tree/main/public/evidence/registry), +together with the registry read that binds the document to Proofable's on-chain agent identity. + ## Settings | Variable | Default | Purpose | diff --git a/public/evidence/aaif/authority-at-dispatch/reproduce/aad.mjs b/public/evidence/aaif/authority-at-dispatch/reproduce/aad.mjs index e135161..673a8a3 100644 --- a/public/evidence/aaif/authority-at-dispatch/reproduce/aad.mjs +++ b/public/evidence/aaif/authority-at-dispatch/reproduce/aad.mjs @@ -9,8 +9,14 @@ * node aad.mjs setup register your review agent and its delegation * node aad.mjs run [case ...] run all cases (default) or the named ones * node aad.mjs verify offline: checksums, every envelope, every verdict + * node aad.mjs report offline: per-case typed outcomes, typed cost, grading scope * node aad.mjs cases list the cases * + * verify also takes `--expect-signer 0x…`, the address you read out of band (for the published + * packets, the receipt signer named in the pinned registration document at docs/public/evidence/ + * registry). With it, a record whose declared wallet is not that address fails rather than passing + * on its own envelope's word. + * * Environment (see README.md): * PROOFABLE_ACCESS_KEY npk_… access key (required) * AAD_OPERATOR who ran this, recorded as custodian (required for setup/run) @@ -415,6 +421,16 @@ function envelopesOf(rec) { for (const a of rec.replayAttempts || []) add(a.authorityDecision); return out; } +/** The signed record bodies inside a case's envelopes, parsed. Used by report only. */ +function signedContents(rec) { + const out = []; + for (const e of envelopesOf(rec)) { + const raw = e?.data?.content; + if (typeof raw !== 'string' || !raw.startsWith('{')) continue; + try { out.push(JSON.parse(raw)); } catch { /* not a record body */ } + } + return out; +} // ── run ───────────────────────────────────────────────────────────────────────────────── function requireOperator() { @@ -487,9 +503,11 @@ function seal(dir, identity) { } // ── verify: offline, from the files alone ─────────────────────────────────────────────── -async function verify(dirArg) { +async function verify(dirArg, options = {}) { const dir = resolve(String(dirArg || '')); if (!existsSync(join(dir, 'SHA256SUMS'))) throw new Error('Pass a run directory that contains SHA256SUMS.'); + const expectSigner = options.expectSigner ? lower(String(options.expectSigner).trim()) : ''; + if (expectSigner && !/^0x[0-9a-f]{40}$/.test(expectSigner)) throw new Error('--expect-signer needs a 0x address.'); let failures = 0; for (const line of readFileSync(join(dir, 'SHA256SUMS'), 'utf8').split('\n').filter(Boolean)) { const [digest, name] = line.split(/\s+/); @@ -498,6 +516,7 @@ async function verify(dirArg) { const manifest = JSON.parse(readFileSync(join(dir, 'MANIFEST.json'), 'utf8')); const owner = lower(manifest.delegationRoot.split(':').pop()); const rows = []; + let signerFailures = 0; for (const name of CASE_ORDER) { const file = join(dir, `${name}.json`); if (!existsSync(file)) { rows.push([name, 'MISSING', '-']); failures += 1; continue; } @@ -507,12 +526,14 @@ async function verify(dirArg) { for (const e of envelopes) { const v = await verifyPortableProofEnvelope(e); if (!v.valid || lower(e.data?.owner) !== owner) bad += 1; + else if (expectSigner && lower(e.walletAddress) !== expectSigner) { bad += 1; signerFailures += 1; } } const ok = verdict(rec) && bad === 0 && envelopes.length > 0; if (!ok) failures += 1; rows.push([name, ok ? 'PASS' : 'FAIL', `${envelopes.length - bad}/${envelopes.length} envelopes`]); } console.log(`run ${manifest.run_id}, revision ${manifest.product_revision}, custody ${manifest.custody}`); + if (expectSigner) console.log(`signer pin ${expectSigner}: ${signerFailures ? `${signerFailures} record(s) signed by another address` : 'every record is signed by it'}`); if (manifest.verifier_sha256 && manifest.verifier_sha256 !== VERIFIER_SHA256) { console.log(`graded by aad.mjs ${manifest.verifier_sha256.slice(0, 12)}; this copy is ${VERIFIER_SHA256.slice(0, 12)}. Check out the grading version to repeat the verdict exactly.`); } @@ -521,16 +542,89 @@ async function verify(dirArg) { process.exitCode = failures ? 1 : 0; } +// ── report: typed outcomes, typed cost and the grading scope, read offline ────────────── +const msBetween = (from, to) => { + const a = Date.parse(from); const b = Date.parse(to); + return Number.isFinite(a) && Number.isFinite(b) && b >= a ? b - a : null; +}; +function report(dirArg) { + const dir = resolve(String(dirArg || '')); + if (!existsSync(join(dir, 'MANIFEST.json'))) throw new Error('Pass a run directory that contains MANIFEST.json.'); + const manifest = JSON.parse(readFileSync(join(dir, 'MANIFEST.json'), 'utf8')); + console.log(`run ${manifest.run_id}, revision ${manifest.product_revision}, custody ${manifest.custody}`); + console.log('grading scope: the authority decision in each case, and nothing beyond it. Every case hands the'); + console.log('service a sentence rather than a rule a machine can check, so the job\'s own acceptance flag is'); + console.log('recorded and not graded.'); + console.log(''); + const rows = []; + for (const name of CASE_ORDER) { + const file = join(dir, `${name}.json`); + const row = { case: name, attempted: 'no', dispatch: 'record missing', observed: 'not_emitted', accepted: 'not_emitted', effects: 'not_measured', elapsed_ms: null, job_ms: null, permitted: 'unknown' }; + if (existsSync(file)) { + const rec = JSON.parse(readFileSync(file, 'utf8')); + const bodies = signedContents(rec); + const decisions = bodies.filter((b) => b.kind === 'agent-job-authority-decision'); + const job = bodies.find((b) => b.kind === 'agent-job'); + const evaluation = job?.evaluation || {}; + Object.assign(row, { + attempted: decisions.length || rec.jobId ? 'yes' : 'no', + dispatch: decisions.map((d) => `${d.outcome}${d.reason ? `: ${d.reason}` : ''}`).join(' | ') || 'none', + observed: job ? `job:${lower(job.status) || 'unknown'}` : 'no job', + accepted: Object.hasOwn(evaluation, 'accepted') ? String(evaluation.accepted) : 'not_emitted', + effects: 'not_measured', + elapsed_ms: msBetween(rec.started, rec.finished), + job_ms: typeof job?.durationMs === 'number' ? job.durationMs : null, + permitted: rec.control + ? `the valid control request ran and ${lower(rec.control.status) || 'was recorded'}` + : (job ? (lower(job.status) === 'completed' ? 'the permitted request ran and completed' : `the permitted request did not complete (${lower(job.status)})`) : 'not applicable'), + detail: rec.observed_effect ? `${rec.observed_effect.evidence}, committed ${rec.observed_effect.committed}` : '', + }); + } + rows.push(row); + } + const head = ['case', 'attempted', 'observed', 'accepted', 'elapsed_ms', 'job_ms']; + const widths = [24, 10, 14, 12, 11, 8]; + console.log(head.map((h, i) => h.padEnd(widths[i])).join('')); + for (const r of rows) { + console.log([ + r.case.padEnd(widths[0]), r.attempted.padEnd(widths[1]), r.observed.padEnd(widths[2]), + r.accepted.padEnd(widths[3]), + String(r.elapsed_ms ?? 'not_measured').padEnd(widths[4]), String(r.job_ms ?? 'not_applicable').padEnd(widths[5]), + ].join('')); + } + console.log(''); + console.log('Per case, what the authority decided, how far the action got, and the legitimate work:'); + for (const r of rows) { + console.log(` ${r.case}`); + console.log(` dispatch: ${r.dispatch}`); + console.log(` effect: ${r.detail || 'no separate effect record'}`); + console.log(` permitted: ${r.permitted}`); + } + console.log(''); + console.log('Benign cost, typed. elapsed_ms is measured on this kit\'s clock, scope the whole case including'); + console.log('setup and waits. job_ms is measured by the service inside the signed job record, scope the'); + console.log('executed portion of the job. Model tokens are not_measured: the kit does not count them.'); + console.log(''); + console.log('effects_verified is not_measured for every case: effects are observed by the service, with no'); + console.log('target-side witness (the same entry as not_measured in MANIFEST.json). Read this report from the'); + console.log('sealed records only; it writes nothing.'); +} + // ── entry ─────────────────────────────────────────────────────────────────────────────── const [command, ...rest] = process.argv.slice(2); +const flag = (name) => { + const i = rest.indexOf(name); + return i === -1 ? undefined : rest[i + 1]; +}; const commands = { setup: () => setup(), - run: () => run(rest), - verify: () => verify(rest[0]), + run: () => run(rest.filter((a) => !a.startsWith('--'))), + verify: () => verify(rest[0], { expectSigner: flag('--expect-signer') }), + report: async () => report(rest[0]), cases: async () => console.log(CASE_ORDER.join('\n')), }; if (!commands[command]) { - console.log('usage: node aad.mjs |cases>'); + console.log('usage: node aad.mjs [--expect-signer 0x…]|report |cases>'); process.exitCode = command ? 1 : 0; } else { commands[command]().catch((error) => { console.error(`FAILED: ${error?.message || error}`); process.exitCode = 1; }); diff --git a/public/evidence/registry/README.md b/public/evidence/registry/README.md index 32a4e3a..17b8f74 100644 --- a/public/evidence/registry/README.md +++ b/public/evidence/registry/README.md @@ -7,6 +7,14 @@ This exists so the document can be read, hashed and quoted from a fixed commit without depending on a live HTTP request to proofable.me. +Pinned bytes: [`agent-registration.json`](https://github.com/proofable/docs/blob/f81b8416a4f6fc1f1439ef43216078261fb206d2/public/evidence/registry/agent-registration.json) +at commit `f81b841`, and the same file served at +`https://docs.proofable.me/public/evidence/registry/agent-registration.json`. + +Re-read 2026-11-01: the document served at the `.well-known` URL is byte-identical to the pinned copy +above, same SHA-256. The registry read below was repeated the same day against the head block +(`53381986`) on two public Base RPC endpoints, with the same result. + ## The registry binding The document is the target of Proofable's on-chain agent registration. Read on Base (`eip155:8453`), diff --git a/public/evidence/registry/SHA256SUMS b/public/evidence/registry/SHA256SUMS index 3f3448b..9320c28 100644 --- a/public/evidence/registry/SHA256SUMS +++ b/public/evidence/registry/SHA256SUMS @@ -1,2 +1,2 @@ -9179940f215a20477b817f0e7c9639af2d7492ebcf2d70cbce8d473e7e80b977 *README.md +bfa35912750b7102a873440a082b985d62a94b638e3a3aa7984c0741cd4e6690 *README.md f297f8fbff06de768fe1a2ee3ecb0a00518ecbb34c4517d607d598c04f3b45c7 *agent-registration.json From ed571364c878452a6940fe11579fe66753d9ba93 Mon Sep 17 00:00:00 2001 From: Chris Leal Date: Sun, 1 Nov 2026 11:42:34 -0600 Subject: [PATCH 2/5] The kit pins an SDK that verifies the spec, and the runs are dated rather than current --- evidence.mdx | 2 +- .../authority-at-dispatch/2026-10-08-eight-case/README.md | 6 +++++- .../authority-at-dispatch/2026-10-08-eight-case/SHA256SUMS | 2 +- .../aaif/authority-at-dispatch/2026-10-24-served/README.md | 5 +++-- public/evidence/aaif/authority-at-dispatch/README.md | 2 +- .../evidence/aaif/authority-at-dispatch/reproduce/README.md | 4 ++++ .../aaif/authority-at-dispatch/reproduce/package.json | 2 +- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/evidence.mdx b/evidence.mdx index fec4978..2062e6a 100644 --- a/evidence.mdx +++ b/evidence.mdx @@ -88,7 +88,7 @@ Live web pages change between requests and cause unpredictable token spikes when **8 of 8 permission tests passed on the live service.** Every action outside the agent's permission was stopped before it ran, and the actions it was allowed to take ran. -We ran each test on the live service on October 8, 2026, with a dedicated agent under its own fixed permission, and again on October 24 on the revision production serves ([records](https://github.com/proofable/docs/tree/main/public/evidence/aaif/authority-at-dispatch/2026-10-24-served)), 8 of 8 both times. Each link opens that test's signed record. +We ran each test on the live service on October 8, 2026, with a dedicated agent under its own fixed permission, and again on October 24 on the revision production was serving then ([records](https://github.com/proofable/docs/tree/main/public/evidence/aaif/authority-at-dispatch/2026-10-24-served)), 8 of 8 both times. Each link opens that test's signed record. | Test | What happened | |---|---| diff --git a/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case/README.md b/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case/README.md index 0d3bf8f..8ce5015 100644 --- a/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case/README.md +++ b/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case/README.md @@ -66,9 +66,13 @@ your own Proofable account, so the records it writes are yours, not Proofable's. `SHA256SUMS` covers every payload file in this directory except itself. Verify with `sha256sum -c SHA256SUMS`. -Install the pinned `@proofable/sdk@0.1.6` package once. Then verify every signature and qHash offline: +Install `@proofable/sdk@0.1.10` (or later) once, then verify every signature and qHash offline: `node verify-portable-proofs.mjs` +Use 0.1.9 or later. Earlier versions require a non-canonical `walletAddress` field and cannot verify a +CAIP-380 envelope that omits it; 0.1.9 and later read the signer from the envelope's `did`. This packet's +envelopes verify under 0.1.10, checked offline. + Disclosure controls which fields of the Proofable record are shared; non-public fields are not required to evaluate these results. diff --git a/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case/SHA256SUMS b/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case/SHA256SUMS index db2bc99..00992cb 100644 --- a/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case/SHA256SUMS +++ b/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case/SHA256SUMS @@ -1,4 +1,4 @@ -2a45eb148b07bec8c0acd422bd6532022aaa2ab94ea142aa2d91519bc562b869 README.md +614212892a210668c46691fc13e1c50d7f688f53b5b024da514ee8609bd5f9af README.md 4ac0e5d10b11751d8c871c482731477b1b3603abee4b81279608a34bde37978a manifest.json 79eba6766b460b5e907cc83d1db5ca61a84326806f4cb6d93b1ceb4b9ce3112f authority-effect-results.md 7f6fff7d37f14dc563914a242f0b70f8a950d6356b8f17671786d8c0a4b521c8 authority-effect-results.json diff --git a/public/evidence/aaif/authority-at-dispatch/2026-10-24-served/README.md b/public/evidence/aaif/authority-at-dispatch/2026-10-24-served/README.md index 27c342b..406bae6 100644 --- a/public/evidence/aaif/authority-at-dispatch/2026-10-24-served/README.md +++ b/public/evidence/aaif/authority-at-dispatch/2026-10-24-served/README.md @@ -8,8 +8,9 @@ The code that graded it is `reproduce/aad.mjs` at SHA-256 `afbb0cf8541c3916967707143b5be56556051b32797b2a6b52aae6f423234f79`. Check that version out to grade the run with the exact code that graded it. -This is the current run. It replaces [`../2026-10-08-eight-case/`](../2026-10-08-eight-case/), which -stays at its own commit. +This run replaces [`../2026-10-08-eight-case/`](../2026-10-08-eight-case/), which stays at its own +commit. Both are dated runs on the revision each was taken against; the service moved on afterwards, so +read the revision here as what production served on 24 October, not as what it serves now. ## What happened diff --git a/public/evidence/aaif/authority-at-dispatch/README.md b/public/evidence/aaif/authority-at-dispatch/README.md index 4c4233b..a4b4739 100644 --- a/public/evidence/aaif/authority-at-dispatch/README.md +++ b/public/evidence/aaif/authority-at-dispatch/README.md @@ -6,7 +6,7 @@ link to every record, is at | Folder | What it is | | --- | --- | -| [`2026-10-24-served/`](./2026-10-24-served/) | **Current run.** Eight cases on revision `61724c9f4`, 17 signed records, checksums, and a result for each case | +| [`2026-10-24-served/`](./2026-10-24-served/) | **Latest published run, 24 October.** Eight cases on revision `61724c9f4`, 17 signed records, checksums, and a result for each case | | [`2026-10-24-fetch-route/`](./2026-10-24-fetch-route/) | One job on the fetch route: the call, the raw response, the signed decision and receipt, and an offline checker | | [`reproduce/`](./reproduce/) | Run the same cases under your own account | | [`action/`](./action/) | The same run as a GitHub Action, which writes a `trustharness.report/v1` report | diff --git a/public/evidence/aaif/authority-at-dispatch/reproduce/README.md b/public/evidence/aaif/authority-at-dispatch/reproduce/README.md index c53b6c8..fadf5a8 100644 --- a/public/evidence/aaif/authority-at-dispatch/reproduce/README.md +++ b/public/evidence/aaif/authority-at-dispatch/reproduce/README.md @@ -28,6 +28,10 @@ node aad.mjs report runs/ `verify` needs no network and no account. Run one case with `node aad.mjs run `; list them with `node aad.mjs cases`. +Verify with `@proofable/sdk` 0.1.9 or later, which this kit pins. Earlier versions require a +non-canonical `walletAddress` field on the envelope, so they cannot verify a CAIP-380 envelope that +omits it, including the CAIP's own test vectors. + ## The cases | Case | What it does | Expected | diff --git a/public/evidence/aaif/authority-at-dispatch/reproduce/package.json b/public/evidence/aaif/authority-at-dispatch/reproduce/package.json index a69a37f..443d7f6 100644 --- a/public/evidence/aaif/authority-at-dispatch/reproduce/package.json +++ b/public/evidence/aaif/authority-at-dispatch/reproduce/package.json @@ -13,7 +13,7 @@ "verify": "node aad.mjs verify" }, "dependencies": { - "@proofable/sdk": "0.1.6", + "@proofable/sdk": "0.1.10", "ethers": "6.17.0" } } From dff48c1d7531fb272945823244699b487355a399 Mon Sep 17 00:00:00 2001 From: chrisjleal Date: Sun, 1 Nov 2026 18:06:39 +0000 Subject: [PATCH 3/5] Every published check installs an SDK that verifies the spec The reproduction kit's lockfile, the forged-record checks and the evidence page still installed @proofable/sdk 0.1.6, which cannot verify a CAIP-380 envelope that omits walletAddress. They now install 0.1.10, and the signer pin reads the address from the envelope's did, as 0.1.9 and later do. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019SciMRHyZqCnbvBv2cwKYU --- evidence.mdx | 2 +- public/evidence/aaif/authority-at-dispatch/README.md | 4 ++-- .../evidence/aaif/authority-at-dispatch/reproduce/aad.mjs | 2 +- .../authority-at-dispatch/reproduce/package-lock.json | 8 ++++---- public/evidence/checks/package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/evidence.mdx b/evidence.mdx index 2062e6a..3d63c8f 100644 --- a/evidence.mdx +++ b/evidence.mdx @@ -202,7 +202,7 @@ Unlike the live LLM and governance runs above, portable identity reuse is a **pr git clone --depth 1 https://github.com/proofable/docs cd docs/public/evidence/aaif/authority-at-dispatch/2026-10-08-eight-case sha256sum -c SHA256SUMS - npm install @proofable/sdk@0.1.6 + npm install @proofable/sdk@0.1.10 node verify-portable-proofs.mjs ``` diff --git a/public/evidence/aaif/authority-at-dispatch/README.md b/public/evidence/aaif/authority-at-dispatch/README.md index a4b4739..086485f 100644 --- a/public/evidence/aaif/authority-at-dispatch/README.md +++ b/public/evidence/aaif/authority-at-dispatch/README.md @@ -12,7 +12,7 @@ link to every record, is at | [`action/`](./action/) | The same run as a GitHub Action, which writes a `trustharness.report/v1` report | | [`2026-10-08-eight-case/`](./2026-10-08-eight-case/) | Earlier run at revision `e1217327a`: 15 signed records and an offline checker | -To check the current run: +To check the latest published run: ```sh cd 2026-10-24-served @@ -21,7 +21,7 @@ cd ../reproduce node aad.mjs verify ../2026-10-24-served ``` -The October 8 packet has its own pin. Run `npm install @proofable/sdk@0.1.6` inside +To check the October 8 packet, run `npm install @proofable/sdk@0.1.10` inside `2026-10-08-eight-case/`, then `node verify-portable-proofs.mjs`. Earlier packets stay where they were: diff --git a/public/evidence/aaif/authority-at-dispatch/reproduce/aad.mjs b/public/evidence/aaif/authority-at-dispatch/reproduce/aad.mjs index 673a8a3..8bb34a4 100644 --- a/public/evidence/aaif/authority-at-dispatch/reproduce/aad.mjs +++ b/public/evidence/aaif/authority-at-dispatch/reproduce/aad.mjs @@ -526,7 +526,7 @@ async function verify(dirArg, options = {}) { for (const e of envelopes) { const v = await verifyPortableProofEnvelope(e); if (!v.valid || lower(e.data?.owner) !== owner) bad += 1; - else if (expectSigner && lower(e.walletAddress) !== expectSigner) { bad += 1; signerFailures += 1; } + else if (expectSigner && lower(String(e.did || '').split(':').pop() || e.walletAddress) !== expectSigner) { bad += 1; signerFailures += 1; } } const ok = verdict(rec) && bad === 0 && envelopes.length > 0; if (!ok) failures += 1; diff --git a/public/evidence/aaif/authority-at-dispatch/reproduce/package-lock.json b/public/evidence/aaif/authority-at-dispatch/reproduce/package-lock.json index 277875f..f8a7b93 100644 --- a/public/evidence/aaif/authority-at-dispatch/reproduce/package-lock.json +++ b/public/evidence/aaif/authority-at-dispatch/reproduce/package-lock.json @@ -7,7 +7,7 @@ "name": "proofable-aaif-authority-reproduction", "license": "Apache-2.0", "dependencies": { - "@proofable/sdk": "0.1.6", + "@proofable/sdk": "0.1.10", "ethers": "6.17.0" }, "engines": { @@ -66,9 +66,9 @@ } }, "node_modules/@proofable/sdk": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@proofable/sdk/-/sdk-0.1.6.tgz", - "integrity": "sha512-beeECxKP4/HC4AJ6xqeiHJwlKVcM3Qo71ryKcJPd0QhE9a+k1YNyIeKcQeEMntt9yju1BhFnYOC1+2MHNTIJ7A==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/@proofable/sdk/-/sdk-0.1.10.tgz", + "integrity": "sha512-jy8tTWZP3enNw6l/GNsskgKHjodrhnbkLmHpFHK1/xA4GDHnmvJZGcPdsvHZBtKA9Ew4JRkGcIUsHxbxwxETyg==", "license": "Apache-2.0", "dependencies": { "@noble/ed25519": "^2.3.0", diff --git a/public/evidence/checks/package.json b/public/evidence/checks/package.json index f413708..a81f9e3 100644 --- a/public/evidence/checks/package.json +++ b/public/evidence/checks/package.json @@ -12,6 +12,6 @@ "reuse": "node reuse-check.mjs" }, "dependencies": { - "@proofable/sdk": "0.1.6" + "@proofable/sdk": "0.1.10" } } From 57f1fa12e47364138407b7fbcbffe54c2534db5f Mon Sep 17 00:00:00 2001 From: chrisjleal Date: Sun, 1 Nov 2026 18:07:57 +0000 Subject: [PATCH 4/5] The changelog reaches the releases on npm: SDK 0.1.10 and MCP 0.1.8 The public changelog stopped at SDK 0.1.6 and MCP 0.1.7 while npm serves 0.1.10 and 0.1.8. It now covers both, including the 0.1.9 CAIP-380 fix and the breaking removal of key saving through a tool argument. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019SciMRHyZqCnbvBv2cwKYU --- CHANGELOG.md | 3 ++- changelog.mdx | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b81644b..96fbcf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ Product release notes: [docs.proofable.me/changelog](https://docs.proofable.me/c ### Added - **Sell a service your server runs.** [Your server runs it](/gates/your-server) covers a listing whose orders go to your own URL with the buyer's inputs and repository, and whose result you post back onto the buyer's receipt. -- **Changelog entries for `@proofable/mcp` 0.1.7 and `@proofable/sdk` 0.1.6.** +- **Changelog entries for `@proofable/mcp` 0.1.7 and 0.1.8, and `@proofable/sdk` 0.1.6 through 0.1.10.** - **Eligibility clause in the Terms of Use.** Section 4 states the minimum age and the capacity to contract. - **One-time purchases in the Terms of Use.** Section 13 says one-time purchases, including the early partner pilot, are final like credit purchases, that pilot setup has no fixed delivery date, and that pilot credits stay on your account after the pilot closes. - **Background jobs keep proofs private and offchain.** [Proofs](/proofs) says that a background job's request for a blockchain record, a public or link-only proof, or a visibility change is refused with `JOB_ONCHAIN_PUBLISH_DENIED`, `JOB_PUBLIC_PROOF_DENIED` or `JOB_VISIBILITY_CHANGE_DENIED`. @@ -25,6 +25,7 @@ Product release notes: [docs.proofable.me/changelog](https://docs.proofable.me/c - **Two checks you can run on the published records.** `public/evidence/checks/tamper-check.mjs` forges each signed record ten ways and confirms every copy is rejected offline; `reuse-check.mjs` times reading and verifying a finished result with no account. - **A fresh run of the eight authority cases on the live service.** All eight passed on the revision production was serving, with 17 signed records. Requests that should not have been allowed were refused before any job ran; the case that needs approval waited for it and then ran; and a valid request ran alongside the refusals to show the check can pass. The records need no account to read or verify, and the run lives at `public/evidence/aaif/authority-at-dispatch/2026-10-24-served/`. - **Jobs run on credits on every plan.** [Jobs](/jobs) says what a run costs and lists the job tools a connection carries, and the team-agents and reproduce guides no longer say jobs need Pro. +- **Every published check installs `@proofable/sdk` 0.1.10.** The reproduction kit, the forged-record checks and the October 8 packet verify CAIP-380 envelopes that omit `walletAddress`, and `aad.mjs verify --expect-signer` requires the receipt signer you read out of band. Each authority-at-dispatch packet says what it establishes and what it does not. - **Agent id format is in the schemas.** `agentId` in `agent-identity` and `agent-delegation` is 1 to 128 letters, digits, hyphens or underscores, the same id the agent page uses. ### Removed diff --git a/changelog.mdx b/changelog.mdx index ea2d3c7..f542bbb 100644 --- a/changelog.mdx +++ b/changelog.mdx @@ -16,6 +16,54 @@ Package records: [`proofable/sdk`](https://github.com/proofable/sdk/blob/main/CH Published APIs and verifier schemas may change between minor versions. Breaking changes are listed in each entry and in the repo changelogs. + +## A ChatGPT endpoint, and keys stay on your profile + +`@proofable/mcp@0.1.8` adds `https://mcp.proofable.me/mcp/openai`, which serves the eight read and guided-verification tools to the ChatGPT plugin with the same OAuth sign-in. Cursor, Claude Code, Codex and every other client keep the full tool list on `https://mcp.proofable.me/mcp`. + +**Breaking:** `/mcp` no longer accepts a key as a tool argument. The tool that saved one is gone from `tools/list`, and a call to it is rejected as an unknown tool. Save keys on your profile; listing, removing and calling a provider with a saved key still work, and never return the key. + +The release also adds `examples/injection-test`, which hides the five AgentDojo attack templates in a note your agent reads and grades every run from its signed receipt. + +```bash +npm install @proofable/mcp@0.1.8 +``` + + + + +## Verify any CAIP-380 envelope, import an agent in one step + +`@proofable/sdk@0.1.10` covers 0.1.7 through 0.1.10. + +- **Any CAIP-380 envelope verifies (0.1.9).** `verifyPortableProofEnvelope` takes the signer from the envelope's `did:pkh` identifier, so an envelope without `walletAddress`, including the specification's test vectors, verifies instead of throwing. Use 0.1.9 or later to verify envelopes from other implementations. +- **`proofable import` creates the agent (0.1.10).** A signed-in terminal creates the agent on your profile with its full instructions and mounts it into the current project. `--expires-at` sets an end to its permissions, `--no-mount` skips the mount, and `--dry-run` shows what would happen. +- **`proofable auth --oauth` signs in the CLI only (0.1.10).** It no longer writes its short-lived token into your editors; pass `--client` to write it to one. +- **`fulfillGate()` completes AI service orders (0.1.7).** It sends `serviceParameters` for the listing's `serviceInputs`, and the run's answer appears on the buyer's receipt at `meta.marketplace.serviceJob.result`. +- **The CLI exits with code 1 after an error on Windows (0.1.8),** and a dry-run mount lists files as "would write". + +```bash +npm install @proofable/sdk@0.1.10 +``` + + + Date: Sun, 1 Nov 2026 18:08:50 +0000 Subject: [PATCH 5/5] The docs changelog names the evidence kits in reader terms Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019SciMRHyZqCnbvBv2cwKYU --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96fbcf6..4b3850c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ Product release notes: [docs.proofable.me/changelog](https://docs.proofable.me/c - **Two checks you can run on the published records.** `public/evidence/checks/tamper-check.mjs` forges each signed record ten ways and confirms every copy is rejected offline; `reuse-check.mjs` times reading and verifying a finished result with no account. - **A fresh run of the eight authority cases on the live service.** All eight passed on the revision production was serving, with 17 signed records. Requests that should not have been allowed were refused before any job ran; the case that needs approval waited for it and then ran; and a valid request ran alongside the refusals to show the check can pass. The records need no account to read or verify, and the run lives at `public/evidence/aaif/authority-at-dispatch/2026-10-24-served/`. - **Jobs run on credits on every plan.** [Jobs](/jobs) says what a run costs and lists the job tools a connection carries, and the team-agents and reproduce guides no longer say jobs need Pro. -- **Every published check installs `@proofable/sdk` 0.1.10.** The reproduction kit, the forged-record checks and the October 8 packet verify CAIP-380 envelopes that omit `walletAddress`, and `aad.mjs verify --expect-signer` requires the receipt signer you read out of band. Each authority-at-dispatch packet says what it establishes and what it does not. +- **The evidence kits install `@proofable/sdk` 0.1.10.** The reproduction kit, the forged-record checks and the October 8 packet verify CAIP-380 envelopes that omit `walletAddress`, and `aad.mjs verify --expect-signer` requires the receipt signer you read out of band. Each authority-at-dispatch packet says what it establishes and what it does not. - **Agent id format is in the schemas.** `agentId` in `agent-identity` and `agent-delegation` is 1 to 128 letters, digits, hyphens or underscores, the same id the agent page uses. ### Removed