Skip to content

test(profiles): prove profile recovery and fenced rollback evidence - #1048

Draft
0xPlayerOne wants to merge 136 commits into
mainfrom
feat/profile-recovery-rollback-1025
Draft

0xPlayerOne wants to merge 136 commits into
mainfrom
feat/profile-recovery-rollback-1025

Conversation

@0xPlayerOne

@0xPlayerOne 0xPlayerOne commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Current custody — integrated CP #1204 + #1048 backend outcome — 7d599a7d2b48bc5ebfc0a8a125f6fd335df1aec6

Draft, auto-merge OFF. Root retains readiness and merge. No readiness, merge, issue closure, native qualification, SDK publication, installed acceptance or production activation is claimed.

This head integrates the complete existing CP #1204 + #1048 backend outcome onto current remote main (27f17bd55e0266439b5b3089163195c9e7a669be) and closes one concrete gap inside it.

Custody and preservation

Item Value
Published #1204 head (preserved) 253b4ada58e3560fedef142fc7cbd926ed5662ce — unchanged branch feat/pi-durable-completion-20261020, now also addressable as refs/cp/pr/1204
Published #1048 head (preserved) 7cf6d67e7175fa25bc4012f666aa02c53819335e — an ancestor of this head, now also addressable as refs/cp/pr/1048
Integration base remote main at 27f17bd55e0266439b5b3089163195c9e7a669be
Publication fast-forward 1c6cb7d2b..7d599a7d2 on feat/profile-recovery-rollback-1025. No force push, no history rewrite, no deletion

The #1048 branch already contained the #1204 head as an ancestor, so the integrated outcome is published here. The #1204 branch is preserved untouched at its published head.

The corrections root required

Root's complete review of ae9cbb812 found that the writer-coverage qualification overstated what it proved. This head corrects all three points.

1. A digest over a supplied restoreGeneration is tamper consistency only, not restore authority. The previous test changed the generation while retaining its old digest, which missed the rollback that restores the generation and recomputes a matching digest. The qualification now proves that the pure contracts accept that rollback: the retained intent schema accepts the rolled-back body with its recomputed digest, the permit schema accepts a permit over it, the permit snapshot accepts it when the current fence agrees, and the native receipt binding accepts it. The assertion is non-vacuous — inverting it fails the file.

Why: nothing in the pure contracts holds an independent generation authority. restoreGeneration is a caller-supplied reference, the only PiCancellationOwnerPort implementation is UnavailablePiCancellationOwner (it throws PI_CANCELLATION_AUTHORITY_UNAVAILABLE), and no production consumer reads a current fence to compare it against the target's generation. Establishing independent, non-rewound restore-generation authority needs production authority that does not exist in the current architecture. The full-writer restore-generation acceptance remains an explicit open gap, recorded in docs/pi-durable-complete-writer-coverage.md and in the acceptance ledger.

2. The writer universe now covers every writer of the durable state. The previous registry covered only the two cancellation modules and excluded the effect gate, journal, lease, upgrade manifest and resume permit writers, so it could not substantiate complete-writer coverage or a claim that no writer accepts a rollback. The writers are now enumerated from the source and classified by the authority each one actually holds:

Writer Authority it holds Proved
cancellation-owner.ts a target, a permit, a barrier epoch a non-advancing barrier epoch and a permit behind the current fence are refused
native-cancellation-boundary.ts a native target, a fence epoch, a commit receipt a non-advancing fence epoch is refused; the fence receipt must match every field of its request; the commit receipt must carry the exact generation of its intent
journal.ts an epoch over its records, a process claim a claim or transition expecting a superseded epoch is refused with STALE_STATE; a released claim no longer holds the record
effect-gate.ts a revision over its records a compare-and-set against a superseded revision is refused
lease.ts a host process identity a second owner is refused while the first holds the lease
resume-permit.ts an in-process identity the permit is identity-bound, not shape-bound
upgrade-manifest.ts byte identity of the store it reads a store rolled back to different bytes is refused by the manifest check

The five writers that carry no independent generation authority are named, not excluded. The enumeration is derived from the source, so a module that starts writing the durable state without being classified fails the file.

3. The vacuous safeParse().not.toThrow assertion is gone. Every safeParse result is asserted on .success, and the intended binding properties are asserted directly.

The CP #1210 production integration

This head also carries the complete CP #1210 backend outcome, consumed as delivered by its own published branch 95021f73a1127d117317ed78e5d7466f3ad61783 (PR #1210, still open as a draft). That contract is merged forward unchanged: every W2-owned path is byte-identical to W2's published head, and no W2-owned file is edited here.

The production seams that carry the accepted model are W1-owned and now wired:

  • apps/control-api/src/executions/execution-acceptance.service.ts forwards the accepted request payload's modelId into commands.acceptExecution, so the execution read model records the model the caller accepted.
  • apps/hosted-control-plane/src/composition.ts passes the per-model map to the real RuntimeDiscoveryAttemptRouter, and apps/hosted-control-plane/src/index.ts resolves it from the deployment environment with the contract's strict parsing. An absent variable leaves routing unchanged; a present map is a policy that denies an execution it does not name.

The new end-to-end qualification apps/hosted-control-plane/src/hosted-model-forwarding.integration.test.mjs drives the real chain over HTTP against the real hosted router: HTTP acceptance, the persisted execution read model, and the router carrying the accepted model to its mapped harness. It covers the configured map, an unmapped model, an execution with no model, a pin that conflicts with the map, the no-map behavior, and the unchanged execution plan digest. The provider/model independence, the exposing-runtime and pinned-harness guards, the auth and tenant boundaries, and the historical replay semantics are unchanged.

The qualification is a source integration proof. It activates nothing: no provider is called, no native effect is performed, and no production resource is touched. The workflow runtime is an external service, so the acceptance path's post to its ingress is answered by a minimal local stub; nothing else about the runtime is exercised.

The CP #1048 restore-generation authority gap stays open. This work does not close it, and the writer-coverage qualification still records that a generation rollback with a matching digest is accepted by the pure contracts.

The narrow CI inventory repair

The hosted model-forwarding integration test was discovered by the integration file inventory but had no local shard owner, so the disposable-local PostgreSQL shards did not run it. This head registers it on shard 3, next to the other apps/hosted-control-plane integration files, and every existing entry is preserved (63 entries before, 64 after, none removed).

