Skip to content

Commit cdedd9e

Browse files
committed
docs(audit-base): sync README + architecture + glossary + agent rule/skill + changeset (Tracer 5)
- README.md: 'audit --base origin/main' code block + cache caveat - docs/architecture.md: Audit wiring extended with --base details (worktree + atomic populate + cache + LRU + non-git error + GIT_* env hygiene); audit-engine.ts inventory mentions runAuditFromRef + makeWorktreeReindex; audit-worktree.ts added to application/ inventory - docs/glossary.md: 'audit --base / git-ref baseline' entry; existing 'audit' entry now mentions 3 mutually-exclusive sources - docs/roadmap.md: drop the v1.x backlog item (it shipped) - docs/research/fallow.md: B.5 row updated to 'v1 + v1.x partial shipped'; Adjacent-shipped bullet referencing PR #51 (plan) + #52 (impl) - .agents/rules/codemap.md + templates/agents/rules/codemap.md: new 'Audit vs git ref' table row + paragraph rewrite (Rule 10 lockstep) - .agents/skills/codemap/SKILL.md + templates/agents/skills/codemap/SKILL.md: audit tool args + behavior reflect new 'base' field (Rule 10 lockstep) - src/agents-init.ts: ensureGitignoreCodemapPattern now adds '.codemap/audit-cache/' alongside '.codemap.*' (the audit cache lives inside .codemap/ but .codemap/recipes/ stays git-tracked); test updated. - .changeset/codemap-audit-base.md: minor — full design rationale - docs/plans/audit-base.md: deleted per docs-governance Rule 3
1 parent 30c79a3 commit cdedd9e

13 files changed

Lines changed: 95 additions & 173 deletions

File tree

.agents/rules/codemap.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ A local database (default **`.codemap.db`**) indexes structure: symbols, imports
2525
| Save / diff a baseline || `bun src/index.ts query --save-baseline -r visibility-tags` then `… --json --baseline -r visibility-tags` |
2626
| List / drop baselines || `bun src/index.ts query --baselines` · `bun src/index.ts query --drop-baseline <name>` |
2727
| Per-delta audit || `bun src/index.ts audit --json --baseline base` (auto-resolves `base-files` / `base-dependencies` / `base-deprecated`) |
28+
| Audit vs git ref || `bun src/index.ts audit --base origin/main --json` — worktree+reindex against any committish; sub-100ms second run via sha-keyed cache. Mutually exclusive with `--baseline`; per-delta overrides compose. |
2829
| MCP server (for agent hosts) || `bun src/index.ts mcp [--watch] [--debounce <ms>]` — JSON-RPC on stdio; one tool per CLI verb. See **MCP** section below. |
2930
| HTTP server (for non-MCP) || `bun src/index.ts serve [--host 127.0.0.1] [--port 7878] [--token <secret>] [--watch] [--debounce <ms>]` — same tool taxonomy over POST /tool/{name}. |
3031
| Watch mode (live reindex) || `bun src/index.ts watch [--debounce 250] [--quiet]` — long-running; debounced reindex on file changes. Combine with `mcp --watch` / `serve --watch` (or `CODEMAP_WATCH=1`) so every tool reads a live index without per-request prelude. |
@@ -52,7 +53,7 @@ Validation: SQL is rejected at load time if it starts with DML/DDL (DELETE/DROP/
5253

5354
**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.
5455

55-
**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).
56+
**Audit (`bun src/index.ts audit`)**: structural-drift command; emits `{head, deltas: {files, dependencies, deprecated}}` (each delta carries its own `base` metadata). Three mutually-exclusive snapshot sources: `--base <ref>` materialises a git committish via `git worktree add` to a sha-keyed cache under `.codemap/audit-cache/`, reindexes a temp DB, then diffs (sub-100ms second run; requires git; `base.source: "ref"`); `--baseline <prefix>` auto-resolves `<prefix>-files` / `<prefix>-dependencies` / `<prefix>-deprecated` from saved B.6 baselines (`base.source: "baseline"`); `--<delta>-baseline <name>` is the explicit per-delta override (composes with both). 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).
5657

