Skip to content

feat(e13-wsb): CaptureReceipt — universal bind-purpose-before-f() primitive - #282

Merged
mdheller merged 3 commits into
mainfrom
feat/e13-wsb-capture-receipt
Aug 4, 2026
Merged

feat(e13-wsb): CaptureReceipt — universal bind-purpose-before-f() primitive#282
mdheller merged 3 commits into
mainfrom
feat/e13-wsb-capture-receipt

Conversation

@mdheller

Copy link
Copy Markdown
Contributor

Epoch E13 / WS-B — CaptureReceipt

Lands the keystone capture-time receipt as a universal primitive. It generalizes TwinAttestation.envelope.authorization (already on main in schemas/TwinAttestation.json) into a domain-agnostic object that binds a declared purpose + authorization to a datum before the transform f() that consumes it runs.

Why bind at capture

The reidentification-economy result: purpose is provably unrecoverable from the signal — I(purpose; Q) = 0 between a purpose bit and a quasi-identifier-bearing signal Q. Purpose cannot be inferred post-hoc, so it must be sealed at capture or it is gone. CaptureReceipt is that seal.

Contract

  • declaredPurpose, authorizationProof, boundBeforeTransform: true (all required) gate a named transform, optionally bound against a contextRef (reference-at-ingest / VRF).
  • Fail-closeddisposition ∈ {admitted, refused, inert}: no valid purpose+proof ⇒ cannot be admitted.
  • reversibilityFloorBits ties WS-B to WS-D (ReversibilityDistance).

Machine-checked invariants (beyond schema)

  1. id starts with urn:srcos:capture-receipt:
  2. boundBeforeTransform is exactly true
  3. missing/empty declaredPurpose OR authorizationProof ⇒ disposition must be refused/inert
  4. disposition in the closed enum

Files

  • schemas/CaptureReceipt.json
  • examples/capture_receipt.json (admitted) · examples/capture_receipt_refused.json (refused)
  • tools/validate_capture_receipt_examples.py (wired into make validate)
  • docs/adr/0019-capture-receipt.md

Verification

$ python3 tools/validate_capture_receipt_examples.py
OK examples/capture_receipt.json
OK examples/capture_receipt_refused.json
All CaptureReceipt examples valid (schema + invariants).
$ python3 scripts/check_duplicate_schema_ids.py
OK: 353 unique schema $id values

🤖 Generated with Claude Code

@mdheller
mdhellerforce-pushed the feat/e13-wsb-capture-receipt branch 3 times, most recently from c3738aa to 2689b0aCompareAugust 4, 2026 19:59
…efore-f() primitive
Generalizes TwinAttestation.envelope.authorization into a domain-agnostic
capture-time receipt. Purpose is provably unrecoverable from the signal
(I(purpose;Q)=0), so it must be bound BEFORE the transform runs, at capture.
Fail-closed disposition; ties reversibilityFloorBits to WS-D.
Adds schemas/CaptureReceipt.json, examples/capture_receipt.json (admitted),
examples/capture_receipt_refused.json (refused), an invariant validator wired
into make validate, and ADR-0019.
contract-reconciliation CI requires the registry to be regenerated whenever a
schema is added; this PR's schema was missing from it.
@mdheller
mdhellerforce-pushed the feat/e13-wsb-capture-receipt branch from 2689b0a to 6cdc8bcCompareAugust 4, 2026 20:03
Previous commit's registry regen was run but never staged before push,
leaving a stale registry that failed contract-reconciliation CI.
@mdheller
mdheller merged commit 71d3f7d into mainAug 4, 2026
9 checks passed
@mdheller
mdheller deleted the feat/e13-wsb-capture-receipt branch August 4, 2026 20:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@mdheller