Skip to content

fix(graph): report uninspected status fields as not inspected - #215

Merged
theDakshJaitly merged 2 commits into
mex-memory:mainfrom
chiliec:fix-204-status-not-inspected
Sep 22, 2026
Merged

theDakshJaitly merged 2 commits into
mex-memory:mainfrom
chiliec:fix-204-status-not-inspected

Conversation

@chiliec

@chiliec chiliec commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

What

Fixes #204.

When inspectGraphStatus skips immutable inspection — a stranded graph.db-wal, an unreadable sidecar, a containment failure, a failed quick-check or invariant audit — it still filled lastSuccessfulIndexAt, parseHealth and changes with placeholders, and printStatus rendered them in the same shape as measurements: Last successful index: never, Sources: 0 changed, Parse health: 0 ok. All three are false for an intact store.

Why

Per the issue, the JSON contract keeps parseHealth and changes non-nullable (~160 references, invariant checks in read-session.ts), so this is the additive-flag option:

  • GraphStatus.inspected?: boolean — optional, additive. graphStatus() defaults it to true; every early return that fills parseHealth with the empty placeholder passes false (15 sites). The GRAPH_INDEX_MISSING path stays true: there is no store, and Sources: N added is a real live-tree measurement there.
  • printStatus prints Last successful index: not inspected / Sources: not inspected / Parse health: not inspected when inspected === false; the diagnostic line and Next: remediation are unchanged.
  • --json gains "inspected": false on those paths; parseHealth and changes keep their shape.

Text output on the stranded-WAL repro now reads:

Graph status: degraded
Repository: main @ …
Last successful index: not inspected
Sources: not inspected
Parse health: not inspected
WARNING GRAPH_INDEX_SIDECAR_ACTIVE: Graph maintenance or recovery is active (graph.db-wal); immutable inspection was skipped.
Next: mex graph repair

Tests

  • src/graph/__tests__/status.test.ts: inspected is false on the corrupt and active-WAL paths, and true (with a real parseHealth.total) once the WAL is checkpointed.
  • src/graph/__tests__/cli-graph.test.ts: builds a store, strands a graph.db-wal, runs runGraphStatus and asserts the three not inspected lines, the sidecar warning, no 0 ok/never, and inspected: false under --json.

Both new tests fail on main (expected undefined to be false, expected […] to include 'Last successful index: not inspected') and pass with the change.

Ran locally:

npx vitest run src/graph/__tests__/cli-graph.test.ts src/graph/__tests__/status.test.ts
  Tests  55 passed | 1 skipped (56)
npx vitest run test/graph-integration.test.ts test/graph-cli-freshness.test.ts test/graph-cli-parse-degraded.test.ts src/hub/__tests__/services.test.ts test/reporter.test.ts test/tui.test.ts packages/hub-contracts
  Tests  140 passed | 1 skipped (141)
npx tsc --noEmit  # clean

A full npx vitest run on my box hit the 15 s per-test timeout on unrelated Relay/hub tests under load, so I relied on the targeted runs above plus CI.

Changelog entry added under [0.8.2] → Fixed.

When immutable inspection is skipped — a stranded graph.db-wal, an
unreadable sidecar, a containment failure or a failed invariant audit —
mex graph status printed the placeholder values in the same shape as
measurements: "Last successful index: never", "Sources: 0 changed" and
"Parse health: 0 ok", all false for an intact store.

Add an additive inspected flag to GraphStatus, set false on every early
return that fills parseHealth with an empty placeholder, and render those
three lines as "not inspected" in the text output. parseHealth and
changes keep their shape so no consumer changes.

Fixes mex-memory#204
@chiliec

chiliec commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Note: #213 was opened for the same issue shortly before this one (it was not up when I started on #204). This one keeps the diff to status.ts / cli-graph.ts / the contract type plus tests, and leaves src/drift/index.ts untouched. Happy to close in favour of #213 if you prefer that one.

