fix(incremental): refresh stale scan inventory before batching#584
Closed
jiang4wqy wants to merge 24 commits into
Closed
fix(incremental): refresh stale scan inventory before batching#584jiang4wqy wants to merge 24 commits into
jiang4wqy wants to merge 24 commits into
Conversation
jiang4wqy
force-pushed
the
codex/fix-incremental-inventory-refresh
branch
from
July 16, 2026 11:32
b395bf8 to
57c0ca8
Compare
…-inventory-refresh
jiang4wqy
marked this pull request as ready for review
July 17, 2026 18:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Incremental
/understandruns previously trusted the retained scan inventory, allowing added files to be missed, deleted files to remain selectable, and rename or ignore-rule membership changes to escape graph pruning.This PR reconciles retained inventory with validated current membership before incremental batching. Structural drift triggers a deterministic, atomic scan/import refresh; inventory deltas are propagated through
effectiveChangedFilesand a retry-safe pending journal. The same validated membership now supplies bounded project context, while unsafe symlink or junction aliases fail closed.Modified-only runs still avoid inventory refresh. If membership reconciliation and the pending journal leave no effective changes, batching exits before source export extraction or clustering and emits an empty-batch payload. Full mode remains outside the incremental refresh path.
Linked issue(s)
N/A
Root cause
compute-batches.mjsfiltered Git changes againstscan-result.jsonbefore synchronizing the retained inventory with the current repository. The Git changed-file list was therefore neither a complete analysis target set nor a sufficient old-graph pruning set.What changed
pending-inventory-changes.jsonjournal so additions and removals survive retries until Phase 7 cleanup.effectiveChangedFilesfrom validated Git paths, the before/after inventory symmetric difference, and pending journal paths..ua/legacy state directories and retained scan files before reading; atomically replace the scan and preserve the previous bytes on pre-commit failure.projectContextonly from validated inventory membership in full and incremental flows, avoiding direct README/manifest re-reads and rejecting unsafe aliases..understandignorerules as ordered individual patterns across LF, CRLF, and CR files; apply data-directory, root, and CLI rules in that order..ua/and.understand-anything/roots and fail closed on external symlink/junction aliases without disclosing external content./understandempty-diff flow so hidden inventory drift can still produce incremental work.Before / after
Validated against a repository-scale fixture with 8 additions, 2 deletions, 1 modification, and 1 rename:
The refreshed POSIX run, Windows CRLF/backslash run, and fresh full-scan oracle produced the same complete JSON document and SHA-256 digest (
3ce73f778b8d001a548e29a18fef890aae097e6473d2f5955d417d474cb98e53). Ignore re-include/exclude, journal propagation, multi-line ignore ordering, and external-junction canaries also passed.Scope
Relative to current
main, the PR touches 12 files (10 modified, 2 added):+4607/-247total. Runtime scripts account for+1815/-174, tests for+2690/-26, skill/agent documentation for+101/-46, and the CI workflow for+1/-1. It adds no runtime dependency or lockfile change.Verification
pnpm lintpnpm buildOn the 459-file fixture, direct refresh had a three-run median duration of 4.61 seconds and a median parent-process peak working set of 65.69 MiB.
Known verification boundaries
/understandLLM end-to-end run could not start because the local Claude CLI returned HTTP 403 before plugin startup. Scanner, import extraction, refresh, batching, oracle, build, and test surfaces were verified independently.Math.random(). Analysis targets, imports, and exported symbols were stable; a test-only seeded RNG was used only for byte-level community-number parity across path formats.lstat/realpathchecks fail closed before reads, but Node's path APIs cannot completely remove the syscall-level race between validation and open without a platform-specific no-follow file-handle implementation.Versioning
2.9.4in all six manifests required byCLAUDE.md.