feat(graph): surface unindexed source files instead of leaving them silent - #175
feat(graph): surface unindexed source files instead of leaving them silent#175abhinav-phi wants to merge 4 commits into
Conversation
…ilent The supported-source glob covers exactly the extensions extractors understand, so a .go or .svelte file is invisible to every discovery path: `mex graph` reports a complete-looking build, `mex doctor` stays green, and an agent asking about a symbol that exists gets the same TARGET_NOT_FOUND a typo gets. Count the complement at the one seam every consumer shares. The corpus policy now walks its own ignore list and reports recognized source extensions no extractor claims — self-removing as extractors land, because candidates are checked against the live extension map. - `mex graph` prints the histogram after the build summary and emits `unindexedSources` behind --json - `mex graph query` / `mex impact` TARGET_NOT_FOUND records gain coverage context (filesIndexed, unindexedSources) only when it changes the record's meaning, so healthy repositories keep their exact shape - `mex doctor` shows a Coverage line and next-steps hint Reporting is best-effort by contract: bounded by a file-scan cap with an explicit truncated flag, and never fails the command that carries it. Resolves mex-memory#163
An empty store legitimately adds filesIndexed: 0 to a TARGET_NOT_FOUND record, so the synthetic /repo fixture becomes a real empty temp root — the histogram walk needs a readable cwd, and a fake path made the golden's outcome depend on the host filesystem.
2e66869 to
7b1ed1f
Compare
|
Rebase note: this branch now sits on current CI: the first run on the rebased head failed only in All green — ready for review. |
Resolves #163.
Problem
EXTENSION_MAPcovers ten extensions, and every discovery path is built from it, so a file with any other extension is invisible everywhere. The failure mode is silence:0 nodeswith exit code 0, andmex doctorshows four green ticks;indexedFiles: 1with no warning, and an agent asking about a symbol that exists gets the sameTARGET_NOT_FOUNDa typo gets.Approach
Count the complement at the one seam every consumer already shares.
corpus-policy.tsgainsunindexedExtensionHistogram: a walk with the same glob options and the same ignore list as source discovery (so a repository's owngraph.ignoreshapes the answer), keeping only files whose extension is recognized source but no extractor claims it.The recognized set is checked through
isSupportedSourceFileagainst the live extension map, so an extension stops being reported the moment an extractor lands for it — the list cannot go stale.Reporting is bounded and best-effort by contract: a file-scan cap with an explicit
truncatedflag, a capped histogram, and a walk that can never fail the command it decorates.What changes
mex graph: printsNot indexed: N source file(s) have extensions no extractor handles: .go (2), ...after the build summary;--jsongainsunindexedSources(total,byExtension,truncated), absent when the histogram finds nothing, so existing consumers are unchanged.mex graph query/mex impact:TARGET_NOT_FOUNDrecords gain coverage context (filesIndexed,unindexedSources) — but only when it changes the record's meaning (nothing indexed, or unindexed source files exist). Ordinary misses in a healthy repository keep their exact prior shape.mex doctor: aCoverageline plus a next-steps hint when recognized source files are unindexable.Verification
coverage-histogram.test.ts(recognition, noise exclusion,graph.ignorehandling, truncation, entry cap).cli-agent.test.ts: two new tests —TARGET_NOT_FOUNDstays bare on a fully covered repository, and names unindexed sources on a mixed TS/Svelte/Go repo.filesIndexed: 1+unindexedSources: {total: 2, byExtension: {".go": 1, ".svelte": 1}}on both the build output and theTARGET_NOT_FOUNDrecord; a clean repo's output is byte-identical to before.npm run typecheck,npm run buildpass locally; targeted suites green. (The pre-existing Windows-local failures in symlink/SHM tests reproduce identically on cleanmainand are unrelated.)No identity, reconciliation, schema, or drift-semantics changes are included.