- P2-1 (real): spring.ts route loop dropped every @value_expr match — the
'!valueNode' guard ran before the operand branch, so ingestion emitted zero
constant-referencing routes. Guard now accepts @value_expr when @value is
absent; two downstream valueNode dereferences made conditional.
Added 2 extractor-level regression tests (16 total).
- P2-2 (real): collectSpringTypes copied rawPath:'' for constant routes into
the shared Spring inheritance view — now skipped there (fold happens in
scan(); empty-path noise would leak into inheritance-based providers).
- P1-1 (false positive): Java 'static final' allows exactly one initializer
(duplicate declarations are compile errors), so the Python-style rebinding
shadowing cleanup does not apply — documented at the site.
- P1-2 (false positive): constant-resolver.ts and prepareDurableParsedFileChunk
both exist on upstream main (#2391 / parsedfile-store.ts:562); the bot's
'repository lookup' appears to have compared against a stale index.
- P3: removed dead FQN_CONTROLLER fixture.
Real-repo regression: 589 cross-links / 2423 contracts (was 2424 — the
dropped contract is the empty-path inheritance artifact fixed above).
- prepareRepo builds repo-wide Java constant map (constant-definition files only,
cheap regex gate; per-file try/catch so one bad file degrades not forfeits)
- bind parser language in prepareRepo (orchestrator hands over a bare Parser)
- scan() lazily overlays the importing file's own import table (extracted from
the tree already in hand, zero extra parses) before folding operands
- foldJavaOperands resolves qualified refs (Class.CONST) + static imports +
string concatenation against the merged view; unresolved refs are skipped,
never guessed
Real-repo validation (winning-winex-opt, 23k Java files):
providers 2 -> 1701 (1700 source_scan_resolved), cross-links 0 -> 589 exact
Unit: 14/14 (java-route-const-resolver.test.ts)