Files
meshcore-analyzer/internal
Kpa-clawbot d9ba9937a6 fix(dbschema): canonical source for optional column migrations — fixes startup race (closes #1321) (#1322)
Red commit `2a8102b9` (failing test) → green commit `bb957c9f`. CI:
https://github.com/Kpa-clawbot/CoreScope/actions/workflows/ci.yml?query=branch%3Afix%2Fissue-1321

Fixes #1321.

## Why

On staging `/api/scope-stats` 500'd with `scope_name column not present`
despite the ingestor adding the column ~0.5s after server startup.
`cmd/server/db.go detectSchema()` runs in `OpenDB` and caches
`hasScopeName`/`hasDefaultScope`/`hasObsRawHex` booleans. With
supervisord launching server + ingestor simultaneously, the server's
PRAGMA can fire BEFORE the ingestor's `ALTER TABLE` completes — and the
boolean stays false until the server restarts. Same race class as #1283;
#1289 moved server-side ensures to `dbschema` but the optional columns
the ingestor still owned were left out.

## Fix — option (c) from the issue

Made `internal/dbschema/dbschema.go` the single source of truth for the
optional columns the server detects.

**Migrations moved from `cmd/ingestor/db.go applySchema` into
`dbschema.Apply`:**
- `transmissions.scope_name` + `idx_tx_scope_name` partial index
- `nodes.default_scope`
- `inactive_nodes.default_scope`
- `observations.raw_hex`

**`AssertReady` now asserts** every one of those columns. The server
cannot start with stale-false booleans because `AssertReady` will fatal
first if the columns are missing. The ingestor's old gated blocks are
replaced with pointer comments so anyone hunting for them lands in
`dbschema.go`. The `_migrations` marker rows are preserved (`INSERT OR
IGNORE`) to keep legacy DBs idempotent.

**Documented invariant** in the package doc: any new optional column the
server PRAGMA-detects belongs in `internal/dbschema/dbschema.go`, NOT in
`cmd/ingestor/db.go applySchema`.

## Tests

Added `internal/dbschema/dbschema_test.go` (RED in `2a8102b9`):
- `TestApplyAddsOptionalColumns_CanonicalSource` — post-`Apply`, all
four columns must exist.
- `TestAssertReady_RequiresOptionalColumns` — `AssertReady` must refuse
a DB missing them AND pass after full `Apply`.

`cmd/ingestor` and `cmd/server` full suites green.

---------

Co-authored-by: openclaw-bot <bot@openclaw.local>
2026-05-23 08:33:21 -07:00
..