Two registrations are distinct, and the repair covers only the one that was missing:

  • The local sharded registration — the explicit inventory in scripts/integration-shards.mjs. This is what the disposable-local PostgreSQL shards read, and it did not name the file. It is now registered.
  • The package integration glob — apps/hosted-control-plane runs bun test --timeout 30000 src/*.integration.test.mjs, which already matches the file. This registration was already present and is unchanged.
  • The remote runner — the postgres-pull-request workflow runs the dedicated local-DB qualifications and the shard suite; it did not name this file and is unchanged.

The inventory regression in tests/integration-shards.test.mjs asserts the shard owner, the exact arguments the local runner uses for the file, and the package glob separately, so the two registrations cannot be conflated. It is negative-proven: removing the registration fails both the file-ownership check and the new registration check.

Only scripts/integration-shards.mjs and tests/integration-shards.test.mjs are edited. No other path, owner, shared runner, production resource or credential is touched.

The focused light checks at this head

Check Result
bun test tests/integration-shards.test.mjs 8 pass, 0 fail, 188 assertions (was 6 pass, 1 fail)
bun test tests/repository.test.mjs 30 pass, 1 fail — pre-existing, see below
bun scripts/workspace-boundaries.mjs 1268 files in 45 packages, 0 boundary violations
bun scripts/check-locale-compare.mjs canonical ordering clean
bun scripts/check-digest-writers.mjs 39 digest writer flows matched
oxfmt --check on both edited files all matched files use the correct format
oxlint on both edited files 0 warnings, 0 errors

The tests/repository.test.mjs failure (discovers disjoint Bun test groups for Code Foundry) is pre-existing at the owner head f4310854d with a clean tree — it reproduces with this repair's edits stashed, and its failure signature is byte-identical before and after this change. Its cause is that the Code Foundry group-discovery expectation list in that file does not name the hosted model-forwarding test, which the earlier CP #1210 commit added. That file is outside the two paths cleared for this repair, so it is reported rather than edited. It needs one line added to the expected integration list:

'apps/hosted-control-plane/src/hosted-model-forwarding.integration.test.mjs',

Only the focused light checks were run for this repair. No aggregate heavy lane was run.

The repository integration inventory follow-up

The narrow CI inventory repair registered the hosted model-forwarding test in the local shard inventory, but the Code Foundry group-discovery expectation list in tests/repository.test.mjs still did not name it. That exact-list assertion therefore failed at the owner head 1c6cb7d2b with a clean tree, even though the file was discovered correctly.

This head adds the file to the existing exact expected integration inventory, in its sorted position, and adds a focused regression. Every existing entry is preserved: 60 entries before, 61 after, none removed, and the assert.deepEqual exact-list assertion itself is unchanged.

The focused regression states this file's registrations separately:

  • it is discovered as an integration test, so the expected inventory must name it — a file that is discovered but absent from the exact list is a stale inventory, not a passing test;
  • it appears exactly once in that inventory;
  • it has exactly one local shard owner, so the local sharded lane cannot silently drop it;
  • its package integration command selects it, so the package integration lane and the local sharded lane remain distinct registrations of one file.

Both assertions are negative-proven: removing the expected-inventory entry fails the exact-list assertion, and removing the shard registration fails the focused regression.

Only tests/repository.test.mjs is edited. The shard files are untouched, and the registered historical detached worktree with its staged unrelated inventory entries was neither modified, staged, reset, nor otherwise touched.

The focused light checks at this head

Check Result
bun test tests/repository.test.mjs 32 pass, 0 fail (was 30 pass, 1 fail)
bun test tests/integration-shards.test.mjs 8 pass, 0 fail, 188 assertions (the shard files are untouched)
bun scripts/workspace-boundaries.mjs 1268 files in 45 packages, 0 boundary violations
bun scripts/check-locale-compare.mjs canonical ordering clean
bun scripts/check-digest-writers.mjs 39 digest writer flows matched
oxfmt --check on the edited file all matched files use the correct format
oxlint on the edited file 0 warnings, 0 errors

Pre-existing failures, preserved and reported separately: the tests/repository.test.mjs failure that this head fixes was pre-existing at the owner head 1c6cb7d2b with a clean tree, and it is now fixed. No other failure was present in the focused light checks at either the owner head or this head.

Only the focused light checks were run. No aggregate heavy lane was run, and no readiness, merge, issue closure, production change, or credential action was taken.

The aggregate unit lane: the exact failure baseline

The lane is the shared runner scripts/run-bun-test-group.mjs, which is not W1-owned. Its failures are handed to their owners with the exact command and logs. No threshold, check, hook, timeout or assertion is waived, suppressed or weakened, and the full suite is not called green.

The lane is load-sensitive: the pristine published head ac143c19d produced 7 failures plus the Bun panic in one run and 29 in another, with no source change between them. At this head it produces 12 entries (11 failures plus the same panic). Every failure in the pristine baseline also fails here. Three appear at this head that appear in neither baseline run — actual process exit and restart retain native tool source and approval checkpoint without replaying inference or settled effect, distinct workspace processes retain isolated input receipts despite shared idempotency keys and one process restart, and operator CLI provisions scoped grants and registrations and preserves revocation. All three are outside the CP #1210 scope, and all three pass in isolation at this head (11 pass / 0 fail and 6 pass / 0 fail). They are load-sensitive timeouts in the same family as the 22 extra baseline failures, not regressions from this repair.

The Bun panic (range end index 1884 out of range for slice of length 1024) is W4's active CP #1030 isolation scope, not W1's.

The focused qualification at this head

Lane Result
The model-forwarding end-to-end qualification 6 pass, 0 fail, 30 assertions
The writer-coverage qualification (the CP #1048 gap, still open) 12 pass, 0 fail, 53 assertions
The durable adapter lane 338 pass, 0 fail across 33 files
The control API execution acceptance lane 15 pass, 0 fail
The hosted control plane unit lane 13 pass, 0 fail
The hosted control plane HTTP integration lane 8 pass, 0 fail
The workflow worker router lane (the model-map contract) 27 pass, 0 fail
The workflow worker index lane 11 pass, 0 fail
The build 47/47 tasks successful
The type check 200 requirements and 103 issue audits; 45 packages, 55 operations, 4 profiles; no type errors in 208 infrastructure files
The lint 1268 files in 45 packages, 0 boundary violations; canonical ordering clean; 39 digest writer flows matched
The format all matched files use the correct format
The architecture audit 45 packages, 55 operations, 4 profiles
The OpenAPI artifact check 33/33 tasks successful

The model-forwarding qualification is negative-proven: removing the model forwarding from the acceptance breaks 4 of its 6 cases.

Qualification at this exact head

Gate Result
The durable adapter lane 338 pass, 0 fail across 33 files
The writer-coverage qualification 12 pass, 0 fail, 53 assertions. Negative-proven three ways: inverting the rollback assertion fails the file, inverting the upgrade-manifest assertion fails the file, and dropping a writer from the classification fails the file
The profile recovery lane 12 pass, 0 fail
The build 47/47 tasks successful
The type check 200 requirements and 103 issue audits; 45 packages, 55 operations, 4 profiles; no type errors in 208 infrastructure files
The lint 1266 files in 45 packages, 0 boundary violations; canonical ordering clean; 39 digest writer flows matched
The format all matched files use the correct format
The architecture audit 45 packages, 55 operations, 4 profiles
The disposable restore drill backup and restore preserved full evidence and restored application-role reads, immutable replay and new evaluation writes without DDL or role-administration privileges
The disposable PostgreSQL integration lane 359 pass, 12 fail across 40 files. Every failure is in tests/profile-recovery-self-hosted-simple-sigkill.integration.test.mjs: PINNED_PROCESS_UNSUPPORTED: platform darwin has no pidfd, plus the RESTATE_OWNERSHIP_UNRECORDED consequence. That file and its fixture are byte-identical to the published #1048 head, and the CI runs this lane on ubuntu-latest only

The proofs ran on the repository's pinned toolchain (bun@1.4.3, node@24.21.0, darwin-arm64) against a disposable local PostgreSQL from the repository's own compose.yaml on 127.0.0.1:54329, using the repository's three distinct roles. That database was created for this qualification and torn down with it. No account, credential or production resource was touched.

What remains unproved

  • Native zero-effect acceptance. The boundary refuses a rewound request before any native effect. Nothing here observes a native effect or proves it is zero.
  • SDK adoption and upstream publication. The outcome is repository source, tests and docs. No SDK release, upstream publication or consumer adoption is performed or claimed.
  • Installed cross-repo and profile acceptance. The proofs are repository tests against a disposable local PostgreSQL and the local composition. No installed profile, cross-repo consumer or production topology is exercised.
  • Production activation. No production action is taken. Nothing is deployed, activated or released.
  • The aggregate unit lane. It hits a Bun 1.4.3 panic (range end index 1884 out of range for slice of length 1024) and 7 test failures: the runtime-gateway host credential startup case, the two qualified-cancellation deadline and revocation cases, the crash-at-admission-boundary case, and the three canonical recovery-outage cases. The same 7 failures and the same panic reproduce with the writer-coverage file held aside, so they are pre-existing on the integrated tree and not caused by this qualification. The Bun panic is W4's active CP M17.03.1 — Correlate runtime telemetry and measure operations #1030 isolation scope.
  • The independent restore-generation authority. Nothing outside the restored snapshot holds the current restore generation, so a rolled-back generation with a matching digest is indistinguishable from a genuine request. The five writers with no independent generation authority are named above. Closing this needs production authority beyond the current scope.
  • The source-plan and Railway lifecycle scope. Held by W4 for CP M17.03.1 — Correlate runtime telemetry and measure operations #1030. No source-plan path is in this change set.
  • The Linux-pidfd proof family. The self-hosted-simple SIGKILL proof fails closed on macOS because the pinned-process fixture needs a Linux pidfd. The file and its fixture are byte-identical to the published test(profiles): prove profile recovery and fenced rollback evidence #1048 head, and the CI runs the lane on ubuntu-latest, where the proof is intended to run.

Custody boundaries observed

W4's CP #1030 lifecycle, architecture, inventory and shared-runner paths were not edited. The only shared-runner edit is the mechanical merge resolution that keeps both sides' files. Sol's shared runner and inventory surfaces carry no feature work from this outcome. The published branches, the stale preservation refs and the untracked .bun-cache are preserved.

The full acceptance ledger is in docs/pi-durable-cp1204-1048-acceptance-ledger.md; the writer-coverage scope, its corrected findings and the open restore-generation gap are in docs/pi-durable-complete-writer-coverage.md.


Current retained-intent review repair — 7cf6d67e7175fa25bc4012f666aa02c53819335e

Draft, auto-merge OFF; fresh root exact-head review required. Three files changed; no native capability or production behavior was activated.

assertPiNativeCancellationReceiptBinding now parses its retained-intent input with PiCancellationRetainedIntentSchema before timestamp/digest comparisons. Two regression-first negatives cover malformed requestedAt and changed idempotencyKey retaining the old request digest: both failed before the fix and pass afterward. Older drain-before-ACK protocol/outcome prose is explicitly marked superseded history and points to current F<A<R, permitted N<F<R<D semantics.

Exact combined contracts plus repository/inventory/shards:83 pass,351 assertions,5 files,2.41s. Unchanged aggregate type-check97/97 plus schema/compatibility/requirements/architecture/infra pass. Full formatting:1,991 files pass. The matching CP1204 repair passed the full affected Pi package:262 pass,1,662 assertions.

Native engine/composition, shared Adea writers, SDK and original zero-effect gate file are unchanged. No native qualification is claimed: the prior executed combined native gate receipt remains4 pass/2 fail; that file was not rerun for this pure validation/docs repair. All-writer/restore-generation/installed acceptance remains pending. No review approval, readiness, merge or issue closure is claimed.


Prior exact-head source and qualification receipts (historical)

Current dormant native-boundary slice — 1272e45e790d465034230095324b9f204f434d25

Draft, auto-merge OFF. Fresh complete exact-head root review is required. No readiness, merge, native qualification or migration completion is claimed. Scope remains adea-ai/adea#1173 and the preserved CP migration/recovery work; no aggregate issue is closed.

This four-file slice adds strict native preparation/target/receipt and mutation-owned fence-installation contracts, pure evidence-binding comparisons, negative tests and documentation. The default port rejects every prepare/commit/install/read/drain operation. No adapter/engine/composition injection, SDK installation, Context/Storage proxy, shared Adea authority writer, restore proof, permission or production change is included. Preparation is neither permission nor a frozen in-memory cut: an eventual N must reread persisted scope/task/input/ownership transactionally. Lost-response publication/drain must resolve the exact persisted generation and never abort a successor.

Andrew approved unavailable/not-confirmed revocation when runtime fencing cannot be confirmed and post-R drain D for cancellation N committed before R. Required F<A<R and permitted N<F<R<D remain; no new old-epoch N after F and no transaction gate held through D. Handshake B does not imply bounded end-to-end success/response.

Current source validation

Exact combined contracts plus repository/inventory/shards:81 pass / 349 assertions across5 files. Aggregate type-check97/97 plus schema/compatibility/requirements/architecture/infra passes. Full format check:1,991 files pass. Unchanged cross-store native cancellation gate file:4 pass / 2 fail,38 assertions; final revocation/deadline requirements still receive PI_LEAD_CANCELLATION_OUTCOME_UNKNOWN.

Source lint/build/format, boundary, canonical-order and digest-writer checks pass. Full smoke was not rerun for this inert slice; earlier b9/e93 smoke receipts below are historical exact-head results. Released/installed SDK, authenticated product timeline, native atomic cancellation/all-writer/restore-generation and installed Mac acceptance remain open.

Actual public-facade qualification, not native-effect acceptance

  • Disposable Node SQLite + installed Pi1.1.0: a closed host database gate prevents pending-task admission but also blocks cancellation itself.
  • Public Tx can atomically retain a conservative empty-root no-effect receipt without scheduler resume; fence/owner drift rolls the receipt back. This separate path is not recursive scope or actual guarded abort.
  • Ambient operation identity tagged four native transactions (abort, reservation, completion, terminalization), so it does not selectively identify N.
  • Three isolated extension reference tests remain intentionally red: empty-abort operation receipt, rejected-abort scheduler admission, and ambient selectivity. They are preserved with executable evidence in Library design revision5, not presented as green repository tests or a documented SDK regression.

The additive guarded-abort contract remains the reference. Selective native operation identity, exact persisted scope/zero-write handling, all required writer closure and independent restore generation are not qualified. No current outer check or retained request is described as atomic cancellation permission.


Historical exact-head receipts (not current-head acceptance)

Preserved reconciliation published — e93f29cde469504063227b373ec6cbb7646afbdf

Draft, auto-merge OFF; fresh complete exact-head root review and acceptance remain required. No issue is closed.

This is a fast-forward from old published e635101384587b6d9e66dd6d1dbfb0eec8666883. Its preserved history now includes current main f4f17194e04bcf8af65e8b5ff7aed7926b51ca88 and exact #1204 b9ea19ddc3986b9641cc63651109f217f432731b. All nine original source conflicts are resolved. Old clean checkouts, custody archives and partial integration records were preserved; no archived session was revived and no force push used. The final ancestry-only merge has the same source tree as tested merge 11d70aa0b2d61f9d76f2d4895122b780e7493a11 (bd1ab9cf7383b02bff886c34876a0f9fa9626d44).

Reconciliation decisions

  • Preserve unique process-claim identities, safe recovery cleanup, canonical actor/retained binding, task/public/periodic drain, wake/rebind and cleanup work. Keep current prepared/armed physical markers and test(pi-restart): prove lead run recovery across a real process restart #1200 unknown/zero-resend semantics; do not authorize restored generations from copied journal evidence.
  • Explicitly supersede old “committed cancellation survives later revocation,” startup abort delivery and ordinary-capability removal. Preserve current ordinary/fenced authority and fail-closed unknown reporting. Retained request is not permission. The disconnected history classifier retains exact target/digest/idempotency and same-epoch G2 race negatives without aborting, acknowledging or changing execution state. Complete old-assertion replacement map: docs/pi-durable-committed-cancellation-authority.md.
  • Retain current child/runtime composition and durable advisory delivery; do not count a CP resultRef or publication as authenticated Adea timeline acceptance. The actual child integration uncovered and repaired SQLite conclusion CAS/receipt propagation; the exact canonical bounded conclusion is now durable and immutable. No artifact read grant added.
  • Merge all reviewed inventory/shard/portable cleanup and owned PostgreSQL target-confinement repairs. Resolve duplicate restart-suite registration from automatic merge while preserving one owner and exact expected lists. Preserve measured sharding and every existing gate.
  • Legacy graph/Restate/profile evidence remains historical, explicitly superseded for supported Railway Pi acceptance. No legacy service was activated or rebuilt as the migration architecture. Database-owner restore proof and Railway/installed acceptance remain separate.

Validation

macOS arm64, Bun1.4.3 / Node24.18.0, PostgreSQL18.6 disposable private cluster, October20 UTC. No paid providers, credentials/grants, deployment, package publication or production action.

  • Normal hooks: 47/47 build, 97/97 aggregate checks, schema/compatibility,200 requirements/103 issue audits,45 packages/55 operations/4 profiles,208 infrastructure files passed. Full formatter 1,989 files passed; source tree clean.
  • Repository/shard/architecture/confinement/portable cleanup: 73 pass /486 assertions across6 files.
  • Actual PostgreSQL request/outbox tests: 9 pass /42 assertions each, private and explicit normal modes. Normal Mac proof uses existing peer identity/private socket; Docker TCP/distinct-role topology is unqualified. Zero owned DBs remain; cluster stopped.
  • SQLite conclusion/receipt/publication/orchestration: 66 pass /805 assertions. New conclusion regressions failed before the repair; current positive/reopen/concurrent replay/rollback and changed/removed/injected text negatives pass.
  • Cross-component child/canonical/workspace: 60 pass /423 assertions across4 files. No installed released-SDK qualification claimed.
  • Retained non-Pi wake/crash/rebind/hosted cleanup regressions: 86 pass /390 assertions across7 files. Local fixture proofs are not production profile qualification.
  • Broader Pi+lead/fence run: 410 pass /2 fail,2,543 assertions across39 files. Subsequent focused corrected zero-effect gate run: 4 pass /2 fail,38 assertions. Both failures are retained executed requirements for revocation/deadline change after the final asynchronous callback: observed PI_LEAD_CANCELLATION_OUTCOME_UNKNOWN, required rejection before effect. No skip, weakened assertion or timeout increase. Current native Pi public API/all-writer protocol does not provide the qualified atomic effect fence.
  • **Full unchanged smoke PASSED at this exact source tree:**612 pass,2 existing conditional PostgreSQL skips,0 fail;5,398 assertions across49 files, seed1104,134.63s. The prior20s runner-double timeouts did not recur; no timeout, assertion, skip or gate was changed. This is a passing receipt for test(profiles): prove profile recovery and fenced rollback evidence #1048 e93, not a passing claim for the distinct feat(pi-durable): compose child reads and drain recovery #1204 b9 head. Native zero-effect and installed acceptance gates remain open.

Precise exact-head native effect gate observations

The complete Pi+lead/fence suite was rerun on this exact e93 source: 410 pass /2 fail,2,543 assertions,412 cases across39 files,33.86s. The executed failing names are:

  1. qualified cancellation must reject revocation after its final asynchronous authorization with zero effect
  2. qualified cancellation must reject deadline change after its final asynchronous authorization with zero effect

Separate observation using the unchanged disposable local live harness confirmed both: final callback entered; response PI_LEAD_CANCELLATION_OUTCOME_UNKNOWN; journal cancelling; cancellation intent retained; provider streams aborted 1; physical requests 1; starts 1; reconciliation calls 0. Thus this is a demonstrated post-final-callback effect-authority gap, not missing metrics or mere review bookkeeping. Zero-effect rejection is still required. No finite-read atomicity claim, gate weakening, coordinator activation or irrevocable-grant restoration is accepted. Native commit-time compare-and-cancel plus the all-writer/restore-generation protocol remains gated.

Exact paired local package consumer qualification

CP e93f29c, clean source digest sha256:a9e30b837df54f4784529a37b4f1984fe0fcf068885114be6d76953d935f8776, was locally packed using the existing no-publication script and installed into disposable consumers from Adea a4a5059b115530b0002ada9400a24770e430294a. Both actual lead and model consumers passed their TypeScript checks and fixture suites. Adea source and repository dependency pins were unchanged. Exact archive SHA256:

  • contracts1.21.4: 8b2f536bb39b313e31576c8b658f9daf67957c85ee93f5ffd8739330ead0b180
  • runtime-sdk1.17.0: 20e467843f11b9b84ac79eab53fb949c8a80aec57c5fd4dfdb03629b7b431d5c
  • sdk1.20.0: ed9c35eaf0e93620968977d18ed8b90006b6a1221608a8c11746bf5b473a64a5

These are local candidate manifest versions, not registry releases. No connected PostgreSQL, authenticated Adea timeline, device or desktop acceptance follows. The connected runner requires an existing qualified loopback Adea fixture and shared light-lane handoff; this session owns only the stopped UNIX-socket PostgreSQL fixture. Root/database-owner coordination must supply that authorized target/handoff without new credentials or access grants.

The distinct #1204 b9 head also now passed its own unchanged full smoke:595 pass,2 existing conditional PostgreSQL skips,0 fail,5,311 assertions, seed1104,117.65s. Both smoke results supersede their own prior timeout receipts without establishing a timeout cause.

Remaining acceptance gates

Native commit-time compare-and-cancel plus all relevant authority writers; independently qualified restore generation/cross-store restore; production trusted no-send authority; real supported release-pair upgrade/rollback; installed released SDK/runtime+authenticated Adea reader/canonical timeline+Mac desktop/Railway combined acceptance. UI implementation belongs to Claude and is not touched. No retained intent or post-effect unknown response closes these gates. Full migration remains incomplete.

Refs adea-ai/adea#1173, #1025, #942. Current reconciliation map · Historical100-path ledger.


Earlier receipts (historical; not current-head acceptance)

Current published head and reconciliation status

Published head: e635101384587b6d9e66dd6d1dbfb0eec8666883, branch feat/profile-recovery-rollback-1025. Draft; auto-merge off; conflicted with current main. The historical b145de receipt below is not exact-head qualification of this published source. No issue or PR is complete from this reconciliation.

Sole Pi owner has begun isolated reconciliation with main f4f17194e04bcf8af65e8b5ff7aed7926b51ca88 and CP #1204. Three preserved old checkout heads were clean, with no nonignored untracked source, and already ancestors of this published head. Source archives, patches, refs, custody metadata and hashes were retained before integration; old checkouts remain unchanged. No archived session was revived. The isolated candidate still has unresolved source conflicts and is not published or qualified.

The complete old100-path inventory and updated24-path Pi overlap are recorded in the source map and per-path ledger. Standalone portable cleanup qualification is published in #1204: 14 tests / 71 assertions, with the original historical tests preserved. This does not qualify old native recovery or Railway restore.

Two concrete semantic conflicts: the old Pi restart delta changes unknown/zero-send to completed/one-send and drops dispatch-replay rejection evidence; preserve merged #1200 semantics. Old pending committed-cancellation intent delivery runs before fresh authorization and can deliver after revocation/expiry; it cannot replace the current revocable authority/unknown contracts. A test coordinator or two reads do not supply native commit-time authorization. Unique supported recovery work still needs integration/tests, with shared CI/database path ownership respected. Legacy LangGraph/Restate proof is historical, not the supported Railway Pi replacement.

No deployment/retrigger, credentials, grants, force-push, auto-merge or issue closure is authorized or performed. Refs adea-ai/adea#1173, #1025 and #942 remain open.


Preserved historical description and validation

Requested by Andrew · project thread

M17.02.2 — Profile recovery evidence and current validation receipt

Issue linkage: Refs #1025 (M17.02.2). Parent #942 remains open. This PR does not close either issue.

Status: Draft, auto-merge off. #1025 remains open. The milestone is not complete. This PR proves the clauses listed below at the named composition roots. The authoritative map is docs/profile-recovery-acceptance-map.md.

Historical validation head — b145de3697e8ae41d3bc7935bd01c7eb534ac959

Tree 7110d03ff387fb12e7b8e59054ad8e5d473ceacd. Base: main f96ff8fb934f3ebfccdd72c749698b775ad7beb1 (#1160, after release 1.100.5), contained in this head. One documentation-only commit over 2d4f6f19, fast-forward, no history rewritten.

Acceptance map reconciled with this receipt (review of 2d4f6f19). docs/profile-recovery-acceptance-map.md (the "Revalidate target generations" row, the per-profile "Target-generation fencing" cell, and gap 7) no longer says channel-generation fencing is proven against disposable PostgreSQL. They now say the test is not qualified at the current head: it needs PostgreSQL 17 or newer (transaction_timeout), it failed on local PostgreSQL 16, and the pinned PostgreSQL 18.6 lane has not run. The only passing evidence cited is the recorded full integration run on head 9cd9bd48 (2026-10-12, 316 passed; that head contains the test), labelled as a historical receipt and not a result for this head.

Code at 2d4f6f19 is unchanged, so its qualification below carries over; only the acceptance map differs. After the doc edit: format check (1,896 files), architecture audit, tests/repository.test.mjs (31) and the two tests that read the map (7) pass.

Previous head — 2d4f6f1987243b5c77092e04109b7fc4daf7ebf5 (code identical to the current head)

Tree f53d7bfbfce13749db7673a57496305d1f83cf09. Two commits over d4973c92, both fast-forward: the merge of main, and a fix so the merged result builds.

Merge of main (#1134, #1156, #1160 and releases). Four Pi Durable files conflicted; both lines are kept:

  • packages/pi-durable-adapter/src/adapter.ts: main's wider turnKey signature (used by its new completed-turn usage helpers) is kept. This branch's resume path no longer calls the owner-contention helper, so the helper is not carried.
  • apps/control-api/src/pi-durable/node-admission.ts: this branch's fence-pin split is kept, and the new children operation is added to its operation types.
  • apps/control-api/src/pi-durable/node-composition.ts: this branch's tracked public recoveries on recover and close are kept, and the child terminal settlement is added to recovery and to close.
  • apps/control-api/src/pi-durable/pi-durable-lead.service.ts: this branch's admission path and retained-fence lookup are kept. The new children read is rebuilt on that lookup: it refuses under any fence, and uses the start request for the observed target.
  • node-admission.test.mjs: main's children-under-fence test now supplies the fence adapter that fenced status observation needs on this branch.

The merge commit alone does not build (one unused helper left from the conflict); the head does.

Qualification of the code (Linux, pinned Node 24.21.0 and Bun 1.4.2 side-installed in the container; existing infrastructure only):

Command Result
Forced bun run build 45/45 tasks passed.
bun run type-check 47/47 tasks passed.
Format check (1,896 files), bun run lint, architecture audit Passed (45 packages, 54 operations, 4 profiles).
bun run test:smoke / test:e2e 538 passed / 458 passed, 0 failed.
bun run test:group:unit as root 4,062 passed, 2 failed: the two chmod-based permission tests, which cannot fail as expected under root.
apps/control-api/src/pi-durable tests 403 passed, 0 failed.
tests/profile-recovery-self-hosted-simple-sigkill.integration.test.mjs 55 passed, 0 failed, two consecutive runs; no restate-server left.

Build, type-check, smoke, e2e and the SIGKILL runs executed one test-file line before 2d4f6f19 (the added fence: adapter in node-admission.test.mjs); format, lint, architecture, the unit group and the Pi Durable directory ran on 2d4f6f19 itself. The non-root unit run and the PostgreSQL 16 integration run below were done on d4973c92, before the merge, and were not repeated.

What did not run, and why:

  • The pinned PostgreSQL 18.6 docker compose lane, the Docker disruption and restore drills, and the cloud remote drill did not run on this head. docker version shows the client (29.8.2) and docker compose v5.6.0, but there is no daemon and no /var/run/docker.sock; docker compose up -d --wait postgres fails with failed to connect to the docker API at unix:///var/run/docker.sock; check if the path is correct and if the daemon is running. No DOCKER_HOST, remote database or Neon credentials are configured in this session. Starting a Docker daemon was refused by the session's permission policy earlier and was not retried; no access was changed.
  • Earlier supplementary PostgreSQL run (at d4973c92, not this head): the repository's integration shards (50 files) against a disposable non-root PostgreSQL 16.15 passed 393 and failed 3, all in packages/database/src/integration.test.mjs, each on set_config('transaction_timeout', …) in runtime-inventory-unit-of-work.ts. That is a PostgreSQL 17 setting and is absent on 16. One of the three is the channel-fencing test this PR adds, so it is unproven, not passing. The cloud remote drill timed out at inventory-ingested on the same unit of work (cause not confirmed). The restore integration file passed 4/4 on 16. Not claimed as the pinned lane.
  • GitHub's runner-heavy checks do not run while the PR is a draft, and skipped checks are not passes. Nothing here is hosted production recovery.

Linux pidfds remain required; unsupported platforms fail closed. This is legacy LangGraph composition evidence with manual orphan reap, not hosted production recovery. Unexpected Restate launcher death before complete parent capture, product orphan adoption, Restate drain, upgrade/rollback, Hosted live recovery and production authority/reconciliation evidence remain unqualified. Refs #1025 and #942; both remain open. Refs #612 for the integration handoff; its remaining scope stays open.

Correction (earlier description): it said main e688eb9a was contained. That commit is contained but was not current main; the real main at that time was 2a02db89 and then f96ff8fb. 2d4f6f19 was the first head that contains f96ff8fb.

Changes in the line since 59fe25fd (review of 2026-10-16)

  1. Runner cleanup race. afterEach and the SIGINT/SIGTERM/SIGHUP path share one chained cleanup runner (tests/fixtures/runner-cleanup.mjs). A signal that arrives while afterEach is awaiting a callback waits for it instead of seeing an empty queue and exiting. Callbacks are taken one at a time, so one registered during cleanup still runs. Cleanup stays handle-only with no force-kill fallback. Deterministic held-cleanup regressions deliver the signal during an in-flight cleanup; the first fails against the previous splice(0) implementation.
  2. Real-process signal proof (d4973c92). A child process (tests/fixtures/runner-cleanup-signal.child.mjs) installs the same shared runner and handlers and holds a cleanup callback. Real SIGINT, SIGTERM and SIGHUP must not end it mid-cleanup and must end it with 130, 143 and 129 afterwards; a signal with nothing in flight still cleans up. Seven tests; the SIGKILL file is 55 tests.
  3. Parent-gone cleanup. A composition whose parent ended its pipe held its ports, data directory and Restate child: initial until its 120 s keep-alive and recover indefinitely. Both now close on stdin end. Two regressions fail on the old fixture.
  4. Reconciliation resume under the retained Hosted wake. Reconciliation re-drove the workflow without the plan graph, which the retained-wake guard correctly refuses for a graph plan, so such executions never recovered. The Hosted reconciliation submitter now adds the graph from the retained plan using the same helper acceptance uses (graphWorkflowInput). A missing plan, a non-graph plan and an input that already has a graph pass through unchanged; a plan read failure fails closed. Applies only when the opt-in wake is configured. The same omission exists on the non-wake Hosted path and the Local reconciliation resume; not changed here.
  5. Ordinary cancel target. cancel() derives its target from the journal after authorization, not from a record read before it. Reproduced first: a generation that started during authorization left the cancel superseded and the run running. Regression added.
  6. Inference resume permit. A permit has to be one the adapter issued (resume-permit.ts, not exported from the package entry). A structurally matching literal, a frozen literal and a cloned permit are rejected with PI_INFERENCE_RESUME_PERMIT_INVALID.
  7. Earlier in this line: the recovered one-file process-cleanup repair (patch SHA-256 fb3a2937…, base 405a21e8) is merged with the remote cleanup line; the remote handle-owner design stands, with unconfirmedHandles on the teardown error and the shell kill $var scan kept.
  8. The Hosted composition source digest in the architecture audit is updated for item 4 (one field).
Historical validation receipts — tied to their original heads

Historical head — d4973c920b6ba597b04292e5603a8b75971bb59a (superseded by the merge above)

Tree c7ac5b260239b99afe381a37a3681be72db65b89, fast-forward over d119fb39; tests, a fixture and the acceptance map only. Pinned Node 24.21.0 / Bun 1.4.2: forced build 45/45; format (1,884 files), lint, architecture audit and type-check passed; smoke 538 and e2e 408; unit 4,003 passed with the two root-only chmod failures and 4,014 passed, 0 failed as a non-root user (uid 1000, clean clone) including both permission tests; SIGKILL file 55/55 three times; the real-process signal proof passed on every run. Integration shards on a disposable PostgreSQL 16.15: 393 passed, 3 failed on the missing transaction_timeout setting (details above). The pinned PostgreSQL 18.6 lane and Docker drills did not run.

Historical head — d119fb39c71442eac61eb104ac9d9c08ce659879 (condensed)

Tree 7ba3508a45ffebec278011657fd70d38df0a129c, fast-forward over 59fe25fd. Linux, Bun 1.4.2 and container Node 22: build 45/45; format, lint and architecture clean; SIGKILL file 48/48; smoke 538, e2e 408; unit 4,003 passed with the 2 root-only chmod failures; adapter package 261/261; Hosted wiring and index tests 34/34. test:integration, PostgreSQL restore and type-check were not run there.

Historical head — 43ad930b7334eb925c8f8421b2a863b44295e9d7 (superseded; not results for the current head)

Tree: 9cad270fe034a1b58d39832c449af4c1204fe2ee. Repair base: 3b59d23991dcce1d3e9625f68b03e971cdc115d9. This preserves the existing partial-start/stop-failure regression and adds the main-test cleanup repair. Changes are limited to the SIGKILL test, its fixture, and the acceptance map.

The main test previously sent SIGKILL before recording Restate ownership after a startup timeout or partial identity capture. A Linux regression reproduced a live native Restate child after that cleanup. Teardown now requests a fresh ownership handshake from the live fixture, waits for startup to settle (including rejection), and pins the complete launcher/native chain before SIGKILL and child-first reap. The fixture retains the original launched process handle and keeps its control pipe alive until that handle's exit promise settles, including stop failures that clear the runtime health PID. A failed handshake preserves the live owner, partial handles, and work directory without a force-kill fallback.

New regressions exercise the same releaseOwnership path as the main recovery test: a pending-start barrier, startup timeout, failure between launcher and native capture, rejected startup with an injected stop failure, a provider stop timeout after the runtime clears its process reference, and failed ownership repair retaining live handles without signalling. Independent observer handles make the runtime regressions safe when run against the defective cleanup.

Validation on that head, using Node 24.21.0 / Bun 1.4.2: SIGKILL plus self-hosted-simple integration files 46 passed, 0 failed (335 assertions); bun run build 45/45; bun run format:check, bun run lint and bun run type-check passed. Full repository unit/E2E/smoke groups and the complete PostgreSQL integration lane were not rerun for that repair.

Historical head — 405a21e838febb13f4f639e9bf1029a16242d7a0

Tree: 3d1bbd5ad89759d83a5f54859bf44ee0888532df. Parent: 7657120a78099ccfc0753e9f5e0517863388d790 (tree 23cd8b64), which merged main dbd94385 (release 1.97.1). Only tests/profile-recovery-self-hosted-simple-sigkill.integration.test.mjs changed; no product source and no fixture changed.

Owner teardown on pinned handles only (review of 7657120a)

Before: the real-owner test's cleanup called process.kill(childPid, 'SIGKILL') unconditionally, even after that child had been terminated and its pinned handle closed. If the pid had been reused, teardown could have killed an unrelated process.

After: teardown is one helper, releaseSpawnedOwner, that works only through handles: the owner's ChildProcess (SIGTERM, then SIGKILL after the bound) and the pinned child and anchor, each terminated through its handle if still running and then closed. Every step is attempted after an earlier failure, and a handle that cannot be confirmed gone is reported in an AggregateError. The numeric-pid kill is gone from the test file and no test or fixture calls process.kill.

Local validation at that head (pinned Bun 1.4.2; container Node 22): bun run format:check, bun run lint, bun run architecture:check passed, and bun test on the SIGKILL, repository and integration-shard files 64 passed, 0 failed. The build, unit, E2E and smoke lanes were not rerun for that one-test-file commit; their last results were at 7657120a (build 45/45, unit 3,908 passed / 2 failed, E2E 403, smoke 521), where the two unit failures were the root-only chmod tests. type-check and the full test:integration lane were not run and are not claimed.

Earlier heads, each with its own recorded results: 7657120a (launcher ownership anchored to the spawned composition; SIGKILL file 23/23), 99c645f7 (kernel start ticks required; SIGKILL file 17/17), 1d759c8b (pinned pidfd handles for orphan termination; SIGKILL file 13/13), 4fd4e090 (resume-identity repair splitting resumeGenerationKey and safeResumeInferenceKey; adapter package 259 passed, E2E 397, unit 3,827 passed / 2 failed).

Reviewed code receipt — exact code head eb4b1a802f241f21f78aeec31e54af15130eea11

Tree: 364dad8250b7ebf343eecc1b1ac8f4fd4158b196. Main/merge base: d6321979e44245e73a2a7ba3c4a913ddff149789. The reviewed code commit adds only the reviewed sibling-scenario fixture repair; it does not implement production cancellation authority. The fixture uses the existing test-only SQLite committed-cancellation coordinator, with its binding derived from retained admission and canonical execution/attempt records. Reviewed-tree results: the concurrent-siblings test 1 passed (59 assertions); bun run test:e2e 396 passed, 0 failed; the missing committed-authority refusal test passed. A prior head ran bun run test:unit (3,783 passed, 11 skipped, 0 failed; 83.42% lines / 85.21% functions) and bun run test:smoke (521 passed, 2 skipped). Those prior-head results are not relabeled as reruns at later heads. The Hosted shutdown repair at 7f22f15c has 18 lifecycle tests / 147 assertions and 45 scoped Hosted tests / 211 assertions; they are controlled-port lifecycle proofs, not live PostgreSQL/Restate recovery.

Remaining production acceptance gaps

The authoritative acceptance map and architecture partially_verified assessments retain these gaps. #1025/#942 remain open. Recorded checks at reviewed code head eb4b1a8: 21 contexts, 2 successful policy/draft checks and 19 skipped validations. Skips are not passing CI, and local results do not establish merge readiness.

Prior periodic-scan test receipt — exact head ae29515e8b0fed46eaaa0dc435b71b217eac7bd8 (historical)

Parent: 64bfc2ae5c045de559c9d3e8ef6261e541c42d66; tree: 2f98adfff02e3e80ba7f8f61e544b186c03d0de6. This commit adds only node-composition-lifecycle.test.mjs coverage; no source implementation changed. The test holds the periodic scan at a promise barrier and verifies close waits, concurrent/repeated closes share completion, and no scan/journal access occurs after completion. It proves this composition teardown ordering with a controlled scan, not production authority, runtime task drain, provider cancellation, Hosted replay or global shutdown guarantees. At that tree: lifecycle file 4 passed (21 assertions), related eight-file lead suite 84 passed, scoped Oxfmt/Oxlint and pre-commit passed.

Reviewed architecture repair receipt — exact head 64bfc2ae5c045de559c9d3e8ef6261e541c42d66

Code qualification head: cdd534caa1054fe65533b7070c42f1063395088d; main and merge base: d6321979e44245e73a2a7ba3c4a913ddff149789. That reviewed commit contains only the two-file architecture documentation repair (complete patch SHA-256 6278153719f8880901884c2ecc8572c4a241a7e14038cb9d5be7424b510da385): it records the exact Hosted composition digest and regenerates one whitespace-only Markdown row. At cdd534c, 295 focused tests passed across adapter journal/claim/recovery/cancellation, lead lifecycle/fencing, profile wake, Hosted reconciliation wiring, Local crash/restore, fenced rollback, Pi SIGKILL restart and Hosted boundary suites. These tests qualify the original code head and were not rerun on the documentation-only repair.

Hosted wake, lifecycle and production proof boundaries

Current code has an opt-in bindRetainedProfileWorkflowWake binding in HostedServerControlPlaneComposition, used only with caller-provided placement and guards. Fresh wiring tests cover binding, startup-failure cleanup, failed scheduler-drain cleanup and draining an accepted unstarted reconciliation before clearing its binding. They use injected guards and fixture resources, not live PostgreSQL + Restate active-attempt SIGKILL/replay. Original-product-actor/current-grant, trusted-residency and independently-current-topology sources remain unqualified. The binder admits retained zero-attempt wakes only. Revalidation does not make separate authority stores and dispatcher effects atomic.

The Pi restart proof uses the real production startup factory, disposable SQLite, SIGKILL and loopback requests: it adopts the same retained handle/attempt/execution without resend. Safe continuation relies on test-only exact-key no-send evidence; production reconciliation evidence remains unqualified. Default committed-cancellation owner remains absent and fails closed.

Prior merged-tree validation receipt — exact head 9cd9bd4852483027b2310a6303c99b870afc7ce9 (2026-10-12; historical)

The full bun run test:integration run on that published two-parent merge tree completed with 316 passed, 0 skipped, 0 failed against runner-owned disposable PostgreSQL, which the runner removed afterwards. That head contains the channel-fencing test. Qualification limits: the Cloud remote drill seeded the approval response and scripted the node/cancellation waiter; native permission origination, active cancellation confirmation, usage settlement and live provider execution remain unverified. This is a recorded receipt, not a result for the current head, and I could not re-run it here.

Published feature-head validation receipt — exact head 7369e2fbf233fdf18f54e75f02530be15e6a1cb2 (2026-10-12)

Recorded locally on that head before the current-main merge: format:check passed (1,791 files); lint passed; type-check passed; bun run test build 45/45, unit 3,660 pass / 11 skip, E2E 347 pass, smoke 501 pass / 2 skip; database integration 66 pass; test:integration 299 pass / 3 skip (the three skips were Hosted Server graph over PostgreSQL/Restate cases, unverified and not counted). These counts are historical for that exact head.

Changed-test inventory review (66 PR files, historical)

The 33 active changed .test.mjs modules were assigned to lanes (16 unit, 4 integration, 7 E2E, 6 smoke); all 13 changed fixture/helper files had a consumer; no active changed test used .only or an unconditional .skip. This was an inventory check, not assertion-for-assertion equivalence. The self-hosted simple SIGKILL test is the legacy LangGraph composition with a manual orphan reap; it does not prove Pi Durable orphan adoption.

Evidence carried forward from the prior receipts

  • Local composition: crash/restart recovery, fencing of the crashed owner, drain of a scheduled reconciliation pass at close, portable backup refusal, and total-loss restore into a fresh composition.
  • Self-hosted simple (legacy hosted-simple, pinned Restate 1.7.13): paused-approval close/reopen, filesystem checkpoint restore, portable restore, and SIGKILL of the composition while its Restate child runs, with a manual orphan reap.
  • Self-hosted server portable backup and restore into a freshly provisioned PostgreSQL database.
  • Channel-generation fencing is not carried forward as current evidence; see the acceptance map and the historical 9cd9bd48 receipt above.

Not proven (owners in the map's gap list)

Open Pi items, unchanged: product revocation that reaches admission as evidence drift fails closed and persists no marker, and whether it should persist is a pending policy decision. Child-continuation denials are no longer persisted because message matching was removed; per-site classification is the follow-up.

Current remote state: Draft PR #1048; auto-merge remains off. The current head and its qualification are stated above.

🤖 Generated with Claude Code

https://claude.ai/code/session_01736NpDk6FAncqnfJiSCvUt

Executable evidence for M17.02.2 (#1025), proof-only — no source changes.

- tests/profile-recovery-crash-restore.test.mjs: crash/restart through the
  real LocalControlPlaneComposition (lease abandonment, fencing, single
  recovery at attempt 2, terminal outcomes never reclaimed), portable
  backup/restore with active-work and digest fail-closed paths, physical
  snapshot total-loss restore, and the hosted/self-hosted fail-closed
  binding matrix (no silent Hosted→local fallback). The hosted-server
  Postgres total-loss restore is integration-gated (RUN_DATABASE_INTEGRATION).
- tests/profile-recovery-fenced-rollback.test.mjs: one attempt owner via
  WorkflowJobStore lease tokens, stale channel-generation rejection and
  heartbeat fencing, evaluateRuntimeEligibility reconnect-grant
  revalidation, exact rollback input binding with typed parent mismatch,
  interrupted/repeated operations with stored-command replay, and the
  interrupted local→hosted-server import rollback through applyPortableImport.
- tests/profile-qualification.test.mjs: the qualification facts — profile
  mapping, exact wake dispatcher binding, topology/authority guard
  fail-closed instances, CLOUD_PROFILE_UNQUALIFIED, no implicit fallback.
- docs/profile-recovery-acceptance-map.md: clause→test→result map with the
  per-profile supported/unproven matrix and explicit remainders.

Registered additively in the smoke lane (tests/repository.test.mjs and
scripts/run-bun-test-group.mjs). Ordinary sessions stay Pi-independent; no
Pi-owned surfaces, recovery engines, or cross-harness transplants.
@0xPlayerOne 0xPlayerOne changed the title feat: profile-recovery-rollback-1025 test(profiles): prove profile recovery and fenced rollback evidence Oct 9, 2026
…1025)

- Register the self-hosted-server PostgreSQL restore as an integration test
  (tests/profile-recovery-postgres-restore.integration.test.mjs) in the
  unsharded integration runner, the shard-3 root group, and the repository
  integration inventory. Disposal of every provisioned database runs after
  partial setup or body failure, and disposal failures surface.
- Dispose every LocalControlPlaneComposition before its directory is removed,
  and surface failures from every release step.
- Add a local graceful-drain proof: close() waits for an in-flight scheduled
  reconciliation pass before storage closes.
- Route the local backup/restore proof through the composition's persistence.
- Consolidate the adapter-level rollback fence and managed-Pi rebind proofs
  from PR #1046 (tests/profile-recovery-rebind-fencing.test.mjs). Its
  restore-binding test duplicates packages/profile-adapters and is not carried.
- Remove fixture-only duplicates already pinned by package tests:
  tests/profile-qualification.test.mjs, lease-fencing, cancellation,
  import-rollback, topology, and hosted fail-closed cases.
- Correct docs/profile-recovery-acceptance-map.md to the exact tests and
  results; drain and upgrade remain partial or unproven.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
The drain proof held a reconciliation pass open and released it only after its
assertions. A failing assertion left the pass pending and the close unsettled.
Release the gate in finally and settle the drain before the assertions after
it run. Verified: a deliberately failing assertion now fails the test in about
2s instead of hanging.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
0xPlayerOne and others added 5 commits October 9, 2026 20:17
The Validation integration lane runs `turbo run test:integration`, whose
tasks depend only on their dependencies' builds (^build). The profile
recovery restore file runs as a root-level bun test afterwards and imports
@control-plane/profile-portability through its package exports (dist/),
but nothing builds that package in this lane, so the import fails with
"Cannot find module" and the lane goes red.

Build the consumed package explicitly in the unsharded runner before the
root-level files. The remote lifecycle expectation rises from three to
four bun invocations to account for the build, and a new test pins that
the build precedes the root-level file.
The J1 evidence poller parses process-evidence.jsonl while live child
processes append to it. The CI failure for run 37985178251 reports
JSON.parse rejecting an unterminated fragment at column 11, which fits a
poll that reads a row before its newline is written. Only
newline-terminated rows are complete, so parse those and leave any
fragment for the next poll, the same way the stdout reader already
buffers lines.

This is a hardening change. The partial-row mechanism was not reproduced
locally; the J1 concurrent-recovery flake that does reproduce is a
different failure mode and is not addressed by this commit.
The J1 proof readers parsed process-evidence.jsonl while killed or live
children were still appending, so a partial final row failed the poll with
"Unterminated string". Both readers now share one parser
(tests/process-evidence.fixture.mjs) that consumes only newline-terminated
rows; a malformed complete row still throws.

The child descriptor was truncated in place before it was written, so a
recovery that started during a kill could read an empty file and fail with
"Unexpected end of JSON input". It is now written to a temporary file and
renamed over the descriptor.

Adds a regression that writes a partial tail, completes it, and then rejects
a malformed complete row.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Recovery claimed an interrupted record with an epoch-only compare-and-set. A
recovery contender could therefore take the epoch from a live owner, and a
concurrent write during the probe surfaced as a state conflict that was then
recorded as authority revocation. Two parallel recoveries of one child could
produce PI_PROCESS_UNEXPECTED_RECOVERY_STATE or a blocked recovery, and a run
that could not start could leave a record running with no owner.

- Recovery claims go through the journal's owner-liveness check. A live owner
  in this or another process is observed (status returned), never claimed,
  probed, or resumed; an unknown record waits briefly for its owner's decision.
- A stale claim resamples the record. A concurrent epoch change while a claim
  is held is a stale result, not a revocation.
- Authority is checked only under a held claim. A denial there is authoritative
  and is persisted as PI_RECOVERY_AUTHORITY_BLOCKED; the claim is undone so the
  retained record is unchanged. Any other failure is PI_RECOVERY_UNCLASSIFIED,
  fenced for this start and retried at the next one, with no durable revocation.
- A claim that cannot be driven (lease held elsewhere, or a failure before the
  drive) leaves the record unknown with a reason code, never ownerless and
  running.
- Shutdown undoes recovery claims it has not decided, restoring the epoch.

Regressions cover a concurrent epoch change during probing, a Pi store lease
held elsewhere, a contended record that is not classified as revoked, a live
owner that is not stolen, and an unclassified failure that is recoverable.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
@0xPlayerOne
0xPlayerOne marked this pull request as draft October 10, 2026 03:47
0xPlayerOne and others added 2 commits October 10, 2026 00:17
A declared authority denial now writes its recoveryBlocked marker and advances the epoch in the same transaction that releases the recovery claim, so composition no longer writes after the claim ends. A claim superseded while its check was pending writes no marker and leaves the newer epoch alone. Typed unavailable and untyped transport failures are no longer denials: they undo the claim, persist nothing, and fence the start as PI_RECOVERY_UNAVAILABLE or PI_RECOVERY_UNCLASSIFIED.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…ansient results

Add competing-recovery-owners evidence through the real composition. An old recovery owner loses its claim to a competing cancel, to another live process, or to a run-path inference authorization, then returns a declared denial, a typed unavailable failure, an untyped transport failure, or a successful probe. Each old result leaves the current owner's epoch, owner fields, record, and receipts unchanged and is reported in memory only.

Restarts with transient probe failures persist no revocation marker across repeated attempts; a healthy restart resolves the competing cancellation. An orphaned settlement replayed by the current owner yields one receipt and one ledger entry, and a conflicting replay fails closed. The shared race fixture moves to recovery-races.fixture.mjs.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
0xPlayerOne added a commit that referenced this pull request Oct 10, 2026
…roduction composition

The target-bound observation contract (observedTarget: server-owned session +
plan task) was only proven by the isolated DurablePiDurableLeadService test
(pi-durable-lead-target.test.mjs), never through the REAL production
composition that installs the adapter. Adds the missing focused integration
assertion: after the composed lead service dispatches, observedTarget is
populated and its sessionId equals the adapter's runtimeSessionId (the actual
external session), proving the composition invokes the existing adapter for
target-bound identity rather than only an isolated policy mock.

No canonical authorization or attempt-fencing change; no duplicate of the
#1047/#1048 work. Purely additive assertion in the owned composition test.

Validation: production-child-composition 1/0; control-api 482/0;
runtime-sdk 101/0; policy 39/0; pi-durable-adapter 189/0; build exit 0.

Refs #937, #935
0xPlayerOne and others added 11 commits October 10, 2026 02:22
…ls persist

Canonical authority collapsed every port, transport, and parse failure into PI_CANONICAL_AUTHORITY_REJECTED, and recovery then persisted that code as a revocation. Only explicit policy decisions are denials now: canonical reject() sites, adapter expiry, and scope checks record an outcome in a module-private registry. Every other failure is unavailable or unclassified. The public message is unchanged; only the internal outcome differs.

Caller-controlled strings no longer establish a denial. A port or probe that throws a denial code persists nothing, and the adapter's denial-code matching is removed.

Child-continuation denials were matched by message, so they are no longer persisted. They fail closed and need per-site classification as a follow-up.

Regressions run through the production lead composition with real canonical authority and SQLite stores: transport, typed-unavailable, and forged-string outages during recovery fail closed and resume on a healthy startup; an explicit canonical lifecycle denial persists the marker under the claim; an admission outage fails closed and a healthy retry admits the intent. Expected-claim fencing tests keep their assertions and create denials through the authority.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
… reconnects

Replace the fake-transaction acceptance evidence for channel-generation fencing with a real PostgreSQL proof. Two owners compete for generation 1 over independent physical sessions, the loser advances the channel to generation 2, and the dropped winner reconnects over new sessions. Its heartbeat, release, claim, and inventory effect are refused, and the generation-2 inventory effect runs exactly once. Effects run through PostgresRuntimeInventoryUnitOfWork, and sessions are terminated server-side between steps.

The profile fenced-rollback smoke file drops its fake-seam block, and the acceptance map cites the PostgreSQL proof and states that a live gateway handshake remains unproven. The reviewed shard inventory gains this one foundation case: 66 cases, with shard 1 at 38 of its 45 allowed. Fence-removal mutants fail the proof.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…the composition

Drive the hosted-simple composition with the pinned @restatedev/restate-server.
A graph approval paused in Restate is closed and reopened, and separately
restored from a filesystem checkpoint. The reopened composition keeps the
execution identity, attempt, and plan record; refuses a superseded execution
version; starts no second effect from a duplicate run submission; and resumes
the approval exactly once.

The portable backup refuses active work, exports from the composition's SQLite
persistence, and restores into a fresh composition after total loss.

Registered once in run-integration-tests, integration-shards, and the
repository integration inventory. The completed managed-Pi client moves to a
shared fixture that the standalone suite imports.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
releaseProcess matched any owner recorded by this pid, so two adapters in one
process could let a late cleanup from an earlier claim clear a later owner.
claimProcess now returns a token (command epoch, owner pid, owner epoch, claim
id). Every release and abandon requires the token it holds, and the claim id
keeps a reissued epoch from matching an earlier claim. Detail writes cannot
erase or replay stored owner fields. A run ends its claim exactly once: a failed
engine close still releases the claim, and the scheduler no longer issues a
second cleanup.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…n and cancel

Observation and cancel under a v2 fence now run on the retained authority instead
of failing closed. A ready marker must match the fence on authority revision,
scope, allowed principals and canonical actor, and cancel is limited to the
original actor. The receipt is verified against the retained admission, request
and handle, and the admission digest is re-derived with the canonical function,
so the withheld prompt is never re-read. Current authority is rechecked after
each awaited effect. Prepare and dispatch stay refused under a fence.

Legacy markers that lack a canonical actor pin are refused. Admissions without an
explicit scope now retain the canonical actor they were given.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…live in-flight run

- lead-fence-live-harness.mjs: shared fixture over the production lead composition, real SQLite,
  the real Pi adapter, and a scripted HTTP model whose turn is held open until the test releases it
  or the client aborts. Receipts and admission digests are read and written as they are; no journal
  state is rewritten.
- lead-fence-service.test.mjs: fenced status, progress, and original-actor cancel against the
  in-flight run, with zero extra starts, inferences, or reservations; changed pins, outsider and
  second-principal denials; the configured preparation path; receipt tamper refusals; recheck after
  awaited effects.
- lead-fence-late-authority.test.mjs: deterministic late-authority cases (fence revision, execution
  deadline, retained expiry, scoped execution-scope read) and the superseded-attempt qualification.
  Current behavior that is a gap is asserted and named as a gap.

No production code changed.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…d Restate child

Adds a test-only proof: the supported LocalControlPlaneComposition (profile hosted-simple, durable execution restate) runs in a child process, which is SIGKILLed while its pinned Restate launcher and native server run. The parent records both identities before the kill, verifies they are orphaned and alive, reaps exactly those identities, and starts a second composition on the same disposable data. The paused approval keeps its execution, attempt, and version; a duplicate run submission starts no second effect; one approval resumes the workflow; prepare runs once, finalize once, and one result artifact is written across both incarnations. A second test shows reaping never signals a reused pid.

Production code is unchanged. The helper and proof are separate files; the shard, runner, and inventory registrations list the new integration file.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…wn errors, and cleanup

Protocol: stdout records carry an explicit prefix. Non-protocol JSON, bare protocol-shaped lines, and malformed records are ignored and never throw from the stdout handler.

Spawn: spawn errors resolve the exit promise and reject protocol waits with PROTOCOL_CHILD_SPAWN_FAILED instead of hanging.

Bounded waits: every exit wait is bounded. Cleanup SIGKILLs and awaits each spawned composition incarnation and the bystander before removing the data directory.

Scope: process control reads only recorded identities (ps -p <pid>) and direct children of the recorded launcher (pgrep -P). The full process-table listing is removed.

Paths: the test file's repositoryRoot now uses a single parent step from tests/.

Labels: this proof uses the legacy LangGraph test composition, not Pi Durable host wiring. The parent reaps the orphaned Restate processes manually before restart. It does not adopt orphans.

Production code is unchanged.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…t confirm exits

Cleanup now attempts every spawned composition and every recorded Restate identity, even after an earlier failure. Each unconfirmed child or identity is reported with its pid and start time.

reapOwned no longer splices the ledger up front. A confirmed identity leaves it; a failed one stays with its reason, and one retry covers only the identities still recorded.

The work directory is removed only when nothing remains unconfirmed. Otherwise it and the recorded identities are kept, and the error names the directory.

A composition whose start or failure record never arrived is reported as RESTATE_OWNERSHIP_UNRECORDED, since its Restate processes were never recorded.

A focused test drives releaseOwnership with a child that never exits and one that does: both are attempted, the error is aggregated, and the directory remains. A live identity that survives SIGKILL cannot be produced safely in a test, so the retention branch is covered by review only.

This proof remains the legacy LangGraph test composition with a manual orphan reap before restart. It is not Pi Durable host wiring and does not adopt orphans. Production code is unchanged.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
… proof

The map said self-hosted simple SIGKILL recovery was unproven. The
SIGKILL proof (tests/profile-recovery-self-hosted-simple-sigkill
.integration.test.mjs) now exists. It runs the legacy hosted-simple
composition and reaps the orphaned Restate child manually before
restart, so product startup does not adopt orphans.

- Add the SIGKILL test to the ownership table, with its legacy scope.
- Update the clause map, per-profile matrix, and gaps 3, 4, 7 to match.
- Add gap 8: Pi Durable startup recovery and orphan adoption are
  unproven at composition level. Name the startup entry points and the
  fixture that would close it. Adapter-level SIGKILL proofs exist, but
  no test kills the lead composition and starts a fresh one.
- Give every remaining gap an existing owner issue or say that none
  is open.

Docs only. No source or test changes.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
* chore(deps): update dependency @opentelemetry/sdk-metrics to v3

* chore(deps): keep @opentelemetry/sdk-metrics on the 2.x line

The Renovate major to @opentelemetry/sdk-metrics 3.0.0 cannot be taken under
this repository's API policy. sdk-metrics 3.0.0 depends on
@opentelemetry/core 3.0.0 and @opentelemetry/resources 3.0.0, and all three
declare a hard peer requirement of @opentelemetry/api ">=1.10.0 <1.11.0".

The repository pins @opentelemetry/api at exactly 1.9.1 in packages/telemetry,
apps/control-api and apps/workflow-worker, and packages/telemetry declares the
optional peer "@opentelemetry/api": "^1.9.0". The graph resolved by this
branch carried a single @opentelemetry/api 1.9.1 and no nested 1.10, so those
three peer requirements were unsatisfied.

Moving the api to 1.10 would break the same policy elsewhere:
@sentry/node 11.4.0 depends on api "^1.9.1", @sentry/opentelemetry 11.4.0
peers on "^1.9.0", and vitest 5.0.5 peers on "^1.9.0". Moving the api is a
repository-wide upgrade rather than a dependency update, and it would also
require widening this package's own declared peer range.

2.12.0 is the newest release whose peer requirement (">=1.9.0 <1.10.0") the
pinned api 1.9.1 satisfies, so the dependency stays there and the lockfile
returns to the 2.12.0 resolution. The lockfile is otherwise unchanged from
main: `bun install --frozen-lockfile` reports no changes against it, so the
install churn the update carried is not kept.

Verified with the existing dependencies: packages/telemetry test 42 pass / 0
fail, and build, typecheck and lint clean.

* chore(deps): take @opentelemetry/sdk-metrics 3.0.0 with @opentelemetry/api 1.10.0

The Renovate major to @opentelemetry/sdk-metrics 3.0.0 is taken together with
the API move it requires. sdk-metrics 3.0.0 depends on @opentelemetry/core
3.0.0 and @opentelemetry/resources 3.0.0, and all three declare a hard peer
requirement of @opentelemetry/api ">=1.10.0 <1.11.0", which the pinned api
1.9.1 did not satisfy.

The api moves to 1.10.0 in the three manifests that pin it - packages/telemetry,
apps/control-api and apps/workflow-worker - because the graph resolves one api
copy for the whole workspace. Nothing else in the tree blocks that:
@sentry/node 11.4.0 and @sentry/server-utils 11.4.0 depend on api "^1.9.1",
@sentry/opentelemetry 11.4.0 and vitest 5.0.5 peer on "^1.9.0", and
drizzle-orm 0.45.3 peers on "^1.4.1"; every one of those ranges admits
1.10.0. This package's own declared peer range stays "^1.9.0", which also
admits 1.10.0, so no peer policy changes.

The lockfile is regenerated from the published packages: api 1.10.0,
sdk-metrics 3.0.0, core 3.0.0 and resources 3.0.0, and exactly four of the
598 resolution entries change. No override, resolution or peer rule is added.

Checked with the upgraded graph: packages/telemetry test 42 pass / 0 fail with
build, typecheck and lint clean; apps/control-api and apps/workflow-worker
build and typecheck clean, with 700 and 158 unit tests passing; the repository
lint and format checks pass; and a fresh `bun install --frozen-lockfile` leaves
the lockfile byte-identical and resolves a single api version, 1.10.0.
…tory (#1208)

* fix(ci): qualify the task cache from the real output inventory

The lane proved a cache hit by grepping the runner log for '45/45 cache
hit': a hardcoded task count matched against a human-facing string, so a
changed build graph could keep passing or start failing for the wrong
reason.

The lane now reads the task runner's own machine-readable run summary and
compares it with the build graph, so the expected task set, the expected
commands and the expected outputs all come from the graph itself. It also
compares the build outputs of a clean build with the outputs of the cached
replay, byte for byte, and it checks that the cache holds one entry per
cached task the graph declares.

A malformed summary, a missing or unexpected task, a command that does not
match the graph and an output inventory that differs from the clean build
all fail closed. A changed source, a changed configuration input and a
changed toolchain each have a fixture.

* fix(ci): make the task cache qualification fail on what it compares

Four defects in the qualification, all found in review:

The compare command reported equal:false for differing artifacts but the
command line only failed on a failure list or ok:false, so an inequality
passed. It now reports the difference as a failure and exits non-zero, and
subprocess tests cover a changed, a missing and an extra output.

The expectation evaluation returned success immediately when no cache
pattern was given, so the semantic checks were skipped: a run that did not
execute the expected tasks, that executed tasks outside the graph, that
ran a command the graph does not declare, that failed a task or that exited
non-zero passed. Those checks now hold for every run, and the command line
without a cache pattern is tested.

The lane compared the outputs of a build that could inherit files left on
disk with the outputs of a clean build, and never asserted that the
inventory covered anything. The declared outputs are now removed before
every build the lane compares, only the outputs the build graph declares
are removed, and an empty inventory or an empty output coverage fails.

The source probe left an entry for the changed source, so the following
configuration probe could not attribute its miss to the configuration. The
source baseline is reseeded between the two mutations, and the
configuration probe now has to name the configuration input that changed
instead of accepting any invalidation.

* test(ci): register the task cache qualification test in the smoke lane

The shared test inventory and sharding runners are owned outside this
lane. The root-reviewed artifact from that owner, library file
libfile_6547c0e2e4ac819191e8ed8a579b004e, SHA-256
b7119105f4ba7ea5d92fdf21b2f4791df35de1eb33e4103319e6d01d99d237c7, declares
base ae372d4 and adds exactly two
registrations:

- scripts/run-bun-test-group.mjs claims tests/task-cache-qualification.test.mjs
  in the smoke lane.
- tests/repository.test.mjs lists the same path in its expected discovery
  inventory.

Without the registration the shared inventory guard fails closed with
"Test lane inventory drift: unowned [tests/task-cache-qualification.test.mjs]",
which failed the smoke lane and the two aggregate gates.

The artifact was applied with git apply --index after its checksum, its
declared base and both file preimages were verified byte for byte. No
guard, assertion, threshold or sharding behaviour changed, and no other
file was touched.
…eneration

The native cancellation boundary states that matching installation evidence
never proves complete writer coverage. This qualification proves the coverage
is complete and proves two properties independently: no writer that accepts a
target or an epoch accepts a rewound one, and the restore generation is bound
into the request digest so a restore cannot re-point it and replay the request.

The writers are enumerated from the source, so a writer that starts accepting a
target or an epoch without a proof here fails the file.
…#1048 acceptance ledger

The writer-coverage qualification closes the restore-generation and all-writer
sub-gaps that the native cancellation boundary states it never proves. The
ledger records what the integrated source proves, what remains unproved, and
which gate proves what, including the native zero-effect, SDK adoption,
installed cross-repo/profile acceptance and production activation holds.
CP #678: a deployment can now map a model id to the harness that must serve
it, so "deepseek harness for deepseek-flash tasks, ZCode for GLM models"
becomes a deployment policy instead of a single deployment pin.

The carrier is the execution read model, not the execution plan: the
execution carries the accepted model (ExecutionSchema.modelId, nullable in
the row so historical executions replay exactly), and the execution plan
and its content digest are untouched. The public acceptance request takes
the optional accepted model, the command inbox records it, and the Postgres
and SQLite projections carry it.

The map lives beside the deployment pin (ManagedCloudRuntimeConfiguration.
harnessByModel, CONTROL_PLANE_HARNESS_BY_MODEL) with strict model-id and
harness-id validation; an absent map leaves routing exactly as it is, and
a present map is a policy rather than a fallback.

At attempt time the router resolves the mapped harness from the execution's
model and passes it through the same pin path, so a mapped model reaches
only a runtime exposing the mapped harness, the mapped harness is bound
into the routing digest, and the reason code HARNESS_MAPPED records that
the map decided it. With a map configured an execution without a model
denies with HARNESS_MAP_MODEL_ABSENT, a model the map does not name denies
with HARNESS_MAP_MODEL_UNMAPPED, and a deployment pin that names another
harness denies with HARNESS_MAP_CONFLICTS_WITH_PIN: the explicit harness
choice and the explicit model stay independent and nothing is silently
substituted. The decision layer applies the same map to an explicit
session or workspace harness pin.

The map is wired in the real managed cloud worker composition, not in a
helper. The hosted control-plane composition and the execution acceptance
service that forwards the accepted model are owned by another lane, so
those two seams are handed off rather than co-owned.
The lane ran 359 pass and 12 fail across 40 files. Every failure is in the
self-hosted-simple SIGKILL proof, which fails closed on macOS because the
pinned-process fixture needs a Linux pidfd. That file and its fixture are
byte-identical to the published #1048 head, and the CI runs the lane on
ubuntu-latest. The ledger now states the exact count and the limit.
…kups

Two defects in the per-model harness map, both in the configuration and
mapping path this lane owns.

The map loader carried its own id patterns, so the configuration could
name an id the execution contract would refuse and the entry could never
be reached. It now validates the model ids and the harness ids with the
canonical ModelIdSchema and HarnessIdSchema, so the configuration accepts
exactly what the contract accepts and the two can no longer drift.

The mapping rule read the model id straight off the map, so a model id
such as `constructor` or `toString` resolved an inherited object property
instead of being unmapped. The lookup is now an own-property lookup and
the configuration builds a null-prototype map, so an inherited name is
either an ordinary configured key or unmapped.

The accepted read-model carrier, the absent-map compatibility, the
no-fallback denial, the provider/model independence, the explicit harness
conflict rejection, the pinned and exposing-runtime checks and the
unchanged execution plan digest are all unchanged.
…generation gap

The previous qualification overstated what it proved. Three corrections.

A digest over a supplied restoreGeneration proves tamper consistency only. The
old test changed the generation while retaining its old digest, which missed
the rollback that restores the generation and recomputes a matching digest. The
qualification now proves that the pure contracts accept that rollback, so the
limit is recorded rather than papered over. No independent generation authority
exists in the current architecture, and the full-writer restore-generation
acceptance stays open.

The old registry covered only the two cancellation modules and excluded the
effect gate, journal, lease, upgrade manifest and resume permit writers, so it
could not substantiate complete coverage. The writers are now enumerated from
the source and classified by the authority each one actually holds. A rewound
epoch is refused where the architecture grants one, and the five writers with
no independent generation authority are named.

The vacuous safeParse not.toThrow assertion is replaced with assertions on
safeParse().success and on the intended binding properties.
… lane failures

The upgrade manifest is named in the writer universe, so it now carries a real
restore-state test: it detects a store that was rolled back to different bytes
by byte identity. That is byte identity, not a generation, and the gap stays
open.

The acceptance ledger now records the aggregate unit lane exactly: the Bun 1.4.3
panic and 7 test failures, and that the same failures and the same panic
reproduce with the writer-coverage file held aside, so they are pre-existing on
the integrated tree.
…branch

The CP #1210 contract is consumed as delivered by its own branch: the modelId
carrier on the acceptance request and the acceptExecution command, the
execution read-model projection, the per-model harness map policy, the
deployment configuration, and the runtime attempt router. No W2-owned path is
edited here; the merge brings their accepted contract forward unchanged.

The CP #1048 history and patch are preserved: this is a fast-forward for the
published #1048 branch, and no commit is rewritten.
…router

The CP #1210 contract puts the accepted model on the execution read model and
maps it to a harness through the deployment's per-model map. This wires the
production seams that carry it there.

The control API acceptance service forwards the accepted request payload's
modelId into the acceptExecution command, so the execution read model records
the model the caller accepted. The hosted control plane composition passes the
per-model map to the real worker router, and its index resolves the map from
the deployment environment with the same strict parsing the contract uses: an
absent variable leaves routing unchanged, and a present map is a policy that
denies an execution it does not name.

The new end-to-end qualification drives the real chain over HTTP and the real
hosted router: HTTP acceptance, the persisted execution read model, and the
router carrying the accepted model to its mapped harness. It covers the
configured map, an unmapped model, an execution with no model, a pin that
conflicts with the map, the no-map behavior, and the unchanged execution plan
digest.

The CP #1048 restore-generation authority gap stays open and is not closed by
this work.
… inventory

The hosted model-forwarding integration test was discovered by the integration
file inventory but had no local shard owner, so the disposable-local PostgreSQL
shards did not run it. It is now registered on shard 3, next to the other
hosted-control-plane integration files, and every existing entry is preserved.

This is the local sharded registration. The hosted-control-plane package's own
integration glob already matches the file, and that is a different
registration: the package script runs the package's files directly, while the
local sharded lane runs this explicit inventory. The inventory is what gives
the local lane its coverage, so the regression asserts the shard owner, the
arguments the local runner uses, and the package glob separately.

The inventory regression is negative-proven: removing the registration fails
both the file-ownership check and the new registration check.
…ation inventory

The Code Foundry group-discovery expectation list did not name the hosted
model-forwarding integration test, so the exact-list assertion failed at the
owner head even though the file was discovered correctly. The file is now in
the expected inventory, in its sorted position, and every existing entry is
preserved.

The new focused regression states this file's registrations separately: it is
discovered as an integration test, it appears exactly once in the inventory, it
has exactly one local shard owner, and its package integration command selects
it. The package integration lane and the local sharded lane are distinct
registrations of one file.

Both assertions are negative-proven: removing the expected-inventory entry
fails the exact-list assertion, and removing the shard registration fails the
focused regression.

This branch has not been deployed

No deployments
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