Skip to content

Add effect-free native cancellation publication classifier (unwired) - #1311

Merged
0xPlayerOne merged 5 commits into
mainfrom
claude/project-thread-qxfh20
Oct 24, 2026
Merged

0xPlayerOne merged 5 commits into
mainfrom
claude/project-thread-qxfh20

Conversation

@0xPlayerOne

@0xPlayerOne 0xPlayerOne commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Summary

Pi Durable scope 1, bounded. Nothing is wired: no import from construction, startup, recovery, a composition root or the package index.

Adds classifyPiNativeCancellationPublication: journal record + caller-held pins + an already-observed historical native receipt → published, receipt_absent, receipt_unpublished, receipt_superseded or a coded conflict. A label grants no authority. Nobody acts on receipt_unpublished in this increment; recovery stays advisory and unwired until all-writer coverage, fencing/authority validation and a separate root review exist. receipt_absent is not proof of zero native effect.

Root review repair (7b1dd97d): retained receipts bind all six pins; container and active-generation identity are validated before any absent/published result; cross-attempt and cross-turn evidence conflicts; mismatched-pin, malformed-generation and cross-attempt/turn tests added.

The frozen receipt snapshot boundary originally pushed here (9013e235) moved to its own PR #1312; this branch retires its copy with a normal revert commit (b7876c21), no force-push. The two are independent.

Dist budget fold (206cd092)

Hosted qualification of b7876c21 failed one test, budget-regression.test.mjs:131: the separate module's two emitted files cost 12,288 allocated bytes against 8,192 bytes of headroom on main, so the built output measured 12,587,008 bytes against the committed 12 MiB (12,582,912 byte) dist budget (4,096 over). Main (fc26f84d) and the merge-base measure 12,574,720.

206cd092 moves the classifier unchanged into cancellation-history.ts (not exported from the package index) and reuses that file's identical digest(); the separate module is removed. Validation order, every PI_PUBLICATION_RECOVERY_* code and the exported names are unchanged. The budget and every check are unchanged. Measured dist after the fold: 12,578,816 bytes (4,096 bytes of headroom). Root approved exact head 206cd092; the PR was merged by the repository owner.

Validation

  • Commands run (local sandbox: Node 22.22.0, Bun 1.4.4, fresh worktree with the patched SDK): bun run build; scripts/check-budgets.mjs dist OK (12,578,816 B); bun test src/native-cancellation-publication-recovery.test.mjs (10 pass); package bun test src 442 pass, 2 fail; oxfmt --check, oxlint --deny-warnings, check:boundaries, check:canonical-ordering and check:digest-writers clean.
  • The 2 local failures were recorded on Node 22.22.0 / Bun 1.4.4, not on the repository-pinned toolchain (Node 24.21.0 / Bun 1.4.4): "SIGKILL after guarded native N and before journal publication stays unresolved without resending after two authorized restarts" and "compiled adapter preserves post-native publication uncertainty in actual pinned Node SQLite".
    • The SIGKILL test is confirmed failing on a clean rebuild of b7876c21 in the same local environment, so it is not introduced by the fold.
    • For the "compiled adapter" test the b7876c21 baseline is unverified: the baseline run used leftover build output from the fold, not a clean b7876c21 rebuild.
    • These local Node 22.22.0 failures were not shown to pass or be fixed locally.
  • Verified hosted result on 206cd092: M9 Production Readiness run 40082010325, Core hardening job 120837324139, on the pinned Node 24.21.0 / Bun 1.4.4 workflow with frozen install and the patched SDK. Both tests passed there: "compiled adapter preserves post-native publication uncertainty in actual pinned Node SQLite" at 09:28:33Z and "SIGKILL after guarded native N and before journal publication stays unresolved without resending after two authorized restarts" at 09:29:14Z. The hosted pinned full-unit run (Code Foundry Test / Unit) on 206cd092 also succeeded.
  • CI or deployment links: hosted runs on 206cd092 all terminal (39 passed, 3 skipped, none failed) before merge.

Impact and rollout

  • No migration or rollout action is required
  • Migration or rollout steps are documented below
  • Environment or secret changes are documented below
  • Security, privacy, compatibility, or performance impact is documented below
  • Rollback or follow-up work is documented below

No behavior change; the module is not imported by any runtime path.

Review notes

Auto-merge was off; the merge was performed by the repository owner.

Related issue

Part of Pi Durable migration #1025 / #935 / #942 (references only; does not close them).

🤖 Generated with Claude Code

https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc

Classifies a journal record plus an already-observed historical native
receipt as published, receipt_absent, receipt_unpublished,
receipt_superseded or a coded conflict. Unwired; grants no authority and
performs no effect. Documents the boundary.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc
Defines the sealed detached/coherent/SELECT-only snapshot handle, a
refusing default issuer port and a fail-closed receipt reader. The seal
is not exported from the package index and nothing is wired.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc
@0xPlayerOne 0xPlayerOne changed the title Add effect-free native cancellation publication classifier Pi Durable: publication classifier and frozen receipt snapshot boundary (unwired) Oct 24, 2026
…ying

