Status: spike validated 2026-07-16; project approved, not yet started. Owner context: the last structural lever for fresh-index wall clock after the 2026-07-16 arc (#1305, #1320, #1321, #1322) exhausted Node-side scheduling.
Post-arc, the fresh-index profile on dubbo (4,402 Java files) is: parse-loop ~4.7s, resolution ~5.5s (persist-bound), synthesis ~0.9s, total ~11.1s vs codebase-memory-mcp v0.9.0 at 7.1s. Two levers were measured dead:
synchronous=OFF already writes at page-cache speed.
The parse phase is CPU-bound.node.kind,
.childForFieldName, .text crosses the boundary.The only remaining parse lever is doing the walk on the native side and crossing the boundary once per file instead of once per node.
Minimal Rust binary (tree-sitter 0.25 + tree-sitter-java, TreeCursor walk
touching every node's kind/range + name-field text, emitting flat
(kind_id, start, end, name_len) rows — the extraction access pattern).
Dubbo's 4,048 .java files, 17MB, 3.59M AST nodes, Apple M3 Pro:
| wall | |
|---|---|
| Current pipeline parse-loop (7 wasm workers, incl. extraction + store dispatch) | 4,700ms |
| Rust parse+walk, rayon | 202ms |
| Rust parse+walk, single thread | 1,067ms |
One native thread beats the whole 7-worker wasm pool 4.4×; at equal parallelism the walk is ~14× faster. Even charging the kernel for the extraction logic it must still perform, parse-loop 4.7s → ~1.0–1.5s is realistic, putting dubbo ≈ 7.5–8s total (parity with cbm).
codegraph-kernel, napi-rs, links tree-sitter's C library and
vendored grammars natively. Input: (filePath, content, language). Output:
flat typed buffers (nodes, edges, unresolved refs) — one boundary crossing
per file..scm) executed by a generic Rust emitter; bespoke TS logic that queries
can't express (macro salvage, dialect sniffing, content-gated .h
detection) stays as TS pre/post passes over the returned buffers..node per platform through the existing
release-bundle pipeline (same per-platform packages as the Node runtime).
The wasm path remains as the universal fallback — same crate compiled to
wasm keeps one implementation.Byte-identity against hand-written extractors is NOT expected (bespoke logic ports approximately). The gate is:
docs/design/dynamic-dispatch-coverage-playbook.md),
agent A/B shows no regression per the standard methodology..scm expressiveness ceilings — budget for a per-language "escape hatch"
callback in the emitter before declaring a language blocked.