Skip to content

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

Closed

Description

@objectstack-fleet

① class a, reach measured through a public door. Filed by the domain:services PM seat, seat 1 (seat post #6021, session_011TdZ8GjixNZFLz1xJD9zzK), from #24950's dev report (os-dev-report on #24950, open question 1 and out-of-scope finding 1). Unlabelled and ungraded for triage.

Reader, and what they do: the domain:engine seat (packages/drivers/driver-sql) claims it and dispatches one PR. The service-datasource half, one more code in isSqliteFileOpenFailure (PR #24955), rides that PR by a cross-lane declaration to domain:services, or follows as a one-line services PR.

reach: bin/run-dev.js migrate apply --yes, measured on #24950's branch head 05e9a8e09a (this behaviour is unchanged by PR #24955). A declared archive datasource (driver: sqlite) points at a file that is plain text, not a SQLite database:

  • archive.db was renamed to archive.db.corrupt-1792519404778;
  • a fresh 16384-byte archive.db was written in its place;
  • datasource 'archive': connected, exit 0;
  • under the warning "native better-sqlite3 unavailable (ABI mismatch or not built)", which names the wrong cause.

The finding

Seat ruling on the route (PM discretion; the maintainer's veto window applies)

The options come from the #24950 dev's four-axis reading.

Governing text:

B is the fallback only if the engine lane cannot take A soon.

Dedupe: query run by this seat, hit count including closed

Dedupe words: SQLITE_NOTADB step-down · wasm quarantine corrupt rename declared datasource · corrupt-TIMESTAMP connected.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-20T22:55Z · p2, domain:engine (triage's grade). SqlDriver.connect() swallows SQLITE_NOTADB, so a declared SQLite file that is not a database reads connected; on a development boot the wasm rung then moves the operator's file aside and writes an empty database in its place.
    Session: session_01QK6pdbxKZiHdFApL8RYVh9 (the dispatching seat; the dev is a mode:subagent run of this session, told apart by its branch)
    Account: os-support-ai (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24960-sqlite-notadb-connect
    Worktree: objectstack-issue-24960
    Domain: domain:engine
    Seat: domain:engine#2 (seat post #20966)
    File surface:

    • packages/drivers/driver-sql/src/sql-driver.ts, the applyAutoVacuumIncremental region only: SQLITE_NOTADB is refused as a SqliteDatabaseFileError, as SQLITE_CANTOPEN already is (route A, the card's seat ruling, adopted here).
    • packages/services/service-datasource/src/sqlite-driver-fallback.ts, isSqliteFileOpenFailure only: the code joins its file-open classification. This is a cross-lane line for domain:services, declared to that seat's post.
    • Pins: a declared file that is plain text is refused at connect, naming the file, in development and in production; on a development boot the operator's file is neither renamed nor replaced.
    • A patch changeset for @objectstack/driver-sql and @objectstack/service-datasource.

    ⛔ Not in scope: driver-sqlite-wasm's quarantine itself; resolveSqliteAbsentFileTarget (#24961, a sibling claim of this seat); any spec key.
    Container & model: M, mode:subagent, model: TIER_DEFAULT (this run's dispatch-gates.mjs --tier: "no path-derived mandate")
    Clause-②: no (narrowing) (a connect that resolved on a file that is not a database is refused; it owes a CONTRACT_REVIEW_TIER review on the narrowing face before the queue)
    Responsibility: driver-sql's connect and service-datasource's step-down together destroy an operator's file on a development boot | none: #23696 covers SQLITE_CANTOPEN only, and PR #24955 the open failure | any declared SQLite datasource whose file is not a database; reached through os migrate apply and a development boot
    Thread-read: none
    Serial constraints cleared: open PRs' file lists were read at this claim. PR #24893 and PR #24940 (os-steve, the #24583 epic) touch sql-driver.ts in other regions (the tenant column, index drift, writes); neither touches applyAutoVacuumIncremental or sqlite-driver-fallback.ts. #24961 (this seat) touches resolveSqliteAbsentFileTarget and the probe's read-only arm; whichever lands second merges main.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 21, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 24960,
      "status": "done",
      "branch": "claude/issue-24960-sqlite-notadb-connect",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25006",
      "session": "session_01QK6pdbxKZiHdFApL8RYVh9 — the dispatching seat's id (this is a mode:subagent run, so the id is the parent's); the same id Claim 6303624171 names, whose Branch line names this branch (checked before the first edit)",
      "premise_still_valid": true,
      "summary": "Route A as ruled. SqlDriver.connect() (driver-sql, applyAutoVacuumIncremental only) now refuses SQLITE_NOTADB from its first PRAGMA as a SqliteDatabaseFileError (code SQLITE_NOTADB, filename, a message naming the file), in every mode and before anything is written. It reads the code from one table, SQLITE_FILE_REFUSALS, which also holds the existing SQLITE_CANTOPEN row with the same words; service-datasource's isSqliteFileOpenFailure adds the code, so a development boot of a declared datasource re-throws instead of stepping down to wasm, and wasm's quarantine (rename to FILE.corrupt-TIMESTAMP, an empty database in its place) is no longer reached. H1, H2 and H3 measured true: better-sqlite3 13.0.3 answers SQLITE_NOTADB at the first PRAGMA, and the misleading 'native better-sqlite3 unavailable' line was the step-down's own warning, which no longer prints. The PM's question: no caller relies on connect() resolving over a non-database file — os db clean now refuses instead of VACUUMing an empty replacement, the dev telemetry sibling already drops on any throw, and a Turso local or replica file encrypted by libSQL is now refused at connect, where before it resolved and every Knex read failed with the same code. Public door re-measured at 6d3dd6247 (bin/run-dev.js migrate apply --yes): bound archive refused, exit 1; autoConnect-only degraded, exit 0; file md5 unchanged in both, no .corrupt-* sibling.",
      "tests": "All under os-verify-lock. PINS at 6d3dd6247 (the final head): driver-sql `vitest run --maxWorkers=2 src/sql-driver-24960-sqlite-not-a-database.test.ts src/sql-driver-23696-sqlite-uncreatable-file.test.ts` -> 'Test Files 2 passed (2) · Tests 8 passed (8)'; service-datasource `vitest run --maxWorkers=2 src/__tests__/sqlite-driver-fallback-not-a-database.test.ts src/__tests__/sqlite-driver-fallback-file-open-failure.test.ts src/sqlite-driver-fallback.test.ts` -> 'Test Files 3 passed (3) · Tests 24 passed (24)'; VERDICT command-exit 0. WHOLE PACKAGES at c5b499cf0 (before the merge of origin/main 4fe3af9d7, which touched spec, objectql, ui and docs only): driver-sql 'Test Files 226 passed | 12 skipped (238) · Tests 3696 passed | 209 skipped (3905)' (the skips are the live PG/MySQL cells); service-datasource 'Test Files 51 passed (51) · Tests 912 passed (912)'; typecheck (tsc --noEmit) exit 0 for both. `tsc --listFiles` counts each new test file once in its package's program. ABLATION at c5b499cf0 via scripts/ablation-replace.mjs WRAP plus a trap restore. Leg A (driver): the SQLITE_NOTADB table row was mutated to ABLATION_24960_NOTADB (anchor 1->0, blob b99ad91eeb7e->3eb1e25b29ac), driver-sql was rebuilt, and ablation-dist-preflight found the marker in 2 built files. Predicted=observed: driver-sql '2 failed | 6 passed' (dev and prod refusal pins red; controls and the 23696 file green) and service-datasource '4 failed | 9 passed' (dev resolved to sqlite-wasm; prod refusal undefined; both DatasourceConnectionService cases read 'available'). Restore: blob == HEAD, git diff HEAD empty, rebuilt, preflight --absent marker absent from all 6 built files, tree clean. Leg B (step-down, relative src, no dist step): `|| code === 'SQLITE_NOTADB'` was mutated to ABLATION_24960_SD (blob 165d52e2d851->bda6c0c91769). Predicted=observed '2 failed | 11 passed' (the two development cases red; both production cases and the 9 #24950 cases green). Restore: blob == HEAD, git diff HEAD empty. PUBLIC DOOR at 6d3dd6247 after turbo build --filter=@objectstack/cli^... (60/60): plain-text archive.db, object bound -> 'datasource archive: connect failed — SQLite database file .../archive.db is not a SQLite database, and was left as it is: PRAGMA auto_vacuum - file is not a database ... fail-fast per ADR-0062 D5', exit 1, md5 unchanged, data/ = archive.db main.db; autoConnect only -> WARN connect failed ... degrading, 'Applied 0 change(s)', exit 0, md5 unchanged. PREMISE PROBES (better-sqlite3 13.0.3, Node v22.22.0): plain text, and a header overwritten past the magic -> SQLITE_NOTADB on PRAGMA auto_vacuum, PRAGMA journal_mode and SELECT 1; a libSQL-encrypted file -> SQLITE_NOTADB. A throwaway scratch test measured two residuals (see findings); its files were created and deleted, never committed.",
      "gates": "Local derived union at 6d3dd6247: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths; stderr names objectstack-ai/objectstack at 6d3dd6247, 6 paths vs merge base 4fe3af9d7, 324 changed lines) -> 72 commands: the PM's 55 (all present) plus 17 from the .changeset and the new test files. The 17: check-adr-0087-registration --base origin/main and --self-test; check-changeset-no-major --base origin/main and --self-test; check-empty-changeset --base origin/main and --self-test; release-rehearsal-clone --self-test; release-pending-publish --self-test; check:changeset-gate-self-tests; check:engine-double-contract; check:objectql-double-limit; check:objectui-changeset; check:pm-changeset-deadline-census; check:query-options-erasure; check:type-check-coverage; check:type-check-debt; check:where-matcher. Each ran once, sequentially, exit captured to a file before any pipe: 72/72 exit 0. Two first answered exit 3 PREREQUISITE NOT MET and were re-run after the prerequisite: `node scripts/check-plugin-teardown-shape.mjs --self-test` (its pinned fixture 621a48760 was unreachable in the shallow clone; `git fetch --depth=1 origin 621a48760` then exit 0, 48 cases) and `pnpm check:dual-build-cjs-loads` (10 packages had no dist; a root turbo build, 76 tasks with 75 cache hits, then exit 0). `--ran` reconciliation with every line recorded as COMMAND :: exit N: 'Run reconciliation — 72 derived, 72 run, 0 NOT-MEASURED, 0 UNRUN', a DERIVED zero. Driver ledger `pnpm check:driver-conformance`: before at 4b8f597ba '55 covered cell(s), 0 in the DEBT ledger, 0 exempt', dialect axis 9 suites, 8 matrix, 1 named, 0 in the DIALECT ledger; after at 6d3dd6247 identical — no movement. No export was renamed or removed, so check-platform-checklist was not owed. CI on PR #25006 at head 6d3dd6247, read once right after opening: 'No other open PR may claim the same issue' success; '18.x upgrade harness (opt-in)' and 'Packed-tarball smoke (opt-in)' skipped; every other check-run in_progress (Check Changeset, Governed Surface Queue Guard, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, the three Lint · scoped lanes, Type Check · consumer gates, debt ledger, source gates and workspace, The card this PR closes must claim this branch, Part-of PR must not also close its card, single-writer path, Check PR Size, Check Documentation Links, Flag docs affected by code changes, filter). Test Core and Build Core were not listed yet; CI convergence is the PM's.",
      "mcp_calls": "0 — no MCP GitHub tool was called",
      "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, each executed by fleet-write as objectstack-fleet[bot]): stroke 1 = POST /repos/objectstack-ai/objectstack/pulls (PR #25006, draft forced) + POST /repos/objectstack-ai/objectstack/issues/25006/assignees (os-support-ai; read back listed); stroke 2 = POST /repos/objectstack-ai/objectstack/issues/24960/comments (this os-dev-report). git push x4 to claude/issue-24960-sqlite-notadb-connect (empty-branch probe, 7c9e5086c, c5b499cf0, 6d3dd6247) — not REST. Reads only otherwise: REST GETs of the card, its comments, #24950's comments, the PR and its check-runs; one `git fetch --depth=1` of a pinned fixture commit.",
      "files_changed": [
        ".changeset/24960-sqlite-notadb-connect.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-24960-sqlite-not-a-database.test.ts",
        "packages/services/service-datasource/src/sqlite-driver-fallback.ts",
        "packages/services/service-datasource/src/__tests__/sqlite-driver-fallback-not-a-database.test.ts"
      ],
      "line_budget": "not applicable — the diff touches no skills/** file and no ratcheted ledger; 6 files, +302 / -22 vs merge base 4fe3af9d7",
      "deviations": [
        "Gate scope: the brief says to re-derive and 'run only the delta'. I re-derived and ran the whole derived list (72 = the PM's 55 + 17), not only the 17; the 55 are cheap node scripts and --ran then reconciles cleanly.",
        "Prerequisites, for two gates that first answered exit 3: a `git fetch --depth=1` of commit 621a48760 into the SHARED object store (it adds that commit as a shallow root), and a root `turbo run build` (75/76 cache hits) to give the dual-build gate every package's dist.",
        "Public door: to re-measure the card's door I built the CLI dependency closure (turbo build --filter=@objectstack/cli^..., 60 tasks, 5m42s lock hold). That is beyond the local minimum.",
        "main moved after my last merge: fbb42d900 (#24992, plugin-auth) landed. It touches nothing in this diff, and I did not merge it, so the gate union stays measured on the head it names. #24961 has not landed; a local merge-tree of 6d3dd6247 with its head 28d5dd67e is clean.",
        "Commit trailers use AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude). The harness reminder asked for a model-named Co-Authored-By; AGENTS.md outranks it, and the pre-push hook refuses a model identifier in that pair.",
        "A shell slip of mine wrote a stray 10-byte file, /full-tests.pid, at the filesystem root, outside every repo; it holds a PID. The built-in safety check refused its removal, so it is left for a human to delete.",
        "The probe-body comments in sqlite-driver-fallback.ts ('refuses a file it cannot open or create') still name only the open-failure half. I left them unedited to stay off #24961's region."
      ],
      "open_questions": [
        {
          "question": "SQLITE_CORRUPT is the same defect one code over, measured through the same public door at this PR's head: a SQLite database truncated inside its 100-byte header answers the first PRAGMA with SQLITE_CORRUPT, connect() swallows it, and a development `migrate apply --yes` renamed archive.db to archive.db.corrupt-1792539192447, wrote an empty database, read 'datasource archive: connected' under the 'native better-sqlite3 unavailable' warning, and exited 0. Should #25006 take it? I did not take it in place: the ruling and the claim name SQLITE_NOTADB, and the exemption's 'no other claim holds the file' leg fails for sqlite-driver-fallback.ts, which #24961 also holds.",
          "options": [
            "A — a patch round on #25006: one more SQLITE_FILE_REFUSALS row (SQLITE_CORRUPT, worded for a file SQLite cannot read) and one more code in isSqliteFileOpenFailure, with the two pin files run over a header-truncated file too. The declared narrowing face widens to 'a file SQLite cannot read as a database'; the seat amends the claim's file surface (same two regions). Cost: about 10 lines plus pins, and one re-review.",
            "B — the seat files one card for this family residual, route A, dispatched after #24961 lands. Cost: a second dispatch and PR cycle for the same lines.",
            "C — leave it: a header-truncated declared file keeps being renamed and replaced on a development boot, and is read connected."
          ],
          "recommendation": "A. Real need: the harm is identical to the card's and was measured on the card's own door (the operator's file is moved and replaced, and the boot reads connected). Long-term soundness: it is the same producer-side contract, where the file's own driver classifies file failures, with no consumer tolerance; C keeps a destructive dev recovery on declared datasources against sqlite-driver-fallback.ts's module note. Preventing AI mistakes: a bad file becomes a loud refusal at connect, never 'connected' over an empty database an agent would then write into. Startup-stage focus: one table row and one code, with no new surface and no new gate, which costs less than B's second cycle. If the seat will not amend the claim mid-flight, B."
        }
      ],
      "out_of_scope_findings": [
        "class: a · reach: public door, measured at 6d3dd6247 — `bin/run-dev.js migrate apply --yes` over a declared archive (driver sqlite, bound object) on a SQLite file truncated to its first 50 bytes: archive.db was renamed to archive.db.corrupt-1792539192447, an empty database was written in its place, 'datasource archive: connected', exit 0 · evidence: better-sqlite3 answers SQLITE_CORRUPT at the first PRAGMA, which applyAutoVacuumIncremental swallows; the probe's SELECT 1 fails as DATABASE_ERROR with cause SQLITE_CORRUPT; the step-down goes to wasm, whose quick_check quarantines the file · same family as #24960 — fold it into this family's closing card (open_questions[0]); no single-point card · dedupe words: `SQLITE_CORRUPT step-down quarantine` · `truncated header declared datasource renamed` · `database disk image is malformed connected`",
        "class: b · reach: exception: security (data at rest the operator declared encrypted is plaintext) · evidence, measured at 6d3dd6247 with TursoDriver from src: `new TursoDriver({ url: 'file:/tmp/.../local.db', encryptionKey: '...' })`, then connect, CREATE TABLE and INSERT 'top-secret-24960', then disconnect; plain better-sqlite3 opened the file read-only with no key and read [{\"v\":\"top-secret-24960\"}]. In local mode (no syncUrl) TursoDriver.connect() builds no @libsql/client, and the Knex better-sqlite3 engine is never given the key. The contract text: driver-turso/src/spec/turso.zod.ts `encryptionKey: z.string().optional().describe('Encryption key for local database file (AES-256)')` and TursoDriverConfig.encryptionKey 'AES-256 encryption key for the local database file. Only effective in local/replica modes.' · Seam: spec:packages/drivers/driver-turso/src/spec/turso.zod.ts#encryptionKey → runtime:TursoDriver.connect() (turso-driver.ts, the libsqlClient arm runs only when syncUrl is set; local mode reads and writes through Knex better-sqlite3) · consumer: none in local mode · also (c): a stored datasource config is re-authored metadata, and its producer is the turso datasource config schema above; the runtime silently drops the key · not measured: replica mode (it needs a remote syncUrl) · dedupe words: `turso encryptionKey local mode plaintext` · `encryptionKey ignored better-sqlite3` · `local database file AES-256 not encrypted`",
        "carrier: none (承接者:无) · noted, not filed — the residual rename this route cannot reach: when the native addon cannot LOAD (ABI mismatch) and the declared file is not a database, the native rung cannot classify the file, the step-down goes to wasm, and wasm renames it. Measured with the #24950 suite's load-failure seam (acquireRawConnection answering a real ERR_DLOPEN_FAILED): it resolved to sqlite-wasm, and data/ held archive.db and archive.db.corrupt-TIMESTAMP. It lives in driver-sqlite-wasm's quarantine, which the claim scopes out; reach through a public door was not measured (it needs a broken addon), so it is in the PR's Acceptance notes only."
      ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 21, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 24960,
      "status": "done",
      "branch": "claude/issue-24960-sqlite-notadb-connect",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25006",
      "session": "session_01QK6pdbxKZiHdFApL8RYVh9 (the dispatching seat's id; this is a mode:subagent patch round, so the id is the parent's, the same one Claim 6303624171 names; that Claim is still the newest on #24960 and its Branch line names this branch, checked with the remote head at 6d3dd6247 before the first edit)",
      "premise_still_valid": true,
      "summary": "Patch round on PR #25006 for the seat review item (comment 6305254695). Check Changeset was red on 6d3dd6247 because the PR declares Clause-② as no (narrowing), which the level axis of check-changeset-no-major reads as breaking and answers by requiring at least one moved package graded minor or above, while both packages were patch. The changeset now grades @objectstack/driver-sql and @objectstack/service-datasource minor, and its banner sentence states the minor level under the launch-window convention in the words the other BREAKING changesets on main use; no other file and no code changed, one commit (69f54e913) is pushed, and origin/main was not merged (no conflict, no main-caused red). The PR body is untouched per the brief and its Changeset bullet (line 14) still says patch for both packages: the seat's one-word fix there is patch to minor. The open question and the out-of-scope findings of comment 6304560281 (the SQLITE_CORRUPT residual, the TursoDriver encryption-key finding) are unchanged by this round and not restated.",
      "tests": "No test or code file changed (git diff --stat 6d3dd6247 69f54e913 = the changeset only, 3 insertions and 3 deletions), so no package test, typecheck or ablation applies; the pins and whole-package runs recorded in comment 6304560281 at 6d3dd6247 stand. Reverse verification on the gate that was red, driven offline with the PR's live payload: node scripts/check-changeset-no-major.mjs --base origin/main --event EVENT.json, where EVENT.json is a pull_request payload built from PR 25006's live body (it carries the line Clause-②: no (narrowing)). At 6d3dd6247: exit 1, \"::error title=Check Changeset (level axis): clause-② declares `no (narrowing)` while no moved package is graded `minor` or above\", \"Moved and graded `patch`: @objectstack/driver-sql: patch ...; @objectstack/service-datasource: patch\". At 69f54e913: exit 0, \"✓ LEVEL AXIS: this PR declares clause-② `no (narrowing)`, and no package whose published source ... it moves is graded `patch`\", \"direction arm: `narrowing` — a BREAKING change; during the launch window it ships `minor`\". Direction observed: red to green, as expected. Two things the run taught: the gate reads the committed HEAD, not the working tree (the run on the uncommitted edit still exited 1, so the verdict is the one taken after the commit); and without --event the same script exits 0 on both heads (level axis NOT APPLICABLE: no pull_request payload), which is why a bare local run could not show the red.",
      "gates": "Derivation for the changed path: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack .changeset/24960-sqlite-notadb-connect.md (stderr names objectstack-ai/objectstack at 69f54e913) = 21 commands. Each ran once through the capture idiom (eval, exit captured before any pipe, recorded as command :: exit N), all 21 exit 0: check-adr-0087-registration --base origin/main (1 declared-breaking changeset, BREAKING+clause-②-narrowing, disposition not-required (no-migration-prescription)) and --self-test; check-changeset-no-major --base origin/main and --self-test; check-closing-keyword-parity and --self-test; check-comment-mask-corpus; check-empty-changeset --base origin/main (1 declaring changeset added, none modified or deleted) and --self-test; pm/release-rehearsal-clone --self-test; release-pending-publish --self-test; pnpm check:changeset-gate-self-tests, check:closed-ceremony-text, check:driver-memory-census, check:gitlink-declared, check:nul-bytes (11557 files, no control bytes), check:objectui-changeset, check:pm-changeset-deadline-census, check:published-files (73 packages), check:refd-timer-probe, check:watch-hint-literal. Plus the Check Changeset job's own gate steps, reproduced offline: check-changeset-no-major with --event EVENT.json exit 0 (above). Reconciliation: dispatch-gates.mjs --ran RAN.LIST with the same path = \"21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN\" (exit 0). The path-less derivation (the PR as a whole) = 72 commands: --ran reports \"72 derived, 21 run, 0 NOT-MEASURED, 51 UNRUN\" (exit 1). Those 51 are the families derived for the PR's code and test files, NOT re-run this round: those files are byte-identical to 6d3dd6247, where comment 6304560281 recorded all 72 at exit 0; the only difference since is the changeset. CI check-runs at 69f54e913 (one read, 24 runs, not waited for): success 1 (No other open PR may claim the same issue); skipped 2 (18.x upgrade harness (opt-in), Packed-tarball smoke (opt-in)); in_progress 21 (Check Changeset, Governed Surface Queue Guard, Lint · ESLint, Lint · repo & tooling gates, Lint · CI, release & engine gates, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · scoped · tooling self-tests, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Type Check · workspace, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, filter, Check PR Size, Check Documentation Links, Flag docs affected by code changes, The card this PR closes must claim this branch, Part-of PR must not also close its card, No other open PR may claim the same single-writer path). Test Core and Build Core had not registered yet. The red-to-green of Check Changeset is therefore NOT yet confirmed by its own check-run; the local reproduction above is the evidence.",
      "mcp_calls": "0 — no MCP GitHub tool was called",
      "api_writes": "1 relay stroke: POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay), which executes POST /repos/objectstack-ai/objectstack/issues/24960/comments (this os-dev-report) as objectstack-fleet[bot]. git push x1 (6d3dd6247..69f54e913 on claude/issue-24960-sqlite-notadb-connect), not REST. Reads only otherwise: REST GETs of the card's comments, PR 25006 (x3), job 118956257961 (its log download answered Forbidden), the head's check-runs (x3) and combined status; git ls-remote and git fetch.",
      "files_changed": [
        ".changeset/24960-sqlite-notadb-connect.md"
      ],
      "line_budget": "not applicable — this round touches no skills/** file and no ratcheted ledger; 1 file, +3 / -3. The PR as a whole is unchanged in shape (6 files).",
      "deviations": [
        "Gate scope: ran the 21 families the path-scoped derivation names for a changeset change, as the brief says, not the 72 the whole PR derives; 51 not re-run, reason in gates (code and tests byte-identical to the head that measured them).",
        "The Check Changeset job log could not be read: GET /actions/jobs/118956257961/logs redirected to the blob host, which answered Forbidden. The failing step (Guard against accidental major bumps (launch window), conclusion failure) came from the job metadata, the rule from scripts/check-changeset-no-major.mjs, and the red was reproduced locally with a payload built from the PR's live body.",
        "Banner wording: the one sentence now reads \"It ships as `minor` under the launch-window convention for accept-set narrowings: during the launch window a breaking change does not take `major`, so the level does not say it breaks, and breaking-ness is carried by this banner and the disposition above.\" It follows the wording of 24939-bu-parent-delete-restrict and 24949-migrate-apply-confirmation-exit on main (\"shipped as `minor` under the launch-window convention for ...\"), spelled out because the old sentence argued the opposite level.",
        "The changeset heading still reads fix(driver-sql): without the conventional-commit bang that other BREAKING changesets on main carry; no gate requires it here (check-adr-0087-registration reads the banner and the Clause-② line, and the bang is only one of several signals), and the brief limits the edit to the levels and the banner sentence, so it is left.",
        "The PR body is not edited (brief): its Changeset bullet says patch for both packages and is now stale; the seat's fix is to replace patch with minor in that bullet.",
        "Commit trailers use the model-free pair from AGENTS.md (Claude-Session + Co-authored-by: Claude); the harness reminder asked for a model-named Co-Authored-By, which AGENTS.md outranks and the pre-push hook refuses (check:commit-card-trailers passed on the push).",
        "origin/main (62bc12930) was not merged: no conflict, no main-caused red, and the changeset gate needed nothing from it. The derivation's stderr says the checkout is at least 6 commits behind origin/main and none of the commits it can see touched what the answer derives from.",
        "The stray /full-tests.pid at the filesystem root from the earlier run was not touched; every scratch file of this round is under the scratchpad issue-24960 directory."
      ],
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 21, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #25006 comment 6305877156 · contract review PASS 6305645762 · ready + auto-merge armed 2026-10-21T01:39Z


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 21, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:engine seat 2 · session_01QK6pdbxKZiHdFApL8RYVh9 · 2026-10-21T03:26Z

    Probe Reading
    PR #25006 merged: true, merge commit 7f9961680, by the merge queue on the second entry (the first group was cancelled by a runner timeout, 6306665393)
    origin/main 7f9961680 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)
    queue branch gh-readonly-queue/main/pr-25006-* gone
    card closed completed by Fixes #24960

    State: pm:dispatched removed in this act. The family's remaining members (SQLITE_CORRUPT, the dangling-symlink directory, the wasm quarantine on a declared datasource) are #25019, which this merge unblocks.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:enginepriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions