Skip to content

Commit 114303f

Browse files
feat: codemap audit v1 (B.5) — structural-drift command with per-delta baselines (#33)
* feat(audit): tracer 1 — CLI scaffold + auto-incremental-index prelude (B.5 v1) First vertical slice per docs/plans/codemap-audit.md § 8 tracer-bullet sequence step 1. End-to-end working: bare `codemap audit` exits 1 with a clean message; --baseline missing emits {"error":"…"}; --baseline <existing> emits the {base, head, deltas} envelope (deltas: {} until tracer 2 fills it in). File layout per the design pass (Q6): - src/cli/cmd-audit.ts — argv parse, --no-index opt-out, runAuditCmd bootstrap + auto-incremental-index prelude (calls runCodemapIndex({mode: "incremental", quiet: true}) unless --no-index), stub renderer. - src/application/audit-engine.ts — types (AuditEnvelope / AuditBase / AuditHead / AuditDelta / AuditError), runAudit({db, baselineName}) — loads baseline via getQueryBaseline (B.6 helper), assembles envelope. Caller owns the DB lifecycle and the index-prelude decision (engine reads whatever's there). Tests: - src/cli/cmd-audit.test.ts — 9 parser tests (all four flags + mutex / error paths). - src/application/audit-engine.test.ts — 2 engine tests (missing baseline error path; happy-path envelope shape). - src/cli.test.ts — `audit --help` + `audit` (no flags) integration. Wiring: src/cli/main.ts dispatch + src/cli/bootstrap.ts validateIndexModeArgs allow-list ("audit"). No deltas yet — tracer 2 ships `files`. No verdict, no exit codes 1/2, no codemap.config.audit (per Q3). No --base <ref> (per Q1, defers to v1.x). * feat(audit): tracer 2 — files delta + canonical-projection registry (B.5 v1) Per docs/plans/codemap-audit.md § 8 step 2. End-to-end working: a files-shaped baseline produces a real diff (added/removed paths); column-mismatch baselines surface the clean re-save guidance per § 4. Engine additions (src/application/audit-engine.ts): - AuditDeltaSpec — {key, sql, requiredColumns, recipeIdHint}. - V1_DELTAS — readonly registry (one entry: files; tracer 3+ adds the rest). New deltas land here as plain data. - runAudit now iterates V1_DELTAS, populating the deltas map. First delta error short-circuits the audit and propagates the AuditError envelope verbatim. - computeDelta(db, baselineName, baselineRows, spec) — pure function: validates baseline column-set membership, projects baseline rows down to spec.requiredColumns (drops extras — schema-drift-resilient per Q4), runs spec.sql against the live DB via the caller's connection, set-diffs via diffRows. - projectRow helper picks required columns into a fresh object. Pre-req refactor: extract diffRows from cli/cmd-query.ts to src/ diff-rows.ts. Engine importing from cli/ would be a layering back-edge (application → cli); same pattern as src/git-changed.ts where pure helpers needed by both layers live at src/. cli/cmd-query.ts updated to import from the new location; tests moved to src/diff-rows.test.ts; parseQueryRest tests previously mis-nested inside the diffRows describe block re-labeled (functional no-op — describe is just a label — but stops being misleading). Tests: - src/application/audit-engine.test.ts grows from 2 to 9 tests: end-to-end runAudit flow (existing baseline → empty deltas; wrong-shape → error envelope), then 6 computeDelta cases for files (no-diff, added, removed, schema-drift projection, column-mismatch error, empty-baseline-treated-as-all-added). - src/diff-rows.test.ts — 6 multiset cases ported verbatim from cmd-query.test.ts. Smoke: tested against this clone — files-snap baseline saved BEFORE this commit's two new files diff-rows.ts/.test.ts surfaced exactly those two as `added`. wrong-shape baseline saved from `SELECT name FROM symbols` produces: codemap audit: baseline "wrong-shape" is missing required columns for delta "files": got [name], need [path]. Re-save with: codemap query --save-baseline=wrong-shape a query that returns `path` (e.g. `--recipe files-hashes` or `"SELECT path FROM files"`) bun:sqlite null vs better-sqlite3 undefined coercion already handled in the B.6 getQueryBaseline helper; audit reuses it cleanly. * feat(audit): tracer 3 — per-delta baselines (A+B hybrid) + dependencies + deprecated Design fork surfaced during tracer 2 implementation: a baseline saved from `SELECT path FROM files` satisfies the files delta but not dependencies (needs from_path/to_path) or deprecated (needs name/kind/file_path). One baseline can't naturally satisfy every delta. Grilled the user, who picked option A+B (per-delta CLI flags as primary + --baseline <prefix> as auto-resolve sugar). Plan §3 / §6 / §7 / §8 updated inline with the new shape. Engine (src/application/audit-engine.ts): - AuditDelta now carries its own `base` metadata — different deltas can reference different baselines (mixed-baseline audits are first-class; e.g. `--baseline base --dependencies-baseline override`). - AuditEnvelope drops the top-level `base` (was a single source of truth that doesn't fit the per-delta model). New shape: `{head, deltas}`. - AuditBaselineMap = Partial<Record<deltaKey, baselineName>>. Audit iterates the map keys, not V1_DELTAS — only requested deltas run; others are absent from the envelope. - runAudit(opts: {db, baselines}) — empty map errors with a clean "missing snapshot source" message; explicit baseline-not-found errors name the delta key for context. - computeDelta now returns just `{added, removed} | AuditError`; runAudit wraps with the per-delta `base` metadata. Cleaner separation: computeDelta is pure-diff, runAudit is composer. - V1_DELTAS adds two more entries: dependencies + deprecated. Each has its own canonical SQL, required columns, and recipe-id hint for the column-mismatch error message. CLI (src/cli/cmd-audit.ts): - parseAuditRest now handles two flag families: - `--baseline <prefix>`: auto-resolve sugar; looks up `<prefix>-<key>` in query_baselines for each known delta key. Slots that don't exist are silently absent (no error per missing slot — convention-driven users can save just what they need). - `--<key>-baseline <name>`: explicit per-delta override. Names must exist or audit exits 1 with a delta-tagged error message. - PER_DELTA_FLAGS map is generated from V1_DELTAS — adding a delta in the engine surfaces a `--<key>-baseline` flag automatically. - New `resolveAuditBaselines({db, baselinePrefix, perDelta})` exported for testing; per-delta flags override auto-resolved slots. - consumeFlagValue helper consolidates the `--flag <v>` / `--flag=<v>` parsing pattern (used by all four baseline flags). - Error message when no slot resolves explains both flag families + the v1.x --base <ref> path. Help text updated with the new flag matrix + 4 example invocations (convention path, explicit per-delta, mixed override, --no-index). Tests: - src/cli/cmd-audit.test.ts grows from 9 to 16 tests: parser cases for each flag shape (--baseline / --baseline= / --<key>-baseline / --<key>-baseline= / mixed mode / no-value errors) + the new resolveAuditBaselines describe (4 cases covering auto-resolve, per-delta override, per-delta-only, and no-match-empty-map). - src/application/audit-engine.test.ts restructured: 5 runAudit cases (empty map error / explicit-baseline-not-found / single-delta-only / mixed-baseline per-delta `base` metadata / column-mismatch error propagation), 6 computeDelta cases for files (unchanged shape). - src/cli.test.ts integration test asserts the new --help output surface (--baseline <prefix> + all three --<delta>-baseline flags). Smoke (against this clone): codemap query --save-baseline=base-files "SELECT path FROM files" codemap query --save-baseline=base-dependencies "SELECT from_path, to_path FROM dependencies" codemap query --save-baseline=base-deprecated -r deprecated-symbols codemap audit --json --summary --baseline base → {head, deltas: {files: {base, added: 0, removed: 0}, dependencies: {base, added: 2, removed: 0}, deprecated: {base, added: 0, removed: 0}}} codemap audit --files-baseline base-files → only files delta runs codemap audit --baseline nonexistent → exit 1, "no delta baselines provided" with both flag families explained * feat(audit): tracer 5 — terminal-mode renderer per plan §7.1 Per plan §8 step 4. Three output modes from one envelope: No-drift (default terminal): audit: 3 delta(s), no drift across files / dependencies / deprecated. files ← base-files @ abc12345 (no drift) dependencies ← base-dependencies @ abc12345 (no drift) deprecated ← base-deprecated @ abc12345 (no drift) With drift (default terminal): audit: 1 delta(s), drift in 1 (+2 / -0) files ← base-files @ abc12345 (+2 / -0) files added (+2): ┌─────┬──────────────────────┐ │ │ path │ ├─────┼──────────────────────┤ │ 0 │ src/cli/cmd-audit.ts │ │ 1 │ src/diff-rows.ts │ └─────┴──────────────────────┘ --summary (terminal): same header + per-delta lines, no console.table blocks. JSON --summary unchanged from tracer 3. Adapted from §7.1's single-baseline-header sketch to the per-delta `base` shape settled in tracer 3 — each delta carries its own provenance line (`← <name> @ <sha8>`) so mixed-baseline audits (e.g. `--baseline base --dependencies-baseline override`) make their divergence visible without burying it in JSON. Per-delta header layout: - Drifting deltas show counts (`(+N / -M)`); no-drift deltas show `(no drift)` as a literal label so the line shape is uniform. - Per-delta key padded to a column width derived from the longest key — keeps the `←` markers vertically aligned. - Sha rendered as a 8-char prefix (consistent with git's default short-sha length) and elided when `git_ref` is null. Without `--summary`, drifting deltas get added/removed `console.table` blocks one after the other (no `(no results)` placeholders for empty deltas — they're just absent from the expanded output). Smoke (this clone, three baselines saved with the convention): - 3 deltas, no drift → uniform 4-line output (header + 3 lines). - 1 delta, contrived drift via 3-row baseline → header counts match per-delta line counts; `console.table` renders the 169 new paths cleanly. - --summary on both modes drops the row tables, keeps the per-delta provenance. No envelope shape change — this is pure presentation. JSON output unchanged (still `{head, deltas}` with per-delta `base`). * docs(audit): tracer 6 — lift plan into canonical homes; ship & retire docs/plans/codemap-audit.md Final tracer per docs/plans/codemap-audit.md § 8 step 5/6 (plan itself is now deleted per Rule 2: "delete plans on ship; lift the canonical bits into architecture.md"). Lifted into canonical homes: - docs/architecture.md § CLI usage — new "Audit wiring" paragraph next to "Query / Validate / Context wiring": cmd-audit.ts (CLI) + application/audit-engine.ts (engine), V1_DELTAS registry + canonical SQL projections, computeDelta + per-delta `base` metadata, resolveAuditBaselines auto-resolve sugar + per-delta override composition, runAuditCmd's auto-incremental-index prelude with --no-index opt-out, v1 vs v1.x scope (no verdict / no --base <ref>). - docs/glossary.md — new "audit" entry under § A. Disambiguates from `codemap query --baseline` (one query, one diff) and from `fallow audit` (code-quality verdicts — explicit non-goal per roadmap.md § Non-goals). - README.md § CLI — 4 new example lines under the Daily commands block (auto-resolve, --json --summary, explicit per-delta, --no-index). Per Rule 10 (core surface change → both rule + skill in lockstep): - .agents/rules/codemap.md + templates/agents/rules/codemap.md — new "Per-delta audit" CLI table row + new bold "Audit (`codemap audit`)" section explaining the two snapshot-source flag families. - .agents/skills/codemap/SKILL.md + templates/agents/skills/codemap/ SKILL.md — new "Audit" subsection in the Output flags block, covering --baseline / --<delta>-baseline / per-delta `base` metadata / --summary / --no-index / v1 no-verdict + jq idiom / schema-bump-resilient projection. Roadmap entries (docs/roadmap.md): - v1 line replaced with v1.x scope notes for the two deferred slices: --base <ref> (worktree+reindex) and verdict + threshold config. Each carries the explicit revisit trigger settled during the grill-me design pass. Plan deleted: - docs/plans/codemap-audit.md — Plan lifecycle is "delete on ship" per docs/README.md Rule 2 + § Document Lifecycle. The decisions of record (snapshot strategy, delta registry, verdict scope, file layout, terminal output, per-delta baselines design fork) are now in architecture.md / glossary.md / roadmap.md / README.md / rule + skill. Anything else (the grilling rationale, the rejected alternatives, the open-question triggers) lives in the PR description and git log. Patch changeset (no schema bump; reuses query_baselines; pre-v1 default per .agents/lessons.md "changesets bump policy"). * fix(audit): address PR #33 CodeRabbit feedback (1 Major + 3 Minor) All 4 verified correct against the actual code; all applied. Major: - audit-engine.ts: validate baseline rows_json is an array before diffing. JSON.parse("null") / "{}" / "true" all parse successfully but produce non-array values that crash computeDelta on .length / .map. New explicit check returns a structured AuditError naming the actual type so the user knows what to re-save. Tests cover both the null and object cases. Minor: - README.md: add a fourth example line showing the prefix + per-delta override composition (`--baseline base --files-baseline hotfix-files`). The behavior is implemented + tested in resolveAuditBaselines but the README only showed the standalone forms. - cmd-audit.ts: harden consumeFlagValue's two-token path to reject empty-string values (`--flag ""`) and whitespace-only values (`--flag " "`). The `--flag=` path was already strict; the positional path silently accepted these and the failure surfaced later as a less-clear baseline-not-found error. Two new parser tests cover both cases. - SKILL.md (mirrored across .agents/ and templates/agents/ per Rule 10): add the "no slot resolves → exit 1" failure mode to the Audit subsection. The "silently absent" wording read like --baseline <prefix> could produce an empty envelope; clarified that audit errors instead of doing nothing.
1 parent 035ee23 commit 114303f

21 files changed

Lines changed: 1392 additions & 455 deletions

.agents/rules/codemap.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,26 @@ A local database (default **`.codemap.db`**) indexes structure: symbols, imports
1212

1313
## CLI (this repository)
1414

15-
| Context | Incremental index | Query |
16-
| ------------------------------ | ------------------ | --------------------------------------------------------------------------------------------------------- |
17-
| **Default** — from this clone | `bun src/index.ts` | `bun src/index.ts query --json "<SQL>"` |
18-
| Same entry | `bun run dev` | (same as first row) |
19-
| Query (ASCII table — optional) || `bun src/index.ts query "<SQL>"` |
20-
| Recipe || `bun src/index.ts query --json --recipe fan-out` (see **`bun src/index.ts query --help`**) |
21-
| Recipe catalog / SQL || `bun src/index.ts query --recipes-json` · `bun src/index.ts query --print-sql fan-out` |
22-
| Counts only || `bun src/index.ts query --json --summary -r deprecated-symbols` |
23-
| PR-scoped rows || `bun src/index.ts query --json --changed-since origin/main -r fan-out` |
24-
| Bucket by owner / dir / pkg || `bun src/index.ts query --json --group-by directory -r fan-in` |
25-
| Save / diff a baseline || `bun src/index.ts query --save-baseline -r visibility-tags` then `… --json --baseline -r visibility-tags` |
26-
| List / drop baselines || `bun src/index.ts query --baselines` · `bun src/index.ts query --drop-baseline <name>` |
15+
| Context | Incremental index | Query |
16+
| ------------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------- |
17+
| **Default** — from this clone | `bun src/index.ts` | `bun src/index.ts query --json "<SQL>"` |
18+
| Same entry | `bun run dev` | (same as first row) |
19+
| Query (ASCII table — optional) || `bun src/index.ts query "<SQL>"` |
20+
| Recipe || `bun src/index.ts query --json --recipe fan-out` (see **`bun src/index.ts query --help`**) |
21+
| Recipe catalog / SQL || `bun src/index.ts query --recipes-json` · `bun src/index.ts query --print-sql fan-out` |
22+
| Counts only || `bun src/index.ts query --json --summary -r deprecated-symbols` |
23+
| PR-scoped rows || `bun src/index.ts query --json --changed-since origin/main -r fan-out` |
24+
| Bucket by owner / dir / pkg || `bun src/index.ts query --json --group-by directory -r fan-in` |
25+
| Save / diff a baseline || `bun src/index.ts query --save-baseline -r visibility-tags` then `… --json --baseline -r visibility-tags` |
26+
| List / drop baselines || `bun src/index.ts query --baselines` · `bun src/index.ts query --drop-baseline <name>` |
27+
| Per-delta audit || `bun src/index.ts audit --json --baseline base` (auto-resolves `base-files` / `base-dependencies` / `base-deprecated`) |
2728

2829
**Recipe `actions`:** with **`--json`**, recipes that define an `actions` template append it to every row (kebab-case verb + description — e.g. `fan-out``review-coupling`). Under `--baseline`, actions attach to the **`added`** rows only. Inspect via **`--recipes-json`**. Ad-hoc SQL never carries actions.
2930

3031
**Baselines** (`query_baselines` table inside `.codemap.db`, no parallel JSON files): `--save-baseline[=<name>]` snapshots a result set; `--baseline[=<name>]` diffs the current result against it (added / removed rows; identity = `JSON.stringify(row)`). Name defaults to the `--recipe` id; ad-hoc SQL needs an explicit `=<name>`. Survives `--full` and SCHEMA bumps.
3132

33+
**Audit (`bun src/index.ts audit`)**: structural-drift command; emits `{head, deltas: {files, dependencies, deprecated}}` (each delta carries its own `base` metadata). Reuses B.6 baselines as the snapshot source. Two CLI shapes — `--baseline <prefix>` auto-resolves `<prefix>-files` / `<prefix>-dependencies` / `<prefix>-deprecated`; `--<delta>-baseline <name>` is the explicit per-delta override. v1 ships no `verdict` / threshold config — consumers compose `--json` + `jq` for CI exit codes. Auto-runs an incremental index before the diff (use `--no-index` to skip for frozen-DB CI).
34+
3235
After **`bun run build`**, **`node dist/index.mjs`** matches the published **`codemap`** binary (same flags). **`bun link`** / global **`codemap`** also work when testing the packaged CLI.
3336

3437
Index another project: **`--root /path/to/repo`**, or set **`CODEMAP_ROOT`** or **`CODEMAP_TEST_BENCH`** (e.g. in **`.env`** — see [docs/benchmark.md § Indexing another project](../../docs/benchmark.md#indexing-another-project)). Full rebuild: **`--full`**. Targeted re-index: **`--files path/to/a.ts path/to/b.tsx`**.

.agents/skills/codemap/SKILL.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ Replace placeholders (`'...'`) with your module path, file glob, or symbol name.
4646
- **`--baselines`** lists saved baselines (no `rows_json` payload); **`--drop-baseline <name>`** deletes one. Both reject every other flag — they're list-only / drop-only operations.
4747
- **Per-row recipe `actions`** — recipes that define an **`actions: [{type, auto_fixable?, description?}]`** template append it to every row in **`--json`** output (recipe-only; ad-hoc SQL never carries actions). Under `--baseline`, actions attach to the **`added`** rows only (the rows the agent should act on). Inspect via **`--recipes-json`**.
4848

49+
**Audit (`bun src/index.ts audit`)** — separate top-level command for structural-drift verdicts. Composes B.6 baselines into a per-delta `{head, deltas}` envelope; v1 ships `files` / `dependencies` / `deprecated`. Two snapshot-source shapes:
50+
51+
- **`--baseline <prefix>`** — auto-resolves `<prefix>-files` / `<prefix>-dependencies` / `<prefix>-deprecated` in `query_baselines`. Slots that don't exist are silently absent (the convention-following user just saves what they need). **If no slot resolves at all** (every auto-resolved name is missing AND no `--<delta>-baseline` flag is passed), audit exits 1 — never produces an empty envelope.
52+
- **`--<delta>-baseline <name>`** — explicit per-delta override (e.g. `--files-baseline X --dependencies-baseline Y`). Names must exist or audit exits 1. Composes with `--baseline` (per-delta flag overrides one slot).
53+
54+
Each emitted delta carries its own `base` metadata so mixed-baseline audits are first-class. `--summary` collapses each delta to `{added: N, removed: N}`. `--no-index` skips the auto-incremental-index prelude (default is to re-index first so `head` reflects current source). v1 ships no `verdict` / threshold config — `codemap audit --json | jq -e '.deltas.dependencies.added | length <= 50'` is the CI exit-code idiom until v1.x ships native thresholds. Each delta pins a canonical SQL projection and validates baseline column-set membership before diffing — schema-bump-resilient (extras dropped, missing columns surface a clean re-save command).
55+
4956
**Determinism:** Bundled recipes use stable secondary **`ORDER BY`** tie-breakers (and ordered inner **`LIMIT`** samples where applicable). Prefer **`--recipe`** over pasting SQL when you need the maintained ordering. **Canonical SQL** is **`src/cli/query-recipes.ts`** (`QUERY_RECIPES`).
5057

5158
The blocks below match **`fan-out`** and **`fan-out-sample`** in **`QUERY_RECIPES`**; other recipes align with “Conditional aggregation”, “Codebase statistics”, and component sections later in this skill.

.changeset/codemap-audit-v1.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@stainless-code/codemap": patch
3+
---
4+
5+
`codemap audit` (B.5 v1) — structural-drift command emitting `{head, deltas}` where each `deltas[<key>]` carries `{base, added, removed}`. Three v1 deltas: `files`, `dependencies`, `deprecated`. Two snapshot-source shapes — `--baseline <prefix>` (auto-resolves `<prefix>-files` / `<prefix>-dependencies` / `<prefix>-deprecated` in `query_baselines`) and `--<delta>-baseline <name>` (explicit per-delta override; composes with `--baseline`). Reuses B.6 baselines; no schema bump. `--summary` collapses to per-delta counts; `--no-index` skips the auto-incremental-index prelude. v1 ships no `verdict` / threshold config — consumers compose `--json` + `jq` for CI exit codes (v1.x slice). `--base <ref>` (worktree+reindex snapshot) defers to v1.x.

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@ codemap query --baseline=pre-refactor "SELECT file_path FROM symbols"
9494
codemap query --baselines # list saved baselines
9595
codemap query --drop-baseline visibility-tags # delete
9696
# --group-by is mutually exclusive with --save-baseline / --baseline (different output shapes)
97+
# Diff per-delta baselines vs current — files / dependencies / deprecated drift in one envelope
98+
codemap query --save-baseline=base-files "SELECT path FROM files"
99+
codemap query --save-baseline=base-dependencies "SELECT from_path, to_path FROM dependencies"
100+
codemap query --save-baseline=base-deprecated -r deprecated-symbols
101+
codemap audit --baseline base # auto-resolves base-{files,dependencies,deprecated}
102+
codemap audit --json --summary --baseline base # counts-only — useful for CI dashboards
103+
codemap audit --files-baseline base-files # explicit per-delta — runs only the slots provided
104+
codemap audit --baseline base --files-baseline hotfix-files # mixed — auto-resolve deps + deprecated; override files
105+
codemap audit --baseline base --no-index # skip the auto-incremental-index prelude (frozen-DB CI)
97106
# Recipes that define per-row action templates append "actions" hints (kebab-case verb +
98107
# description) in --json output; ad-hoc SQL never carries actions. Inspect via --recipes-json.
99108
# List bundled recipes as JSON, or print one recipe's SQL (no DB required)

docs/architecture.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ A local SQLite database (`.codemap.db`) indexes the project tree and stores stru
121121

122122
**Validate wiring:** **`src/cli/cmd-validate.ts`****`computeValidateRows`** is a pure function over `(db, projectRoot, paths)` returning `{path, status}` rows where `status ∈ stale | missing | unindexed`. CLI wraps it with read-once-and-print + exits **1** on any drift (git-status semantics). Path normalization: **`toProjectRelative`** converts CLI input to POSIX-style relative keys matching the `files.path` storage format (Windows backslash → forward slash); same convention as `lint-staged.config.js`.
123123

124+
**Audit wiring:** **`src/cli/cmd-audit.ts`** (argv, `--baseline <prefix>` auto-resolve sugar, `--<key>-baseline <name>` per-delta explicit overrides, `--json`, `--summary`, `--no-index`) + **`src/application/audit-engine.ts`** (delta registry + diff). Mirrors the `cmd-index.ts ↔ application/index-engine.ts` seam — CLI parses + dispatches; engine does the diff. **`runAudit({db, baselines})`** iterates the per-delta baseline map; deltas absent from the map don't run. Each entry in **`V1_DELTAS`** pins a canonical SQL projection (`files`: `SELECT path FROM files`; `dependencies`: `SELECT from_path, to_path FROM dependencies`; `deprecated`: `SELECT name, kind, file_path FROM symbols WHERE doc_comment LIKE '%@deprecated%'`) plus a `requiredColumns` list. **`computeDelta`** validates baseline column-set membership, projects baseline rows down to the canonical column subset (extras dropped — schema-drift-resilient), runs the canonical SQL via the caller's DB connection, and set-diffs via the existing **`src/diff-rows.ts`** multiset helper (shared with `query --baseline`). Each emitted delta carries its own **`base`** metadata so mixed-baseline audits (e.g. `--baseline base --dependencies-baseline override`) are first-class. **`runAuditCmd`** runs an auto-incremental-index prelude (`runCodemapIndex({mode: "incremental", quiet: true})`) before the diff so `head` reflects the current source — `--no-index` opts out for frozen-DB CI scenarios. **`resolveAuditBaselines({db, baselinePrefix, perDelta})`** composes the baseline map: auto-resolves `<prefix>-<delta-key>` for slots that exist (silently absent otherwise) and lets per-delta flags override individual slots. v1 ships no `verdict` / threshold config / non-zero exit codes — consumers compose `--json` + `jq` for CI exit codes; v1.x adds `verdict` + `codemap.config.audit` thresholds + `--base <ref>` (worktree+reindex snapshot strategy).
125+
124126
**Context wiring:** **`src/cli/cmd-context.ts`****`buildContextEnvelope`** composes the JSON envelope from existing recipes (`fan-in` for `hubs`, `markers` SELECT for `sample_markers`, `QUERY_RECIPES` map for the catalog). **`classifyIntent`** maps `--for "<text>"` to one of `refactor | debug | test | feature | explore | other` via regex against the trimmed input; whitespace-only intents are rejected. `--compact` drops `hubs` + `sample_markers` and emits one-line JSON; otherwise pretty-prints with 2-space indent.
125127

126128
**Performance wiring:** **`--performance`** plumbs through **`RunIndexOptions.performance`****`indexFiles({ performance, collectMs })`**. `parse-worker-core.ts` records per-file **`parseMs`** on each `ParsedFile`; main thread times the four phases (`collect`, `parse`, `insert`, `index_create`) and assembles **`IndexPerformanceReport`** under `IndexRunStats.performance`. Note: `total_ms` is `indexFiles` wall-clock, **not** end-to-end run wall — `collect_ms` happens before `indexFiles` and is reported separately.

docs/glossary.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ See **language adapter**.
3131

3232
A `.agents/rules/<name>.md` file with YAML frontmatter. Distinct from a **skill** (longer, scenario-specific). Distinct from a **bundled recipe** (which is SQL, not Markdown).
3333

34+
### audit
35+
36+
Two-snapshot structural-drift command: `codemap audit --baseline <prefix>` (or `--<delta>-baseline <name>`) diffs the live `.codemap.db` against per-delta saved baselines (B.6) and emits `{head, deltas}` where each `deltas[<key>]` carries `{base, added, removed}`. v1 ships three deltas: `files`, `dependencies`, `deprecated`. Each delta pins a canonical SQL projection (in `V1_DELTAS`) and a required-columns list — projects baseline rows down to that subset before diffing so schema bumps that add columns don't break pre-bump baselines. Distinct from `codemap query --baseline` (that's one query, one diff; audit composes multiple per-delta diffs into one envelope). Distinct from `fallow audit` (that runs code-quality verdicts — dead code, dupes, complexity — which are explicit non-goals per [`roadmap.md` § Non-goals (v1)](./roadmap.md#non-goals-v1); codemap audit stays structural).
37+
3438
---
3539

3640
## B

0 commit comments

Comments
 (0)