Version: v0.1
Date: 2026-07-25
Status: DRAFT — F-2 gate artifact, HOLD for the Operator read.
Mandate: review register v0.2, findings F-2 (evidence custody / data availability — R-B, R-D; "the best single finding of the cycle") and F-5 (key management — R-D, adopted into this artifact). The register's action order placed this artifact before /proofs "so /proofs implements it"; events ran the other way — /proofs shipped first, practiced the discipline live, and anchored five custody-complete demonstrations. This document therefore codifies what practice already proved, adopts practice where it exceeded prior doctrine (each adoption reported in the truth-pass), and governs everything forward.
Governing instruments: the custody ops log lineage (docs/proofs-material/foray-custody-material-ops-log-v0_2.md — the founding incidents); the custody sheets and exhibits v0.2 (the practiced discipline); the body-availability design (foray-api/docs/design/foray-body-availability-design-v0_2.md, §3.4 — consumer custody by design); Verifier Specification v0.2 (input class A — custody guarantees verification's inputs exist); amendment v0.7 (OQ-8 F3 form salts; D5 and the formula-repository disposition; OQ-13 evidence-is-innocent); the Stele Agentic ID requirements note v0.1 §5 (identity/revocation custody reservation).
The anchor is permanent; the holder's ability to use it is exactly as durable as their custody. A Kaspa mainnet anchor cannot be lost, altered, or repudiated — and by itself it proves nothing. It is a 32-byte commitment whose meaning is recoverable only by a party holding the material that reproduces it. FORAY's independence claim (verification requires no access to DUNIN7) has a price, and this is it: the hard problem moves from trusting a service to keeping a package. Lose the package and the anchor becomes what the ops log calls an unprovable commitment — permanently on-chain, permanently mute.
This is the holder's side of the OQ-13 bargain. The protocol rules that evidence is innocent — accepted permanently, never punished for its producer's lateness. The symmetric obligation is that evidence must exist: the protocol never re-creates proof material, because it never held it.
Who holds what, per role:
| Role | Holds | Notes |
|---|---|---|
| Originator (the system where transactions originate; its adaptor) | The source records and the field-map sheet — the ability to re-derive and explain what was mapped. Where the originator is also the anchoring caller, it is a consumer below. | Origination-side material is about meaning; it does not by itself reproduce any commitment |
| Consumer / holder (the party that calls the anchoring endpoint and later needs the proof) | The custody package (§2), in full, for every anchor it intends to ever use. The anchoring response is delivered exactly once; nothing in it is recoverable from FORAY afterward | This is the load-bearing role. "Consumer custody" is the ruled design (body-availability §3.4), not a default that a service upgrade will later relax |
| DUNIN7-as-demonstrator | The demonstration population's packages, public by design — custody sheets carrying bodies, salts, and full anchor responses openly (docs/proofs-material/) | A deliberate inversion of the production confidentiality posture (§2.1, salt row) to show what complete custody looks like. Demonstration custody is the worked example, not the production pattern |
| FORAY-the-service | Nothing durable (§5) | By design, and the design is the point |
One package per anchor. The package is complete when a class-A verification (Verifier Specification v0.2 §5.4) can be run from the package plus public chain data alone.
| # | Member | What it proves alone | What its loss forfeits |
|---|---|---|---|
| 1 | Record body — the exact bytes (not a re-serialization, not a pretty-print; the byte stream that was hashed) | SHA-256(body) = txHash: that this content is the content committed to — but only once the commitment chain to the chain is intact | With body lost, nothing ties any content to the anchor. The body-availability proof anchor (2026-07-14; tx d6d704ed…, ops log v0.2) shows the inverse half in its recovery: body recovered and hash-verified, salt missing → "the body existed and hashes to the recorded txHash" is provable; the on-chain commitment remains unreproducible. Body-without-salt is a bounded loss; no-body is a total one |
| 2 | The full anchoring response: leafSalt, lane name, windowId (request-time), plus jobId, expectedAnchoredValue, spentUtxo, fee, extension echo — retained whole, as returned | Salt + lane + window + body reproduce the commitment end-to-end: leaf = SHA-256(0x00‖txHash‖salt); direct-mode header (lane_id, windowId) → SHA-256(0x02‖header) = the on-chain payload. expectedAnchoredValue gives the Worker's self-report to triangulate against; spentUtxo corroborates the serial-execution chain | Salt loss is terminal: a fresh salt is drawn per signing, salts are never derivable and never retained by the service (§5), and a different job's salt for the same body is provably useless (the recovery session's flagged near-miss). The first production anchor (2026-07-14; tx f23d499a…, ops log v0.2) is the founding worked example — its endpoint discarded the salt in-request, so the material never existed: NOT RECOVERABLE, closed, terminal. windowId loss is severe but not always terminal — both v0.2 demonstration anchors' windows were recovered by brute force over the request-time neighborhood; custody exists so that recovery by search is never the plan |
| 3 | Formula packages — for every F18 in the record: formula text, its salt, the resulting hash_… ID, and the catalog version it was declared under (the D5 disposition: a defined package format is protocol; a hosted repository is a downstream product option, never load-bearing) | The F18 claim ladder's honest rung: which formula was declared and that it is unaltered since (definition retention — the F-18 rider bounds this; never execution correctness) | Loss of formula text + salt orphans the formula ID exactly as off-chain body loss orphans the anchor (the ratification sheet's own words). The record stays valid; its F18 becomes an opaque token no one can ever expand |
| 4 | F3 form salts — where the record owner is carried in the salted-digest form (sha256: + 64 hex, OQ-8) | Holder can demonstrate whose record this is to a party entitled to know, without the wire ever carrying the cleartext | Loss makes the owner claim unprovable-by-holder: the digest still binds (tamper-evidence intact) but can never again be opened. Note the migration parallel: a legacy entity_hash is preserved into F25 precisely because it is not re-derivable — its salt was never on the wire (amendment §4 step 5) |
| 5 | Identity and revocation artifacts — reserved member class, not designed: attester identity documents (self-contained, signed, digest-identified, riding F29) and the revocation records relevant to them, per the Stele Agentic ID requirements note §5–§6 | (Reserved — the artifact class exists so the attestation joint can close without amending this model's shape) | (Reserved. Design belongs to the Agentic ID cadence; nothing here rules it) |
| 6 | The anchor reference: Kaspa tx id + the on-chain payload value (+ accepting block time as practiced) | The public half: where the commitment lives and what byte value the chain carries. Independently re-checkable against any chain source at any time | Strictly recoverable (it is on-chain) — but a package without it cannot be verified offline, and a holder who has lost track of which transaction carries their commitment has converted verification into a chain-wide search |
Confidentiality classes, stated once: production salts (members 2, 3, 4) are proof material held in confidence — disclosure lets anyone who obtains the body demonstrate the linkage. Demonstration packages invert this deliberately (custody sheets: "salts included by design — custody-transparency exhibit"). The class is a property of the package's purpose, chosen at creation, recorded on the sheet.
shasum -a 256 < file), never via copy-paste through an editor or chat surface; never re-serialize, reformat, or "clean up" a body in custody; verify byte-equality with cmp, not visual inspection; record the hash beside the file at capture time. The practiced form — body file + sibling .sha256 — is the pattern.A holder demonstrates completeness for a given anchor by producing a custody sheet: the practiced form of foray-custody-sheet-record-{a,b}-v0_2.md, promoted here to the model's normative instrument. A sheet is complete when every applicable row is filled and the verification row shows the three-way match. Normative appendix — the sheet form:
Identity: record designation · F1/F2 identifiers · body file name · body size · exhibit/context reference · validation result at submission.
Body hash: SHA-256 of the exact bytes, computed via stdin, stated in full.
Anchoring custody material:jobId·txHash(stated equal to the body hash) ·leafSalt· lane ·expectedAnchoredValue·spentUtxo· fee · Kaspa tx id · broadcast time · confirmation time · accepting block hash · on-chain payload · recomputed commitment (withwindowIdstated) · verification result: PASS only when on-chain payload == expectedAnchoredValue == independently recomputed commitment, all three byte-identical.
Formula/F3 custody rows (where applicable): per F18, the formula package's location and ID; per salted F3, the salt's custody location (production: named store, not the value; demonstration: the value).
Serial-discipline note (where applicable): what the spentUtxo chain corroborates.
Custody statement: confidentiality class (production-confidential | public-demonstration), storage location(s), steward, and the succession pointer.
The completeness proof is executable: a second party, given the sheet and the named files, reproduces the verification row's PASS with no other inputs. A sheet whose verification row cannot be reproduced is an inventory, not a proof.
Custody status vocabulary (from the ops log, adopted as doctrine): CUSTODY-COMPLETE (three-way match reproducible) · PARTIALLY RECOVERED / BOUNDED (named members missing, absence fully accounted, no further search expected to change it — the body-availability proof anchor) · NOT RECOVERABLE — terminal (material never existed or provably destroyed — the first production anchor). Honest terminal states are custody information; "in progress" indefinitely is not.
What FORAY-the-service holds: at most, the record body, content-addressed under its own hash, for a declared TTL window — the body-availability design's ruled compromise ("available here for N days from anchor; from the producer thereafter"). Storage-before-enqueue: nothing is anchored whose body was never at least momentarily retained.
What it never holds: salts. The direct endpoint returns the leaf salt to the caller once and does not retain it beyond the request (§3.4, ruled). No later request, subpoena, or goodwill can produce it from the service, because it is not there.
Why this is the independence claim's foundation: a service that retained proof material durably would become the thing verification depends on — the single custodian whose availability, honesty, and continued existence every five-years-out verification would silently assume. F-15 made "verification requires no access to DUNIN7" checkable; this model is what makes it survivable: the verifying inputs live with the party who needs them, and DUNIN7's disappearance changes nothing about any complete package.
The honest cost, on the record: the founding incident. The first production anchor was created through a test endpoint that derived its commitment server-side and discarded the salt in-request — proof material that never existed, discovered only when custody was audited. The body-availability proof anchor had its response read for a boolean and not kept — body later recovered and hash-verified from session residue, salt gone. Both anchors are permanent; neither will ever verify end-to-end. The five custody-disciplined anchors that followed (the auth-probe anchor, Records A and B v0.1, Records A and B v0.2 — each verified three-way, each spending the prior's UTXO) are the same machinery under the discipline this document codifies. The difference between the two outcomes is nothing but custody.
This section is implementer and operator guidance, not protocol law. No key-management choice changes what a conformant record or verifier is.
KASPA_ANCHOR_WALLET_KEY, entered via wrangler secret put per the rotation procedure); signing happens server-side in the Worker. The extension-wallet path the R-D review critiqued is legacy-surface residue, not the production path. No key material ever appears in any log, sheet, or custody document — the ops log's standing rule, absolute.DUNIN7 — Done In Seven LLC
FORAY — Evidence Custody Model — v0_1 — 2026-07-25