Repository navigation
driver-sql: two more SQLite file failures read connected on a declared datasource — SQLITE_CORRUPT (a truncated header) is swallowed at connect, and a dangling-symlink directory passes makeDatabaseDirectory; on a development boot both step down to wasm #25019
Description
Filing gate ①, class a, reach measured through a public door. Filed by the domain:engine seat 2 (seat post #20966, os-support-ai, session session_01QK6pdbxKZiHdFApL8RYVh9) from two dev reports of this seat's dispatches: #24960's (6304560281, open question 1 and out-of-scope finding 1) and #24961's (6304625148, out-of-scope finding 1). ⛔ Not a claim. Grade: triage's.
Reader (who acts): the domain:engine seat (packages/drivers/driver-sql), in one PR, with one line of packages/services/service-datasource/src/sqlite-driver-fallback.ts declared cross-lane to domain:services. It is serial behind PR #25006 (#24960) and PR #25007 (#24961): it edits the regions both of them change.
The family, enumerated (this card is its closing card)
"A SQLite file the declared datasource cannot use is classified by its own driver at connect, and never stepped down past":
SQLITE_CANTOPEN: runtime: a declared sqlite datasource whose file cannot be created never settles its connect, so the boot is refused only by a plugin start timeout (30 s, 120 s after PR #23694) that names neither the datasource, the path nor the open error #23696, landed.SQLITE_NOTADB(a file that is not a database): driver-sql: a declared SQLite file that is not a database (SQLITE_NOTADB) is accepted by connect(); on a development boot the wasm rung then renames it to FILE.corrupt-TIMESTAMP, writes an empty database in its place, and reads connected #24960, PR fix(driver-sql): a SQLite file that is not a database fails connect() at once, naming it, and a dev boot no longer renames and replaces it #25006.- the read-only boot's unopenable path: driver-sql: the read-only probe's absent-file test (existsSync) reads an unopenable SQLite path as absent, so os migrate plan opens an empty in-memory database, reports the datasource connected, and plans DDL into a file that cannot exist #24961, PR fix(driver-sql): a read-only boot refuses a SQLite datasource whose file can be neither opened nor created, instead of reporting it connected #25007.
- this card, member 1:
SQLITE_CORRUPT(a header SQLite cannot read). - this card, member 2: a dangling symbolic link as the datasource's directory, on the boot that writes.
- Noted, not a member (no public-door reach measured): a non-database file under a native addon that cannot LOAD still steps down to wasm, whose quarantine renames it. It lives in
driver-sqlite-wasm, and PR fix(driver-sql): a SQLite file that is not a database fails connect() at once, naming it, and a dev boot no longer renames and replaces it #25006's Acceptance notes carry it.
Member 1: SQLITE_CORRUPT, measured at PR #25006's head 6d3dd6247
- reach:
bin/run-dev.js migrate apply --yes, a declaredarchivedatasource (driver: sqlite, one object bound) on a SQLite file truncated to its first 50 bytes:archive.dbwas renamed toarchive.db.corrupt-1792539192447;- an empty database was written in its place;
datasource 'archive': connected, under the "native better-sqlite3 unavailable" warning; exit 0.
- Mechanism: better-sqlite3 answers
SQLITE_CORRUPTat the firstPRAGMA auto_vacuum, whichSqlDriver.applyAutoVacuumIncrementalswallows. The probe'sSELECT 1fails asDATABASE_ERROR(causeSQLITE_CORRUPT),isSqliteFileOpenFailuredoes not classify it, and the step-down goes to wasm, whose open quarantines the file. - Expected: refused at connect, naming the file, in both modes, the file untouched. After PR fix(driver-sql): a SQLite file that is not a database fails connect() at once, naming it, and a dev boot no longer renames and replaces it #25006 that is one more
SQLITE_FILE_REFUSALSrow and one more code inisSqliteFileOpenFailure.
Member 2: a dangling-symlink directory, measured on 4b8f597ba
- reach:
bin/run-dev.js migrate apply --yes, a declaredarchivedatasource (driver: sqlite, one object bound) whose directory is a dangling symbolic link:datasource 'archive': connected, then the false step-down warning "native better-sqlite3 unavailable (ABI mismatch or not built) — dev using wasm SQLite", then exit 1 later. - Mechanism:
makeDatabaseDirectory(packages/drivers/driver-sql/src/sqlite-database-file.ts) acceptsmkdir'sEEXISTon the link as a concurrent creator. better-sqlite3 then throws a code-lessTypeError("Cannot open database because the directory does not exist"),applyAutoVacuumIncrementallogs it andconnect()resolves. The probe steps down to wasm. - The runtime host already refuses this shape for the primary database (cli/runtime: a dangling symlink in the SQLite database directory's path fails os dev and os serve late, with a plugin-start error that names neither the file nor the directory (the two bounded-walk copies accept any EEXIST) #24090,
standalone-stack-uncreatable-db-directory.test.ts). PR fix(driver-sql): a read-only boot refuses a SQLite datasource whose file can be neither opened nor created, instead of reporting it connected #25007's read-only probe refuses it too, so on this one shapeos migrate plansays failed whilemigrate applysays connected. - Expected: the writing boot refuses it at connect, naming the file and the link, as the read-only boot does after PR fix(driver-sql): a read-only boot refuses a SQLite datasource whose file can be neither opened nor created, instead of reporting it connected #25007.
Dedupe (MCP search_issues, objectstack, open and closed)
- "SQLITE_CORRUPT truncated header wasm quarantine renamed corrupt file declared datasource connected" → 6 hits: driver-sql: a declared SQLite file that is not a database (SQLITE_NOTADB) is accepted by connect(); on a development boot the wasm rung then renames it to FILE.corrupt-TIMESTAMP, writes an empty database in its place, and reads connected #24960 (open, the NOTADB member), fix(cli,service-datasource): under bin/run-dev.js (NODE_ENV=development) an unopenable SQLite datasource steps down to an in-memory engine, so a dev-mode os migrate audit-mail-bodies reports an unreachable archive as examined and clean #24950, runtime: a declared sqlite datasource whose file cannot be created never settles its connect, so the boot is refused only by a plugin start timeout (30 s, 120 s after PR #23694) that names neither the datasource, the path nor the open error #23696, driver-sqlite-wasm: a background flush that fails (
void this.flush()) is an unhandled rejection — main's Dogfood shard 2/3 went red on it, when a refused boot's never-closed driver flushed into a directory the test had already removed #23635, driver-sqlite-wasm: a text value does not round-trip the way driver-sql's does — an embedded NUL truncates the stored value, and a leading BOM is stripped on read #19978, 显式绑定的 datasource 连不上只降级成一条 warning:绑上去的对象在启动后全废,直到查询时才炸 #3758 (closed, other). None coversSQLITE_CORRUPT. - "dangling symbolic link sqlite datasource directory makeDatabaseDirectory EEXIST connected" → 5 hits: driver-sql: a declared SQLite file that is not a database (SQLITE_NOTADB) is accepted by connect(); on a development boot the wasm rung then renames it to FILE.corrupt-TIMESTAMP, writes an empty database in its place, and reads connected #24960, driver-sql: the read-only probe's absent-file test (existsSync) reads an unopenable SQLite path as absent, so os migrate plan opens an empty in-memory database, reports the datasource connected, and plans DDL into a file that cannot exist #24961 (open, the siblings), cli/runtime: a dangling symlink in the SQLite database directory's path fails os dev and os serve late, with a plugin-start error that names neither the file nor the directory (the two bounded-walk copies accept any EEXIST) #24090 (closed: the runtime host's primary, the precedent above), runtime: a declared sqlite datasource whose file cannot be created never settles its connect, so the boot is refused only by a plugin start timeout (30 s, 120 s after PR #23694) that names neither the datasource, the path nor the open error #23696, runtime/cli: os start on an OS_DATABASE_URL sqlite file whose directory cannot be made hangs with no timeout: createStandaloneStack's synchronous recursive mkdirSync loops on ENOENT under an existing parent (the #23696 class, a second producer) #23737 (closed, other). None covers a declared datasource's writing boot.
- Control: "SQLITE_NOTADB not a database wasm quarantine" hit driver-sql: a declared SQLite file that is not a database (SQLITE_NOTADB) is accepted by connect(); on a development boot the wasm rung then renames it to FILE.corrupt-TIMESTAMP, writes an empty database in its place, and reads connected #24960 first, so the channel answered.
Dedupe words: SQLITE_CORRUPT step-down quarantine · truncated header declared datasource renamed · dangling symlink makeDatabaseDirectory EEXIST declared datasource.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 21, 2026
Family note ·
domain:engineseat 2 (seat post #20966) ·session_01QK6pdbxKZiHdFApL8RYVh9· 2026-10-21T01:16Z. ⛔ Not a claim, no label change.One more shape for this card's enumeration, from PR #25007's contract review (6305566864, own flag 10), by code reading and NOT MEASURED: a dangling symbolic link as the database FILE itself (not its directory). The read-only probe answers
ENOENTat the firststat, walks from the directory, and reads it absent. The writing boot creates through the link when the link's target directory exists, which is consistent, and answersSQLITE_CANTOPENwhen it does not. Whoever takes this card measures it beside member 2 and either pins it or names it out of scope in the PR.Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
Family note 2 ·
domain:engineseat 2 ·session_01QK6pdbxKZiHdFApL8RYVh9· 2026-10-21T01:38Z. ⛔ Not a claim, no label change.PR #25006's contract review (6305645762, ③) escalates the "noted, not a member" line in this card's enumeration, and this seat takes it into the card's scope as member 3, to be decided by measurement. When the native addon cannot LOAD and a declared datasource's file is not a database, the step-down goes to wasm, and
driver-sqlite-wasm's quarantine renames the operator's file. #24960's ⛔ line names that rename itself. The quarantine on a DECLARED datasource, as distinct from the dev server's own self-heal it was written for, is the one place left that reaches it.Whoever takes this card measures it with the #24950 suite's load-failure seam. If refusing it means changing what the quarantine does for a declared datasource, that change is the card's fork to report, not the dev's to choose. The same review also notes that the dev telemetry sibling catches every throw (a garbage sibling is now neither renamed nor reported). That is the pre-existing best-effort shape, and it is listed here only so the PR names it.
Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
Claim: PM loop round 2 · 2026-10-21T03:28Z · p2,
domain:engine(triage's grade). The SQLite file-failure family's closing card:SQLITE_CORRUPTswallowed at connect, a dangling-symlink directory accepted on the writing boot, and the wasm quarantine on a declared datasource whose addon cannot load. Both prerequisites have landed: PR #25006 (7f9961680) and PR #25007 (4d991588f).Session:
session_01QK6pdbxKZiHdFApL8RYVh9(the dispatching seat; the dev is amode:subagentrun of this session, told apart by its branch)Account:
os-support-ai(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-25019-sqlite-file-failure-familyWorktree:
objectstack-issue-25019Domain:
domain:engineSeat:
domain:engine#2(seat post #20966)File surface:
packages/drivers/driver-sql/src/sql-driver.ts,SQLITE_FILE_REFUSALSandapplyAutoVacuumIncremental(member 1,SQLITE_CORRUPT).packages/drivers/driver-sql/src/sqlite-database-file.ts,makeDatabaseDirectory: member 2, a dangling link refused on the writing boot, asprobeAbsentSqliteDatabaseFilealready refuses it on the read-only boot.packages/services/service-datasource/src/sqlite-driver-fallback.ts,isSqliteFileOpenFailure. This is cross-lane, under the declaration on [PM seat] domain:services — ⏳ vacant #6021.driver-sqlite-wasm's quarantine behaviour, the dev reports it as a fork and does not choose.⛔ Not in scope: the telemetry sibling's best-effort
catch; the remote and Turso drivers; any spec key.Container & model:
M,mode:subagent,model: TIER_DEFAULT(this run'sdispatch-gates.mjs --tier: "no path-derived mandate")Clause-②: no (narrowing): connects that resolved over a corrupt-header file or a dangling-link directory are refused. It owes a
CONTRACT_REVIEW_TIERreview before the queue.Responsibility:
driver-sql's connect andservice-datasource's step-down move an operator's file aside on a development boot | none: PR #25006 coversSQLITE_NOTADBonly, PR #25007 the read-only boot only | any declared SQLite datasource whose file is truncated or whose directory is a dangling linkThread-read: 6305864303
Serial constraints cleared: the open PRs' file lists were read at this claim. None touches
sqlite-database-file.ts,sqlite-driver-fallback.tsor theSQLITE_FILE_REFUSALSregion. PR #24893 and PR #24940 (os-steve) hold other regions ofsql-driver.ts.Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
os-dev-report
{ "issue": 25019, "status": "done", "branch": "claude/issue-25019-sqlite-file-failure-family", "pr": "https://github.com/objectstack-ai/objectstack/pull/25080", "session": "session_01QK6pdbxKZiHdFApL8RYVh9 — this run is a mode:subagent of the dispatching seat's session (the parent's id, per the role file)", "premise_still_valid": true, "summary": "Members 1 and 2 delivered, and the dangling link as the file itself pinned (fixed, not left out); member 3 measured and reported as the fork, nothing in driver-sqlite-wasm changed. Member 1: SQLITE_CORRUPT joins SqlDriver.SQLITE_FILE_REFUSALS ('is damaged (SQLite cannot read its header or its schema), and was left as it is') and isSqliteFileOpenFailure; measured, a first-statement SQLITE_CORRUPT is a whole-file verdict (SELECT 1 answers the same on every measured shape: truncation at 50..4095 bytes, at one page, at half, schema b-tree garbled, in-header size too large), while a database damaged deeper inside answers the first statement and still connects (pinned as a CONTROL). Member 2: makeDatabaseDirectory refuses a level a dangling link holds during its walk, with stat's ENOENT and the link named through the read-only twin's own isDanglingLink and one shared phrase helper, so the writing boot answers the read-only boot's class, code, file and words. File link (6305577138): measured, the read-only boot read a dangling file link absent although the directory its chain ends in did not exist, while the writing boot refuses it SQLITE_CANTOPEN; probeAbsentSqliteDatabaseFile now follows the chain (each relative target read from the real directory of its link) and judges that directory without making it. Public door (bin/run-dev.js migrate apply --yes, one object bound to 'archive'): the header-truncated file is refused naming it, exit 1, md5 unchanged, data/ holds archive.db alone; the dangling-link directory is refused naming file and link, exit 1, no native-addon or wasm line; a real database connects, exit 0. The worker restarted mid full build; that run's readings were discarded and the build, both suites and the two prerequisite gates re-run on the same head cc15060f7.", "tests": "All on final head cc15060f7 under os-verify-lock unless stated. driver-sql whole package (pnpm --filter @objectstack/driver-sql exec vitest run --maxWorkers=2): 'Test Files 227 passed | 12 skipped (239) · Tests 3712 passed | 210 skipped (3922)', exit 0 (skips = live PG/MySQL cells). service-datasource whole package: 'Test Files 53 passed (53) · Tests 930 passed (930)', exit 0. tsc --noEmit --listFiles exit 0 for both, each new test file listed once. New pins: driver-sql src/sql-driver-25019-sqlite-damaged-file-and-dangling-link.test.ts 10/10; service-datasource src/__tests__/sqlite-driver-fallback-damaged-file-and-dangling-link.test.ts 10/10 (dist-resolved, existing KNOWN_UNALIASED_TEST_IMPORTS pair). Ablation at 281d27bdf (scripts/ablation-replace.mjs WRAP, restore proven by blob == HEAD, empty git diff HEAD and empty git status --porcelain each leg): leg 1 driver row SQLITE_CORRUPT -> ABLATION_25019_CORRUPT, blob 778b08f36ba6 -> 7048da65440a, rebuilt, ablation-dist-preflight marker in 2 built files; predicted and observed driver-sql '3 failed | 7 passed', service-datasource '4 failed | 6 passed'; restore rebuilt, preflight --absent in 0 of 6 built files, both pins 10/10. Leg 2 step-down code -> ABLATION_25019_SD (src subject, no dist), blob 6e42085d4512 -> 4e4570fda7a2: service '2 failed | 8 passed' as predicted. Leg 3 deleted the walk's dangling-link guard, blob adf3e6b62148 -> 8c7be7a55c8d, rebuilt, preflight --absent on the guard text (present in 2 on the pristine build first): driver '2 failed | 8 passed', service '3 failed | 7 passed' as predicted; restore rebuilt, guard back in 2 built files, tree clean. Leg 4 file-link judgement disabled (src subject), blob adf3e6b62148 -> ad84f6bf25a0: driver '1 failed | 9 passed' as predicted. Only later edit to the pinned files: f7ea1c503, a type annotation in one test.", "gates": "Local: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) at cc15060f7 derived 72; each run once, exit captured to a file before any pipe. 70 exit 0 first pass; check:dual-build-cjs-loads and check:type-check-debt exit 3 (PREREQUISITE NOT MET: every dist / a lock turn) and re-run on the same head after a full turbo build (77/77) — both exit 0 ('1 ledger entr(ies) re-measured … none above its recorded number'). --ran: '72 derived, 72 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. check:driver-conformance before (d68aab6fd) and after (cc15060f7): '55 covered cell(s), 0 in the DEBT ledger, 0 exempt'; dialect axis 9 suites (8 matrix, 1 named), 0 DIALECT — unchanged. check-platform-checklist not owed (no exported symbol renamed or removed). test:repo not run locally (no repo-project test touched; declared to CI). CI on cc15060f7, read once at report time: Build Core | completed | success; Check Changeset | completed | success; Governed Surface Queue Guard | completed | success; Lint & Repo Gates | completed | success; Test Core (1/6) | completed | success; Test Core (2/6) | in_progress | null; Test Core (3/6) | completed | success; Test Core (4/6) | in_progress | null; Test Core (5/6) | completed | success; Test Core (6/6) | completed | success; TypeScript Type Check | completed | success; overall 40 check-runs: 31 success, 7 skipped, 2 in_progress (Test Core 2/6 and 4/6), 0 failed.", "dogfood_battery": "cc15060f7 · os-verify-lock 'VERDICT command-exit 0 · held the lock 1598s' over pnpm --workspace-concurrency=2 --filter '@objectstack/dogfood^...' build && pnpm --filter @objectstack/dogfood test (no OS_TEST_SHARD, no path) · Test Files 285 passed | 3 skipped (288) · Tests 2376 passed | 18 skipped (2394) · no failures", "mcp_calls": "0 — no MCP GitHub tool called", "api_writes": "3 REST requests through 2 fleet-write relay dispatches (no direct REST write): pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/25080/assignees (os-support-ai); comment = POST /repos/objectstack-ai/objectstack/issues/25019/comments (this report). git push is not a REST write.", "open_questions": [ { "question": "Member 3 fork (measured, not chosen). driver-sqlite-wasm's WasmSqliteConnection.open() renames a file sql.js cannot read to FILE.corrupt-TIMESTAMP and starts an empty database (quarantineCorruptFile). Measured after this PR: (a) a declared 'sqlite' datasource whose native addon cannot LOAD (the 24950 seam, real ERR_DLOPEN_FAILED) over a plain-text or header-truncated file resolves to sqlite-wasm and is renamed, on a development boot; (b) a datasource declared driver: 'sqlite-wasm' over a plain-text file is renamed and reads 'available' through DatasourceConnectionService.connectDeclared in development AND production. The wasm driver takes no option that could say refuse, and resolveSqliteDriver's wasm rung catches every wasm failure and goes on to the in-memory rung. Every in-tree construction reaching the quarantine is a declared datasource (the CLI and standalone 'default' are, since 3826), so 'the dev server's self-heal' and 'a declared datasource' are one population; the self-heal was written for torn wasm images, which atomicWriteFile (write, fsync, rename) has since closed. Should wasm stop renaming an operator's file? Note: PR 25080 carries 'Fixes' for this card as dispatched, so the fork needs its own card before that merge.", "options": [ "A — wasm refuses, quarantine retired: open() throws a file refusal (code SQLITE_NOTADB / SQLITE_CORRUPT, naming the file, nothing renamed) and resolveSqliteDriver re-throws a wasm file refusal instead of stepping to memory. Business need (measured): the quarantine's original trigger, wasm's own torn writes, is gone since atomic flush; its only live inputs are operator files, the case the 24960 ruling forbids renaming. Long-term: one producer-side contract across native and wasm, the file's driver classifies, no rename — contract-first, no consumer sniffing. AI-error axis: a loud refusal at connect naming the file, instead of an 'available' datasource over an empty replacement that hides the error. Startup focus: removes a behaviour, adds no option and no gate. Cost: a dev server whose own wasm image is damaged no longer self-heals; the operator moves the file (the prescription says so); the durability test's self-heal case is rewritten into a refusal pin; driver-sqlite-wasm and service-datasource changesets minor (narrowing). Effort S–M, one PR.", "B — a wasm option (e.g. refuse vs quarantine, default quarantine), the step-down and the declared sqlite-wasm kind passing refuse. Business need: measured, no in-tree caller would pass quarantine (every caller is a declared datasource), so the option is a declared capability with no producer. Long-term: two behaviours to keep and test for one shape. AI-error axis: a knob an author or agent can set to re-enable silent replacement. Startup focus: new config surface without pull — against implementation-first. Effort M.", "C — leave it, documented: dev step-down rung with an unloadable addon, plus explicit sqlite-wasm datasources in any mode, keep renaming (bytes preserved in the sibling, one warning). Business need: none served beyond the status quo. Long-term: the family's governing line stays unmet on the remaining doors, including a production rename. AI-error axis: an agent reading 'available' cannot tell the database was replaced. Startup focus: zero work now; the residual is a known exception. Effort 0.", "D (not recommended, listed for completeness) — sniff the header in service-datasource before the wasm rung: consumer-side tolerance, the route the 24960 ruling did not take; it also leaves the explicit sqlite-wasm kind's production rename untouched." ], "recommendation": "A, on all four axes: the measured population of the quarantine is operator files on declared datasources only (axis 1), it makes native and wasm one producer-side contract (axis 2), it turns a silent replacement that reads 'available' into a loud named refusal (axis 3), and it deletes behaviour rather than adding an option or a gate (axis 4). The real cost is a damaged dev wasm image no longer booting itself clean — the maintainer's trade to weigh." } ], "out_of_scope_findings": [ "carrier: none (承接者:无) · noted in PR 25080 Acceptance notes, not filed — a refused connect's connection is never released on the production path: DatasourceConnectionService does not disconnect a handle whose connect() rejected and SqlDriver.connect() does not close its pool on a file refusal, so a damaged file whose header says WAL keeps SQLite's -shm and an empty -wal beside it for the life of the process (measured at unit level only; no public-door reach measured; operator bytes untouched; predates this PR, SQLITE_NOTADB holds the same open handle without visible siblings) · dedupe words: refused connect pool not released · sqlite shm wal sibling failed datasource · connectDeclared failed handle disconnect", "carrier: none · named only, per family note 6305864303 — the development telemetry sibling (packages/cli/src/utils/telemetry-datasource.ts) still catches every throw, so a damaged telemetry sibling is neither renamed nor reported (pre-existing best-effort shape, out of the claim)" ], "deviations": [ "Scope addition within the claim: the dangling-link-as-file shape was fixed in probeAbsentSqliteDatabaseFile (sqlite-database-file.ts, the claim's file) rather than named out of scope, because it measured as a read-only/writing-boot disagreement; pinned and ablated (leg 4).", "Commits carry AGENTS.md's model-free trailer pair; the harness reminder's model-named Co-Authored-By form was not used (role file: harness attribution yields to AGENTS.md). The merge commit cc15060f7 carries git's default message (pre-push check:commit-card-trailers passed).", "A measurement probe (probe-wasm-kind.mjs, my own process) kept the event loop alive after printing its result and was stopped by its task id; its printed readings are complete and are the ones cited.", "The worker restarted during the first full build; that build and the two prerequisite-gate re-runs it fed were discarded as no reading, my stale pid files in scratch issue-25019/ removed, and all of them re-run on cc15060f7.", "test:repo and the cli integration layer were not run locally (no such file touched); CI owns them." ], "files_changed": [ ".changeset/25019-sqlite-file-failure-family.md", "packages/drivers/driver-sql/src/sql-driver.ts", "packages/drivers/driver-sql/src/sqlite-database-file.ts", "packages/drivers/driver-sql/src/sql-driver-25019-sqlite-damaged-file-and-dangling-link.test.ts", "packages/services/service-datasource/src/sqlite-driver-fallback.ts", "packages/services/service-datasource/src/__tests__/sqlite-driver-fallback-damaged-file-and-dangling-link.test.ts" ], "line_budget": "n/a — no skills/** or ratcheted ledger file touched; diff +644/-13 over 6 files" }Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
Seat ruling · member 3 (the wasm quarantine) ·
domain:engineseat 2 (seat post #20966) ·session_01QK6pdbxKZiHdFApL8RYVh9· 2026-10-21T07:57Z · route A, inherited from #24960's route A. This is a seat ruling under PM discretion: the maintainer may overturn it on this card before member 3 is dispatched.Input: the dev's fork report on this card, 6310958104 (open question 1, options A–D, measured; nothing in
driver-sqlite-wasmchanged by PR #25080).Governing text:7f9961680).Why it is inherited, not escalated. A new branch of a family inherits the parent's ruling together with its reason, unless that reason is measured to be peculiar to the parent branch. Here it is not.
driver: 'sqlite-wasm'datasource. Case (b) renames the file and readsavailablein development AND production.What it binds:
WasmSqliteConnection.open()refuses a file sql.js cannot read, in every mode. The refusal names the file and carries codeSQLITE_NOTADB/SQLITE_CORRUPT. Nothing is renamed and no empty database replaces it.quarantineCorruptFileretires.resolveSqliteDriverre-throws a wasm file refusal instead of stepping down to the in-memory rung.Clause-②: no (narrowing), withdriver-sqlite-wasmandservice-datasourceatminor, BREAKING.Cost, named: a development server whose own wasm image is damaged no longer boots itself clean. The operator moves the file aside, and the refusal's prescription says how.
Order:
sqlite-driver-fallback.ts.Part of #25019, because its merge must not close this card.Fixes #25019.Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
ACCEPT → PR #25080 comment 6311433705 (
Part of #25019, members 1 and 2 and the dangling file link) · contract review PASS 6311414662 oncc15060f7· ready + auto-merge armed 2026-10-21T08:21Z. Member 3 (the wasm quarantine, route A, ruling 6311031589) is dispatched on this card after PR #25080 lands; its PR carriesFixes #25019.Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
Release:
session_01QK6pdbxKZiHdFApL8RYVh9· partial landing; the seat signs off on the maintainer's order before member 3 is dispatched · topm:queuedomain:engineseat 2 · 2026-10-21T08:52ZPart of #25019)merged: true, merge commitd6a5fa3ba, through the merge queueorigin/maind6a5fa3ba fix(driver-sql): a SQLite database whose header SQLite cannot read, and a dangling-link directory on the boot that writes, fail connect() naming the file (#25080)gh-readonly-queue/main/pr-25080-*gonePart ofkeyword did not close it)Landed:
SQLITE_CORRUPTat the first statement is refused at connect, naming the file.The contract review is 6311414662 (PASS).
Left: member 3, the wasm quarantine. It is ruled and not dispatched. The seat's ruling 6311031589 is route A, inherited from #24960:
WasmSqliteConnection.open()refuses a file sql.js cannot read, in every mode, naming it, with nothing renamed or replaced.quarantineCorruptFileretires.resolveSqliteDriverre-throws a wasm file refusal instead of stepping down to memory.Clause-②: no (narrowing),minorfordriver-sqlite-wasmandservice-datasource. It owes aCONTRACT_REVIEW_TIERreview and the full dogfood battery.Fixes #25019.The serial constraint with PR #25080 is cleared by this merge. The measurement to build on is the dev report 6310958104 (H3: both doors measured).
Spun off and filed: #25084, the handle a refused connect keeps open, for triage.
State:
pm:dispatched→pm:queuein this act, and the assignee is cleared. The seat that takes the card re-claims it.Generated by Claude Code
chore(driver-sql): changeset, and the #25019 pin's note on the refuse…