Skip to content

fix: dogfood fixes 9.1–9.4 — version warning, barrel exports, quieter tsconfig, Set compat#634

Merged
carlos-alm merged 5 commits intomainfrom
feat/dogfood-fixes-9.1-9.4
Mar 26, 2026
Merged

fix: dogfood fixes 9.1–9.4 — version warning, barrel exports, quieter tsconfig, Set compat#634
carlos-alm merged 5 commits intomainfrom
feat/dogfood-fixes-9.1-9.4

Conversation

@carlos-alm
Copy link
Copy Markdown
Contributor

Summary

Addresses four dogfooding issues from the v3.4.0 report:

  • 9.1 DB Version Warning: openReadonlyOrFail() now checks build_meta.codegraph_version against the running version and warns (once per process) with a suggestion to build --no-incremental
  • 9.2 Barrel File Export Tracing: Barrel-only files were entirely skipped in buildImportEdges, so no reexports edges were created. Now only non-reexport imports are skipped, letting codegraph exports follow re-export chains through barrel files
  • 9.3 Quieter tsconfig.json Warning: Demoted "Failed to parse tsconfig.json" from warn to debug so it only appears with --verbose
  • 9.4 EXTENSIONS/IGNORE_DIRS Set Compat: Documented the Array→Set breaking change in CHANGELOG. Added .toArray() convenience method and exported ArrayCompatSet type for consumers migrating from the pre-3.4 array API

Test plan

  • codegraph build && codegraph exports src/index.ts — should show re-exported symbols instead of "No exported symbols found"
  • Edit build_meta.codegraph_version in DB to a different value, run any query — should see version mismatch warning once
  • codegraph build without --verbose — no tsconfig.json warning
  • import { EXTENSIONS } from '@optave/codegraph'; EXTENSIONS.toArray() — returns string array

@claude
Copy link
Copy Markdown

claude bot commented Mar 26, 2026

Claude finished @carlos-alm's task —— View job


PR Review Analysis

Todo List

  • Phase 1: Root cause analysis - understand what problems this PR solves
  • Phase 2: Configuration change detection - check for rule relaxation
  • Phase 3: Test integrity verification
  • Phase 4: Code quality review
  • Phase 5: Backlog compliance assessment
  • Final recommendation

Phase 1: Root Cause Analysis ✅

Problems Being Solved:

  • Issue 9.1 (DB Version Warning): Users get no feedback when running queries against stale databases built with different codegraph versions, leading to confusion about incorrect results
  • Issue 9.2 (Barrel Export Tracing): codegraph exports fails to follow re-export chains through barrel files, showing "No exported symbols found" instead of actual exports
  • Issue 9.3 (Noisy tsconfig Warning): Non-critical tsconfig.json parse failures spam users with warnings during normal operation
  • Issue 9.4 (EXTENSIONS/IGNORE_DIRS Set Compat): Breaking change in v3.4.0 converted arrays to Sets without migration path for existing consumers

Root Cause Assessment: All fixes address real user pain points without masking underlying issues. The approaches are sound.

Phase 2: Configuration Change Detection ✅

No HIGH-RISK changes detected:

  • No biome/linting rules disabled or relaxed
  • No test timeouts increased or coverage thresholds lowered
  • No build configuration changes
  • No TypeScript strict mode flags disabled

Appropriate warning level change: tsconfig.json parse failure demoted from warn to debug — justified since it's non-critical during path alias loading.

Phase 3: Test Integrity ✅

No test integrity issues:

  • No tests removed or weakened
  • No assertions made less strict
  • No eslint-disable comments added
  • Changes are additive (version warning, reexport edges, compat methods)
  • Test plan in PR covers all 4 changes

Phase 4: Code Quality ✅

Implementation Quality:

