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>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9ad5cd7ba2
commit
c8cca9a601
@@ -72,9 +72,16 @@ describe.skipIf(!kernelBuilt)('kernel scaffold', () => {
|
||||
expect(info.languages).toContain('javascript');
|
||||
});
|
||||
|
||||
it('no language routes to the kernel by default (R1: wasm path unchanged)', () => {
|
||||
it('TS/JS family routes to the kernel by default (R3 default-on); others stay wasm', () => {
|
||||
for (const lang of ['typescript', 'tsx', 'javascript', 'jsx'] as const) {
|
||||
expect(kernelRoutes(lang), lang).toBe(true);
|
||||
}
|
||||
expect(kernelRoutes('python')).toBe(false);
|
||||
expect(tryKernelExtract('src/a.py', 'def f():\n pass\n', 'python')).toBeNull();
|
||||
// CODEGRAPH_KERNEL_LANGS REPLACES the default set when present.
|
||||
process.env.CODEGRAPH_KERNEL_LANGS = 'tsx';
|
||||
expect(kernelRoutes('typescript')).toBe(false);
|
||||
expect(tryKernelExtract('src/a.ts', 'function f() {}', 'typescript')).toBeNull();
|
||||
expect(kernelRoutes('tsx')).toBe(true);
|
||||
});
|
||||
|
||||
describe('with typescript routed (CODEGRAPH_KERNEL_LANGS)', () => {
|
||||
@@ -170,12 +177,14 @@ describe.skipIf(!kernelBuilt)('kernel scaffold', () => {
|
||||
await loadGrammarsForLanguages(['typescript']);
|
||||
});
|
||||
|
||||
it('unrouted language flows through the wasm extractor unchanged', () => {
|
||||
// `const f = () => 1` yields a function node on the wasm path; the seed
|
||||
// kernel query deliberately doesn't extract it — so its presence proves
|
||||
// which path ran.
|
||||
it('kill switch routes through the wasm extractor unchanged', () => {
|
||||
process.env.CODEGRAPH_KERNEL = '0';
|
||||
const result = extractFromSource('src/a.ts', 'export const f = () => 1;\n', 'typescript');
|
||||
expect(result.nodes.some((n) => n.kind === 'function' && n.name === 'f')).toBe(true);
|
||||
delete process.env.CODEGRAPH_KERNEL;
|
||||
// Default-routed path produces the same node (R2 parity).
|
||||
const viaKernel = extractFromSource('src/a.ts', 'export const f = () => 1;\n', 'typescript');
|
||||
expect(viaKernel.nodes.some((n) => n.kind === 'function' && n.name === 'f')).toBe(true);
|
||||
});
|
||||
|
||||
it('routed language takes the kernel and falls back per file on kernel absence', () => {
|
||||
|
||||
@@ -110,6 +110,21 @@ describe.skipIf(!kernelBuilt)('kernel TS/JS extraction parity', () => {
|
||||
assertParity(rel, fs.readFileSync(file, 'utf8'), 'typescript');
|
||||
});
|
||||
|
||||
it('files with parse errors defer to the wasm extractor (recovery is encoding-dependent)', () => {
|
||||
// tree-sitter error RECOVERY differs between UTF-8 (native) and UTF-16
|
||||
// (web-tree-sitter) parsing — same grammar, same core version — so the
|
||||
// kernel defers any erroring file to keep routing graph-neutral.
|
||||
const broken = 'export function f( {\n return }} 12 (\n';
|
||||
process.env.CODEGRAPH_KERNEL_LANGS = 'all';
|
||||
delete process.env.CODEGRAPH_KERNEL;
|
||||
expect(tryKernelExtract('src/broken.ts', broken, 'typescript')).toBeNull();
|
||||
// The seam still serves the file — through the wasm path.
|
||||
process.env.CODEGRAPH_KERNEL = '0';
|
||||
const viaWasm = extractFromSource('src/broken.ts', broken, 'typescript');
|
||||
delete process.env.CODEGRAPH_KERNEL;
|
||||
expect(viaWasm.nodes.some((n) => n.kind === 'file')).toBe(true);
|
||||
});
|
||||
|
||||
it('typescript fixture parsed as plain typescript variant', () => {
|
||||
// Same content through the non-tsx grammar exercises the typescript
|
||||
// (vs tsx) LangSpec pairing.
|
||||
|
||||
Reference in New Issue
Block a user