diff --git a/doc/plans/2026-10-10-boat-validation.md b/doc/plans/2026-10-10-boat-validation.md index 3a76a9f9bcf..fce7528dfae 100644 --- a/doc/plans/2026-10-10-boat-validation.md +++ b/doc/plans/2026-10-10-boat-validation.md @@ -38,6 +38,14 @@ Run `ab8c460d` retained the original native and logical identities and immutable A controller-only manifest projection confirms the exact deployed source and package digest, matching Node/lock/sidecar artifact hashes, and presence of all four expected bounded-read/fatal-import features. Therefore this is not explained by a missing deployed patch. The error category still combines several loader fences; the exact rejecting check is **unproved**. The local corrected-package pass does not establish production-package success. Narrow closed reason diagnostics are under investigation, with no guard relaxation or saved-state reset. [Failed task](assets/2026-10-10-boat/staging27-claude-post-failed.png), [complete source-bound receipt](assets/2026-10-10-boat/evidence/staging27-live-evidence.json). +## Closed rejection diagnostics and staging28 candidate (2026-10-11 11:02 UTC) + +Core `8f62eef8f13e199f7a98d8a9ec27d617385e6fde` preserves the existing module guards and broad `agent_startup_unverified_module` classification while adding one fixed, allowlisted `moduleFence` reason. No module paths, specifiers, arguments or raw errors are exposed. Rejection conditions, bounded rereads, authority and deadlines remain unchanged. The regression matrix had 29 failing assertions before the change; afterward 140 tests passed with six existing platform skips, all 14 Rust transport tests passed, and typecheck/build/format checks plus two independent reviews passed. [Verification receipt](assets/2026-10-10-boat/evidence/loader-fence-verification.json). + +Production pack `152fcacb` and locally passing `f6fbd13c` have identical sidecar and production-lock bytes, but Node versions differ: staging24.21.0 versus local24.18.1. An isolated fixture using the **exact production Node executable hash** passed stable and ctime-only reads and rejected a moved descriptor without executing it. This does not reproduce or explain the staging failure. [Offline comparison](assets/2026-10-10-boat/evidence/loader-node2421-proof.json). + +Deployment28 was dispatched for compatible staging candidate `70fb0988c0aa760f9c84818aaf3fabbc339854b7`, request `d28faf91-db3f-4a80-a28a-5a0a1c45ac2e`, through the official workflow. It is diagnostic-only and not yet verified serving. Existing failed sessions and immutable packages remain preserved. A newly selected matched runner/package is required to obtain the new fence reason; no live acceptance pass is inferred from this instrumentation. + ## Local48 and deployment25 follow-up (2026-10-11 08:57 UTC) - **Local cold and warm Claude passed.** Cold run `2651f86d` succeeded at 08:40:21.872 after uploading and verifying the full 1166MiB pack. Warm run `1983527f` succeeded at 08:42:28.390 with the same native session, logical runner, Claude thread and physical owner/boot/launch identity. Both original proof hashes were unchanged. The owner remained warm beyond 130 seconds after the turn, retired after its configured 08:47:28 deadline, and Boat finished archive at 08:47:49.418. [Cold response](assets/2026-10-10-boat/local48-claude-cold.png), [warm response](assets/2026-10-10-boat/local48-claude-warm.png). diff --git a/doc/plans/assets/2026-10-10-boat/evidence/loader-fence-verification.json b/doc/plans/assets/2026-10-10-boat/evidence/loader-fence-verification.json new file mode 100644 index 00000000000..75722eab2e2 --- /dev/null +++ b/doc/plans/assets/2026-10-10-boat/evidence/loader-fence-verification.json @@ -0,0 +1,30 @@ +{ + "sourceRevision": "8f62eef8f13e199f7a98d8a9ec27d617385e6fde", + "capturedAt": "2026-10-11T11:00:58.549683+00:00", + "scope": "Closed module-fence diagnostics only; existing rejection conditions and authority unchanged.", + "red": { + "failedAssertions": 29, + "passedAssertions": 4 + }, + "green": { + "testsPassed": 140, + "existingPlatformSkips": 6, + "rustTransportTestsPassed": 14, + "typecheck": "passed", + "typescriptAndVerifiedEntrypointBuild": "passed", + "rustfmt": "passed", + "diffCheck": "passed", + "independentReview": "approved by both reviewers" + }, + "productionComparison": { + "sameSidecarSha256": "sha256:498d9027da6d3da9aeb7377b29b8558ef18b6cd2d082f589bf863a80d1df9039", + "sameProductionLockSha256": "sha256:df5143e56269823c040be51a5e45bd53cadb60fecb50fb09ba2848f23e621b67", + "productionNodeVersion": "24.21.0", + "localPassedNodeVersion": "24.18.1", + "productionNodeSha256": "sha256:7fde7b8afa198da66257f42ee2001d874c7355631e6d1579a5fb5ef1f246df4c", + "exactProductionNodeOfflineFixture": "Stable and ctime-only reads pass; moved descriptor rejects without execution." + }, + "liveCause": "UNPROVED: staging27 rejected an unverified module; old diagnostics cannot identify the exact fence. Node version difference alone did not reproduce the failure.", + "liveStateChanged": false, + "oldImmutablePacksChanged": false +} diff --git a/doc/plans/assets/2026-10-10-boat/evidence/loader-node2421-proof.json b/doc/plans/assets/2026-10-10-boat/evidence/loader-node2421-proof.json new file mode 100644 index 00000000000..995f5b2b2d0 --- /dev/null +++ b/doc/plans/assets/2026-10-10-boat/evidence/loader-node2421-proof.json @@ -0,0 +1,68 @@ +{ + "capturedAt": "2026-10-11T10:58:48.462Z", + "platform": "linux", + "node": "v24.21.0", + "sourceRevision": "8e8999d681b42a19bfee2540c4345193f29f31ca", + "packDigest": "sha256:f6fbd13c71cdaf93060a7c240cbce1c8dfce2aefe5669db27d254b3b95dfb0a0", + "fixtureOnly": true, + "liveGuestAccess": false, + "results": [ + { + "transition": "stable", + "drift": false, + "exitCode": 0, + "signal": null, + "dependencyExecuted": true, + "integrityRejected": false, + "metadataChanged": { + "dev": false, + "ino": false, + "mode": false, + "size": false, + "mtimeNs": false, + "ctimeNs": false + }, + "sameBytes": true, + "sha256": "0ac25ebbcc92d605ac90db175ed44984da2351f3923770605b00a12eaaba0c8a", + "metadataHookObserved": false + }, + { + "transition": "once", + "drift": true, + "exitCode": 0, + "signal": null, + "dependencyExecuted": true, + "integrityRejected": false, + "metadataChanged": { + "dev": false, + "ino": false, + "mode": false, + "size": false, + "mtimeNs": false, + "ctimeNs": true + }, + "sameBytes": true, + "sha256": "0ac25ebbcc92d605ac90db175ed44984da2351f3923770605b00a12eaaba0c8a", + "metadataHookObserved": true + }, + { + "transition": "rename", + "drift": true, + "exitCode": 1, + "signal": null, + "dependencyExecuted": false, + "integrityRejected": false, + "metadataChanged": { + "dev": false, + "ino": false, + "mode": false, + "size": false, + "mtimeNs": false, + "ctimeNs": true + }, + "sameBytes": true, + "sha256": "0ac25ebbcc92d605ac90db175ed44984da2351f3923770605b00a12eaaba0c8a", + "metadataHookObserved": true + } + ] +} diff --git a/doc/plans/assets/2026-10-10-boat/evidence/staging27-live-evidence.json b/doc/plans/assets/2026-10-10-boat/evidence/staging27-live-evidence.json index 14c0b104fd3..20ab2d63705 100644 --- a/doc/plans/assets/2026-10-10-boat/evidence/staging27-live-evidence.json +++ b/doc/plans/assets/2026-10-10-boat/evidence/staging27-live-evidence.json @@ -1,5 +1,5 @@ { - "observedAt": "2026-10-11T10:54:58.172257+00:00", + "observedAt": "2026-10-11T10:59:56.839327+00:00", "source": "2605a03f00bc3d7decc8b8d5549ee06f8d77ae85", "deployment": { "version": 1, @@ -1158,6 +1158,18 @@ "authority_indeterminate", "runner_state_identity_mismatch" ] + }, + "nodeComparison": { + "production": { + "observedAt": "2026-10-11T10:57:15.525Z", + "packDigest": "sha256:152fcacb43ccb019b9be3c0ca058c61a5a7275f46a9d429dc4800489b768a105", + "status": 0, + "version": "v24.21.0" + }, + "localVersion": "v24.18.1", + "sameAcpxSidecarDigest": true, + "sameProductionLockDigest": true, + "causeEstablished": false } }, "resets": false,