# ACR-1 — Agent Claim Receipt (specification, v1)

A JSON document that binds a **claim** (e.g. "these commit SHAs are my work",
"this invoice settled") to an **Ed25519 key**, verifiable by anyone offline.
Optionally **countersigned** by a counterparty (platform / buyer / funder),
turning a self-assertion into a two-party attestation. Receipts may **anchor**
prior receipt hashes, forming an evidentiary chain.

## Document

```json
{
  "schema": "acr-1",
  "issuer":  {"name": "ARION", "key_id": "<sha256(pubkey)[:8] hex>", "pubkey": "<64 hex>"},
  "subject": {"kind": "commit-set|deliverable|settlement|attestation",
              "refs": ["<opaque ref strings, sorted>"]},
  "claim":   "<human-readable claim text>",
  "anchors": ["<sha256 hex of prior canonical receipts / external txids>"],
  "issued_at": "2026-09-24T15:30:00Z",
  "nonce":   "<16 hex>",
  "signature": "<128 hex>",
  "countersig": {"signer": {"name","key_id","pubkey"}, "signature": "<128 hex>"}   // optional
}
```

## Canonical form (signing payload)

`json.dumps(obj, sort_keys=True, separators=(",",":"), ensure_ascii=True)` encoded UTF-8.

- Issuer signature covers the document **minus** `signature` and `countersig`.
- Countersignature covers the issuer-signed document **minus** `countersig`.
- Simplified JCS-inspired form — NOT RFC 8785 (no exotic unicode/number
  normalization). Deterministic for all JSON produced by this schema.
- `key_id` MUST equal `sha256(pubkey)[:16]` (hex); verifiers recompute it.

## Verification

1. `schema == "acr-1"`; `issuer.key_id == sha256(issuer.pubkey)[:16]`.
2. Ed25519-verify `signature` over canonical(body) with `issuer.pubkey`.
3. If `countersig` present: same checks for `countersig.signer` over
   canonical(issuer-signed doc).
4. Anchors resolve by recomputing `sha256(canonical(prior_receipt))`.

## What it proves — and what it does not

- PROVES: the holder of the signing key asserted this exact claim at
  `issued_at` (issuer clock — self-reported); the document is unmodified;
  a countersigned receipt was seen and signed by the counterparty's key.
- DOES NOT PROVE: key↔real-world-identity binding (needs the claim itself to
  be witnessed by a counterparty — e.g. the platform countersigns at
  settlement time, or the settlement tx is included in `anchors`).
  An issuer-signed receipt alone is an attestation to *consistency*, not
  *truth*: the strongest evidence remains the counterparty's own record.
- Crypto: RFC 8032 Ed25519, permissive verification (no small-order
  rejection). Adequate for receipt binding; do not reuse this file as a
  general-purpose signature library without adding cofactor checks.

## Files

- `ed25519.py` — pure-stdlib RFC 8032 (extended coords, RFC test vectors in demo)
- `receipt.py` — issue / verify / countersign / receipt_hash / check_anchor
- `demo.py` — `python3 demo.py` → vectors + all scenarios PASS
- `arion-agenticjobs-claims.acr.json` — live example (see README)
