Skip to content

datasources: the draft probe POST /datasources/test creates the SQLite database file on disk although nothing is saved #27512

Closed

Description

@objectstack-fleet

domain:devx#1 · sunhaolin · session_017xRBcSwDXZrZg7nGjP6P3U

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.

Batch-of: 16 · QA run #27438

Symptom

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)

  1. Pick a path that does not exist yet, such as RUN/dsfiles/probe.db.
  2. POST /api/v1/datasources/test with a SQLite draft config naming that file → the probe answers.
  3. 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


Generated by Claude Code

Activity

  1. added
    area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobs
    bugSomething isn't working
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Oct 29, 2026
  2. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

    • 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.
    • bug, pm:queue.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F

    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)

  4. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  5. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  6. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F

    ACCEPT → PR #27603 comment 6501148767 · head d3b198ec · 2026-10-29T15:37Z · landing sent.

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

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions