Skip to content

feat(incremental): incremental re-scan + scan --update/--watch (6.1, D1/G2)#59

Merged
officialCodeWork merged 1 commit into
developmentfrom
build/phase-6/step-6.1-incremental-rescan
Jul 16, 2026
Merged

feat(incremental): incremental re-scan + scan --update/--watch (6.1, D1/G2)#59
officialCodeWork merged 1 commit into
developmentfrom
build/phase-6/step-6.1-incremental-rescan

Conversation

@officialCodeWork

Copy link
Copy Markdown
Owner

Phase 6.1 — Incremental re-scan (failure modes D1, G2) · completes Phase 6 / Gate 6

Re-scan only what changed, with a graph provably byte-identical to a full re-scan.

Design

  • scanReact split into createScanProject (build + load the ts-morph project) and scanProject (the full analysis).
  • New IncrementalScanner keeps one project alive. update() calls refreshFromFileSystemSync on each source file — ts-morph re-parses only files whose bytes changed — picks up added files, drops deleted ones, then re-runs scanProject.
  • Correctness by construction: every node and cross-file edge is re-derived from the current ASTs on each update, so an update's graph is byte-identical to a fresh full scan. The hard "dependents" problem (a changed component's parents' instance/prop-flow attribution, store/route/journey wiring) is handled for free because the global passes always re-run; the incremental win is parsing (unchanged files keep cached ASTs).

Provenance & CLI

  • GraphMeta.fileHashes (relative path → sha256; schema regenerated, drift gate green); projectFileHashes computes it.
  • scan --update: short-circuits when every file hashes identically to the prior graph (else reports the changed set and full-rescans — correct, ~2 s at scale).
  • scan --watch: re-emits the graph on each debounced file change (ignores the output file, node_modules, .coderadar).

Tests

  • Property test: an interconnected app (pages → components → atoms + hook, cross-file imports/fetches) stays byte-identical to a full re-scan across 20 randomized single-file edits (rendered text / endpoint / re-pointed cross-file import), plus add-file and delete-file cases with exact changed reporting.
  • Verified end-to-end via the CLI (--update no-change/changed, --watch live edit).

Also

Strips a stray NUL byte that shipped in the 6.3 edgeSortKey join separator (now the intended space) — functionally inert (both are valid separators) but it flagged the file as binary in git.

Verification

  • pnpm eval → 317 pass · determinism 1.000
  • parser-react 151 tests; full suite, typecheck, lint green.

Gate 6 passes (6.1 incremental · 6.2 scale · 6.3 determinism · 6.4 version-skew · 6.5 generated/PII). M6 reached — production-grade: incremental, fast, deterministic, versioned. Tracker + milestone table updated.

🤖 Generated with Claude Code

…ch (6.1, D1/G2)

Re-scan only what changed, with a graph provably identical to a full re-scan.

- Split scanReact into createScanProject (build/load the ts-morph project) and
  scanProject (the full analysis).
- New IncrementalScanner keeps one project alive; update() refreshes only files
  whose bytes changed (refreshFromFileSystemSync), adds new / drops deleted
  files, then re-runs scanProject. Correctness by construction: every node and
  cross-file edge is re-derived from current ASTs, so an update's graph is
  byte-identical to a fresh scan — the changed file's dependents are recomputed
  for free. The win is parsing: unchanged files keep cached ASTs.
- Property test: an interconnected app stays byte-identical to a full re-scan
  across 20 randomized single-file edits, plus add/delete with exact `changed`.
- GraphMeta.fileHashes (path -> sha256; schema regenerated) records provenance;
  projectFileHashes computes it.
- CLI: `scan --update` short-circuits when nothing changed (else reports the
  changed set and full-rescans); `scan --watch` re-emits on debounced changes.

Also strips a stray NUL byte that shipped in the 6.3 edgeSortKey join separator
(now the intended space) — functionally inert but flagged the file as binary.

eval 317/0/0/0, determinism 1.000; parser-react 151 tests, typecheck + lint
clean. Gate 6 passes; M6 reached.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@officialCodeWork
officialCodeWork merged commit f05adb9 into development Jul 16, 2026
1 check passed
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.

2 participants