jcp: an erasure path that neither breaks the chain nor loses the joules (re-land) #77

Merged
dcharlot merged 1 commit from jcp/erasure-tombstone-v2 into main 2026-09-03 15:17:04 -04:00
Owner

Re-land of #74, rebuilt on current main after the environment-binding change landed. The original branch conflicted at a shared test-insertion point, and rebuilding was cleaner than resolving text that did not split at function boundaries.


No receipt chain in open-standards had a redaction primitive. Chains are append-only by construction — right for evidence, wrong for a deployment that must honour a data-subject erasure request.

Why erasure has to be forward-only

The chain links on envelope bytes: each entry's prev is the content id of the one before it. An entry cannot be edited or removed, because either breaks every link after it — and a chain that no longer verifies is not evidence of anything, including of the erasure.

So ReceiptLog::erase appends a jcp.tombstone/1 entry. The erased envelope stops being retained; its content id is unchanged, so links still resolve.

What is lost is the ability to read what was done. What survives is that something was done and what it cost.

The joules stay, deliberately

Every energy total and facility rollup over this log is a sum across its entries. An erasure that dropped the cost would silently shrink all of them — and the shrinkage would be indistinguishable from a genuine efficiency gain. A conservation break arriving through the back door of a privacy feature.

Joules and a provenance label are not personal data. The payload hash, resource, subject and action are — and a test asserts none of them appear. The authority field is a request reference, never the requesting party's identity: a tombstone naming the subject would re-introduce the datum the erasure removed.

Verification

278 jcp-rs tests pass · conformance passes all classes · the chain test compares the sealed payload byte-for-byte against the expected chained wire rather than re-parsing it.

🤖 Generated with Claude Code

**Re-land of #74**, rebuilt on current `main` after the environment-binding change landed. The original branch conflicted at a shared test-insertion point, and rebuilding was cleaner than resolving text that did not split at function boundaries. --- No receipt chain in open-standards had a redaction primitive. Chains are append-only by construction — right for evidence, wrong for a deployment that must honour a data-subject erasure request. ## Why erasure has to be forward-only The chain links on **envelope bytes**: each entry's `prev` is the content id of the one before it. An entry cannot be edited or removed, because either breaks every link after it — and a chain that no longer verifies is not evidence of anything, **including of the erasure**. So `ReceiptLog::erase` **appends** a `jcp.tombstone/1` entry. The erased envelope stops being retained; its content id is unchanged, so links still resolve. > What is lost is the ability to read *what was done*. What survives is *that something was done* and *what it cost*. ## The joules stay, deliberately Every energy total and facility rollup over this log is a sum across its entries. An erasure that dropped the cost would silently shrink all of them — **and the shrinkage would be indistinguishable from a genuine efficiency gain.** A conservation break arriving through the back door of a privacy feature. Joules and a provenance label are not personal data. The payload hash, resource, subject and action are — and a test asserts **none of them appear**. The `authority` field is a request reference, **never the requesting party's identity**: a tombstone naming the subject would re-introduce the datum the erasure removed. ## Verification 278 jcp-rs tests pass · conformance passes all classes · the chain test compares the sealed payload **byte-for-byte** against the expected chained wire rather than re-parsing it. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jcp: an erasure path that neither breaks the chain nor loses the joules
All checks were successful
standards workspaces build + test / aac-rs (pull_request) Successful in 42s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 46s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m48s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m13s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m11s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 4m26s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m0s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 34s
standards workspaces build + test / map-rs (pull_request) Successful in 34s
standards workspaces build + test / mesh-rs (pull_request) Successful in 30s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 2m29s
standards workspaces build + test / openpay (pull_request) Successful in 1m40s
standards workspaces build + test / arl-rs (pull_request) Successful in 7m58s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 8m15s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 8m33s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 8m9s
standards workspaces build + test / sense-rs (pull_request) Successful in 8m1s
dc84399ffd
No receipt chain in open-standards had a redaction primitive. Chains are
append-only by construction — right for evidence, wrong for a deployment that
has to honour a data-subject erasure request, so the absence was a hard blocker
rather than a missing convenience.

The chain links on envelope bytes: each entry's `prev` is the content id of the
one before it. An entry therefore cannot be edited or removed to satisfy a
request, because either breaks every link after it, and a chain that no longer
verifies is not evidence of anything — including of the erasure. Erasure has to
be forward-only.

`ReceiptLog::erase` appends a `jcp.tombstone/1` entry. The erased envelope stops
being retained by the operator; its content id is unchanged, so the links still
resolve; the tombstone records that the erasure happened, where in the order,
and under what authority. What is lost is the ability to read what was done.
What survives is that something was done and what it cost.

**The joules stay, deliberately.** Every energy total, efficiency figure and
facility rollup over this log is a sum across its entries. An erasure that
dropped the cost would silently shrink all of them, and the shrinkage would be
indistinguishable from a genuine efficiency gain — a conservation break arriving
through the back door of a privacy feature. The acquisition class rides along
for the same reason: a figure without one is not comparable to the others in the
same sum. Joules and a provenance label are not personal data; the payload hash,
resource, subject and action are, and a test asserts none of them appear.

The authority field is a request reference or policy id, never the requesting
party's identity — a tombstone that named the subject would re-introduce the
datum the erasure removed.

A tombstone carries its own profile so no reader mistakes it for a decision that
happened to have no payload, and the chain test compares the sealed payload
byte-for-byte against the expected chained wire rather than re-parsing it.

Re-applied on current `main` after the environment-binding change landed;
the original branch conflicted at a shared test-insertion point, and rebuilding
was cleaner than resolving text that did not split at function boundaries.

Surfaced by the 2026-08-29 sweep, inside its refutation of the IETF agent
audit-trail draft: that draft proposes a tombstone with a content fingerprint
and cannot retain the cost, having no energy field at all.

Verified: full jcp-rs workspace green, conformance passes all classes.

Co-Authored-By: Claude Opus 5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!77
No description provided.