Skip to content

Commit 1101d24

Browse files
authored
fix(native): keep nativeDb open through finalize for correct build_meta (#784)
* fix(native): keep nativeDb open through finalize for correct build_meta (#751) nativeDb was closed before finalize(), making persistBuildMetadata fall back to the JS (better-sqlite3) path. After native WAL truncation the JS connection's page cache was stale, causing the setBuildMeta write to silently fail and leaving stale version/engine metadata. This broke incremental builds by triggering a spurious "version changed" full rebuild on every subsequent run. Keep nativeDb alive through finalize so all metadata writes, advisory checks, and count queries use the native path. Refresh the JS DB beforehand so it has a valid page cache if finalize falls back to JS. * fix(native): use npm version for engine_version in build_meta (#751) engine_version was set to ctx.engineVersion which comes from the Rust crate's CARGO_PKG_VERSION via native.engineVersion(). When the Rust crate version drifts from the npm package version (e.g. Cargo.toml not bumped during release), build_meta stores the wrong version. Use CODEGRAPH_VERSION (the npm package.json version) for both codegraph_version and engine_version since the native engine is distributed as part of the npm package. Also strengthens the #751 regression test to assert engine_version equals the npm version and uses a full rebuild to ensure metadata is written for the small test fixture.
1 parent 2848205 commit 1101d24

3 files changed

Lines changed: 41 additions & 5 deletions

File tree

src/domain/graph/builder/pipeline.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,13 @@ async function runPipelineStages(ctx: PipelineContext): Promise<void> {
300300

301301
await runAnalyses(ctx);
302302

303-
// Close nativeDb after analyses — finalize uses JS paths for setBuildMeta
304-
// and closeDbPair handles cleanup. Avoids dual-connection during finalize.
305-
closeNativeDb(ctx, 'post-analyses');
303+
// Keep nativeDb open through finalize so persistBuildMetadata, advisory
304+
// checks, and count queries use the native path. closeDbPair inside
305+
// finalize handles both connections. Refresh the JS db so it has a
306+
// valid page cache in case finalize falls back to JS paths (#751).
307+
if (ctx.nativeDb) {
308+
refreshJsDb(ctx);
309+
}
306310

307311
await finalize(ctx);
308312
}

src/domain/graph/builder/stages/finalize.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function persistBuildMetadata(
8686
ctx.nativeDb!.setBuildMeta(
8787
Object.entries({
8888
engine: ctx.engineName,
89-
engine_version: ctx.engineVersion || '',
89+
engine_version: CODEGRAPH_VERSION,
9090
codegraph_version: CODEGRAPH_VERSION,
9191
schema_version: String(ctx.schemaVersion),
9292
built_at: buildNow.toISOString(),
@@ -97,7 +97,7 @@ function persistBuildMetadata(
9797
} else {
9898
setBuildMeta(ctx.db, {
9999
engine: ctx.engineName,
100-
engine_version: ctx.engineVersion || '',
100+
engine_version: CODEGRAPH_VERSION,
101101
codegraph_version: CODEGRAPH_VERSION,
102102
schema_version: String(ctx.schemaVersion),
103103
built_at: buildNow.toISOString(),

tests/integration/build.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,38 @@ describe('version/engine mismatch auto-promotes to full rebuild', () => {
477477
expect(output).toContain('promoting to full rebuild');
478478
expect(output).not.toContain('No changes detected');
479479
});
480+
481+
test('build_meta reflects actual engine and version after build (#751)', async () => {
482+
// Force a full rebuild to ensure build_meta is freshly written
483+
await buildGraph(promoDir, { skipRegistry: true, incremental: false });
484+
485+
const db2 = new Database(promoDbPath, { readonly: true });
486+
const meta = Object.fromEntries(
487+
(
488+
db2.prepare('SELECT key, value FROM build_meta').all() as { key: string; value: string }[]
489+
).map((r) => [r.key, r.value]),
490+
);
491+
db2.close();
492+
493+
// codegraph_version must match the npm package version
494+
const pkg = JSON.parse(
495+
fs.readFileSync(path.join(__dirname, '..', '..', 'package.json'), 'utf8'),
496+
);
497+
expect(meta.codegraph_version).toBe(pkg.version);
498+
499+
// engine must be either 'native' or 'wasm' (not empty, not stale)
500+
expect(['native', 'wasm']).toContain(meta.engine);
501+
502+
// engine_version must equal the npm package version (#751: was using Rust crate version)
503+
expect(meta.engine_version).toBe(pkg.version);
504+
505+
// built_at must be a valid ISO timestamp from the current build
506+
expect(new Date(meta.built_at).getTime()).toBeGreaterThan(0);
507+
508+
// node/edge counts must be positive
509+
expect(Number(meta.node_count)).toBeGreaterThan(0);
510+
expect(Number(meta.edge_count)).toBeGreaterThan(0);
511+
});
480512
});
481513

482514
describe('typed method call resolution', () => {

0 commit comments

Comments
 (0)