Skip to content

🐛 Join Claude backend close and complete startup disposal - #1118

Merged
taras merged 7 commits into
mainfrom
codex/claude-startup-disposal-1086
Nov 5, 2026
Merged

taras merged 7 commits into
mainfrom
codex/claude-startup-disposal-1086

Conversation

@taras

@taras taras commented Nov 4, 2026 •

Copy link
Copy Markdown
Owner

Why

Claude startup disposal can return before its native backend closes (#1086). The repair also needs reproducible packaging without committing a complete Claude package or carrying pristine and patched SDK copies together.

What changes

Before: disposal can return while the backend is closing. The repair's earlier packaging commits a Claude tarball and an encoded copy containing both SDK inputs and output.

After: disposal joins actual backend close and complete opening cleanup. Repository source carries pinned public inputs, readable patches and a deterministic preparation recipe. Each distribution carries one ready-to-run snapshot containing one patched SDK runtime.

How it works

Pinned public adapter source + SDK + readable patches
  -> deps: verify inputs, build in private scratch, verify executable hashes
  -> atomically publish one ignored generated Claude module
  -> source / JSR / npm / canonical compiled graph
  -> verified materialization, one patched SDK, explicit host Claude executable

The adapter source is pinned at 8710ce1cbccf562cb04b4bcc30e053e960aee05f, SDK remains 0.3.238, and isolated compilation uses pinned TypeScript 6.0.3. The 73,312-byte source patch retains the established metadata, materialization, SessionStart and cleanup changes. The small SDK transform validates its pristine input hash and every patch site.

Preparation verifies all 29 executable hashes against the previously reviewed runtime. The runtime archive omits pristine SDK source, declarations, build recipes, the unused original SDK dependency and platform executables. Required adapter and SDK notices remain. Codex's descriptor and decoded bytes are unchanged.

Review guide

Start with packages/acp/vendor/adapters/PROVENANCE.md, Claude's recipe.json, adapter.patch and sdk-transform.mjs. Then inspect scripts/lib/prepare-claude.ts, scripts/lib/claude-snapshot-module.ts, the preparation guards and the existing snapshot owner.

Check input/toolchain pins, strict patch validation, deterministic container bytes, atomic publication, cancellation joins, readiness invalidation, single-runtime installation and all cold graph consumers. CI ordering and JSR inclusion must prepare the module before it is needed. Lifecycle behavior remains tied to the exact reviewed executable map.

The original Architect and Planner passed the packaging amendment at signed 7f244bcb. Their focused correction reviews remain attached to the actual reviewed commits: Architect at fc1a5961 for mkdir ownership and Planner at 3b6519e6 for ANSI inventory parsing.

Independent Codex Astra (gpt-6-astra) closeout passes signed 423d6e8dc9c5d625369f9957fb63800219c7b982 with no findings. It resolves the original public P2, inspects both corrections and the Main interaction, and retains its earlier whole-packaging/lifecycle judgments through measured payload correspondence.

What must stay true

  • Disposal joins actual native close, the held helper and complete opening cleanup. Identity confirmation, first-turn acceptance and retained history keep their existing authority.
  • deps owns fetching and building Claude. Offline builds consume verified prepared output and refuse missing, altered or stale preparation with deno task setup.
  • Failed or interrupted preparation cannot publish partial output or report readiness. Owned tools and writes join before scratch cleanup.
  • Source, JSR, npm and compiled distributions carry the same prepared runtime. Runtime availability does not fetch or patch producer source.
  • Repacking uses the existing digest identity and does not migrate old snapshots or restart retained hosts.

How to verify it

Focused candidate evidence has explicit correspondence to the signed feedback commit:

  • Two isolated fresh setups reproduce identical archive/module hashes. Real corrupted-input, lock, SDK-site and adapter-preimage negatives refuse without replacing valid output.
  • Actual payload inspection matches all 29 executable hashes; fresh installed trees lack the original SDK/platform packages and complete a fake initialize/session/prompt/close exchange.
  • The emitted npm package, JSR inventory and selected layout, and a canonical host binary exercise the prepared output. The compiled smoke uses ordinary Agent/Prompt syntax and an explicit fake host executable.
  • Existing Deno protocol/materialization/vendor selection passes 4 suites / 59 steps; Node protocol passes 25/25.
  • Serializer/publication tests cover block boundaries, fixed metadata, actual held native writes, failed tools and sibling staging preservation. Fresh/private-state comparisons report no changes to owned shared state.
  • Earlier original-fails/repaired-passes lifecycle evidence is retained through exact executable equality, with current packaged regressions rerun. Complete first failures and corrections remain preserved.

On signed final feedback head 7f244bcb, full deno task lint, deno task check, deno task check:jsr and committed deno task verify:clean all pass. The clean proof prepares the new module in a clone, validates it through target preparation and offline builds, and passes the resolution/interference proof with dependencies and locks unchanged.

Signed correction 93c4a620 fixes both CI2441 compatibility defects: the existing tar-stream 3.2.0 pin is now a direct package dependency with aligned lock metadata, and ADD7 uses a private prepared candidate with config-based manual/frozen publication on pinned Deno 2.9.5. Fresh Bun 1.4.0 passes both affected suites (11 tests); Deno 2.9.5 and 2.9.7 each pass all seven distribution steps. Original Planner affected review, full Root lint and committed verify:clean pass at 93c4a620. First failures and candidate-evidence limitations remain preserved.

The original packaging review found one P2: recursive mkdir could finish after cancellation cleanup and recreate scratch. Signed fc1a5961 joins each directory mutation through a registered scoped finalizer. The same held native-operation witness changes from mkdir-start -> halt-return -> mkdir-settle to mkdir-start -> mkdir-settle -> halt-return, with no scratch residue. Focused preparation/staging tests pass under Deno, Node and Bun; native error identity and cleanup failure precedence are covered. Astra's later closeout explicitly resolves that finding.

CI2443 attempt1 exposed a separate test parser defect: Deno's ANSI-coloured inventory heading failed a literal match despite a successful 86-file ACP inventory. Signed 3b6519e6 uses existing stripVTControlCharacters before the unchanged inventory boundaries. The original parser fails the retained coloured fixture; the repair passes coloured/plain parsing, missing-heading and foreign-URL refusals. Actual Deno 2.9.5 coloured and 2.9.7 plain publication runs each pass all 11 distribution steps. The full first failure is retained; this is a diagnosed correction, not a flake claim or unchanged CI retry.

Final stable source 423d6e8d cleanly integrates published Main 234a5961; the entire feature patch is byte-identical relative to the new base. On exact 423d6e8d, setup regenerates the reviewed module hash, full lint passes, and committed deno task verify:clean passes isolated setup, target preparation, offline builds/compile, resolution and the Deno/Node/Bun interference proof with owned state unchanged. Initial sandbox network/signing failures are retained separately.

Required CI2445 is pending on 423d6e8d. Complete runner measurement77, attempt1, was dispatched once on the same frozen source. Its three complete runtime records and official assembly must qualify before an artifact-only commit. That resulting final head still requires its own required green CI. Historical CI and current local results do not substitute. The PR remains draft; no merge or release is authorized.

Scope

Included

Native-close/opening cleanup repair, reproducible Claude preparation, one-runtime packaging, generated publication, cold-consumer CI ordering, and focused lifecycle/distribution/ownership evidence.

Intentionally unchanged

SDK version, public XMD SDK/ACP shapes, synchronous snapshot APIs, Codex bytes and other providers' registry resolution. The only lock addition maps existing tar-stream 3.2.0 directly; no dependency version is upgraded.

Generated or mechanical changes

The committed Claude tarball and its encoded data are removed. packages/acp/generated/claude-snapshot.ts is ignored in Git, generated only during dependency preparation, and explicitly included in JSR. npm and compiled outputs carry its imported graph. The maintained committed adapter module now carries Codex only.

Claude archive SHA-256: 773db68c6b94fcf34540d387017247d6893f42359337a167a42baf636eef2685 (2,004,653 bytes). Generated module SHA-256: 117a2bf6356bb7ec567fa6b3e35266db38dda095ac9f12252bc5ca88b3c39444.

Risks and limitations

Local focused tools are Node 26.5.1 and Deno 2.9.7; supported CI runtimes and final exact-head CI remain delivery requirements. Controlled backends provide the regression evidence; no live-provider qualification is claimed. The PR stays draft while remaining reviews, measured weights and CI are pending.

Closes #1086.

Scope confirmation

  • Every changed file supports the disposal repair and requested packaging amendment.
  • Unrelated cleanup is excluded.
  • Generated outputs and their pinned source/recipe are identified.
  • Current review, local evidence and remaining delivery requirements are distinguished.

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

PR #1118: 🐛 Join Claude backend close and complete startup disposal

52 files, +4145 / -3012

Scope

🔴 PR has 7157 lines changed. Split into focused PRs.

🟡 7157 lines changed. PRs under 400 receive more thorough review.

🟡 52 files changed. Are all changes related?

🟡 Changes span 14 directories.

🟡 PR mixes config and source changes.

🟡 New abstraction files: packages/acp/src/adapter-snapshot-type.ts, scripts/lib/adapter-manifest.ts, scripts/smoke-claude-adapter.ts. Verify 3+ consumers.

Structural

🟡 7 console statements.

Oxlint structural signals:

  • no-empty-function ×5: packages/acp/src/adapter-snapshots.ts, scripts/build-npm.ts, scripts/lib/prepare-claude.ts
  • no-unnecessary-type-assertion ×3: scripts/tests/fixtures/claude-preparation-driver.ts, scripts/lib/prepare-claude.ts
  • no-unused-vars ×1: scripts/tests/fixtures/claude-preparation-driver.ts

Slop

Oxlint slop signals:

  • no-console ×13: scripts/verify-clean.ts, scripts/build-adapter-snapshots.ts, scripts/smoke-claude-adapter.ts (+4)

Static Analysis

Oxlint: 36 diagnostics across 10 files (10 rules)
Density: 0.009 violations/added-line

no-console (13): scripts/verify-clean.ts, scripts/build-adapter-snapshots.ts, scripts/smoke-claude-adapter.ts (+4)
no-array-sort (5): packages/acp/src/adapter-snapshots.ts, scripts/lib/prepare-claude.ts
no-empty-function (5): packages/acp/src/adapter-snapshots.ts, scripts/build-npm.ts, scripts/lib/prepare-claude.ts
no-floating-promises (5): scripts/deps.ts, scripts/smoke-claude-adapter.ts, scripts/tests/fixtures/claude-preparation-driver.ts (+2)
no-unnecessary-type-assertion (3): scripts/tests/fixtures/claude-preparation-driver.ts, scripts/lib/prepare-claude.ts
no-shadow (1): scripts/verify-clean.ts
no-unused-vars (1): scripts/tests/fixtures/claude-preparation-driver.ts
no-control-regex (1): scripts/tests/claude-archive.ts
no-useless-escape (1): scripts/lib/prepare-claude.ts
no-unnecessary-template-expression (1): packages/acp/src/adapter-snapshots.ts

Correctness

No extraneous code patterns detected.

taras commented Nov 4, 2026

Copy link
Copy Markdown
Owner Author

Packaging requirement before acceptance: replace the committed Claude package/duplicated pristine and patched SDK copies with pinned upstream input and a small readable deterministic patch/build recipe, applied during preparation/build. Distributions should carry only the required patched runtime copy. This reopens the affected packaging contract for source, npm, JSR and compiled delivery, including exact input verification, reproducibility and fail-closed patch validation. Runtime fetching or patch mutation is not a substitute for build work.

The PR remains draft. The earlier Architect/Planner/Astra PASS results apply to their recorded revisions and existing packaging; they do not approve this changed packaging. Unchanged lifecycle evidence may be reused only with explicit correspondence. The revised contract and final implementation need their applicable reviews and checks. Any concrete distribution conflict will be presented as explicit options before an exception or supported-format change. No merge or release is authorized.

@taras taras left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent affected review by Codex Astra (gpt-6-astra) at 93c4a6202fd745cc37d4951b9fb71ab040dc2fc9: CHANGES REQUIRED.

Scope: the complete build-time Claude packaging amendment since the earlier independent review, plus both pinned-runtime CI corrections. All 29 runtime executables match the previously reviewed payload; the two CI corrections are supported by focused Bun 1.4.0 and Deno 2.9.5/2.9.7 evidence.

One blocking P2 remains: scratch directory creation is not joined during cancellation. A held native mkdir probe recorded mkdir-promise-started → halt-returned → mkdir-settled; the removed scratch directory reappeared after halt returned. Join these mutations before scratch teardown and add a bounded cancellation regression. See the inline finding.

Earlier lifecycle judgment remains applicable through measured byte correspondence. This review does not establish final-head CI, runner-weight qualification or live-provider qualification, and grants no merge or release authority.

Comment thread scripts/lib/prepare-claude.ts Resolved

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found 2 redundant comments. Inline suggestions to remove them below.

cancelled: boolean;
/** FIFO of in-flight prompts. The head is the turn the SDK is currently
@@ -1175,6 +1200,13 @@ const SESSION_ENDED_MESSAGE = "The Claude Agent session has ended. Please start
// message and without invoking the model.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant comment — restates what the code does.

Suggested change
// message and without invoking the model.

];

export function transformSdk(source) {
// Validate all sites before replacing any, so a partial transform is never returned.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant comment — restates what the code does.

Suggested change
// Validate all sites before replacing any, so a partial transform is never returned.

@taras taras left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent review by Codex Astra (gpt-6-astra), continuing the same reviewer, at 423d6e8dc9c5d625369f9957fb63800219c7b982: PASS, no remaining findings in this bounded closeout.

The original public P2 is resolved. The preparer now starts each directory mutation inside a registered scoped finalizer, so native mkdir settles before scratch removal and halt return; native and cleanup failures remain observable. The held-native witness and focused regression distinguish this from the original early return. ANSI normalization uses the existing platform API before parsing actual publisher output, preserves section and foreign-URL boundaries, and passes actual coloured Deno 2.9.5 and plain 2.9.7 distribution evidence. Main integration changes projection context and test weights without changing this ownership or packaging path. Independent inspection of the current prepared module confirms all 29 executable hashes, metadata and the complete archive equal the previously reviewed payload, preserving the lifecycle and packaging judgments. No blocking finding remains in this bounded closeout. This is implementation review, not final-head CI, committed verify:clean, live-provider qualification, merge or release approval; those delivery obligations remain with Root.

This closes the original scratch-directory P2. The earlier full packaging review and original lifecycle judgment remain attached to their actual revisions; the closeout reuses them through measured executable/archive correspondence. Final delivery verification, measured weights and exact-head required CI remain separate gates.

@taras
taras marked this pull request as ready for review November 5, 2026 03:41
@taras
taras merged commit 7da1eb6 into main Nov 5, 2026
61 checks passed
@taras
taras deleted the codex/claude-startup-disposal-1086 branch November 5, 2026 05:00
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.

flake: Claude startup disposal can return before backend close

1 participant