5.0 KiB
title, date, category, module, problem_type, component, symptoms, root_cause, resolution_type, severity, related_components, tags
| title | date | category | module | problem_type | component | symptoms | root_cause | resolution_type | severity | related_components | tags | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Schema-version literal sweep must include plugin workspaces | 2026-06-05 | test-failures | packages/core schema-version sweep | test_failure | testing_framework |
|
missing_workflow_step | test_fix | medium |
|
|
Schema-version literal sweep must include plugin workspaces
Problem
When packages/core's SCHEMA_VERSION was bumped 108 → 109 (adding the workflow_settings table), the established "broad literal sweep" — grep -rn 'toBe(108)' packages/ — was executed correctly and updated ~40 assertion sites. CI still failed: plugins/fusion-plugin-roadmap has a store test asserting getSchemaVersion() against a hard-coded literal, and plugins/ lives outside the sweep's grep scope.
Symptoms
FAIL plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-store.test.ts
RoadmapStore > schema version > schema version is 108 after init
AssertionError: expected 109 to be 108
- CI shard 4/4 red on the first run after the bump landed; all
packages/suites green. - Invisible locally: the plan's execution note and pre-push verification both scoped to
packages/, and the roadmap plugin's suite is not part of apackages/-only vitest run.
What Didn't Work
- Following the documented sweep convention diligently. After the bump,
grep -rn 'toBe(108)' packages/returned zero hits — the sweep looked complete. The gap was scope, not carefulness: at least two plan cycles (step-inversion v108, workflow-settings v109) codified the sweep aspackages/-scoped, an assumption that silently became false whenfusion-plugin-roadmapgrew a store layer on@fusion/core'sDatabaseand added a schema-version pinning test.
Solution
One-line fix in plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-store.test.ts:
// Before (failing)
it("schema version is 108 after init", () => {
expect(db.getSchemaVersion()).toBe(108);
});
// After
it("schema version is 109 after init", () => {
expect(db.getSchemaVersion()).toBe(109);
});
The durable fix is the corrected sweep command — run at the repo root, not packages/, whenever SCHEMA_VERSION changes (substitute the old version):
grep -rn --exclude-dir=node_modules 'toBe(108)' .
Why This Works
SCHEMA_VERSION in packages/core/src/db.ts is the authoritative migration counter. Any workspace that instantiates @fusion/core's Database runs all migrations on init() and therefore observes the current version — including plugin workspaces. pnpm-workspace.yaml globs both packages/* and plugins/* (plus named plugin dirs); schema-version assertions can live in any of them. The sweep convention predated plugin store layers, so its packages/ scope was stale, not wrong-by-construction.
Prevention
-
Sweep the whole repo, not
packages/. Canonical command for a bump old → new:grep -rn --exclude-dir=node_modules 'toBe(<OLD>)' .— the workspace globs inpnpm-workspace.yamlare the authoritative list of places assertions can hide. -
Prefer the import over the literal.
SCHEMA_VERSIONis a named export of@fusion/core; plugin store tests should pin against it instead of a number, which survives every future bump with no sweep at all:import { SCHEMA_VERSION } from "@fusion/core"; it("schema version matches core after init", () => { expect(db.getSchemaVersion()).toBe(SCHEMA_VERSION); });(Core's own migration tests legitimately keep literals — they pin specific forward-path versions. The import pattern is for downstream consumers that just track core.)
-
As of 2026-06-05,
fusion-plugin-roadmapis the only plugin with a livegetSchemaVersion()assertion, but any plugin adding a store layer backed by core'sDatabasebecomes a candidate. CI shards do runplugins/suites, so CI is the backstop — the sweep exists to catch it pre-push.
Related Issues
- bundled-plugin-registration-drift (
docs/solutions/integration-issues/bundled-plugin-registration-drift.md) — companion failure class: an operation scoped topackages/silently missing theplugins/workspace peer. Itspackages/-scoped grep example is correct for its own domain (registration points live inpackages/); do not read it as endorsingpackages/-only scope for schema sweeps. docs/solutions/architecture-patterns/i18n-foundation-vite-ink-monorepo-code-split-catalogs.md— shared principle: eliminate the hardcoded second source of truth in favor of the derived/imported value.