v3/docs/adr/ADR-322C-receipt-ledger-verification.md
RUFLO_FLYWHEEL_RECEIPT_V1This specification defines canonical encoding, identifiers, evidence provenance, statistical decisions, signatures, ledger continuity, independent verification, and projection to @metaharness/flywheel. It does not authorize promotion; ADR-322A consumes a verified accepted receipt.
Canonical JSON: RFC 8785 JCS
Digest: SHA-256
Signature: Ed25519(domainPrefix || 0x00 || canonicalBytes)
Content ID: sha256:<lowercase-hex>
Timestamp: RFC 3339 UTC as YYYY-MM-DDTHH:mm:ss.sssZ
Non-finite numbers and negative zero are forbidden. Signed policy fractions use schema-quantized decimal strings or scaled integers. Metrics declare scale; currency uses integer micros plus ISO-4217 currency, duration uses integer microseconds, and energy uses integer microjoules when available. Unknown fields fail verification for a given schema version.
candidateId = SHA-256(JCS(candidate policy))
evaluationRunId = UUIDv7 per execution attempt
receiptId = SHA-256(JCS(unsigned receipt payload))
lineageId = UUIDv7 per persistent evolutionary lineage
Repeated candidate executions share candidateId but receive distinct run and receipt identities.
The unsigned payload contains:
schemaVersion
receiptIdDomain
lineageId
candidateId
evaluationRunId
baselineRef
expectedLedgerHead
candidatePolicyRef
gateVersion
policySchemaVersion
safetyEnvelopeRef
proposerIdentity
proposerSubstitution
corpusRoleManifestRef
heldoutEvidenceRef
anchorEvidenceRef
canaryEvidenceRef
driftEvidenceRef
replayEvidenceRef
receiptCoverageEvidenceRef
resourceEvidenceRef
statisticalDecision
termVerification[]
decision
issuedAt
expiresAt
Every evidence object records origin/provenance type, producer or attestor, authority scope, subject, transformation lineage, content hash, schema version, and collection time. Each authorizing term is labeled recomputed, signature-verified, or trusted-assertion.
relativeLift >= 0.02
AND pairedBootstrapProbability(candidate > baseline) >= 0.95
AND pairedBootstrapDeltaCILow95 > 0
AND frozenAnchorRegression <= 0
The paired bootstrap uses 10,000 task-level paired resamples. Its deterministic seed is:
SHA-256("ruflo/bootstrap/v1" ||
corpusHash ||
candidateId ||
baselineRef ||
evaluationRunId)
The receipt records the rule, metric epsilon, sample count, seed, implementation version, quantile rule, point estimates, probability, confidence interval, and paired deltas or their content-addressed object. Gate-rule changes require a new version and are not retroactive.
Receipt domain:
ruflo/flywheel-receipt/v1
Ledger-head domain:
ruflo/flywheel-ledger-head/v1
Keys use ADR-103's provider mechanism but a distinct purpose/domain. Private material remains outside the repository. Receipts carry public-key ID, algorithm, purpose, issuance time, and rotation/revocation metadata.
The ledger consists of immutable, content-addressed segments. Each segment binds:
segmentId
previousSegmentId
firstSequence
lastSequence
commits[]
segmentMerkleRoot
createdAt
A signed head binds lineageId, current segment, current sequence, active champion, gate version, and timestamp. Archiving may move segments but cannot delete continuity evidence or report a truncated chain as complete.
Promotion fails closed if the promotion commit and new head cannot be durably committed by ADR-322A.
A verifier:
Verification cannot label a promotion independently verified while any authorizing term remains an unapproved assertion.
The adapter projects ruflo policy and evidence into @metaharness/flywheel types and round-trips the ruflo envelope unchanged. Because the upstream string-valued policy and four-axis evidence are narrower, projection loss is explicit. Any loss affecting an authorizing term prevents an interoperability claim and can never weaken the ruflo gate.