5758
**Targeted reads (`show` / `snippet`)**: precise lookup by exact symbol name without composing SQL. `show` returns metadata (`file_path:line_start-line_end` + `signature`); `snippet` returns the source text from disk plus `stale` / `missing` flags. Both share the same flag set (`--kind <k>` to filter by `symbols.kind`, `--in <path>` for file-scope filter — directory prefix or exact file). Output envelope is `{matches, disambiguation?}` — single match → `{matches: [{...}]}`; multi-match adds `disambiguation: {n, by_kind, files, hint}` so agents narrow without re-scanning. Name match is exact / case-sensitive — for fuzzy use `query` with `LIKE '%name%'`. Snippet stale-file behavior: `source` is always returned when the file exists; `stale: true` means the line range may have shifted (re-index with `bun src/index.ts` or `--files <path>` before acting on the source).
5859

.agents/skills/codemap/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Each emitted delta carries its own `base` metadata so mixed-baseline audits are
6565
- **`query`** — one SQL statement. Args: `{sql, summary?, changed_since?, group_by?, format?}`. Same envelope as `codemap query --json`. Pass `format: "sarif"` or `"annotations"` to receive a formatted text payload (SARIF 2.1.0 doc / `::notice` lines); ad-hoc SQL gets `rule.id = codemap.adhoc`. Format is incompatible with `summary` / `group_by` (parser rejects with a structured `{error}`).
6666
- **`query_batch`** — MCP-only, no CLI counterpart. Args: `{statements: (string | {sql, summary?, changed_since?, group_by?})[], summary?, changed_since?, group_by?}`. Items are bare SQL strings (inherit batch-wide flag defaults) or objects (override on a per-key basis). Output is N-element array; per-element shape mirrors single-`query`'s output for that statement's effective flag set. Per-statement errors are isolated — failed statements return `{error}` in their slot; siblings still execute. SQL-only (no `recipe` polymorphism in items). `format` deferred to v1.x — annotation/sarif on a heterogeneous batch is awkward; call `query` per recipe instead.
6767
- **`query_recipe`**`{recipe, summary?, changed_since?, group_by?, format?}`. Resolves the recipe id to SQL + per-row actions, then executes like `query`. Unknown recipe id returns a structured `{error}` pointing at the `codemap://recipes` resource. With `format: "sarif"`, `rule.id = codemap.<recipe>`, `rule.shortDescription` = recipe description, `rule.fullDescription` = the recipe's `<id>.md` body.
68-
- **`audit`**`{baseline_prefix?, baselines?: {files?, dependencies?, deprecated?}, summary?, no_index?}`. Composes per-delta baselines into the `{head, deltas}` envelope. Auto-runs incremental index unless `no_index: true`.
68+
- **`audit`**`{base?, baseline_prefix?, baselines?: {files?, dependencies?, deprecated?}, summary?, no_index?}`. Composes per-delta snapshots into the `{head, deltas}` envelope. Three mutually-exclusive top-level sources: `base: <ref>` (git committish — worktree+reindex against any committish; sha-keyed cache under `.codemap/audit-cache/`; sub-100ms second run; requires git, errors cleanly on non-git projects); `baseline_prefix: "<prefix>"` (auto-resolve `<prefix>-{files,dependencies,deprecated}` from `query_baselines`); `baselines: {<key>: <name>}` (per-delta override — composes orthogonally with both). Per-delta `base.source` is `"ref"` (with `base.ref` + `base.sha`) or `"baseline"` (with `base.name` + `base.sha`). Auto-runs incremental index unless `no_index: true`; watch-active sessions skip the prelude automatically.
6969
- **`save_baseline`** — polymorphic `{name, sql? | recipe?}` with runtime exclusivity check (mirrors the CLI's single `--save-baseline=<name>` verb). Pass exactly one of `sql` or `recipe`.
7070
- **`list_baselines`** — no args; returns the array `codemap query --baselines --json` would print.
7171
- **`drop_baseline`**`{name}`. Returns `{dropped: <name>}` on success or `isError` if the name doesn't exist.

.changeset/codemap-audit-base.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
"@stainless-code/codemap": minor
3+
---
4+
5+
`codemap audit --base <ref>` — ad-hoc structural-drift audit against any git committish (`origin/main`, `HEAD~5`, `<sha>`, tag, …). Closes the highest-frequency post-watch agent loop: "what changed structurally between this branch and `origin/main`?". Replaces today's 3-step `--baseline` dance (switch branches, reindex, save baselines, switch back) with one verb.
6+
7+
**Three transports, one engine:**
8+
9+
- **CLI:** `codemap audit --base <ref> [--<delta>-baseline <name>] [--summary] [--json] [--no-index]`
10+
- **MCP tool:** `audit` with new `base?: string` arg
11+
- **HTTP:** `POST /tool/audit` (auto-wired via the existing dispatcher)
12+
13+
All three dispatch the same pure `runAuditFromRef` engine in `application/audit-engine.ts`.
14+
15+
**How it works:**
16+
17+
1. `git rev-parse --verify "<ref>^{commit}"` resolves `<ref>` to a sha (clean error on non-git or unresolvable ref).
18+
2. Cache lookup at `<projectRoot>/.codemap/audit-cache/<sha>/.codemap.db`. Hit → sub-100ms; miss → continue.
19+
3. **Atomic populate**`git worktree add` to a per-pid temp dir + `runCodemapIndex({mode: "full"})` against the worktree's `.codemap.db` + POSIX `rename` claims the final `<sha>/` slot. Concurrent CI matrix runs against the same sha race-safely without lock files (loser's rename fails with EEXIST → falls through to cache hit).
20+
4. Run each delta's canonical SQL on the cached DB vs the live DB; `diffRows` (existing helper) computes `{added, removed}`.
21+
5. Compose `AuditEnvelope` with per-delta `base.source: "ref"` (new value) + `base.ref` (user-supplied string) + `base.sha` (resolved).
22+
23+
**Decisions worth knowing:**
24+
25+
- **`AuditBase` is now a discriminated union** — existing `{source: "baseline", name, sha, indexed_at}` rows untouched; new `{source: "ref", ref, sha, indexed_at}` arm. Consumers narrowing on `base.source` keep compiling.
26+
- **Mutually exclusive with `--baseline <prefix>`.** Parser + handler both guard. Per-delta `--<key>-baseline` overrides compose orthogonally with both, so `--base origin/main --files-baseline pre-refactor-files` is valid (mixed sources).
27+
- **Eviction:** hardcoded LRU 5 entries / 500 MiB; `git worktree remove --force` + `rm -rf` for each victim. Orphan `.tmp.*` dirs older than 10 min get swept on the next cycle. No config knobs in v1; defer to v1.x+ if real consumers ask.
28+
- **Hard error on non-git projects.** No graceful fallback — there's no meaningful "ref" without git. The other audit modes (`--baseline`, `--<delta>-baseline`) still work without git.
29+
- **Env hygiene.** All git spawns in `audit-worktree.ts` strip inherited `GIT_*` env vars so a containing git operation (e.g. running codemap from a husky hook) doesn't route worktree calls at the wrong index.
30+
31+
**Auto-`.gitignore`:** `codemap agents init` now adds `.codemap/audit-cache/` alongside `.codemap.*` so cached worktrees never get committed. `.codemap/recipes/` stays git-tracked.
32+
33+
Plan: PR #51 (merged). Implementation: PR #52.

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ codemap audit --json --summary --baseline base # counts-only
103103
codemap audit --files-baseline base-files # explicit per-delta — runs only the slots provided
104104
codemap audit --baseline base --files-baseline hotfix-files # mixed — auto-resolve deps + deprecated; override files
105105
codemap audit --baseline base --no-index # skip the auto-incremental-index prelude (frozen-DB CI)
106+
codemap audit --base origin/main --json # ad-hoc — worktree+reindex against any committish; no --save-baseline needed
107+
codemap audit --base v1.0.0 --files-baseline pre-release-files # mix --base with per-delta override
108+
# --base materialises <ref> via `git worktree add` to .codemap/audit-cache/<sha>/, reindexes into
109+
# a temp DB, then diffs. Cache hit on second run against same sha is sub-100ms. Requires git;
110+
# non-git projects get a clean `--base requires a git repository` error.
106111
# Recipes that define per-row action templates append "actions" hints (kebab-case verb +
107112
# description) in --json output; ad-hoc SQL never carries actions. Inspect via --recipes-json.
108113
# --format <text|json|sarif|annotations> — pipe results into GitHub Code Scanning (SARIF

0 commit comments

Comments
 (0)