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
docs(plan): tighten Bun-native API references (file read + perf note)
Plan correctly inherits the established Node vs Bun runtime split, but the
single tracer-3 reference understated it. Now:
- Tracer 3 cites `packaging.md § Node vs Bun` as the canonical pattern
source instead of pointing at config.ts in passing.
- Performance section calls out the actual lever — `Bun.file(path).json()`
uses Bun's native JSON parser, materially faster than V8 `JSON.parse`
on multi-MB Istanbul payloads (real coverage files for medium codebases
routinely hit several MB).
No new Bun-native API surfaces are added — the feature doesn't need
globbing, file writes, spawn, or hashing beyond what the existing engines
already use through their abstractions.
| 1 | **Schema + bump** in `src/db.ts`. Add the `coverage` table DDL (natural-key PK per D6 — no FK to `symbols.id`); bump `SCHEMA_VERSION`; add `coverage` to the `query_baselines`-style "preserve across `--full`" exclusion in `dropAll()`. Add `idx_coverage_file_name`. New `meta` keys (`coverage_last_ingested_at` / `_path` / `_source`) need no DDL — `meta` is `(key, value)` already. Unit test (`src/db.test.ts`) inserts + reads back one row; verifies the table survives a `dropAll()` + `createSchema()` round-trip; verifies the orphan-cleanup DELETE removes rows whose `file_path` is no longer in `files`. | Table exists; survives `--full`; orphan sweep works. |
112
112
| 2 | **Istanbul ingester engine** in `src/application/coverage-engine.ts` (new). `ingestCoverage({db, payload, projectRoot}) → {ingested, skipped, pruned_orphans, source}`. Pure: parses the Istanbul JSON shape (`{ [absPath]: {statementMap, s, fnMap, f, branchMap, b, path} }`); maps each statement to the **innermost** enclosing symbol via the SQL `(line_end - line_start) ASC LIMIT 1` projection (D7); upserts `coverage` keyed on `(file_path, name, line_start)`; writes the three meta keys; runs the orphan-cleanup DELETE. Computes `coverage_pct = total_statements > 0 ? hit / total * 100 : NULL`. Reuses `toProjectRelative` from `validate-engine` (D8). Unit tests cover: fresh ingest; re-ingest (UPSERT idempotence); unmatched file → `skipped.unmatched_files`; statement outside every symbol → `skipped.statements_no_symbol`; symbol with 0 statements → no row; nested closure → innermost wins; `total_statements = 0` → `coverage_pct IS NULL`; orphan cleanup after a file deletion. | Pure engine; deterministic upsert; no FS / process side effects beyond `db.run`. |
113
-
| 3 | **CLI verb** `cli/cmd-ingest-coverage.ts` — parses `<path>` + `--source` (auto-detect default) + `--json`, reads the file (`Bun.file` on Bun, `readFile` on Node — same split as `config.ts`), dispatches to `coverage-engine`, renders the result. `main.ts` dispatcher gains the verb between existing entries. Help text in `bootstrap.ts` lists the new command. Unit tests cover: file-not-found, malformed JSON, source-mismatch error (`--source lcov` reserved for v1.x → v1 returns "lcov ingester not yet implemented"), `--json` envelope shape (including `pruned_orphans`). | `bun src/index.ts ingest-coverage fixtures/coverage/coverage-final.json` writes rows; `--help` lists the verb. |
113
+
| 3 | **CLI verb** `cli/cmd-ingest-coverage.ts` — parses `<path>` + `--source` (auto-detect default) + `--json`, reads the JSON via the established runtime split (`Bun.file(path).json()` on Bun for the native-parser perf win on large coverage payloads; `readFile + JSON.parse` on Node) — see [`packaging.md § Node vs Bun`](../packaging.md#node-vs-bun) for the canonical pattern, mirrors `config.ts`. Dispatches to `coverage-engine`, renders the result. `main.ts` dispatcher gains the verb between existing entries. Help text in `bootstrap.ts` lists the new command. Unit tests cover: file-not-found, malformed JSON, source-mismatch error (`--source lcov` reserved for v1.x → v1 returns "lcov ingester not yet implemented"), `--json` envelope shape (including `pruned_orphans`). | `bun src/index.ts ingest-coverage fixtures/coverage/coverage-final.json` writes rows; `--help` lists the verb. |
114
114
| 4 | **Fixture coverage data** — `fixtures/minimal/coverage/coverage-final.json` (small Istanbul shape covering the existing fixture symbols partially: e.g. `usePermissions` 100%, `legacyClient` 0%, `now` 50%). Golden query under `fixtures/golden/minimal/coverage-deprecated.json` exercises the killer recipe ("`@deprecated` symbols with `coverage_pct = 0`"). Adds the fixture row to `fixtures/minimal/README.md` "What's exercised" table. The pre-enriched `legacyClient` / `now` / `epochMs` deprecated symbols (PR #55) directly test the join axis — no new fixture symbols needed beyond the coverage JSON itself. | Golden recipe passes; documents how a real consumer wires `bun test --coverage` into the workflow. |
115
115
| 5 | **Doc + agent rule + skill + changeset + plan deletion** — `docs/architecture.md` § Persistence wiring (new tables, ingester engine, CLI verb), `docs/glossary.md` (`coverage_pct`, `file_coverage`, "Istanbul JSON", "static coverage ingestion"), `.agents/rules/codemap.md` + `templates/agents/rules/codemap.md` (Rule 10 lockstep — new trigger pattern: "What's untested AND structurally dead?", new SQL example), skill SKILL.md `coverage` table row, README.md "What's exercised" + Use section. Minor changeset noting the `SCHEMA_VERSION` bump + the explicit re-ingest needed after upgrade. Plan deleted per `docs/README.md` Rule 3. | All docs consistent; agents see the new tables on next `codemap agents init`. |
116
116
117
117
## Performance considerations
118
118
119
-
-**Ingest cost** — one `JSON.parse` + linear scan of statement maps + one symbol-projection SQL per statement. Per-statement projection is the hot path; backed by `idx_symbols_file` it's an index-bounded lookup. No published benchmark yet — call out as a measurement target during tracer 2.
119
+
-**Ingest cost** — one JSONparse + linear scan of statement maps + one symbol-projection SQL per statement. Per-statement projection is the hot path; backed by `idx_symbols_file` it's an index-bounded lookup. On Bun, the JSON parse uses `Bun.file(path).json()` (native parser, materially faster than V8 `JSON.parse` on multi-MB Istanbul payloads); on Node it's `readFile + JSON.parse`. No published benchmark yet — measurement target during tracer 2.
120
120
-**Read cost** — `coverage` is `WITHOUT ROWID` on `(file_path, name, line_start)`. The killer recipe's `LEFT JOIN coverage ON file_path AND name AND line_start` is a 3-column composite-PK lookup per row; `idx_coverage_file_name` covers the prefix.
121
121
-**Storage** — three INTEGER + one REAL + two short TEXT per row; small. Real disk impact dominated by symbol count, not coverage shape.
122
122
-**No background worker.** Ingest is single-pass; reindex is unaffected.
0 commit comments