Skip to content

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

Description

@theyashasvipandey

When mex graph status finds an active sidecar next to the store it skips
immutable inspection — correctly — but still prints placeholder values in the
same shape it prints measurements. Three of the five lines are then false.

To reproduce

On a 111-file TypeScript repository with a healthy, freshly indexed store:

$ mex graph status
Graph status: stale
Repository: main @ df89810df4f5
Last successful index: 2026-09-13T04:33:14.973Z
Sources: 1 changed (0 added, 0 modified, 1 deleted)
Parse health: 111 ok, 0 partial, 0 failed

Strand a non-empty WAL beside the store — an interrupted write leaves exactly
this — and run the same command against the same untouched database:

$ mex graph status
Graph status: degraded
Repository: main @ df89810df4f5
Last successful index: never
Sources: 0 changed (0 added, 0 modified, 0 deleted)
Parse health: 0 ok, 0 partial, 0 failed
WARNING GRAPH_INDEX_SIDECAR_ACTIVE: Graph maintenance or recovery is active (graph.db-wal); immutable inspection was skipped.
Next: mex graph repair

Nothing about the store changed between those two runs. mex graph repair
restores 111 ok and the real index timestamp immediately.

  • Parse health: 0 ok reads as "nothing parsed". It means "not inspected".
  • Last successful index: never is false — the store was indexed on 09-13.
  • Sources: 0 changed reads as "up to date". Nothing was compared.

--json is partly affected. lastSuccessfulIndexAt, indexedAt,
schemaVersion and the version fields all come back null, which is honest.
But parseHealth and changes come back as fully-populated zero objects:

"parseHealth": { "total": 0, "ok": 0, "partial": 0, "failed": 0,
                 "failedPaths": [], "failedPathsTruncated": false },
"changes":     { "total": 0, "added": [], "modified": [], "deleted": [], ... }

A consumer cannot distinguish that from a store that genuinely parsed nothing.

Cause

  • printStatus (src/graph/cli-graph.ts:181) prints all five lines
    unconditionally, with ?? "never" supplying the index-time placeholder.
  • src/graph/status.ts has 16 early-return paths that fill parse health
    with emptyParseHealth(). The WAL is only the case reproduced here — an
    unreadable sidecar, a containment failure or a failed invariant audit all
    print the same zeros.

Expected behavior

Distinguish "not inspected" from "measured zero". In text, something like
Parse health: not inspected (graph.db-wal present), and suppress or mark the
index-time and sources lines on the same paths — that half is contained to
printStatus.

For JSON, prefer an additive inspected: false (or equivalent) over making
parseHealth and changes nullable. parseHealth alone has ~163 non-test
references, including invariant checks in src/graph/read-session.ts that
compare its counts against the file list, so widening the type is a much larger
change than the reporting bug warrants. An additive flag breaks no consumer.

Additional context

This was diagnosed publicly in #140 — "that placeholder reads like 'zero files
parsed' when it actually means 'not inspected'; we'll fix the wording" — but
nothing on main changes it and no issue tracks it. Filing so it is not lost.
The severity is that a clone's 0 ok was read there as a failed graph when the
store was intact.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcode-graphWork related to the AST and Tree-sitter code graphgood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions