jcp-receipt: Seal a flow verdict as jcp/3 #41

Closed
dcharlot wants to merge 1 commit from jcp-receipt-flow-seal into jcp-runtime-flow-gate
Owner

Increment 4 of the FL-2 flow-lattice design (FLOW_LATTICE_PLAN.md) — a flow verdict becomes a sealed, replayable artifact. Stacks on #40 (the runtime gate, for FlowFacts + the DenyReason variants); base is jcp-runtime-flow-gate.

What. A new jcp/3 profile carries a flow block — the folded label, its origins and readers, the witness commitment, the ceiling it was tested against, the below/above verdict, and the monitor's own evaluation energy — so a third party sees not just that a call was allowed or denied but on what provenance grounds.

Byte-exact compatibility is load-bearing. jcp/3 is minted only when a call is actually tainted. A clean call — no facts, or facts computed and bottom — seals as jcp/2, byte-for-byte identical to the plain path, so a flow deployment and a non-flow one share a stream and every existing receipt is unmoved. A test pins seal_flow(clean) == seal.

  • flow_uj is sealed as its own field, never folded into cost_uj — the tool's energy keeps its meaning; the monitor's cost is accounted separately.
  • The witness is a commitment, not the artifact — the cut is disclosed out of band, so receipts stay small and the disclosure boundary stays where jcp-cite put it.
  • verify_flow recomputes the jcp/3 core from the same seal (round-trips); append_flow keeps seq/prev identical across profiles, so a mixed jcp/2 + jcp/3 log verifies end to end via verify_log, and extract reads a jcp/3 core generically.

Four tests: byte-identity, the tainted seal + block, the above verdict on a flow denial, the mixed-profile chain. Full JCP workspace: 219 pass, 0 warnings.

⚠️ Deferred, and deliberately NOT the plan's §4D fix. Reading the code showed the plan's proposed replay_spend predicate (count caveat-unsatisfied denies toward spend) is unsound: a caveat deny debits in the charge path but not in the decide path, and the receipt cannot tell them apart, so counting them over-counts the decide path. The correct fix needs an explicit debited_uj field on the wire — a separate change with its own compat analysis. Left untouched here rather than replaced with a broken heuristic.

Next (final increment): the gateway relay that computes the facts, drives authorize_flow/charge_flow, and append_flows the sealed verdict; plus the receipt-stream replay().

Release Notes:

  • Added the jcp/3 receipt profile sealing a call flow-provenance verdict
Increment 4 of the FL-2 flow-lattice design (FLOW_LATTICE_PLAN.md) — **a flow verdict becomes a sealed, replayable artifact.** Stacks on #40 (the runtime gate, for FlowFacts + the DenyReason variants); base is `jcp-runtime-flow-gate`. **What.** A new **jcp/3** profile carries a `flow` block — the folded label, its origins and readers, the witness commitment, the ceiling it was tested against, the below/above verdict, and the monitor's own evaluation energy — so a third party sees not just *that* a call was allowed or denied but *on what provenance grounds*. **Byte-exact compatibility is load-bearing.** jcp/3 is minted **only** when a call is actually tainted. A clean call — no facts, or facts computed and bottom — seals as jcp/2, byte-for-byte identical to the plain path, so a flow deployment and a non-flow one share a stream and every existing receipt is unmoved. A test pins `seal_flow(clean) == seal`. - `flow_uj` is sealed as its **own** field, never folded into `cost_uj` — the tool's energy keeps its meaning; the monitor's cost is accounted separately. - The witness is a **commitment**, not the artifact — the cut is disclosed out of band, so receipts stay small and the disclosure boundary stays where jcp-cite put it. - `verify_flow` recomputes the jcp/3 core from the same seal (round-trips); `append_flow` keeps `seq`/`prev` identical across profiles, so a **mixed jcp/2 + jcp/3 log verifies end to end** via `verify_log`, and `extract` reads a jcp/3 core generically. Four tests: byte-identity, the tainted seal + block, the `above` verdict on a flow denial, the mixed-profile chain. Full JCP workspace: 219 pass, 0 warnings. **⚠️ Deferred, and deliberately NOT the plan's §4D fix.** Reading the code showed the plan's proposed `replay_spend` predicate (count `caveat-unsatisfied` denies toward spend) is **unsound**: a caveat deny debits in the charge path but *not* in the decide path, and the receipt cannot tell them apart, so counting them over-counts the decide path. The correct fix needs an explicit `debited_uj` field on the wire — a separate change with its own compat analysis. Left untouched here rather than replaced with a broken heuristic. Next (final increment): the gateway relay that computes the facts, drives `authorize_flow`/`charge_flow`, and `append_flow`s the sealed verdict; plus the receipt-stream `replay()`. Release Notes: - Added the jcp/3 receipt profile sealing a call flow-provenance verdict
The runtime gate decides a call against its argument's provenance; this makes
that decision a sealed, replayable artifact. A new jcp/3 profile carries a flow
block — the folded label, its origins and readers, the witness commitment, the
ceiling it was tested against, the below/above verdict, and the monitor's own
evaluation energy — so a third party can see not just that a call was allowed or
denied but on what provenance grounds.

The compatibility property is load-bearing and byte-exact: jcp/3 is minted only
when a call is actually tainted. A clean call — no facts, or facts that were
computed and came back bottom — seals as jcp/2, byte-for-byte identical to the
plain path, so a flow deployment and a non-flow one share a receipt stream and
every existing receipt is unmoved. A test pins that seal_flow of a clean seal
equals seal.

The flow energy is sealed as its own field, flow_uj, never folded into cost_uj:
a call's tool energy keeps its exact meaning, and the cost of running the monitor
is accounted separately and honestly. The witness is a commitment, not the
artifact — the cut is disclosed out of band, so the receipt stays small and the
disclosure boundary stays where jcp-cite already put it.

verify_flow recomputes the jcp/3 core from the same seal, so a jcp/3 receipt
round-trips; a jcp/2 clean call verifies through it too. The chain path
(append_flow) keeps seq/prev identical regardless of profile, so a mixed
jcp/2 + jcp/3 log verifies end to end via verify_log, and extract reads a jcp/3
core generically because it is jcp/2 plus a block. Four tests cover the
byte-identity, the tainted seal and its block, the above verdict on a flow
denial, and the mixed-profile chain.

Deferred, and NOT the plan's §4D fix: replay_spend under-counts a cost-breached
call, but the plan's proposed predicate (count caveat-unsatisfied denies toward
spend) is unsound — a caveat deny debits in the charge path yet not in the decide
path, and the receipt cannot tell them apart, so counting them over-counts the
decide path. The correct fix needs an explicit debited_uj field on the wire, a
separate change with its own compatibility analysis; it is left untouched here
rather than replaced with a broken heuristic.

Increment 4 of the FL-2 plan; the gateway relay that computes the facts and the
receipt-stream replay follow.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
dcharlot closed this pull request 2026-07-27 19:14:34 -04:00

Pull request closed

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!41
No description provided.