9.1 DB Version Check (src/db/connection.ts:224-241):

  • ✅ Proper once-per-process warning with _versionWarned flag
  • ✅ Graceful error handling with try-catch (older DBs may lack build_meta table)
  • ✅ Clear actionable message suggesting --no-incremental
  • ✅ Uses lazy-loaded package version to avoid unnecessary I/O

9.2 Barrel Export Tracing (src/domain/graph/builder/stages/build-edges.ts:111-112):

  • ✅ Surgical fix: only skip non-reexport imports for barrel-only files
  • ✅ Preserves reexport edges that codegraph exports needs to follow chains
  • ✅ Logic correctly implemented: if (isBarrelOnly && !imp.reexport) continue;

9.3 Quieter tsconfig (src/domain/graph/builder/helpers.ts:152):

  • ✅ Changed warn to debug for tsconfig parse failures
  • ✅ Appropriate since this is non-critical path alias loading
  • ✅ Still logged with --verbose for debugging

9.4 Set Compatibility (src/shared/constants.ts):

  • ArrayCompatSet<T> interface extends Set<T> with toArray() method
  • withArrayCompat() function adds method without mutation
  • ✅ CHANGELOG.md properly documents breaking change and migration path
  • ✅ Exported type allows consumers to type their variables correctly

Potential Issues: None found. All implementations are defensive, well-structured, and maintain backward compatibility where possible.

Phase 5: Backlog Compliance ✅

Zero-dep: ✅ No new runtime dependencies added
Foundation-aligned: ✅ Fully compliant - improves user experience without violating core principles
Problem-fit: 4/5 - Directly improves agent experience by reducing noise and providing better export tracing
Breaking: Partially - Set change is breaking but properly documented with migration path
Tier: 1 (zero-dep ✅ + foundation-aligned ✅)

Final Assessment

## Root Cause Analysis
**Problem Being Solved**: Four specific dogfooding pain points from v3.4.0 - stale DB confusion, broken barrel export tracing, noisy tsconfig warnings, and Set migration friction
**Why This Approach**: Each fix is surgical and addresses root causes without masking symptoms
**Risk Assessment**: Low risk - all changes are additive/defensive with proper error handling

## Backlog Compliance  
- Zero-dep: ✅ — no new dependencies
- Foundation-aligned: ✅ — improves UX without violating principles
- Problem-fit: 4 — directly helps AI agents navigate codebases with less noise
- Breaking: Documented — Set change has migration path in CHANGELOG  
- Tier: 1

## Critical Concerns
None. This is high-quality maintenance work that directly addresses user feedback.

## Final Recommendation
- Rating: ⭐⭐⭐⭐☆ (4/5)
- Action: APPROVE 
- Reasoning: Excellent surgical fixes for real user pain points. Clean implementations with proper error handling. Breaking change is well-documented with migration support. Only minor: could benefit from tests for the new functionality.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 26, 2026

Greptile Summary

This PR resolves four concrete dogfooding issues found during the v3.4.0 release cycle, covering a DB version mismatch warning, barrel-file re-export edge tracing, a noisy tsconfig parse warning, and a backwards-compat shim for the Set-based EXTENSIONS/IGNORE_DIRS API. All three critical concerns raised in earlier review rounds (redundant version-check query, mutation of SUPPORTED_EXTENSIONS, and non-atomic edge deletion) are confirmed fixed in this head commit.

  • 9.1 — version warning (connection.ts): openReadonlyOrFail lazily reads the package version from package.json and checks build_meta.codegraph_version once per process, warning with an actionable --no-incremental suggestion. _versionWarned is now set unconditionally after the first check, eliminating the repeated DB round-trip on subsequent calls.
  • 9.2 — barrel export tracing (build-edges.ts, resolve-imports.ts): Barrel-only files are no longer skipped wholesale in buildImportEdges; only their non-reexport imports are skipped, so reexports edges are correctly emitted. The corresponding edge deletion is now inside the db.transaction() that re-creates the edges, making delete+insert atomic.
  • 9.3 — quieter tsconfig warning (helpers.ts): Demoting the Failed to parse tsconfig.json log from warn to debug is a one-liner with no risk.
  • 9.4 — ArrayCompatSet compat shim (constants.ts, index.ts): EXTENSIONS and IGNORE_DIRS are now ArrayCompatSet<string> instances with a .toArray() method. EXTENSIONS is correctly wrapped in new Set(SUPPORTED_EXTENSIONS) so the original parser export is not mutated. The type is publicly exported via src/index.ts for downstream consumers.