@theDakshJaitly theDakshJaitly left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This fixes the stranded-WAL case, but the GRAPH_SNAPSHOT_CONTENT_MISMATCH early return still reports unmeasured fields as facts. It has read parse-health counts, but has not compared sources and does not populate the index timestamps. The new default therefore labels its placeholder changes and timestamps as inspected: true.

Please handle this partial-inspection return too: mark the unavailable fields as not inspected, using the existing flag conservatively or an equivalent explicit distinction. Add a regression that builds a graph, changes its recorded snapshot digest, modifies a source file, and verifies both text and JSON output.

Non-blocking consistency suggestion: unavailableGraphStatus() in src/drift/index.ts still omits inspected when the status loader throws. Consider setting it to false and covering the failed-loader case so the separate mex check fallback carries the same explicit signal. The requested-changes blocker is the snapshot-mismatch behavior above.

Validation on 857a90d: 197 existing focused tests passed across graph status, CLI, graph integration/freshness/degradation, Hub services/contracts, and reporter/TUI. Workspace typecheck and git diff --check passed. Additional controls confirm fresh/missing-index behavior and stranded-WAL text/JSON output, including unchanged database/WAL bytes. The snapshot-mismatch regression fails; an injected loader failure also confirms the unset fallback flag. Full repository, packaging, and performance suites were not rerun.

Comment thread src/graph/status.ts
… not inspected

The GRAPH_SNAPSHOT_CONTENT_MISMATCH early return had read parse health but
never compared sources or populated the index timestamps, so the placeholder
changes and null lastSuccessfulIndexAt shipped as inspected: true. Mark that
partial inspection as not inspected, and give the mex check fallback status
the same explicit flag when the status loader throws.

Regressions: build a graph, corrupt the snapshot digest, edit a source, and
verify text + JSON output; inject a loader failure and verify the fallback
carries inspected: false.
@chiliec

chiliec commented Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — you're right, the snapshot-mismatch return was a missed case. Pushed 84a5058:

  • GRAPH_SNAPSHOT_CONTENT_MISMATCH now returns inspected: false: parse health was read, but sources were never compared and the index timestamps never populated, so the aggregate is a partial inspection and the placeholders must not read as measured. The corruption diagnostic itself is unchanged.
  • Regression in cli-graph.test.ts: builds a graph, rewrites the snapshot's sourceCorpusDigest to "0".repeat(64), edits the source file, then checks text output (Graph status: corrupt, the three not inspected lines, the ERROR GRAPH_SNAPSHOT_CONTENT_MISMATCH diagnostic, no never/0 changed) and JSON (status: corrupt, inspected: false, lastSuccessfulIndexAt: null). The existing digest-mismatch case in status.test.ts also asserts inspected === false after a source edit.
  • Took the non-blocking suggestion too: unavailableGraphStatus() in src/drift/index.ts now sets inspected: false, with a graph-integration test that injects a throwing readOnlyGroundingRuntimeLoader and checks the fallback carries the flag plus GRAPH_STATUS_UNAVAILABLE.

Both new tests fail on the previous head and pass now; cli-graph, status and graph-integration suites are green (77 passed), tsc --noEmit and git diff --check clean.

@theDakshJaitly theDakshJaitly left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The snapshot-content-mismatch path now reports inspected: false, and the unavailable-status fallback does the same. Both have regression coverage. The final review of the complete PR found no remaining actionable issues.

Validation on 84a5058: 199 focused repository tests, all 5 independent review assertions, and workspace typecheck passed. CI is green, including Node 22/24, Windows/macOS portability, browser, packaging, and release-performance checks: https://github.com/mex-memory/mex/actions/runs/35678969841

@theDakshJaitly
theDakshJaitly merged commit 66c3047 into mex-memory:main Sep 22, 2026
9 checks passed
@chiliec
chiliec deleted the fix-204-status-not-inspected branch September 22, 2026 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

graph status prints uninspected fields as measured zeros — a stranded graph.db-wal reads as an empty graph

2 participants