fix(tests): the health-gate pin follows the verdict, and the VFS suite uses its own store

Two gate failures on main, one real and one long-hidden.

THE HEALTH-GATE PIN encoded the old law — "narrates once per generation, twice
across a generation bump" — which the content-keyed dedupe deliberately
replaced. A provider's `generation` bumps on every ledger mutation and every
rebuild boundary, so keying narration on it re-printed an unchanged health line
on every read that consulted a busy provider, and let a provider that never
bumped suppress a line whose reasons had genuinely changed. The pin now asserts
BOTH directions: an unchanged verdict stays silent however the counter moves,
and a changed verdict is always heard.

THE VFS HYBRID-SEARCH SUITE configured its store with `options.basePath`, an
alias removed at the 8.0 major that configures nothing. The suite was therefore
never using its temp directory — it opened the DEFAULT store, shared with every
other run on the machine, and accumulated tens of thousands of rows until it
failed on that shared store's graph adjacency instead of on anything it tests.
It now passes `storage.path`. The suite drops from 6.5s to 0.3s, which is the
measure of how much foreign data it had been opening.

Neither failure was caused by the release branch; the first is the branch's own
behaviour change meeting its outdated pin, the second predates it.
This commit is contained in:
David Snelling 2026-08-28 12:27:40 -07:00
parent 5ebd3b4061
commit 42e2da259b
2 changed files with 23 additions and 5 deletions

View file

@ -188,7 +188,7 @@ describe('health gate (b) — unledgered is unknown: never blocks a serving prov
describe('health gate (c) — degraded-but-serving narrates once per generation', () => { describe('health gate (c) — degraded-but-serving narrates once per generation', () => {
// PER-FAMILY LAW (10.4.1): a metadata find() consults the METADATA leg only — the // PER-FAMILY LAW (10.4.1): a metadata find() consults the METADATA leg only — the
// degraded report lives on the family the read actually consults. // degraded report lives on the family the read actually consults.
it('a heal:"repair" failure serves; narrates once per generation, twice across a generation bump', async () => { it('a heal:"repair" failure serves; narrates once per DISTINCT VERDICT, not once per generation bump', async () => {
const brain = new Brainy(createTestConfig({ silent: true })) const brain = new Brainy(createTestConfig({ silent: true }))
await brain.init() await brain.init()
brains.push(brain) brains.push(brain)
@ -197,12 +197,13 @@ describe('health gate (c) — degraded-but-serving narrates once per generation'
const internals = internalsOf(brain) const internals = internalsOf(brain)
let generation = 1 let generation = 1
let detail = 'counter drift'
internals.metadataIndex.healthReport = () => internals.metadataIndex.healthReport = () =>
healthReport({ healthReport({
provider: 'vector', provider: 'vector',
serving: true, serving: true,
healthy: false, healthy: false,
invariants: [invariant({ name: 'stale-vector-counter', holds: false, heal: 'repair', detail: 'counter drift' })], invariants: [invariant({ name: 'stale-vector-counter', holds: false, heal: 'repair', detail })],
generation generation
}) })
@ -212,11 +213,22 @@ describe('health gate (c) — degraded-but-serving narrates once per generation'
await expect(brain.find({ where: { team: 'atlas' } })).resolves.toHaveLength(1) await expect(brain.find({ where: { team: 'atlas' } })).resolves.toHaveLength(1)
await expect(brain.find({ where: { team: 'atlas' } })).resolves.toHaveLength(1) await expect(brain.find({ where: { team: 'atlas' } })).resolves.toHaveLength(1)
expect(countNarrations()).toBe(1) // same generation both times — one narration expect(countNarrations()).toBe(1) // same verdict both times — one narration
// THE DEDUPE KEY IS THE VERDICT, NOT THE COUNTER. A provider's `generation`
// bumps on every ledger mutation and every rebuild boundary, so keying the
// narration on it re-printed an UNCHANGED health line on every read that
// consulted a busy provider — and, in the other direction, let a provider
// that never bumped suppress a line whose reasons had genuinely changed.
// An unchanged verdict is silent however the counter moves:
generation = 2 generation = 2
await expect(brain.find({ where: { team: 'atlas' } })).resolves.toHaveLength(1) await expect(brain.find({ where: { team: 'atlas' } })).resolves.toHaveLength(1)
expect(countNarrations()).toBe(2) // generation bumped — a second narration expect(countNarrations()).toBe(1) // generation bumped, verdict identical — still silent
// ...and a CHANGED verdict is always heard, bump or no bump:
detail = 'counter drift widened to 12 rows'
await expect(brain.find({ where: { team: 'atlas' } })).resolves.toHaveLength(1)
expect(countNarrations()).toBe(2) // the reasons changed — a new narration
delete internals.metadataIndex.healthReport delete internals.metadataIndex.healthReport
}) })

View file

@ -21,10 +21,16 @@ describe('Hybrid Search with VFS', () => {
testDir = path.join(os.tmpdir(), `brainy-hybrid-vfs-test-${Date.now()}`) testDir = path.join(os.tmpdir(), `brainy-hybrid-vfs-test-${Date.now()}`)
fs.mkdirSync(testDir, { recursive: true }) fs.mkdirSync(testDir, { recursive: true })
// `storage.path`, NOT the pre-8.0 `options.basePath` alias. That alias was
// removed at the 8.0 major and configures nothing, so this suite silently
// opened the DEFAULT store instead of its own temp directory — sharing one
// on-disk brain with every other run on the machine, accumulating tens of
// thousands of rows, and eventually failing on that shared store's graph
// adjacency rather than on anything it was written to test.
brain = new Brainy({ requireSubtype: false, brain = new Brainy({ requireSubtype: false,
storage: { storage: {
type: 'filesystem', type: 'filesystem',
options: { basePath: testDir } path: testDir
} }
}) })
await brain.init() await brain.init()