Confidence Score: 5/5

Safe to merge — all three previously-flagged critical concerns are confirmed resolved and no new issues were found.

The redundant build_meta query per call (now _versionWarned is set unconditionally), the unintentional mutation of SUPPORTED_EXTENSIONS (now wraps a fresh Set), and the non-atomic barrel edge deletion (now inside the enclosing transaction) are all fixed in this head commit. The four targeted dogfooding fixes are clean, narrowly scoped, and well-guarded with error handling and test-reset hooks. No new bugs or regressions are introduced.

No files require special attention.

Important Files Changed

Filename Overview
src/db/connection.ts Adds lazy getPackageVersion() + once-per-process version mismatch warning in openReadonlyOrFail; _versionWarned is set unconditionally after first check; test-reset helper _resetVersionWarning is exported but not surfaced in the public index.
src/domain/graph/builder/stages/build-edges.ts Barrel-only file handling is restructured: non-reexport imports are skipped per-import instead of skipping the whole file; stale edge deletion is moved inside the enclosing db.transaction(), making delete+insert atomic with no window for silent edge loss.
src/shared/constants.ts Introduces ArrayCompatSet interface and withArrayCompat helper; EXTENSIONS wraps a fresh new Set(SUPPORTED_EXTENSIONS) so the parser module's export is not mutated; IGNORE_DIRS wraps a new inline Set.
src/index.ts Adds export type { ArrayCompatSet } so downstream consumers can type their migrated code; no other surface changes.
src/domain/graph/builder/helpers.ts One-line demotion of Failed to parse tsconfig.json from warn to debug; correctly imports debug alongside warn.
CHANGELOG.md Adds a ### Notes entry under the 3.4.0 section documenting the Array→Set breaking change and the new .toArray() convenience method.

Sequence Diagram

sequenceDiagram
    participant CLI
    participant openReadonlyOrFail
    participant BuildMeta as build_meta table
    participant buildEdges

    CLI->>openReadonlyOrFail: first query call
    openReadonlyOrFail->>BuildMeta: SELECT value WHERE key is codegraph_version
    BuildMeta-->>openReadonlyOrFail: stored build version
    openReadonlyOrFail->>openReadonlyOrFail: compare vs package.json version
    alt versions differ
        openReadonlyOrFail->>CLI: warn once, suggest no-incremental rebuild
    end
    openReadonlyOrFail->>openReadonlyOrFail: set warned flag = true
    openReadonlyOrFail-->>CLI: readonly db handle

    CLI->>openReadonlyOrFail: subsequent query calls
    openReadonlyOrFail->>openReadonlyOrFail: warned flag is true, skip check
    openReadonlyOrFail-->>CLI: readonly db handle

    Note over buildEdges: Incremental build barrel edge rebuild (atomic)
    buildEdges->>buildEdges: begin transaction
    buildEdges->>buildEdges: DELETE all edges for barrel-only files
    buildEdges->>buildEdges: buildImportEdges (reexports only per barrel)
    buildEdges->>buildEdges: buildCallEdges
    buildEdges->>buildEdges: batchInsertEdges
    buildEdges->>buildEdges: commit or rollback atomically
Loading

Reviews (3): Last reviewed commit: "fix: move barrel edge deletion into buil..." | Re-trigger Greptile

