test(doctor): pin the half-built-index diagnostic, which nothing asserted - #195
Merged
Merged
Conversation
…rted
`vector-generation.open` is the doctor row that tells a user an interrupted
rebuild is holding a second, full-size copy of their vectors on disk. It
shipped with the generation-swap work and no test asserted it. The three test
files that mention `vector_generation` seed that metadata key as a fixture for
other behaviour, and the CLI test covers `reindex --discard-generation` — the
action, not the diagnostic that names it. Write side pinned, read side not:
exactly the shape where both halves are correct and the chain between them was
never walked.
Five cases against the built CLI in a throwaway HOME, because the staged count
comes from counting rows in a vec0 virtual table and a stub cannot execute
that:
- silence on a database with no half-built index (the half that gives the
warning meaning — without it a hard-wired row passes every other case)
- the row's width, provider and start time, emitted exactly once
- the staged count, seeded with two rows so a count and a boolean differ
- the unreadable-marker branch, which must NOT offer to resume a generation
whose embedding space is unknown
- the row clearing after the fix it names is actually run
Break-tested in a copy of the tree, rebuilding dist each time — the test spawns
the binary, so a mutation left in src alone grades one that never changed.
Short-circuiting the read, hard-wiring the staged count to 0, and downgrading
the severity to pass: 3/3 KILLED, restored copy green again. A fourth mutant
(inverting `state === 'open'`) was rejected as INVALID rather than counted: it
stops type-checking, and a mutant that does not compile was never executed.
No CHANGELOG entry: no user-visible behaviour changes here.
Verification, this checkout, this session:
npm run typecheck exit=0
node scripts/run-tests-isolated.mjs 158 files, 2314 tests passed, exit=0
npm run verify:release exit=0 (C1 clean after the
exactly-once assertion was added)
17 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
vector-generation.open— thememesh doctorrow that tells a user an interrupted rebuild is holding a second, full-size copy of their vectors on disk — shipped with the generation-swap work and had no test asserting it. The three test files that mentionvector_generationseed that metadata key as a fixture for other behaviour, andcli-reindex-vectors-guard.test.tscoversreindex --discard-generation: the action, not the diagnostic that names it. This adds the missing read-side pin. No production code changes.Type of change
feat)fix)refactor)docs)test)release)Docs synced (project doc-sync rule —
CLAUDE.md)CONTRIBUTING.mdties doc updates to behaviour / API / architecture changes; this is none of them.docs/ARCHITECTURE.md— no module structure changedocs/api/API_REFERENCE.md— no MCP / HTTP / CLI surface changeREADME.md— no user-facing changeREADME.mdunchangeddist/skills-manifest.json— nothing under.claude-plugin/,scripts/hooks/,skills/or version files was touchedmemesh doctorOverall — not run; nothing in this PR can move it, and reporting a check I did not run is what this repository's rules forbidVerification
Run in this checkout, this session:
npx tsc --noEmitclean (vianpm run typecheck, which coverssrc/,tests/and the root configs)npm run build— not run; no source file changed, sodist/is unchangednpm test -- --runpassing — run asscripts/run-tests-isolated.mjs(throwaway HOME): 158 files, 2314 tests, 0 failed. The five new cases are this file's; I did not re-run the suite onmainto state a delta, so none is claimed.Break-test. A green suite is not evidence a guard is protected, so the check was mutated in a copy of the tree, rebuilding
disteach time — the tests spawn the built CLI, so a mutation left insrcalone grades a binary that never changed:readVectorGeneration()short-circuited to{ state: 'none' }const staged = generationRowIds().size→= 0'warn'→'pass'state === 'open'invertedRestored copy green again (exit=0). Restoration is by writing the original file back, never
git checkout.Test plan
npx vitest run tests/cli/doctor-half-built-index.test.ts— 5 passedvector_generationbranch insrc/core/doctor.ts(or setstagedto a constant),npx tsc, re-run the file — it must go rednpm run verify:release— exit=0,C1: new=0Known limitations / follow-ups
already_staged/ stale-hash resume (reindex-reports-what-happened.test.ts:403,438), the reindex circuit breaker (:464), and the body-phase timeout (embedder-provider-fetch.test.ts:152). Verified by reading the assertions, not by the presence of a file name.