Retained receipts now bind requestId, requestDigest, targetDigest,
expiresAt, turnKey and inferenceId. Malformed container or active
generation identity, and cross-attempt or cross-turn evidence, conflict
before receipt_absent or published. Adds mismatched-pin,
malformed-generation and cross-attempt/turn tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc
Reverts 9013e23 as a normal commit; the same content, with root's review
findings applied, now lives in its own draft PR. History is preserved.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc
@0xPlayerOne 0xPlayerOne changed the title Pi Durable: publication classifier and frozen receipt snapshot boundary (unwired) Add effect-free native cancellation publication classifier (unwired) Oct 24, 2026
@0xPlayerOne
0xPlayerOne marked this pull request as ready for review October 24, 2026 08:39
…dist budget

Behavior-preserving code move. The classifier body, validation order and every
PI_PUBLICATION_RECOVERY_* code are unchanged. It now lives in
cancellation-history.ts (not exported from the package index) and reuses that
file's identical digest(); the separate module and its duplicate digest() are
removed. The test imports the new path and the docs path line is updated.

Why: the separate module added two dist files (12,288 allocated bytes) and
pushed the committed 12 MiB dist budget 4,096 bytes over (main has 8,192 bytes
of headroom). The budget and every check are unchanged. After the fold the
measured dist total is 12,578,816 bytes with 4,096 bytes of headroom.

SOURCE APPROVAL IS PENDING: root has not yet approved departing from the
isolated-module layout. Auto-merge stays off; this is not a merge request.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc
@0xPlayerOne
0xPlayerOne merged commit 1a7faf1 into main Oct 24, 2026
42 checks passed
@0xPlayerOne
0xPlayerOne deleted the claude/project-thread-qxfh20 branch October 24, 2026 09:42
0xPlayerOne added a commit that referenced this pull request Oct 24, 2026
…ed) (#1312)

* Add opaque frozen receipt snapshot boundary and reader

Defines the sealed detached/coherent/SELECT-only snapshot handle, a
refusing default issuer port and a fail-closed receipt reader. The seal
is not exported from the package index and nothing is wired.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc

* Validate whole receipt ledger before absent or found; add cross-conversation conflict

Carries root's #1311 review findings into the frozen reader: a malformed
or ambiguous ledger entry fails closed before absent, the same request in
another conversation is a conflict, and every pin is validated. Adds
tests and documents independence from the publication classifier.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc

* Deep-freeze the returned receipt and correct the issuer-boundary wording

Root review of #1312 at 0fe84e6 requested two repairs.

1. readPiFrozenReceipt returned the zod-parsed receipt, a fresh mutable object,
   behind a shallow Object.freeze on the wrapper, so found.receipt, its metadata
   and the id arrays could be altered by the caller. The receipt is now
   deep-frozen. A regression test checks that every level is frozen, that
   mutation attempts throw and leave a later read unchanged; it fails on the
   previous source. The sealing path shares the same deepFreeze helper.

2. The source comments and docs claimed that, because sealPiReceiptSnapshot is
   not exported from the package index, nothing in production can mint a handle.
   They now say what is true: the function is not exported from the index and
   no runtime path calls it, but that is encapsulation and the absence of wiring,
   not an enforced production boundary; the issuer's provenance is its own
   assertion and not SDK attestation. Scope stays unwired.

No budget or check is changed. Size handling for the dist budget is separate.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc

* Fit the frozen receipt snapshot into the dist budget without changing behavior

Root authorized a bounded, behavior-preserving size reduction for #1312 with the
12 MiB dist budget unchanged. Built on current main, the separate module cost
16,384 allocated bytes against 4,096 bytes of headroom (12,595,200 total, 12,288
over).

The reader and issuer seam now live in restore-generation-authority.ts, a module
the package index does not re-export, so sealPiReceiptSnapshot still is not
exported from the index. Every new source file costs at least two allocated 4 KiB
blocks (.js and .d.ts); folding into the restore-generation evidence module
(the snapshot provenance already names a restore generation) costs one. Two
output-only changes keep the declaration file inside one block: the declaration
comments are written as // comments (text unchanged, including the boundary
wording), and PiFrozenReceipt is written out as a readonly type instead of
z.infer of the schema (entries.push(entry.data) fails to compile on drift).

Validation order, error codes, the deep-freeze repair and every test are
unchanged; the snapshot tests now import the reader from the new module path.
Measured on main 1a7faf1 plus this change: 12,582,912 bytes, exactly the
unchanged ceiling (zero headroom). This branch alone (base b5ff16a): 12,578,816.

Draft, auto-merge off. Not an SDK issuer attestation and no activation.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SFXaGbWqpJiihgsqsJRnc

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to 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.

2 participants