Repository navigation
test(missions): identify owned catalog read cancellations - #1247
Conversation
The native-family fixture counts every panel catalog ERR_ABORTED as a navigation failure. Holding the initial catalog request until SSE opens reproduces the exact CI assertion on unchanged dev: the real connected callback supersedes the read through usePanelExtensions.clear, before navigation or page cleanup. The hook's optional-read cancellation is valid. Observe the production list call's owning signal and full API outcome, including body parsing, without changing its result or rejection. A fixture-only request identity binds the native browser failure to that specific call. Keep raw failures and explicit cancellation receipts; only an aborted owning signal plus a native AbortError classifies the exact catalog GET as expected. Unknown identities and network aborts stay failed. Serve the empty catalog with its correct array response shape. The new real-shell regression fails before this collector correction and passes after it. It verifies a successful superseding read and proves a network abort on the same catalog URL, plus an unrelated abort, remain in the failure array. All existing error assertions and production code stay unchanged. Three full native-family runs pass (12 tests each), fixture wiring/shutdown checks pass (8 tests), and UI typecheck and whitespace checks pass. PR #1244 is left unchanged; git-history is outside this work.
pascalandr
left a comment
There was a problem hiding this comment.
P0: 0 · P1: 0 · P2: 0 · P3: 0 — Verdict: PASS (no actionable findings).
Reviewed commit dbcc9058f7354d6b4742b3794b1cca22c66dca4a against dev abb14f83c6168b9eb04001359574e5d31ecc72d0.
Scope and correctness
- The diff changes only
packages/ui/tests/browser/fixtures/mission-native-family.tsxandpackages/ui/tests/browser/mission-native-family.test.ts. Production code, existing navigation/error assertions, and PR #1244 are unchanged. - Traced the collector and all its test callers,
RightPanel→usePanelExtensions.refresh/clear→panelExtensionsApi.list→authenticatedFetch→ native fetch/body parsing, and the EventSource → transport-status dispatcher lifecycle. Read the applicable agent, browser-fixture, panel-extension, native-event and cache conventions. - The request identity is assigned only during the real list call's synchronous fetch dispatch, and the original fetch is restored before yielding. Classification requires the exact same-origin catalog GET,
net::ERR_ABORTED, its recorded identity, its own aborted signal, and a nativeDOMExceptionnamedAbortErrorfrom the full API promise. The original promise/rejection reaches production unchanged. Unknown identities and observation failures fail closed; every raw request failure stays recorded. - The regression uses the real shell, components and dispatcher with held requests and response/failure events. No production hooks, broad cancellation exclusions, new sleeps/retries, or extra abstractions were introduced. The empty installed-extension response now has the correct array shape.
Independent validation
Windows, Node 25.2.1, Chromium 153.0.8010.12.
node --import tsx --test --test-concurrency=1 tests/browser/mission-native-family.test.ts: four complete runs, 12/12 each (48/48), covering every existing caller of the shared collector. Run durations were approximately 103, 125, 135 and 115 seconds.fixture-wiring.test.ts+fixture-shutdown.test.ts: 8/8 passed. Additional cache, navigation-budget and diagnostic-boundary checks: 14/14 passed.panel-extensions.test.ts: 14/14 passed, including real routes and lifecycle fencing.npm run typecheck --workspace @codenomad/ui: passed.git diff --checkand base-to-head whitespace check: passed.- Review-only runtime overlays outside the checkout reproduced the original deferred-child assertion on dev by holding the initial catalog read until the real initial SSE open. The only failure was
/api/panel-extensions net::ERR_ABORTED; selection and the newer sibling draft were already correct. The identical gated scenario passed with this correction, retaining that raw failure as read1's proven cancellation. - Removing only the new collector classification at runtime makes the committed supersession regression fail with the exact catalog-abort assertion. The unchanged head passes, and its diagnostics retain three raw aborts: one owner cancellation plus the same-URL network abort and unrelated abort, with the latter two still in
failures. - An additional review-only real streaming-response control canceled the body after response headers: the full API promise supplied the native cancellation receipt and the replacement succeeded. Missing and unknown identity controls on the same catalog URL remained failures.
Evidence and runtime-overlay script are under C:\Users\Admin\AppData\Local\codenomad-agent-scratch\review-1247-evidence and review-1247-overlay.mjs. These controls change only runtime-loaded test sources; checkout files and branches are untouched. Validated fixture shutdown receipts show zero pending requests, zero active optimizer contexts, matching created/disposed contexts and a closed listener.
No oversized touched files: fixture 160 lines, test 653 lines. The reviewed branch remains clean at the exact commit above. No commits, pushes, merges, branch switches, or shared-daemon operations were performed. Repository-wide CI was still pending when checked; this is a COMMENT review, not a CI completion claim.
Summary
Fix the native-family browser fixture's accounting of intentionally superseded panel-extension catalog reads. Keep production behavior and every existing navigation error assertion unchanged. A uniquely tagged production list call is classified separately only after its own signal is aborted and its full API promise rejects with a native
DOMExceptionnamedAbortError.Root cause and investigation
CI run 41261807276 on #1244 head
0e5820489aeda482369157eaf530e63e26a6fcb1faileddeferred ordinary-child navigation cannot overwrite a newer sibling selectionwith/api/panel-extensions net::ERR_ABORTED. The full failed job log was inspected. Its uploaded browser artifact contains only the fixture-daemon log; that log records clean shutdown and zero active optimizer contexts, and contains no per-family request receipts.A controlled real-shell reproduction on current dev (
abb14f83c6168b9eb04001359574e5d31ecc72d0) held the first catalog request and admitted the initial SSE open after that read began. It reproduced the exact failing assertion, before page cleanup. The observed native signal-abort stack is:EventSource.onopen→ event transport connected callback →ServerEvents.emitTransportStatus→usePanelExtensions.refresh→clear→AbortController.abort.The hook intentionally replaces an optional catalog read on transport reconnection, visibility or instance changes. A sibling selection is incidental to this particular cancellation. The fixture and production catalog/transport sources match dev and #1244; the isolated native-family fixture owns its server/cache and is independent of #1244's changed fixtures. #1244 is unchanged. The separately assigned git-history failure was not investigated.
Correction and safety checks
panelExtensionsApi.listpromise, including response-body parsing, and return that same promise to production callers. Preserve the original rejection.window.fetchimmediately before yielding. Missing/unknown identities fail closed.ERR_ABORTEDand a matching owning-signal/native-AbortError outcome. Retain raw failures and identity-qualified cancellation receipts in the existing diagnostic output.[]shape instead of the catch-all{}response.errors/failuresassertions, other collectors and production lifecycle untouched. Add no sleeps, retries or console suppression.The new regression drives the real transport-status dispatcher and production hook, holds a catalog read, supersedes it, and requires a successful replacement response. It then injects an actual browser network abort on the same URL and error code, followed by an unrelated aborted fetch: both must remain in
failureswhile the owner cancellation remains separately identified and present in the raw log.Before/after evidence
1's proven cancellation and the sibling draft preserved.ERR_ABORTEDassertion and passes afterward.failures.Validation
node --import tsx --test --test-concurrency=1 tests/browser/mission-native-family.test.ts: three runs, 12/12 each (36/36), including all existing real-shell/native-dispatcher callers of the shared collector.fixture-wiring.test.ts+fixture-shutdown.test.ts: 8/8.npm run typecheck --workspace @codenomad/ui: pass.git diff --check: pass.Windows, Chromium 153. Test-only change; public help is unaffected.