Comment on lines +225 to +241
if (!_versionWarned) {
try {
const row = db
.prepare<{ value: string }>('SELECT value FROM build_meta WHERE key = ?')
.get('codegraph_version');
const buildVersion = row?.value;
const currentVersion = getPackageVersion();
if (buildVersion && currentVersion && buildVersion !== currentVersion) {
warn(
`DB was built with codegraph v${buildVersion}, running v${currentVersion}. Consider: codegraph build --no-incremental`,
);
_versionWarned = true;
}
} catch {
// build_meta table may not exist in older DBs — silently ignore
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Version check runs on every call when versions match

_versionWarned is only set to true when a mismatch is detected, so every subsequent call to openReadonlyOrFail() with matching versions will still execute the prepare(...).get(...) round-trip against build_meta. In normal usage (versions match, multiple queries in one session), this adds a redundant DB query per call. The guard comment says "Warn once per process" which is accurate, but the check also runs repeatedly.

Moving _versionWarned = true outside the mismatch conditional would prevent the repeated query:

Suggested change
if (!_versionWarned) {
try {
const row = db
.prepare<{ value: string }>('SELECT value FROM build_meta WHERE key = ?')
.get('codegraph_version');
const buildVersion = row?.value;
const currentVersion = getPackageVersion();
if (buildVersion && currentVersion && buildVersion !== currentVersion) {
warn(
`DB was built with codegraph v${buildVersion}, running v${currentVersion}. Consider: codegraph build --no-incremental`,
);
_versionWarned = true;
}
} catch {
// build_meta table may not exist in older DBs — silently ignore
}
}
// Warn once if the DB was built with a different codegraph version
if (!_versionWarned) {
try {
const row = db
.prepare<{ value: string }>('SELECT value FROM build_meta WHERE key = ?')
.get('codegraph_version');
const buildVersion = row?.value;
const currentVersion = getPackageVersion();
if (buildVersion && currentVersion && buildVersion !== currentVersion) {
warn(
`DB was built with codegraph v${buildVersion}, running v${currentVersion}. Consider: codegraph build --no-incremental`,
);
}
} catch {
// build_meta table may not exist in older DBs — silently ignore
}
_versionWarned = true;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b60fbb7. Moved _versionWarned = true outside the mismatch conditional so the flag is set unconditionally after the first check, eliminating the redundant build_meta query on every subsequent call when versions match.

);

export { SUPPORTED_EXTENSIONS as EXTENSIONS };
export const EXTENSIONS: ArrayCompatSet<string> = withArrayCompat(SUPPORTED_EXTENSIONS);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 withArrayCompat mutates SUPPORTED_EXTENSIONS in place

withArrayCompat(SUPPORTED_EXTENSIONS) casts the original Set to ArrayCompatSet and directly assigns .toArray onto it, mutating the module-level SUPPORTED_EXTENSIONS export from domain/parser.js. Any code that imports SUPPORTED_EXTENSIONS directly will now see the toArray property on it as a side effect of loading constants.ts. While adding a property to a Set won't interfere with .has() or iteration, it's an unintentional mutation of a sibling module's export.

Wrapping in a fresh Set keeps the original untouched:

Suggested change
export const EXTENSIONS: ArrayCompatSet<string> = withArrayCompat(SUPPORTED_EXTENSIONS);
export const EXTENSIONS: ArrayCompatSet<string> = withArrayCompat(new Set(SUPPORTED_EXTENSIONS));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b60fbb7. EXTENSIONS is now wrapped in new Set(SUPPORTED_EXTENSIONS) so withArrayCompat mutates the copy rather than the original SUPPORTED_EXTENSIONS export from the parser module.

… compat

9.1 — Warn on graph load when DB was built with a different codegraph
version. The check runs once per process in openReadonlyOrFail() and
suggests `build --no-incremental`.

9.2 — Barrel-only files now emit reexport edges during build. Previously
the entire file was skipped in buildImportEdges; now only non-reexport
imports are skipped, so `codegraph exports` can follow re-export chains.

9.3 — Demote "Failed to parse tsconfig.json" from warn to debug level
so it no longer clutters every build output.

9.4 — Document EXTENSIONS/IGNORE_DIRS Array→Set breaking change in
CHANGELOG. Add .toArray() convenience method and export ArrayCompatSet
type for consumers migrating from the pre-3.4 array API.
…ge duplication (#634)

- Move _versionWarned flag outside mismatch conditional to avoid
  redundant build_meta queries when versions match.
- Wrap SUPPORTED_EXTENSIONS in new Set() to avoid mutating the
  sibling module's export.
- Delete outgoing edges for barrel-only files before re-adding them
  to fileSymbols during incremental builds, preventing duplicate
  reexport edges.
@carlos-alm carlos-alm force-pushed the feat/dogfood-fixes-9.1-9.4 branch from 62852b8 to b60fbb7 Compare March 26, 2026 08:55
@carlos-alm
Copy link
Copy Markdown
Contributor Author

Both P2 items addressed in b60fbb7:

  1. _versionWarned redundant query — flag now set unconditionally after first check, preventing repeated build_meta queries when versions match.
  2. withArrayCompat mutationEXTENSIONS now wraps new Set(SUPPORTED_EXTENSIONS) to avoid mutating the sibling module's export.
  3. Bonus fix: barrel edge duplication in incremental builds — discovered that the reexport edge change caused duplicate edges during incremental rebuilds (barrel-only files' outgoing edges weren't deleted before buildEdges re-created them). Added deleteOutgoingEdges in resolve-imports.ts when barrel files are loaded into fileSymbols. This also fixes the CI test failures in incremental-parity.test.ts and incr-edge-gap.test.ts.
  4. Commitlint fix — lowercased "DB" to "db" in the commit subject to pass the subject-case rule.

@greptileai

Comment on lines 51 to 62
const deleteOutgoingEdges = db.prepare(
'DELETE FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = ?)',
);
for (const { file: relPath } of barrelCandidates) {
if (fileSymbols.has(relPath)) continue;
const absPath = path.join(rootDir, relPath);
try {
const symbols = await parseFilesAuto([absPath], rootDir, engineOpts);
const fileSym = symbols.get(relPath);
if (fileSym) {
deleteOutgoingEdges.run(relPath);
fileSymbols.set(relPath, fileSym);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Edge deletion is not transactional with edge re-creation

deleteOutgoingEdges.run(relPath) commits immediately to the DB (outside any transaction), but the corresponding reexports edges aren't re-created until buildEdges runs its own db.transaction() later. If the process crashes or buildEdges throws between those two points, the barrel file's outgoing edges are gone from the DB — but because the reexports rows no longer exist, the file won't appear in barrelCandidates on the next incremental run either. The file silently disappears from the barrel graph until the user explicitly runs --no-incremental.

The cleanest fix is to push the deletion into the buildEdges transaction so delete and insert are atomic:

// In buildImportEdges, before inserting reexport edges for a barrel-only file:
if (isBarrelOnly) {
  db.prepare(
    'DELETE FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = ?)',
  ).run(relPath);
}

If keeping the deletion in resolveImports is preferred, wrapping the loop body in a savepoint or a db.transaction() call would achieve the same atomicity guarantee.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 74453fd. Moved the deleteOutgoingEdges call from resolveImports (where it committed immediately outside any transaction) into the buildEdges transaction in build-edges.ts. The deletion now runs inside the same db.transaction() that re-creates the reexport edges, so if buildEdges throws or the process crashes, both the delete and insert are rolled back atomically — no silent edge loss.

@carlos-alm
Copy link
Copy Markdown
Contributor Author

@greptileai

@carlos-alm carlos-alm merged commit 119c8f0 into main Mar 26, 2026
12 checks passed
@carlos-alm carlos-alm deleted the feat/dogfood-fixes-9.1-9.4 branch March 26, 2026 21:37
@github-actions github-actions bot locked and limited conversation to collaborators Mar 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant