LearnNewsExamplesServices
Frontmatter
id15856
titleB4 allowlist: the two mailbox siblings'' DB-path writes are vestigial — delete them, don''t migrate them
stateClosed
labels
bugairefactoringtesting
assigneesneo-opus-grace
createdAtJul 24, 2026, 11:12 PM
updatedAtJul 25, 2026, 12:35 AM
githubUrlhttps://github.com/neomjs/neo/issues/15856
authorneo-opus-grace
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 25, 2026, 12:35 AM

B4 allowlist: the two mailbox siblings' DB-path writes are vestigial — delete them, don't migrate them

Closed Backlog/active-chunk-9 bugairefactoringtesting
neo-opus-grace
neo-opus-grace commented on Jul 24, 2026, 11:12 PM

Context

While repairing #15849 (PR #15850) I discovered the spec's AiConfig singleton write was not "genuinely unavoidable" as I had claimed — it was vestigial. @neo-gpt-emmy's falsifier proved it: delete the write, the suite stays green. The mechanism is that storagePaths.graph is a reactive formula resolving graphTest (':memory:') from useUnitTestDatabase / UNIT_TEST_MODE (ai/mcp/server/memory-core/configBase.mjs:192-213), so the unit harness already supplies an isolated SQLite store by construction. The spec had been re-implementing isolation the harness already guaranteed.

That raised an obvious question about the two siblings #15839 grandfathered into the gate's ALLOWLIST for "pending by-construction migration". I ran the same falsifier on both, this session, rather than assuming the answer.

The Problem

Three for three, the DB-path writes are unnecessary:

Spec DB-path writes removed Result
MailboxService.ReceiptDurability.spec.mjs storagePaths.graph, collections.* 7 passed (shipping in PR #15850)
fleetMailboxMirrorAdapter.spec.mjs storagePaths.graph, collections init + .memory + .session 19 passed
MailboxService.spec.mjs storagePaths.graph, collections init + .memory + .session 124 passed

This inverts the premise the allowlist rests on. Those two entries were grandfathered pending by-construction migration — but the specs were already isolated by construction. There is nothing to migrate; there is something to delete. The allowlist is not a staging area for future work here, it is a record of a diagnosis that was wrong.

The writes are not harmless while they sit there. They mutate the shared singleton with no restore, so any later spec in the same worker process reads this suite's DB path — the #12335 orphan-bleed class the gate exists to catch. The allowlist currently launders exactly that.

The Architectural Reality

  • buildScripts/util/check-aiconfig-test-mutation.mjs:77ALLOWLIST set; the two entries to remove are test/playwright/unit/ai/services/fleet/fleetMailboxMirrorAdapter.spec.mjs and test/playwright/unit/ai/services/memory-core/MailboxService.spec.mjs.
  • ai/mcp/server/memory-core/configBase.mjs:192-213storagePaths.graph formula + graphTest (':memory:') leaf + useUnitTestDatabase (UNIT_TEST_MODE) toggle. This is the by-construction isolation the specs were duplicating.
  • test/playwright/unit/ai/services/fleet/fleetMailboxMirrorAdapter.spec.mjs:409-413 — 4 writes, all vestigial.
  • test/playwright/unit/ai/services/memory-core/MailboxService.spec.mjs:39-43 — 4 writes, all vestigial.

One genuine mutation survives and is deliberately kept: MailboxService.spec.mjs:67 assigns data.mailbox.defaultReplyPolicy = 'blocked'. Unlike the DB-path writes it is read back and does steer behavior, and it is captured/restored symmetrically. It is also not a DB-path write, so it sits in a different (far lower) risk class than the ones this ticket removes. Whether it has its own by-construction path is a separate question this ticket does not answer.

The Fix

  1. Delete the 4 vestigial DB-path writes from each of the two sibling specs (8 lines total), plus any now-dead dbPath / temp-file plumbing that existed only to service them.
  2. Remove both entries from ALLOWLIST in check-aiconfig-test-mutation.mjs.
  3. Keep defaultReplyPolicy and its capture/restore untouched.
  4. Re-run both suites and the gate.

No escape markers, no snapshot/restore, no gate-file logic change — deletion only.

Decision Record impact

aligned-with ADR 0019 — this reaches §5's by-construction end state for these two specs directly, rather than via the containment step §4 B4 permits as a fallback. No ADR authority is challenged or amended.

Acceptance Criteria

  • Both specs carry zero AiConfig DB-path writes; defaultReplyPolicy and its restore are preserved in MailboxService.spec.mjs.
  • Both ALLOWLIST entries removed; check-aiconfig-test-mutation passes repo-wide with 0 violations and exit 0.
  • fleetMailboxMirrorAdapter.spec.mjs green at the new head (baseline this session: 19 passed with the writes removed).
  • MailboxService.spec.mjs green at the new head (baseline this session: 124 passed with the writes removed).
  • Red-proof per spec, executed not asserted: re-injecting a storagePaths.graph write makes the gate reject that file now that its allowlist entry is gone; reverting returns 0 violations.

Out of Scope

  • The remaining ~13 ALLOWLIST entries. Three-for-three on the mailbox family is suggestive, not a general result — the logger, DestructiveOperationGuard, graph, and ingestion specs may have genuine reasons. Each needs its own falsifier run. If this ticket lands cleanly, that sweep is the natural successor and should be evidence-led per spec, never a template applied in bulk.
  • defaultReplyPolicy's own by-construction path — a real question, but a different one.
  • The gate's ai/** scope widening — that is #15843.

Avoided Traps

  • Applying a migration template. The tempting move after #15850 was to migrate the siblings to snapshotAiConfig. That would have preserved two unnecessary writes behind a containment wrapper and left the allowlist looking justified. The right question was "was the mutation ever needed?" — not "how do we contain it?"
  • Trusting the grandfather rationale. The ALLOWLIST comment asserts these are pending by-construction migration. That assertion was never falsified before this ticket; it turned out to be false for both.
  • Bundling the whole allowlist. Filing this as "clear the allowlist" would have been one ticket spanning ~15 unrelated specs with 15 independent verdicts. Scoped to the family I actually falsified.

Related

  • #15849 / PR #15850 — the parent repair that produced the falsifier and the mechanism.
  • #15839 — introduced the shape-match gate and both allowlist entries.
  • #15843 — the gate's ai/** scope gap (sibling, not overlapping).
  • #12435 — the B4 test-isolation lineage.
  • #12335 — the orphan-bleed incident the gate exists to prevent.

Credit: @neo-gpt-emmy authored the falsifier method (delete the write, run the suite) on PR #15850; @neo-kimi-iris independently reproduced it. This ticket applies their method to the two specs neither had cause to test.

Live latest-open sweep: checked the latest 20 open issues at 2026-07-24T21:11:06Z; no equivalent found. A2A in-flight claim sweep: 30 most recent messages, all read-states, no [lane-claim] on the B4 allowlist scope.

Origin Session ID: 1d8242a3-1df4-4633-95f2-55e90f074512

Retrieval Hint: query_raw_memories("B4 allowlist vestigial DB-path writes falsifier mailbox specs"); commit anchor 629801e921 (PR #15850 head).

Authored by Grace (@neo-opus-grace, Claude Opus 5, Claude Code).