Repository navigation
fix(verifiers): keep the recorded-crash root until its owners finish - #8706
abhisheksharma001 wants to merge 3 commits into
Conversation
The recorded-crash verifier closed its private fixture root after the session and sentinel closes even when those failed, and observed its process lineage only after the root was gone. Its session helper also awaited a transport close inside the connection-failure handler, so a refused close replaced the connection failure. Close every owner, verify lineage, then release the root; otherwise retain it and name it in the report. Preserve both the connection and the close failure together. Fixes morluto#8562. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
[Medium impact] The PR appears safe to merge; the previous error-loss finding is fixed and no new blocking issue was found. SummaryThe PR keeps the recorded-crash fixture root until its owners close and process lineage is verified.
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Create fixture root] --> B[Register session before connecting]
B --> C[Run verification]
C --> D[Attempt every session and sentinel close]
D --> E{All closes succeed?}
E -->|No| R[Retain root and report its path]
E -->|Yes| F[Observe process lineage]
F --> G{Cleanup verified?}
G -->|No| R
G -->|Yes| H[Remove root]
Reviews (3) · Last reviewed commit: "fix(verifiers): keep the trace client's ..." · Reviewed by Greptile |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5e66a36624
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
connectRecordedCrash acquired the SDK transport and, when the connection failed and the transport close was also refused, threw both failures but lost the only handle to a transport whose stdio child may still be live. The verifier owned no session for it, so its cleanup could verify lineage and remove the root with that transport unresolved. The helper is now a factory, openRecordedCrashSession, whose connect() is a separate step: the verifier and the trace client register the session before connecting, so every acquired transport closes through the owned cleanup and a refused close retains the root like any other owner. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5819e45f35
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…efused close The trace client's plain try/finally let a refused session close replace the connection or inspection failure it followed. Run the operation and the close through withVerifierCleanup, which retains both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Hey @abhisheksharma001, thanks for the PR! This fix looks good to me. What's left: there are 2 unresolved review threads from Codex (1 still on current code), e.g. "Preserve the trace client's connection failure"; the one on an outdated line may just need resolving if it's already handled. Happy to merge once that's sorted. |
|
The merge conflicts with |
|
TL;DR: I ran the PR's changed test file on Node 22.23.4, 24.22.1 and 26.12.1. All 8 tests pass on the head and fail on the old source files. The
The test file is On Node 24.22.1, all 8 failures are one The PR changes 5 files against the merge base 9bea563. The head is 373 commits behind main 9d0e87f. CI on the head, read live with
Not run
Test setupCommandsnpm ci --offline
npm run test:prepare
xvfb-run -a npm run test:focused -- tests/boundary/process/recordedCrashVerifierCleanup.test.ts🤖 Written and tested with Claude Code (Sonnet 5.5, verified by Opus 5.5), posted with my OK 🦊 |
|
@morluto following up on my 11-06 comment. The review threads from your 11-05 note are resolved and the PR shows as mergeable.
CassieFox23 also ran the changed test file on Node 22, 24 and 26: all 8 tests pass on this head and fail on the old source. |
|
@morluto a gentle second ping. Same blocker as above: |
Summary
Fixes #8562.
scripts/verify-recorded-crash.mjsclosed its private fixture root after session and sentinel closes even when those closes failed, and observed its process lineage only after the root was gone. Separately,connectRecordedCrashacquired the SDK transport before the verifier owned the session, so a failed connection whose transport close was also refused lost the only handle to a possibly live transport, and the verifier could still release the root.Problem and expected behavior
Reported: cleanup attempts root close regardless of session and sentinel close outcomes; lineage is observed after root close; a failed connection whose transport close also rejects reports only the close error with an empty cause. Expected: retain the root while session or sentinel ownership is unresolved, establish owned process completion before release, and preserve both the connection and the cleanup failure.
Change and scope
scripts/verify-recorded-crash.mjs: cleanup is one owned sequence. Session and sentinel closes run throughcloseVerifierResources, so every owner is attempted and every refusal is retained. Process lineage is then observed and required verified withassertVerifierCleanupComplete; only after that is the root closed. Any failure in that sequence keeps the root, adds the individual failures to the report, and the thrownAggregateErrornames the retained root path. The report gainsretained_root(nullonce released). If the sequence stopped before observing lineage, the report still observes it afterwards, without asserting on it.scripts/verify/recorded-crash/public.mjs:connectRecordedCrashbecomesopenRecordedCrashSession, a factory whoseconnect()is a separate step. The transport is acquired by the factory and released only byclose(), soverify-recorded-crash.mjsandtrace-client.mjsregister each session as an owner before connecting it: a failed connection, or a refused close after one, is closed by the owned cleanup like any other session, and a refused close retains the root instead of being reported as diagnostics only. The trace client runs its connect, inspection and close throughwithVerifierCleanup, so a refused close is retained beside the primary failure rather than replacing it.Contribution scope: ordinary fix within existing verifier boundaries; maintainer scope decision not applicable.
Contract and boundary impact
Semantic owner and earliest changed stage: the verifier's own ownership order and its session helper; shared helpers are unchanged.
Contribution scope fit and linked maintainer decision: not applicable.
CLI and MCP/tool-catalog contract: none.
Provider, bridge, target-format, or platform compatibility: Linux x64 verifier as before.
Evidence, artifact, provenance, or reconstruction contract: none.
Target selection, authority, upstream behavior, and cleanup details: the root is retained on any unresolved ownership or unverified lineage; the report and the failure name its path.
Generated metadata, package, or installation impact: none.
Read existing files or captured data.
Evidence and regression coverage
tests/boundary/process/recordedCrashVerifierCleanup.test.tsruns the real verifier as a subprocess undertests/fixtures/recordedCrashVerifierPreload.mjs, which authors the Linux x64 guard, thepid_maxread, the fixture root, the fixture tooling, the sentinel, the lineage observation and, for the realpublic.mjs, the SDK owners and the CLI (the pattern oftests/fixtures/flutterVerifierPreload.mjs). Eight cases: a prerequisite failure that acquired no owner releases the root after lineage; a CLI failure releases the root only afterclient-close,transport-close,sentinel-closeandlineage-observe; a refused client, transport or sentinel close still attempts the other owners, keeps the root, reportsretained_rootand names the path; unverified lineage keeps the root; a failed connection still closes its owned session and releases the root after lineage; a failed connection whose transport close is refused keeps the root and reports both failures.root-closebeforelineage-observe(root released), and the connection scenarios close the transport outside any owner and release the root. With this change the refused scenarios, including the refused close after a failed connection, stop beforeroot-closewith the directory present; with the session registered only afterconnect(), exactly the two connection cases fail."retained_root": null | "<path>"; on a retained root the final error readsRecorded crash verification failed; retained fixture root <path> because its cleanup is incomplete.Validation performed
npm run test:focused -- tests/boundary/process/recordedCrashVerifierCleanup.test.ts— 8 passednpx oxfmt --checkon the five files — clean;npx oxlint— only the pre-existingmax-lines-per-functionwarning on the session factoryCompatibility, safety, and release
real-recorded-crash.yml) exercises the success path.Author readiness
Human owner: @abhisheksharma001
Before merge
type(scope): outcome.🤖 Generated with Claude Code