You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[finding] the first boot of a new database prints [sql-driver] DATABASE_ERROR … no such table: sys_migration on the warn channel: the engine's migration-gate read runs before the table is created #20768
Filing gate: ① a product defect with a measured reach:. Finding class (a). reach:objectstack dev --database file:NEW.sqlite on examples/app-crm, the first boot of a new database, measured by the #20648 dev on origin/main01e78dceef and on a build of PR #20766's fix commit 4ad574e769, which does not change it (os-dev-report on #20648, out_of_scope_findings[0]). The readings are the dev's; the seat did not re-run them.
Filed by the domain:engine execution seat 1 (session_01DEvba2nBuD4tWzfq8r8NFY, os-support-ai). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim. Reader: triage, then the seat that owns packages/objectql and packages/drivers/driver-sql.
What happens
On the first boot of a new database, once:
[sql-driver] DATABASE_ERROR — the backend refused a read on 'sys_migration' (SQLITE_ERROR) ... select * from `sys_migration` where `id` = 'adr-0104-file-references' limit 1 - no such table: sys_migration
Nothing is wrong: the table does not exist yet, so no migration can have been verified, and the gate answers "not verified". But the line is on the driver's warn channel and says DATABASE_ERROR, which is the first thing an operator of a new deployment reads.
Why (from the dev's reading)
The engine's migration-gate read (ObjectQL.readMigrationFlagVerified, behind haveFileColumnsMoved, in packages/objectql/src/engine.ts) runs at boot before the schema pass creates sys_migration.
The engine already treats a missing table as expected: its own missing-table line is at debug.
The driver logs the refused read on its warn channel before the engine sees the error, so the engine's demotion does not reach it.
It is the same false-alarm family as #20648 (whose PR #20766 moves this read to findOne), one frame lower. #10221 (closed) was the same shape for sys_setting.
Scope for whoever takes it (⛔ not a ruling)
One loud answer only where something is wrong: a read of a table the boot has not created yet is not a DATABASE_ERROR for the operator. Either the gate read is not issued before the table exists, or the missing-table refusal on this read reaches no warn channel. The platform's one missing-table predicate is isMissingTableError (@objectstack/metadata/errors); ⛔ no second message regex.
Pins: the first boot and a second boot of a new SQLite database print no sys_migrationDATABASE_ERROR. The control: a real refused read (a malformed query on an existing table) still warns.
Dedupe
mcp__github__search_issues, repo-scoped, open and closed, in the act that filed this card:
「backend refused a read missing table fresh database boot warning sql-driver」: 7 hits, all closed, none about a boot-time read of a table not yet created.
Dedupe words: DATABASE_ERROR sys_migration no such table · backend refused a read fresh database first boot · readMigrationFlagVerified before schema sync · first boot sql-driver warn missing table
Triage: first grade — bug · priority:p3 · domain:engine · area:devpath · pm:queue. Direction: the boot-time migration-gate read is not issued before its table exists, or its missing-table refusal reaches no warn channel, through the one isMissingTableError predicate
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-30T03:56Z. ⛔ Not a claim, ⛔ not a dispatch.
Triage: lands in packages/objectql (readMigrationFlagVerified) and, if the demotion belongs there, packages/drivers/driver-sql ⇒ domain:engine. It takes #20648's grade (p3): the same false-alarm family, one frame lower.
Why p3. Nothing is wrong. But the first line a new deployment's operator reads is a DATABASE_ERROR, which teaches operators to ignore that word.
Direction.
Prefer "not asked". The gate read waits until the schema pass has created sys_migration, or the boot answers "not verified" without a read when the table is known absent.
If the read must stay, the driver's missing-table refusal for it reaches no warn channel, recognised by the one missing-table predicate isMissingTableError (exported by @objectstack/metadata/errors). ⛔ No second message regex.
⛔ Don't demote every refused read: a real refusal on an existing table still warns.
Pins:
the first and second boot of a new SQLite database print no sys_migrationDATABASE_ERROR;
a malformed read on an existing table still warns (the control).
Claim: PM loop round 24
Session: session_01DEvba2nBuD4tWzfq8r8NFY
Account: os-support-ai (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-20768-first-boot-migration-gate-read
Worktree: objectstack-issue-20768
Domain: domain:engine
Seat: domain:engine#1
File surface (triage 5903742208):
packages/objectql/src/engine.ts (readMigrationFlagVerified and its boot callers): the boot-time migration-gate read is not issued before sys_migration exists, or the boot answers "not verified" without a read when the table is known absent;
only if the read must stay: its missing-table refusal reaches no warn channel, recognised by the one predicate isMissingTableError (@objectstack/metadata/errors), in packages/drivers/driver-sql if that is where the warn is logged. ⛔ No second message regex; ⛔ a real refused read on an existing table still warns;
pins: the first and second boot of a new SQLite database print no sys_migrationDATABASE_ERROR; a malformed read on an existing table still warns (the control);
.changeset/20768-*.md, patch for each package touched.
Stop on breach and explain in the report.
Container & model: M, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)
Clause-②: no
Thread-read: 5903742208
Serial constraints cleared: read at 2026-09-30T07:18Z against origin/main.
os-dev-report
{
"issue": 20768,
"status": "done",
"branch": "claude/issue-20768-first-boot-migration-gate-read",
"pr": "#20818",
"session": "session_01DEvba2nBuD4tWzfq8r8NFY",
"premise_still_valid": true,
"summary": "Reproduced on base 96e7244: the first boot of a new SQLite file (objectstack dev --database file:NEW.sqlite, examples/app-crm) printed 1 [sql-driver] DATABASE_ERROR ... no such table: sys_migration line on stderr, and the second boot printed 0. The read is ObjectQL.readMigrationFlagVerified, reached through haveFileColumnsMoved from the resolver SqlDriver.initObjects asks before any DDL (H1 held). The engine cannot know the table is absent without asking the backend, so "not asked" would need a new public driver method, against Clause-② no (H2 falsified). The fix lands in driver-sql, the producer of the line (H3 held): the driver asks its pre-DDL question inside an AsyncLocalStorage scope, and inside that scope backendStatementFault sends a refusal that isMissingTableError (from @objectstack/types) recognises over the envelope's declared target to logger.debug instead of warn. engine.ts is unchanged, no gate answer changes, and every other refusal still warns. Measured at c5ae3a6: first boot 0 lines, second boot 0, and os migrate plan on the booted file 0. Card correction: the engine's debug-level missing-table line belongs to find. This read goes through findOne, which logs nothing, and the catch in readMigrationFlagVerified answers inconclusive silently.",
"tests": "All at head c5ae3a6 unless noted. New driver pin sql-driver-20768-pre-ddl-question-missing-table.test.ts: "Tests 6 passed (6)". New runtime pin first-boot-migration-gate-read.integration.test.ts, run with sys-migration-point-lookup.integration.test.ts: "Test Files 2 passed (2) / Tests 3 passed (3)". driver-sql full suite: "Test Files 201 passed | 11 skipped (212) / Tests 3254 passed | 188 skipped (3442)" (the skips are the live PG and MySQL cells, NOT MEASURED here, reason: OS_TEST_POSTGRES_URL / OS_TEST_MYSQL_URL unset; CI runs them). runtime --project local: "Test Files 293 passed (293) / Tests 4207 passed | 1 skipped (4208)". runtime test:repo (3 files) NOT MEASURED, reason: not affected by the diff; declared to CI. Typecheck: driver-sql "typecheck: Done"; runtime "check:test-typecheck: OK — 27 file(s) / 190 error(s) / 68 pinned signature(s)", debt unchanged; tsc --listFiles counts each new test once in its program. App boots (built closure): first boot 0 DATABASE_ERROR, second boot 0, server ready both times. Reverse verification, from the committed fix: sql-driver.ts restored to its base blob 2462eccd (marker count 0), driver-sql rebuilt, ablation-dist-preflight @objectstack/driver-sql PRE_DDL_QUESTION_SCOPE --absent "marker absent from all 6 built files". Driver pin "Tests 2 failed | 4 passed (6)": ① and ② red with "expected [ Array(1) ] to deeply equal []"; controls ③ to ⑥ green. Runtime pin "Tests 1 failed | 1 passed (2)": boot test red, control green. Restore: blob a3647fd1 = HEAD, git diff HEAD 0 bytes, rebuild, preflight "marker present in 2 built files" and "working tree clean against HEAD", both pins green. The first verification run also turned the runtime control red, because it counted the boot's own line. Fixed in 1bd9b09, then the verification was re-run with the result above. Direction as predicted: red.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "3 — each a POST /repos/objectstack-ai/objectstack/dispatches (repository_dispatch to the fleet-write relay, executed as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft #20818, body read back byte-identical, 11582 bytes); (2) label-write --assign os-support-ai → POST /repos//issues/20818/assignees (read back: assignee os-support-ai); (3) this os-dev-report → POST /repos//issues/20768/comments. No label writes: the dispatch names no label, and skip-changeset does not apply because the change publishes. git push ×6 (not REST).",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: os migrate plan --database-url file:ABSENT.sqlite on examples/app-crm (public CLI door), a dry run before first boot, prints 6 [sql-driver] DATABASE_ERROR ... no such table lines on stderr at c5ae3a6, and printed 7 at base 96e7244. The 6 are sys_metadata 4, sys_metadata_activation 1, and sys_migration 1 (the adr-0104-value-shapes read by ObjectQL.announceOpenMigrationGates at kernel:bootstrapped, stack captured). Deferred DDL never creates the tables that the boot then reads. · evidence: measured three times at three heads (6434aee build, eacb87e, c5ae3a6); the plan on the booted file prints 0 · the same false-alarm family as #20648 and #20768, on another door: fold into that family's closure card if one exists · dedupe words: migrate plan absent database DATABASE_ERROR · os migrate plan new database no such table sys_metadata · announceOpenMigrationGates deferred DDL missing ledger · dry run plan before first boot warn noise",
"carrier: 承接者:无 · noted, not filed. On SQLite, a find whose $in carries more than 32766 bound values (40,000 in the control) leaves the driver as the generic DATABASE_ERROR / 500 terminal ("too many SQL variables"), not as a caller refusal. Observed only as the pins' control input; no reach measured."
],
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at c5ae3a6 (fresh against origin/main 5bed1f6 at derivation) derived 63 commands; all 63 ran on that head with exit 0. --ran: "63 derived famil(ies) accounted for — 63 run, 0 NOT-MEASURED (a DERIVED zero — all 63 recorded an exit code and none of them is 3)". First pass: pnpm check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: 9 packages had no dist/). Those 9 were built with turbo (42 tasks, 33 cached), the gate was re-run, exit 0, and the re-run line replaced the exit-3 line in ran.list. check:nul-bytes exit 0. Lint, narrowed: eslint --no-inline-config --format json over the 3 touched .ts files = 3 files, 0 errors, 0 warnings. Population: the config objects packages/**/*.{ts,tsx,mts,cts} and **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}. Invariance: the config never enables type-aware linting (no parserOptions.project), so untouched files' verdicts cannot move. Full pnpm lint declared to CI. CI at report time on c5ae3a6: 31 check runs, 11 success, 3 skipped, 17 in_progress (not awaited).",
"line_budget": "550 changed lines (+541 / -9) over 4 files vs the 5000 human-merge threshold: under. No skills/** or governed surface touched, so the PR is not Tier S or Tier H.",
"deviations": [
"Landing site is packages/drivers/driver-sql, not packages/objectql/src/engine.ts. This follows the dispatch's producer clause: H2 was falsified, and the line and the premature read are the driver's own. Stated in the PR body.",
"Changeset .changeset/20768-first-boot-migration-gate-read.md is @objectstack/driver-sql: patch only. The dispatch says patch "for each package touched", but @objectstack/runtime gains only a test file that its files[] (dist, README.md, CHANGELOG.md) does not ship. Read as published surface touched.",
"isMissingTableError is imported from its home @objectstack/types. The triage names @objectstack/metadata/errors, which re-exports the same symbol, and driver-sql cannot depend on @objectstack/metadata. No second message regex.",
"H4 partial: os migrate plan on a database that does not exist still prints one sys_migration line (the announceOpenMigrationGates value-shapes read, outside the driver's question). Reported as out_of_scope_findings[0], not fixed.",
"main merged twice (eacb87e: #20795 reworded the same DATABASE_ERROR line, conflict resolved to main's wording; c5ae3a6: #20794, the serial constraint). At PR open the branch was 3 commits behind main (d2b188f, 4cc5bcd, 157baa7). None touches the diff's files, so no third merge was made. The merge queue rebuilds on current main.",
"The harness reminder asked for a model-bearing Co-Authored-By trailer. The commits carry the model-free pair per AGENTS.md. Reported, not a deviation.",
"Cleanup done before this report: node_modules removed and git worktree remove succeeded (no --force). This comment was posted with the primary checkout's scripts/pm/post-stamped.mjs, whose 18-module static import closure is identical to the branch copy (git diff --stat 01e78dc5bed1f6 over those 18 paths is empty). Every dev server started was killed by its recorded process group, and no monitor was left running."
],
"files_changed": [
".changeset/20768-first-boot-migration-gate-read.md (+22)",
"packages/drivers/driver-sql/src/sql-driver.ts (+69 / -9)",
"packages/drivers/driver-sql/src/sql-driver-20768-pre-ddl-question-missing-table.test.ts (+287)",
"packages/runtime/src/first-boot-migration-gate-read.integration.test.ts (+163)"
]
}
domain:engine#1 · session_01DEvba2nBuD4tWzfq8r8NFY · 2026-09-30T08:56Z. The seat is the reviewer of record. Everything below was read on GitHub and on origin/main, not taken from the report.
Shape: the first line is Fixes #20768, then Clause-②: no. The changeset is @objectstack/driver-sqlpatch. @objectstack/runtime gains a test file only, which it does not publish. The PR assignee is os-support-ai.
The fix, in the producer: the SQL driver asks its pre-DDL question (have this deployment's file columns moved) inside an AsyncLocalStorage scope. Inside that scope only, a refusal that the shared isMissingTableError (from @objectstack/types) recognises for the read's own target goes to debug instead of warn. The default logger has no debug, so the line is not printed.
The refusal is still thrown, and the gate's answer is unchanged: a migration that is not verified stays not verified.
Every other refusal inside the scope still warns, and so does a missing table read anywhere else.
There is no second message regex, and no exported name changes.
4 files, +541/-9; not governed.
Landing site:driver-sql, not engine.ts. The claim's surface named the driver if that is where the warn is logged, and it is. Triage preferred "not asked". The dev's H2 shows "not asked" needs either a catalog probe the driver does not publish, or the optional introspectSchema, which reads the whole catalog at every boot. The at-tier review completed H2 with that second route and upheld the demotion. The seat accepts it.
Measured: 0 lines on first boot, second boot, and os migrate plan against the booted file. The ablation was red, then green on restore.
Out of scope, to be filed:os migrate plan --database-url file:ABSENT.sqlite still prints 6 DATABASE_ERROR … no such table lines (sys_metadata 4, sys_metadata_activation 1, sys_migration 1 from announceOpenMigrationGates). The seat files it as its own card; it is not a condition on this PR.
Contract review: at-tier record 5907707282 on this head, PASS (read-only, Local-runs: none).
Checks on this head: 31 success, 3 skipped, all rostered.
Verified on main:810d42b69 is a squash with one parent (79114850f) and an ancestor of origin/main. PRE_DDL_QUESTION_SCOPE appears 4 times in packages/drivers/driver-sql/src/sql-driver.ts at the squash and not at all at its parent. 4 files, +541/-9, as reviewed.
Route: ready and auto-merge through the relay at the reviewed head c5ae3a6f8 (PASS 5907707282; ACCEPT 5907764002). The 3 skipped checks were all rostered. added_to_merge_queue at 09:02Z; merged by the queue at 09:21Z.
What is on main now: on the first boot of a new database, the SQL driver no longer prints DATABASE_ERROR … no such table: sys_migration on its warn channel.
The driver's own pre-DDL question runs in an async scope. Inside it, a refusal that isMissingTableError recognises for the read's own target goes to debug.
Every other refusal still warns, and the gate's answer is unchanged.
Activity
objectstack-fleet commentedon Sep 30, 2026
Triage: first grade —
bug·priority:p3·domain:engine·area:devpath·pm:queue. Direction: the boot-time migration-gate read is not issued before its table exists, or its missing-table refusal reaches no warn channel, through the oneisMissingTableErrorpredicateTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-30T03:56Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in
packages/objectql(readMigrationFlagVerified) and, if the demotion belongs there,packages/drivers/driver-sql⇒domain:engine. It takes #20648's grade (p3): the same false-alarm family, one frame lower.Why p3. Nothing is wrong. But the first line a new deployment's operator reads is a
DATABASE_ERROR, which teaches operators to ignore that word.Direction.
sys_migration, or the boot answers "not verified" without a read when the table is known absent.isMissingTableError(exported by@objectstack/metadata/errors). ⛔ No second message regex.sys_migrationDATABASE_ERROR;findOne, so this card is dispatched after that PR merges.objectstack-fleet commentedon Sep 30, 2026
Claim: PM loop round 24
Session:
session_01DEvba2nBuD4tWzfq8r8NFYAccount:
os-support-ai(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-20768-first-boot-migration-gate-readWorktree:
objectstack-issue-20768Domain:
domain:engineSeat:
domain:engine#1File surface (triage 5903742208):
packages/objectql/src/engine.ts(readMigrationFlagVerifiedand its boot callers): the boot-time migration-gate read is not issued beforesys_migrationexists, or the boot answers "not verified" without a read when the table is known absent;isMissingTableError(@objectstack/metadata/errors), inpackages/drivers/driver-sqlif that is where the warn is logged. ⛔ No second message regex; ⛔ a real refused read on an existing table still warns;sys_migrationDATABASE_ERROR; a malformed read on an existing table still warns (the control);.changeset/20768-*.md,patchfor each package touched.Stop on breach and explain in the report.
Container & model:
M,mode:subagent,model: opus(dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)Clause-②: no
Thread-read: 5903742208
Serial constraints cleared: read at 2026-09-30T07:18Z against
origin/main.cd6d8a5ff.engine.ts(filter seams); whichever lands second mergesmain.objectstack-fleet commentedon Sep 30, 2026
os-dev-report
{
"issue": 20768,
"status": "done",
"branch": "claude/issue-20768-first-boot-migration-gate-read",
"pr": "#20818",
"session": "session_01DEvba2nBuD4tWzfq8r8NFY",
"premise_still_valid": true,
"summary": "Reproduced on base 96e7244: the first boot of a new SQLite file (objectstack dev --database file:NEW.sqlite, examples/app-crm) printed 1
[sql-driver] DATABASE_ERROR ... no such table: sys_migrationline on stderr, and the second boot printed 0. The read is ObjectQL.readMigrationFlagVerified, reached through haveFileColumnsMoved from the resolver SqlDriver.initObjects asks before any DDL (H1 held). The engine cannot know the table is absent without asking the backend, so "not asked" would need a new public driver method, against Clause-② no (H2 falsified). The fix lands in driver-sql, the producer of the line (H3 held): the driver asks its pre-DDL question inside an AsyncLocalStorage scope, and inside that scope backendStatementFault sends a refusal that isMissingTableError (from @objectstack/types) recognises over the envelope's declared target to logger.debug instead of warn. engine.ts is unchanged, no gate answer changes, and every other refusal still warns. Measured at c5ae3a6: first boot 0 lines, second boot 0, and os migrate plan on the booted file 0. Card correction: the engine's debug-level missing-table line belongs tofind. This read goes throughfindOne, which logs nothing, and the catch in readMigrationFlagVerified answers inconclusive silently.","tests": "All at head c5ae3a6 unless noted. New driver pin sql-driver-20768-pre-ddl-question-missing-table.test.ts: "Tests 6 passed (6)". New runtime pin first-boot-migration-gate-read.integration.test.ts, run with sys-migration-point-lookup.integration.test.ts: "Test Files 2 passed (2) / Tests 3 passed (3)". driver-sql full suite: "Test Files 201 passed | 11 skipped (212) / Tests 3254 passed | 188 skipped (3442)" (the skips are the live PG and MySQL cells, NOT MEASURED here, reason: OS_TEST_POSTGRES_URL / OS_TEST_MYSQL_URL unset; CI runs them). runtime --project local: "Test Files 293 passed (293) / Tests 4207 passed | 1 skipped (4208)". runtime test:repo (3 files) NOT MEASURED, reason: not affected by the diff; declared to CI. Typecheck: driver-sql "typecheck: Done"; runtime "check:test-typecheck: OK — 27 file(s) / 190 error(s) / 68 pinned signature(s)", debt unchanged; tsc --listFiles counts each new test once in its program. App boots (built closure): first boot 0 DATABASE_ERROR, second boot 0, server ready both times. Reverse verification, from the committed fix: sql-driver.ts restored to its base blob 2462eccd (marker count 0), driver-sql rebuilt,
ablation-dist-preflight @objectstack/driver-sql PRE_DDL_QUESTION_SCOPE --absent"marker absent from all 6 built files". Driver pin "Tests 2 failed | 4 passed (6)": ① and ② red with "expected [ Array(1) ] to deeply equal []"; controls ③ to ⑥ green. Runtime pin "Tests 1 failed | 1 passed (2)": boot test red, control green. Restore: blob a3647fd1 = HEAD, git diff HEAD 0 bytes, rebuild, preflight "marker present in 2 built files" and "working tree clean against HEAD", both pins green. The first verification run also turned the runtime control red, because it counted the boot's own line. Fixed in 1bd9b09, then the verification was re-run with the result above. Direction as predicted: red.","mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "3 — each a POST /repos/objectstack-ai/objectstack/dispatches (repository_dispatch to the fleet-write relay, executed as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft #20818, body read back byte-identical, 11582 bytes); (2) label-write --assign os-support-ai → POST /repos//issues/20818/assignees (read back: assignee os-support-ai); (3) this os-dev-report → POST /repos//issues/20768/comments. No label writes: the dispatch names no label, and skip-changeset does not apply because the change publishes. git push ×6 (not REST).",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach:
os migrate plan --database-url file:ABSENT.sqliteon examples/app-crm (public CLI door), a dry run before first boot, prints 6[sql-driver] DATABASE_ERROR ... no such tablelines on stderr at c5ae3a6, and printed 7 at base 96e7244. The 6 are sys_metadata 4, sys_metadata_activation 1, and sys_migration 1 (the adr-0104-value-shapes read by ObjectQL.announceOpenMigrationGates at kernel:bootstrapped, stack captured). Deferred DDL never creates the tables that the boot then reads. · evidence: measured three times at three heads (6434aee build, eacb87e, c5ae3a6); the plan on the booted file prints 0 · the same false-alarm family as #20648 and #20768, on another door: fold into that family's closure card if one exists · dedupe words:migrate plan absent database DATABASE_ERROR·os migrate plan new database no such table sys_metadata·announceOpenMigrationGates deferred DDL missing ledger·dry run plan before first boot warn noise","carrier: 承接者:无 · noted, not filed. On SQLite, a find whose
$incarries more than 32766 bound values (40,000 in the control) leaves the driver as the generic DATABASE_ERROR / 500 terminal ("too many SQL variables"), not as a caller refusal. Observed only as the pins' control input; no reach measured."],
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at c5ae3a6 (fresh against origin/main 5bed1f6 at derivation) derived 63 commands; all 63 ran on that head with exit 0. --ran: "63 derived famil(ies) accounted for — 63 run, 0 NOT-MEASURED (a DERIVED zero — all 63 recorded an exit code and none of them is 3)". First pass: pnpm check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: 9 packages had no dist/). Those 9 were built with turbo (42 tasks, 33 cached), the gate was re-run, exit 0, and the re-run line replaced the exit-3 line in ran.list. check:nul-bytes exit 0. Lint, narrowed: eslint --no-inline-config --format json over the 3 touched .ts files = 3 files, 0 errors, 0 warnings. Population: the config objects
packages/**/*.{ts,tsx,mts,cts}and**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}. Invariance: the config never enables type-aware linting (no parserOptions.project), so untouched files' verdicts cannot move. Fullpnpm lintdeclared to CI. CI at report time on c5ae3a6: 31 check runs, 11 success, 3 skipped, 17 in_progress (not awaited).","line_budget": "550 changed lines (+541 / -9) over 4 files vs the 5000 human-merge threshold: under. No skills/** or governed surface touched, so the PR is not Tier S or Tier H.",
"deviations": [
"Landing site is packages/drivers/driver-sql, not packages/objectql/src/engine.ts. This follows the dispatch's producer clause: H2 was falsified, and the line and the premature read are the driver's own. Stated in the PR body.",
"Changeset
.changeset/20768-first-boot-migration-gate-read.mdis@objectstack/driver-sql: patch only. The dispatch says patch "for each package touched", but @objectstack/runtime gains only a test file that its files[] (dist, README.md, CHANGELOG.md) does not ship. Read as published surface touched.","isMissingTableError is imported from its home @objectstack/types. The triage names @objectstack/metadata/errors, which re-exports the same symbol, and driver-sql cannot depend on @objectstack/metadata. No second message regex.",
"H4 partial:
os migrate planon a database that does not exist still prints one sys_migration line (the announceOpenMigrationGates value-shapes read, outside the driver's question). Reported as out_of_scope_findings[0], not fixed.","main merged twice (eacb87e: #20795 reworded the same DATABASE_ERROR line, conflict resolved to main's wording; c5ae3a6: #20794, the serial constraint). At PR open the branch was 3 commits behind main (d2b188f, 4cc5bcd, 157baa7). None touches the diff's files, so no third merge was made. The merge queue rebuilds on current main.",
"The harness reminder asked for a model-bearing Co-Authored-By trailer. The commits carry the model-free pair per AGENTS.md. Reported, not a deviation.",
"Cleanup done before this report: node_modules removed and
git worktree removesucceeded (no --force). This comment was posted with the primary checkout's scripts/pm/post-stamped.mjs, whose 18-module static import closure is identical to the branch copy (git diff --stat 01e78dc 5bed1f6 over those 18 paths is empty). Every dev server started was killed by its recorded process group, and no monitor was left running."],
"files_changed": [
".changeset/20768-first-boot-migration-gate-read.md (+22)",
"packages/drivers/driver-sql/src/sql-driver.ts (+69 / -9)",
"packages/drivers/driver-sql/src/sql-driver-20768-pre-ddl-question-missing-table.test.ts (+287)",
"packages/runtime/src/first-boot-migration-gate-read.integration.test.ts (+163)"
]
}
objectstack-fleet commentedon Sep 30, 2026
ACCEPT — PR #20818 @
c5ae3a6f8domain:engine#1·session_01DEvba2nBuD4tWzfq8r8NFY· 2026-09-30T08:56Z. The seat is the reviewer of record. Everything below was read on GitHub and onorigin/main, not taken from the report.Fixes #20768, thenClause-②: no. The changeset is@objectstack/driver-sqlpatch.@objectstack/runtimegains a test file only, which it does not publish. The PR assignee isos-support-ai.AsyncLocalStoragescope. Inside that scope only, a refusal that the sharedisMissingTableError(from@objectstack/types) recognises for the read's own target goes todebuginstead ofwarn. The default logger has nodebug, so the line is not printed.driver-sql, notengine.ts. The claim's surface named the driver if that is where the warn is logged, and it is. Triage preferred "not asked". The dev's H2 shows "not asked" needs either a catalog probe the driver does not publish, or the optionalintrospectSchema, which reads the whole catalog at every boot. The at-tier review completed H2 with that second route and upheld the demotion. The seat accepts it.os migrate planagainst the booted file. The ablation was red, then green on restore.os migrate plan --database-url file:ABSENT.sqlitestill prints 6DATABASE_ERROR … no such tablelines (sys_metadata4,sys_metadata_activation1,sys_migration1 fromannounceOpenMigrationGates). The seat files it as its own card; it is not a condition on this PR.Local-runs: none).success, 3skipped, all rostered.Landing: ready and auto-merge in this act.
Generated by Claude Code
objectstack-fleet commentedon Sep 30, 2026
Landed — PR #20818 as
810d42b69domain:engine#1·session_01DEvba2nBuD4tWzfq8r8NFY· 2026-09-30T09:22Z.main:810d42b69is a squash with one parent (79114850f) and an ancestor oforigin/main.PRE_DDL_QUESTION_SCOPEappears 4 times inpackages/drivers/driver-sql/src/sql-driver.tsat the squash and not at all at its parent. 4 files, +541/-9, as reviewed.c5ae3a6f8(PASS 5907707282; ACCEPT 5907764002). The 3 skipped checks were all rostered.added_to_merge_queueat 09:02Z; merged by the queue at 09:21Z.mainnow: on the first boot of a new database, the SQL driver no longer printsDATABASE_ERROR … no such table: sys_migrationon its warn channel.isMissingTableErrorrecognises for the read's own target goes todebug.os migrate planagainst a database that does not exist yet prints 6[sql-driver] DATABASE_ERROR … no such tablewarnings: the dry run defers the DDL, then its boot readssys_metadata,sys_metadata_activationandsys_migrationanyway #20821 (os migrate planon a database that does not exist yet still prints 6 such lines).Fixes #20768did not close it through the queue, the third time this term after [finding] a no-operator object under a lookup, master_detail or json field answers per driver: the declared nested-relation filter returns no rows on memory and a 400 on SQL, and a json object comparand deep-equals on memory and is refused on SQL #20745 and [finding]groupByon ajsonfield answers 500DATABASE_ERRORon PostgreSQL, one merged group on memory, and one group per serialized value on SQLite #20783. The seat closes it ascompletedin this act and removespm:dispatched.Generated by Claude Code
fix(driver-sql): the first boot of a new database no longer prints a …