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
datasources: the draft probe POST /datasources/test creates the SQLite database file on disk although nothing is saved #27512
Filing gate: ① a product defect with a reproduction, found by an off-clause probe of QA run #27438 (wave 3 of the 18.3.0 sweep, anchor #27377). reach: measured at the public draft-probe door. A file appears on the server's disk.
Business reason: "Test connection" on a datasource draft is meant to be a read-only probe. Nothing is saved as a datasource, yet for a SQLite draft it creates the database file at the given path. An admin who mistypes a path while testing leaves stray database files on the server, wherever the server process can write.
Reader who acts: the triage seat, then the implementer for packages/services/service-datasource (the draft test route) and the SQLite driver connect path.
Dedupe (open AND closed): "datasources test unknown name returns 200 ok false instead of 404; datasource test draft creates sqlite file" returned 34 hits; none is this side effect. #25019 and #24950 (closed) are about SQLite connect failures being swallowed, not about a probe creating files.
POST /api/v1/datasources/test (the draft probe) creates the SQLite database file on disk even though nothing is saved.
Reproduction (subject c4c515a, scratch copy of the showcase, admin)
Pick a path that does not exist yet, such as RUN/dsfiles/probe.db.
POST /api/v1/datasources/test with a SQLite draft config naming that file → the probe answers.
No datasource row is persisted, but RUN/dsfiles/probe.db now exists on disk (4096 bytes).
Expected: a draft test leaves no trace. For SQLite, it should open the file read-only and must-exist (or in-memory for a non-existent path), and report that the file does not exist instead of creating it.
QA-source: #27438 · integration-system.datasource-admin-lifecycle · observed beside the clauses
Read fresh. The draft datasource probe POST /datasources/test creates the SQLite database file on disk although nothing is saved. A probe meant to be read-only leaves a stored side effect. Admin-only, and the same path is reachable by saving a datasource: p2.
The probe opens SQLite read-only and must-exist through the existing driver connect path, and reports a missing file. No persisted side effect.
Claim: PM loop round 1 · card thread
Session: session_01L6bhgUCizoYWQVJWjhdR6F (the seat); the card thread is session_01L6bhgTUuJysc6ThTQ8Xb1r
Account: os-sales
Branch: claude/project-thread-yhiysu (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: objectstack-issue-27512 in the card thread's own container
Domain: domain:server
Seat: domain:server#2
File surface: packages/services/service-datasource/src/datasource-admin-plugin.ts (probe), contracts/datasource-driver-factory.ts, default-datasource-driver-factory.ts, sqlite-driver-fallback.ts; possibly packages/drivers/driver-sql/src/sql-driver.ts (SqliteAbsentFileMode) (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: service-datasource probe (this lane) | the factory-wide sqliteAbsentFile 'empty-in-memory' option exists but answers ok on a missing file, so it does not cover this | admins drafting a datasource; reached today by the Setup draft probe
Thread-read: 6495171529
Premise: holds (read on main 2026-10-29T13:21Z: probe calls factory.create then driver.connect with no probe intent on ProbeInput or the factory)
Serial constraints cleared: none (no open PR touches service-datasource or the SQL-family drivers)
{
"issue": 27512,
"status": "done",
"branch": "claude/project-thread-yhiysu",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27603",
"session": "session_01L6bhgTUuJysc6ThTQ8Xb1r (card thread; seat session_01L6bhgUCizoYWQVJWjhdR6F)",
"premise_still_valid": true,
"summary": "The draft probe (POST /api/v1/datasources/test) now sets a new optional fileMustExist on DatasourceConnectionSpec, and createDefaultDatasourceDriverFactory().create() refuses a file-backed target whose file does not exist (sqlite/sqlite3, sqlite-wasm, turso/libsql file: url) before any driver is built, using driver-sql resolveSqliteAbsentFileTarget as the one write-free existence judgement; the refusal carries the OS stat error code ENOENT, its cause and the filename. The probe answers it on its existing verdict door, 200 with result.ok false and an error naming the file; neither the file nor its directory is created. Save, boot restore and hot pools are unchanged and still create the file. PM assumptions measured: all three SQL-family file drivers created the file and its missing directories on a probe; memory with file persistence creates nothing. code+status read as the probe verdict door (TestConnectionResult has no code field; adding one is a response-shape addition not made), the machine-readable ENOENT is pinned on the factory refusal. Read-only open not added (must-exist alone stops the creation; read-only would fail probes on legacy auto_vacuum NONE files, read from code).",
"tests": "New src/__tests__/draft-probe-creates-no-database-file.test.ts through the real door (HonoHttpServer + admin routes + plugin probe + default factory). Red on base 72b08eec: Tests 11 failed | 3 passed (14). Green on d9b68b90: Tests 14 passed (14). Package: pnpm --filter @objectstack/service-datasource test, Test Files 59 passed (59), Tests 998 passed (998); typecheck exit 0 (tsconfig includes src, tests included); lock VERDICT command-exit 0. Ablation via scripts/ablation-replace.mjs, source-resolved (relative imports, no build in path): (1) probe flag line deleted in datasource-admin-plugin.ts, anchor 1 to 0, blob fef3565b to 3023b836, Tests 10 failed | 4 passed, restored blob == HEAD fef3565b, git diff HEAD empty; (2) factory guard line deleted in default-datasource-driver-factory.ts on d9b68b90, blob 0122caf1 to 7b5f7834, Tests 11 failed | 3 passed, restored blob == HEAD 0122caf1, git diff HEAD empty.",
"gates": "Local derived set on d9b68b90: dispatch-gates --commands = 60 commands, each run with exit captured before any pipe, 60 x exit 0 (after a full pnpm turbo run build, 115/115 tasks, so check:dual-build-cjs-loads measured; teardown fixture 621a4876 fetched). --ran: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN. First run on bf1d2ab4 caught check:dispatcher-error-vocabulary exit 1 (literal ENOENT class field read as an unregistered code), fixed in d9b68b90 and green. pnpm lint (repo-wide) exit 0 on bf1d2ab4; eslint packages/services/service-datasource on d9b68b90 exit 0. check:driver-conformance before and after: 55 covered, 0 DEBT, 0 exempt. check:nul-bytes exit 0. merge-tree vs open PR 27574 (same package, no shared file): clean. PR check-runs: in_progress at report time, not waited on.",
"dogfood_battery": "n/a: no ! in the PR title and Clause-② no without a (narrowing) arm",
"mcp_calls": "4 reads, 0 writes: issue_read get, issue_read get_comments, search_pull_requests, pull_request_read get_files",
"api_writes": "2 via relays: fleet-write pr_create (POST /repos/objectstack-ai/objectstack/pulls, created 27603, draft, no assignees, no labels, body read back identical 8921 bytes) and this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/27512/comments). git push of claude/project-thread-yhiysu is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"none filed. Noted only (no measurement, so no class): the saved-datasource Test door POST /datasources/:name/test was not examined for file creation; carrier: none"
]
}
{
"issue": 27512,
"status": "done",
"branch": "claude/project-thread-yhiysu",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27603",
"session": "session_01L6bhgTUuJysc6ThTQ8Xb1r (card thread; seat session_01L6bhgUCizoYWQVJWjhdR6F)",
"premise_still_valid": true,
"summary": "Rework round on seat REWORK of d9b68b90 (fileMustExist on the exported DatasourceConnectionSpec widened the published face). New head d3b198ec: the missing-file judgement lives inside DatasourceAdminServicePlugin.probe, before the driver factory is asked for anything, in two module-private helpers (probedDatabaseFile, absentDatabaseFileRefusal) that read sqlite/sqlite3 and sqlite-wasm config.filename and a turso/libsql file: url, and judge it with driver-sql resolveSqliteAbsentFileTarget (write-free). A missing file answers 200 with result.ok false naming the file; an unopenable path answers with the SqliteDatabaseFileError text; nothing is created. contracts/, default-datasource-driver-factory.ts and index.ts are byte-identical to the merged main 1ed33609, so Clause-② no holds. Because the check is the probe s own, it holds for a host-registered factory too (pinned). Save, boot restore and hot pools unchanged. Changeset rewritten. The PR body is written once by rule (no PATCH): the full replacement body for the seat to write is in the project file issue-27512/pr-27603-body-d3b198ec.md; the live body still describes the first shape.",
"tests": "draft-probe-creates-no-database-file.test.ts now 15 cases: 10 door cases (5 driver ids x flat and nested missing path), host-factory spy never called, unopenable path refused with nothing written, 3 controls. Red before any fix on base 72b08eec: Tests 11 failed | 3 passed (14). Final d3b198ec: Tests 15 passed (15). Package: Test Files 59 passed (59), Tests 999 passed (999); typecheck exit 0; lock VERDICT command-exit 0. Ablation on d3b198ec via scripts/ablation-replace.mjs: probe guard line deleted, anchor 1 to 0, blob 9c6083e9 to abcba580, Tests 11 failed | 4 passed (15) (ten door cases plus the host-factory pin red; the unopenable case stays green because the real driver refuses that path at connect itself), restored blob == HEAD 9c6083e9, git diff HEAD empty. Source-resolved, no rebuild in the path.",
"gates": "d3b198ec: dispatch-gates --commands = 59 commands, 59 x exit 0, exits captured before any pipe (full build present, service-datasource rebuilt on this head). --ran: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN. eslint packages/services/service-datasource exit 0; repo-wide pnpm lint exit 0 on bf1d2ab4. check:driver-conformance before and after: 55 covered, 0 DEBT, 0 exempt. merge-tree vs open PR 27574: clean. PR check-runs on d3b198ec: not waited on.",
"dogfood_battery": "n/a: no ! in the PR title and Clause-② no without a (narrowing) arm",
"mcp_calls": "4 reads total across both rounds, 0 writes: issue_read get, issue_read get_comments, search_pull_requests, pull_request_read get_files",
"api_writes": "3 across both rounds via relays: pr_create 27603 (POST /repos/objectstack-ai/objectstack/pulls), os-dev-report 6499708750 and this report (POST /repos/objectstack-ai/objectstack/issues/27512/comments). git push not REST.",
"open_questions": [],
"out_of_scope_findings": [
"none filed. Noted only (no measurement, so no class): the saved-datasource Test door POST /datasources/:name/test was not examined for file creation; carrier: none"
]
}
Activity
objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 可对外的 API | integration-system.datasource-admin-lifecycle | P②
Triage: p2 ·
domain:server·area:api· 2026-10-29T11:15Z⛔ Not a claim.
bug,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
Claim: PM loop round 1 · card thread
Session:
session_01L6bhgUCizoYWQVJWjhdR6F(the seat); the card thread issession_01L6bhgTUuJysc6ThTQ8Xb1rAccount:
os-salesBranch:
claude/project-thread-yhiysu(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree:
objectstack-issue-27512in the card thread's own containerDomain:
domain:serverSeat:
domain:server#2File surface:
packages/services/service-datasource/src/datasource-admin-plugin.ts(probe),contracts/datasource-driver-factory.ts,default-datasource-driver-factory.ts,sqlite-driver-fallback.ts; possiblypackages/drivers/driver-sql/src/sql-driver.ts(SqliteAbsentFileMode) (stop on breach; explain in the report)Container & model:
M,mode:thread,model: default (dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
service-datasource probe (this lane) | the factory-wide sqliteAbsentFile 'empty-in-memory' option exists but answers ok on a missing file, so it does not cover this | admins drafting a datasource; reached today by the Setup draft probeThread-read: 6495171529
Premise: holds (read on main 2026-10-29T13:21Z:
probecallsfactory.createthendriver.connectwith no probe intent onProbeInputor the factory)Serial constraints cleared: none (no open PR touches
service-datasourceor the SQL-family drivers)objectstack-fleet commentedon Oct 29, 2026
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
os-dev-report
{ "issue": 27512, "status": "done", "branch": "claude/project-thread-yhiysu", "pr": "https://github.com/objectstack-ai/objectstack/pull/27603", "session": "session_01L6bhgTUuJysc6ThTQ8Xb1r (card thread; seat session_01L6bhgUCizoYWQVJWjhdR6F)", "premise_still_valid": true, "summary": "The draft probe (POST /api/v1/datasources/test) now sets a new optional fileMustExist on DatasourceConnectionSpec, and createDefaultDatasourceDriverFactory().create() refuses a file-backed target whose file does not exist (sqlite/sqlite3, sqlite-wasm, turso/libsql file: url) before any driver is built, using driver-sql resolveSqliteAbsentFileTarget as the one write-free existence judgement; the refusal carries the OS stat error code ENOENT, its cause and the filename. The probe answers it on its existing verdict door, 200 with result.ok false and an error naming the file; neither the file nor its directory is created. Save, boot restore and hot pools are unchanged and still create the file. PM assumptions measured: all three SQL-family file drivers created the file and its missing directories on a probe; memory with file persistence creates nothing. code+status read as the probe verdict door (TestConnectionResult has no code field; adding one is a response-shape addition not made), the machine-readable ENOENT is pinned on the factory refusal. Read-only open not added (must-exist alone stops the creation; read-only would fail probes on legacy auto_vacuum NONE files, read from code).", "tests": "New src/__tests__/draft-probe-creates-no-database-file.test.ts through the real door (HonoHttpServer + admin routes + plugin probe + default factory). Red on base 72b08eec: Tests 11 failed | 3 passed (14). Green on d9b68b90: Tests 14 passed (14). Package: pnpm --filter @objectstack/service-datasource test, Test Files 59 passed (59), Tests 998 passed (998); typecheck exit 0 (tsconfig includes src, tests included); lock VERDICT command-exit 0. Ablation via scripts/ablation-replace.mjs, source-resolved (relative imports, no build in path): (1) probe flag line deleted in datasource-admin-plugin.ts, anchor 1 to 0, blob fef3565b to 3023b836, Tests 10 failed | 4 passed, restored blob == HEAD fef3565b, git diff HEAD empty; (2) factory guard line deleted in default-datasource-driver-factory.ts on d9b68b90, blob 0122caf1 to 7b5f7834, Tests 11 failed | 3 passed, restored blob == HEAD 0122caf1, git diff HEAD empty.", "gates": "Local derived set on d9b68b90: dispatch-gates --commands = 60 commands, each run with exit captured before any pipe, 60 x exit 0 (after a full pnpm turbo run build, 115/115 tasks, so check:dual-build-cjs-loads measured; teardown fixture 621a4876 fetched). --ran: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN. First run on bf1d2ab4 caught check:dispatcher-error-vocabulary exit 1 (literal ENOENT class field read as an unregistered code), fixed in d9b68b90 and green. pnpm lint (repo-wide) exit 0 on bf1d2ab4; eslint packages/services/service-datasource on d9b68b90 exit 0. check:driver-conformance before and after: 55 covered, 0 DEBT, 0 exempt. check:nul-bytes exit 0. merge-tree vs open PR 27574 (same package, no shared file): clean. PR check-runs: in_progress at report time, not waited on.", "dogfood_battery": "n/a: no ! in the PR title and Clause-② no without a (narrowing) arm", "mcp_calls": "4 reads, 0 writes: issue_read get, issue_read get_comments, search_pull_requests, pull_request_read get_files", "api_writes": "2 via relays: fleet-write pr_create (POST /repos/objectstack-ai/objectstack/pulls, created 27603, draft, no assignees, no labels, body read back identical 8921 bytes) and this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/27512/comments). git push of claude/project-thread-yhiysu is not a REST write.", "open_questions": [], "out_of_scope_findings": [ "none filed. Noted only (no measurement, so no class): the saved-datasource Test door POST /datasources/:name/test was not examined for file creation; carrier: none" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
os-dev-report
{ "issue": 27512, "status": "done", "branch": "claude/project-thread-yhiysu", "pr": "https://github.com/objectstack-ai/objectstack/pull/27603", "session": "session_01L6bhgTUuJysc6ThTQ8Xb1r (card thread; seat session_01L6bhgUCizoYWQVJWjhdR6F)", "premise_still_valid": true, "summary": "Rework round on seat REWORK of d9b68b90 (fileMustExist on the exported DatasourceConnectionSpec widened the published face). New head d3b198ec: the missing-file judgement lives inside DatasourceAdminServicePlugin.probe, before the driver factory is asked for anything, in two module-private helpers (probedDatabaseFile, absentDatabaseFileRefusal) that read sqlite/sqlite3 and sqlite-wasm config.filename and a turso/libsql file: url, and judge it with driver-sql resolveSqliteAbsentFileTarget (write-free). A missing file answers 200 with result.ok false naming the file; an unopenable path answers with the SqliteDatabaseFileError text; nothing is created. contracts/, default-datasource-driver-factory.ts and index.ts are byte-identical to the merged main 1ed33609, so Clause-② no holds. Because the check is the probe s own, it holds for a host-registered factory too (pinned). Save, boot restore and hot pools unchanged. Changeset rewritten. The PR body is written once by rule (no PATCH): the full replacement body for the seat to write is in the project file issue-27512/pr-27603-body-d3b198ec.md; the live body still describes the first shape.", "tests": "draft-probe-creates-no-database-file.test.ts now 15 cases: 10 door cases (5 driver ids x flat and nested missing path), host-factory spy never called, unopenable path refused with nothing written, 3 controls. Red before any fix on base 72b08eec: Tests 11 failed | 3 passed (14). Final d3b198ec: Tests 15 passed (15). Package: Test Files 59 passed (59), Tests 999 passed (999); typecheck exit 0; lock VERDICT command-exit 0. Ablation on d3b198ec via scripts/ablation-replace.mjs: probe guard line deleted, anchor 1 to 0, blob 9c6083e9 to abcba580, Tests 11 failed | 4 passed (15) (ten door cases plus the host-factory pin red; the unopenable case stays green because the real driver refuses that path at connect itself), restored blob == HEAD 9c6083e9, git diff HEAD empty. Source-resolved, no rebuild in the path.", "gates": "d3b198ec: dispatch-gates --commands = 59 commands, 59 x exit 0, exits captured before any pipe (full build present, service-datasource rebuilt on this head). --ran: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN. eslint packages/services/service-datasource exit 0; repo-wide pnpm lint exit 0 on bf1d2ab4. check:driver-conformance before and after: 55 covered, 0 DEBT, 0 exempt. merge-tree vs open PR 27574: clean. PR check-runs on d3b198ec: not waited on.", "dogfood_battery": "n/a: no ! in the PR title and Clause-② no without a (narrowing) arm", "mcp_calls": "4 reads total across both rounds, 0 writes: issue_read get, issue_read get_comments, search_pull_requests, pull_request_read get_files", "api_writes": "3 across both rounds via relays: pr_create 27603 (POST /repos/objectstack-ai/objectstack/pulls), os-dev-report 6499708750 and this report (POST /repos/objectstack-ai/objectstack/issues/27512/comments). git push not REST.", "open_questions": [], "out_of_scope_findings": [ "none filed. Noted only (no measurement, so no class): the saved-datasource Test door POST /datasources/:name/test was not examined for file creation; carrier: none" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
ACCEPT → PR #27603 comment 6501148767 · head
d3b198ec· 2026-10-29T15:37Z · landing sent.