Files
Colby McHenry c8cca9a601 feat(kernel): R3 — TS/JS equivalence gate passed, kernel default-on
Gate evidence (docs/design/rust-kernel-migration-plan.md §4b):

- Graph parity, byte-identical (stronger than the §5 ≤0.5% bar): full
  codegraph-init dump-diffs kernel-vs-wasm on express (13,712 rows),
  excalidraw (89,898), and vscode (2,378,238 rows) — identical bytes.
  Python control repo (flask) identical + timing unchanged. The parity
  harness is now ORDER-sensitive (emission order drives rowids, which
  drive resolution order) and dumps come from the new
  scripts/dump-graph.mjs (natural keys, no rowids/timestamps).

- The one real find, caught by the vscode tier: tree-sitter error
  RECOVERY is encoding-dependent — byte-identical grammar sources and
  the same core (0.25.10) recover erroring files differently under
  UTF-8 (native) vs UTF-16 (web-tree-sitter) parsing; proven by
  reproducing the wasm tree with a native UTF-16 parse. Policy: the
  kernel defers any file whose tree has_error() to the wasm extractor
  (silent 'defer:' signal, per file) — parity by construction on
  erroring files (incidence 0-0.42% across the gate repos), and the
  harness fails if deferrals exceed 10% so a broken kernel can't hide
  behind the fallback.

- Retrieval invariants: canonical excalidraw flow (mutateElement →
  renderStaticScene) connects end-to-end on the kernel-indexed graph;
  synthesized-edge families present. Agent A/B is vacuous under
  byte-identical DBs (same justification as #1320-#1322).

- Perf: vscode init 105.4s → 82.1s (1.28×) on an 11-core Mac;
  excalidraw on a 2-CPU/6GB Linux container (the CI-runner envelope)
  6.2-7.1s → 4.3-4.8s (~1.5×). Linux arm64 in-container build: all 22
  kernel tests green under CODEGRAPH_KERNEL_EXPECT=1. Windows VM leg
  deferred (VM stopped; prlctl start needs Parallels Pro) — benign: a
  missing .node falls back to wasm, and the release matrix builds and
  gates the win32 prebuilds.

- Full suite: 2,465 tests pass WITH default-on routing, so the entire
  extraction corpus now exercises the kernel for TS/JS wherever a
  .node is staged.

DEFAULT_ROUTED = {typescript, tsx, javascript, jsx}. Override:
CODEGRAPH_KERNEL_LANGS (replaces the set) / CODEGRAPH_KERNEL=0 (kill).
Changelog entry added under [Unreleased].

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:50:02 -05:00

58 lines
2.0 KiB
JavaScript

#!/usr/bin/env node
/**
* Dump a .codegraph/codegraph.db graph by NATURAL KEYS (no rowids, no
* timestamps), sorted — two dumps diff clean iff the graphs are semantically
* identical. The byte-identical gate used by every perf/kernel PR:
*
* node scripts/dump-graph.mjs <repo-or-db> > a.dump
* node scripts/dump-graph.mjs <repo-or-db> > b.dump
* diff a.dump b.dump
*
* Volatile fields excluded: nodes.updated_at, files.modified_at/indexed_at/
* content_hash+size (environment-dependent), edges.id / unresolved_refs.id
* (insertion rowids), and unresolved_refs.status (resolution bookkeeping —
* kept, actually: status is deterministic given the same input; excluded only
* if it proves flaky. We keep status.)
*/
import { DatabaseSync } from 'node:sqlite';
import * as fs from 'node:fs';
import * as path from 'node:path';
const arg = process.argv[2];
if (!arg) {
console.error('usage: dump-graph.mjs <repo-root-or-db-path>');
process.exit(2);
}
let dbPath = arg;
if (fs.statSync(arg).isDirectory()) {
dbPath = path.join(arg, '.codegraph', 'codegraph.db');
}
const db = new DatabaseSync(dbPath, { readOnly: true });
function dump(title, sql) {
const rows = db.prepare(sql).all();
const lines = rows.map((r) => JSON.stringify(r)).sort();
process.stdout.write(`== ${title} (${lines.length})\n`);
for (const l of lines) process.stdout.write(l + '\n');
}
dump(
'nodes',
`SELECT id, kind, name, qualified_name, file_path, language, start_line, end_line,
start_column, end_column, docstring, signature, visibility, is_exported,
is_async, is_static, is_abstract, decorators, type_parameters, return_type
FROM nodes`
);
dump(
'edges',
`SELECT source, target, kind, metadata, line, col, provenance FROM edges`
);
dump(
'refs',
`SELECT from_node_id, reference_name, reference_kind, line, col, candidates,
file_path, language, status, name_tail
FROM unresolved_refs`
);
dump('files', `SELECT path, language, node_count FROM files`);