From 7dd489e997ff2727254f5671d4f5837562e59415 Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Wed, 20 May 2026 13:13:27 +0100 Subject: [PATCH] fix(parsing): sequential gap-fill for worker-quarantined chunk files (U20.U1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the worker pool's Layer 3 quarantine filters one or more files out of a chunk's dispatch, the worker results returned to processParsing are silently narrower than the input chunk. Without this reparse, the graph for this run would be missing every quarantined file's symbols/imports/calls/heritage with no failure signal. After the existing per-chunk quarantine log emits in processParsing's worker-path try-block, run processParsingSequential on JUST the quarantined-in-chunk files. The sequential path writes directly to the graph, so symbols for those files land alongside worker output for the surviving files. Mirrors the WorkerPoolDispatchError catch-block's processParsingSequential call shape — same signature, same args, same scopeTreeCache wiring. Emits a structured warn naming `reparsedPaths` so operators can observe the sequential fall-through. This fixes the in-run side of the corruption Codex's adversarial review of PR #1693 flagged. The cross-run side (chunk-cache poisoning) is closed by U20.U2 in a follow-up commit. References plan: docs/plans/2026-05-20-002-fix-chunk-cache-corruption-on-worker-quarantine-plan.md --- .../src/core/ingestion/parsing-processor.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/gitnexus/src/core/ingestion/parsing-processor.ts b/gitnexus/src/core/ingestion/parsing-processor.ts index 44e58a9cb..bc404a6b3 100644 --- a/gitnexus/src/core/ingestion/parsing-processor.ts +++ b/gitnexus/src/core/ingestion/parsing-processor.ts @@ -931,6 +931,42 @@ export const processParsing = async ( files.length, `${quarantinedInChunk.length} worker-quarantined file(s) skipped`, ); + + // U20.U1: Sequential gap-fill. The worker pool's Layer 3 + // quarantine filtered these files out of dispatch, so the + // worker results above are missing their symbols/imports/ + // calls/heritage. Without this reparse, the graph for THIS + // run is silently incomplete — exactly the silent-corruption + // class the Codex adversarial review of PR #1693 flagged. + // + // Running `processParsingSequential` on JUST the quarantined + // files mirrors the WorkerPoolDispatchError catch-block + // shape below (line 961). Worker-extracted data for the + // surviving files flows through `data` to the caller's + // deferred-extraction merge; sequential output for the + // quarantined files writes directly to the graph here. + // + // The chunk-loop caller's cache write at parse-impl.ts:500- + // 507 will NOT cache this chunk because U20.U2's guard + // detects the same quarantine intersection — so next run + // gets a cache miss and a fresh pool gives the file + // another chance. + logger.warn( + { + reparsedPaths: quarantinedInChunk.map((f) => f.path), + count: quarantinedInChunk.length, + }, + `Running sequential reparse for ${quarantinedInChunk.length} worker-quarantined ` + + `file(s) to keep this run's graph complete.`, + ); + await processParsingSequential( + graph, + quarantinedInChunk, + symbolTable, + astCache, + scopeTreeCache, + reportProgress, + ); } } return data;