You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
engine: count pruned directories in the receipt's skip accounting
walkRepo returned filepath.SkipDir before reaching skips.count++, so an
ignored directory's files landed in no bucket: not files_seen, not
files_skipped. The metric counted only ignored FILES the walker reached --
9 on a tree with ~67k ignored files, naming none of them. A bad ignore glob,
the thing this metric exists to catch, is almost always a directory glob.
Count a pruned directory once, in a new dirs_skipped field, rather than
walking node_modules/ purely to size it. Each skipped_sample entry now names
the glob that matched it, so "why is this file missing?" is a lookup. To get
the pattern, matchAnyGlob is split into matchGlob, which returns it;
matchAnyGlob wraps it, so both glob lists still share one matcher.
Exclude the configured output dir: .enola/** is itself a directory glob, so
counting it would make dirs_skipped differ between a repo's first snapshot
and every later one, and land as a phantom delta in diff_snapshot.
No cacheVersion bump -- facts.jsonl is byte-identical across the fix, so no
cachecov entry and no golden regeneration. Adds the tests that were missing:
nothing asserted files_skipped and no golden fixture contains an ignored
directory, which is how this survived 96 bumps.
Copy file name to clipboardExpand all lines: ARCHITECTURE.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -574,7 +574,7 @@ After `generate_snapshot`, these are written to the output directory (default `.
574
574
| `facts.jsonl` | Every extracted fact, one JSON object per line |
575
575
| `insights.json` | Architectural insights with confidence scores |
576
576
| `snapshot.meta.json` | Metadata including per-file content hashes for incremental updates, plus the full receipt fields |
577
-
| `receipt.json` | The **snapshot receipt** — a compact manifest of what the graph was generated over (enola version, git ref + dirty status, a content-fingerprint snapshot ID, the extractor/explainer sets, ignore-glob hash, output-artifact hashes) and extraction-quality metrics (files seen/parsed/skipped, parse errors, coverage gaps). Read it via the `snapshot_receipt` tool. |
577
+
| `receipt.json` | The **snapshot receipt** — a compact manifest of what the graph was generated over (enola version, git ref + dirty status, a content-fingerprint snapshot ID, the extractor/explainer sets, ignore-glob hash, output-artifact hashes) and extraction-quality metrics (files seen/parsed/skipped, directory trees pruned, parse errors, coverage gaps). Read it via the `snapshot_receipt` tool. |
578
578
| `previous/` | The immediately-preceding snapshot, auto-rotated on each write — the `baseline='previous'` source for `diff_snapshot` |
579
579
| `baseline/` | A snapshot pinned by `set_baseline`, preserved across re-snapshots — the default `diff_snapshot` baseline |
580
580
@@ -583,7 +583,9 @@ After `generate_snapshot`, these are written to the output directory (default `.
583
583
`receipt.json` (and the same fields inside `snapshot.meta.json`) exists to answer *"what was this graph deterministic over, and how complete is it?"* — the trust question before an agent relies on an `impact_analysis` or a `diff_snapshot`. It serves two consumers:
584
584
585
585
- **Provenance / audit.** enola version, git ref + dirty-tree status, the extractor/explainer sets actually used, a **config hash** (over the effective extractors/explainers/renderers/globs/output settings) and its narrower `ignore_glob_hash`, per-artifact output hashes, and a **snapshot ID** that is a *content fingerprint* (SHA-256 over the byte-stable fact serialization plus the version and config hash), not a random UUID — so re-running on identical inputs yields the same ID and it can key equivalence. Every hash value carries a `sha256:` prefix.
586
-
- **The improvement loop.** Extraction-quality metrics — files seen vs. parsed vs. skipped, a parse-error count and sample, the count of heuristic (confidence < 1.0) insights, and the cross-repo coverage-gap / unresolved-edge rollup — give a machine-readable signal a consumer (a human, a `diff_snapshot`, or an agent improving enola itself) can poll to detect *thin extraction* (a missing detection, a bad ignore glob, a failing extractor) and turn it into targeted work. The same metrics appear as an **Extraction Quality** section in `llm_context.md`, so an agent reading the snapshot sees thin extraction without a tool call.
586
+
- **The improvement loop.** Extraction-quality metrics — files seen vs. parsed vs. skipped, the number of directory trees pruned, a parse-error count and sample, the count of heuristic (confidence < 1.0) insights, and the cross-repo coverage-gap / unresolved-edge rollup — give a machine-readable signal a consumer (a human, a `diff_snapshot`, or an agent improving enola itself) can poll to detect *thin extraction* (a missing detection, a bad ignore glob, a failing extractor) and turn it into targeted work. The same metrics appear as an **Extraction Quality** section in `llm_context.md`, so an agent reading the snapshot sees thin extraction without a tool call.
587
+
588
+
The two skip counters mean different things, and a bad ignore glob is usually a *directory* glob. `files_skipped` counts ignored files the walker **visited** and dropped — those matched by a file glob like `**/*.test.ts`. An ignored directory is pruned whole (`filepath.SkipDir`), so its contents are never visited and appear in no count: it is tallied once, as one entry in `dirs_skipped`. Each `skipped_sample` entry names the glob that matched it, so *"why is this file missing from the graph?"* is a lookup rather than an investigation; directories appear there with a trailing slash.
587
589
588
590
Because the receipt fields live in `snapshot.meta.json`, they ride into every pinned/`previous` baseline, and `diff_snapshot` reads them to add a **comparability guard**: it warns (above the delta) when the baseline and current snapshots were *not* generated over equivalent inputs — a different repo, enola version, extractor set, or ignore-glob set — since a diff across a mismatched extractor set would report every one of that language's facts as spurious churn. `compare_receipts` surfaces the same verdict plus the metric deltas directly.
0 commit comments