From f6c72cb08482d19e1fd5a05c3b54714204b734e7 Mon Sep 17 00:00:00 2001 From: arkforge Date: Tue, 15 Sep 2026 10:38:00 +0200 Subject: [PATCH] =?UTF-8?q?docs(spec):=203.1.2,=20champs=20payment/buyer/s?= =?UTF-8?q?eller=20recadr=C3=A9s=20en=20facturation=20de=20la=20certificat?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wording seul, aucun changement de format, d'algorithme ni de données de vecteurs. Le but et les descriptions présentaient chaque preuve comme un achat entre acheteur et vendeur ; une note explique que ce sont des noms historiques conservés pour le chain hash. Le README ne présente plus la vérification par concaténation comme générique : elle ne vaut que pour les preuves legacy. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 10 ++++++++++ README.md | 8 +++++--- SPEC.md | 26 ++++++++++++++------------ test-vectors.json | 2 +- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59d147f..2e2c086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,16 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html) --- +## [3.1.2] — 2026-09-15 + +Wording only. No change to the proof format, the algorithms or the test vector data (only the document version in `test-vectors.json` moves to 3.1.2). + +### Fixed +- The goal and field descriptions framed every proof as a purchase between a buyer and a seller. `payment` records how the certification of the proof was billed, and `buyer_fingerprint` / `seller` identify the caller's key and the target domain. A note now says these are historical names kept for chain hash compatibility, and that a payment to a service is recorded only through `provider_payment`. +- The README presented the string-concatenation check as the way to verify any proof. It only applies to legacy proofs; current proofs use per-field commitments (section 5). + +--- + ## [3.1.1] — 2026-09-14 Wording only. No change to the proof format, the algorithms or the test vectors. diff --git a/README.md b/README.md index e58a34d..1351f09 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ # ArkForge Proof Specification -Open standard for verifiable agent-to-agent execution proofs. +Open standard for verifiable proofs of the exchanges between AI agents and the APIs they call. **[Read the spec](SPEC.md)** | **[Test vectors](test-vectors.json)** ## What is this? -A deterministic proof format that binds a request, response, payment, and timestamp into a single SHA-256 chain hash. Anyone can verify a proof without ArkForge's code or infrastructure. +A deterministic proof format that binds a request, a response, the parties, a billing reference and a timestamp into a single SHA-256 chain hash. Anyone can verify a proof without ArkForge's code or infrastructure. ## Quick verification -Given a proof JSON, verify it in one line: +For a legacy proof (`spec_version` `"1.1"`, `"2.0"` or absent), the chain hash is a single concatenation: ```bash printf '%s' "${REQUEST_HASH}${RESPONSE_HASH}${PAYMENT_ID}${TIMESTAMP}${BUYER}${SELLER}${UPSTREAM}${RECEIPT_HASH}" \ @@ -19,6 +19,8 @@ printf '%s' "${REQUEST_HASH}${RESPONSE_HASH}${PAYMENT_ID}${TIMESTAMP}${BUYER}${S `UPSTREAM` and `RECEIPT_HASH` are empty strings when absent from the proof. +Current proofs (`spec_version` `"3.0"` and above) use a Merkle root of per-field commitments instead: see section 5 of the spec. Recomputing the chain hash only shows internal consistency; the independent evidence is the RFC 3161 timestamp and the Sigstore Rekor entry. + If the result matches `proof.hashes.chain`, the proof is intact. ## Implementations diff --git a/SPEC.md b/SPEC.md index 64ce945..6b1291e 100644 --- a/SPEC.md +++ b/SPEC.md @@ -1,6 +1,6 @@ -# ArkForge Proof Specification v3.1.1 +# ArkForge Proof Specification v3.1.2 -An open standard for verifiable agent-to-agent execution proofs. +An open standard for verifiable proofs of the exchanges between AI agents and the APIs they call. ## Status @@ -8,7 +8,7 @@ An open standard for verifiable agent-to-agent execution proofs. ## Goal -Define a deterministic, independently verifiable proof format for agent-to-agent transactions. Any party — buyer, seller, auditor, regulator — can recompute and verify a proof without ArkForge's code or infrastructure. +Define a deterministic, independently verifiable proof format for the exchanges between an AI agent and the services it calls. Any party (the caller, the called service, an auditor, a regulator) can recompute and verify a proof without ArkForge's code or infrastructure. ## Scope @@ -40,13 +40,15 @@ A conformant proof is a JSON object. The following fields are **required**: | `hashes.response` | string | SHA-256 hash of canonical JSON response. Format: `sha256:` | | `hashes.chain` | string | Chain hash binding all components. Format: `sha256:` | | `commitments` | object | One commitment per committed field, `field -> sha256:` (spec_version `"3.0"`) | -| `parties.buyer_fingerprint` | string | SHA-256 hash of the buyer's API key (hex) | -| `parties.seller` | string | Target service domain (e.g. `arkforge.fr`) | -| `payment.provider` | string | Payment provider identifier (see Payment variants) | -| `payment.transaction_id` | string | Payment reference used in chain hash (see Payment variants) | -| `payment.amount` | number | Payment amount | +| `parties.buyer_fingerprint` | string | SHA-256 hash of the caller's API key (hex). Historical name, see the note below | +| `parties.seller` | string | Target service domain (e.g. `arkforge.fr`). Historical name, see the note below | +| `payment.provider` | string | How the certification of this proof was billed (see Billing variants) | +| `payment.transaction_id` | string | Billing reference of the certification, used in chain hash (see Billing variants) | +| `payment.amount` | number | Amount charged for the certification (`0.0` on the free tier) | | `payment.currency` | string | Currency code (e.g. `"eur"`) | -| `payment.status` | string | Payment status (e.g. `"succeeded"`, `"free_tier"`) | +| `payment.status` | string | Billing status (e.g. `"succeeded"`, `"free_tier"`) | + +**Note on field names.** `payment`, `parties.buyer_fingerprint` and `parties.seller` are historical names, kept because they are part of the chain hash of every existing proof. `payment` records how the certification of the proof itself was billed; it is not a payment between the agent and the target service. `buyer_fingerprint` identifies the caller's API key and `seller` is the target domain; neither implies that anything was bought or sold. A payment made by the agent to a service is recorded only when the optional `provider_payment` evidence is present (section 2.1). ### Minimal example (required fields only) @@ -131,9 +133,9 @@ A conformant proof is a JSON object. The following fields are **required**: - `"1.2"`, `"2.1"`: canonical JSON over the values themselves — see section 2 backward compatibility - `"1.1"`, `"2.0"` (legacy): string concatenation — same section -### Payment variants +### Billing variants -The `payment` object reflects how the proof was generated: +The `payment` object records how the certification of the proof was billed: | Plan | `provider` | `transaction_id` | `amount` | `status` | |------|-----------|-----------------|----------|----------| @@ -169,7 +171,7 @@ All variants produce a valid chain hash. The `payment.transaction_id` value is u ## 2. Chain hash algorithm -The chain hash binds every element of a transaction into a single verifiable seal. +The chain hash binds every element of an exchange into a single verifiable seal. ### Algorithm (spec_version "3.1" — current) diff --git a/test-vectors.json b/test-vectors.json index a831d7b..acacbf0 100644 --- a/test-vectors.json +++ b/test-vectors.json @@ -1,5 +1,5 @@ { - "spec_version": "3.1.1", + "spec_version": "3.1.2", "algorithm": "SHA-256", "canonical_json_rule": "json.dumps(data, sort_keys=True, separators=(\",\", \":\"))", "chain_formula_current": "MerkleRoot_RFC6962({ SHA256(field || 0x00 || nonce || canonical_json(value)) for each chain field }, leaves ordered by field name)",