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
New datasource: the file path field holds a real :memory: value, and Test connection passes on the broken path it produces #30331
Filing gate: ③ the maintainer's direct order, verbatim: 「你发现的问题都立卡,安全问题总专用的安全密卡通道,需要进一步分析的进一步测试,还是没有把握的用决策卡。」 (2026-11-05). Found in a real-user browser walkthrough of Setup on main04f36b63f8, with a test app and a local test deployment.
Business reason. An administrator connecting a company database relies on Test connection. A pass here means the connection is right, so a false pass sends them on to a connection with none of their data.
Reader. The UI lane dev for ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx, and the server lane for the test in packages/services/service-datasource.
Duplicates. Searched datasource filename memory prefilled (2 hits) and datasource test connection memory false (134 hits). They are QA run anchors and seat cards; none has this subject.
Measured
Open 新建数据源 and leave the SQLite driver selected. The Filename box looks like a hint, and it already holds :memory: as its value.
Click in and type a path. The box then reads :memory:/private/tmp/…/parts.db.
POST /api/v1/datasources/test with that value answers ok: true.
A correct path that does not exist is refused properly, so the check works in that case.
I did not save a datasource with the broken value, so what it would then read is not measured.
Expected
The default is a placeholder, not a value, so typing replaces nothing by accident.
A filename that is neither exactly :memory: nor a usable path is refused by the test and by save, with a message that says why.
Read fresh. The new-datasource file path field holds a literal :memory: value, and Test connection passes on the broken path it produces. A false success, so p2. Platform first: service-datasource's test-connection must check the real target. The dialog default is the domain:ui half.
Claim: PM loop round 1
Session: session_01Utp6CZMkHvuDeVYgTD73qF (seat) · dev card thread session_01Utp6Cb83ajcseWprEF9C9g
Account: os-bill
Branch: claude/project-thread-541rod (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-30331
Domain: domain:server
Seat: domain:server#4
File surface: packages/services/service-datasource/** (the test-connection door and the datasource save, at the one place both pass through), their tests, one changeset. ⛔ packages/spec/**, docs/adr/**, .claude/**, repo-root AGENTS.md, ui/** (the dialog's :memory: default is the ui residue, recorded at landing), skills/** (stop on breach; explain in the report)
Container & model: S, mode:thread, model: default judgment tier (opus) — dispatch-gates --tier: no path-derived mandate, effort: default
Clause-②: yes (narrowing) — a SQLite filename that is neither exactly :memory: nor a usable path, accepted today by the test and save doors, is refused (the dev confirms the arm)
Metadata-protocol: none
Responsibility: the datasource test door answers ok: true for a SQLite filename such as ':memory:/private/tmp/…/parts.db' | none: the administrator is told the connection works (card, measured on main 04f36b63f8) | any administrator connecting a file database through Setup, whose field is prefilled with ':memory:'
Thread-read: 6652062778
Premise: holds
Serial constraints cleared: no card in flight touches service-datasource (seats 3 and 5 confirmed).
Dispatch order: /mnt/project-files/server-seat4/dispatch-30331.md (project shared folder). Ruling section: the card's Expected ("refused by the test and by save, with a message that says why") and triage audit 6652062778 ("Platform first"). PR Refs #30331 (server half), no closing keyword. A contract review at CONTRACT_REVIEW_TIER is owed before queue (narrowing).
Status: done (server half). Draft PR #30395 carries Refs #30331 (server half), head cca010a64. The card stays open for the ui half.
Why :memory:/… passed. Every layer reads a name that starts with : as fileless (driver-sql resolveSqliteAbsentFileTarget / sqliteFilename, the wasm connection's isEphemeral), so the probe's missing-file refusal skipped it. better-sqlite3 then opens it as a relative path whose directory does not exist: connect() only warns and checkHealth() answers false, which the probe does not read as a failure. sqlite-wasm opens an ephemeral in-memory database.
What a saved one reads (measured).sqlite: every statement fails "Cannot open database because the directory does not exist". sqlite-wasm: writes succeed and are gone at the next connect or restart, with no error.
Fix.DatasourceAdminService.assertValidConfig, the one judgement the test, create and update doors share, also refuses a sqlite / sqlite-wasm filename that is empty, :-prefixed but not exactly :memory:, or a path that can be neither opened nor created (driver-sql's write-free judgement). Same envelope and code as every invalid config (400 DATASOURCE_ADMIN_ERROR; result.ok: false from the test). No new error code.
Follow-up owed (seat files): the spec SqliteConfigSchema.filename refinement, so the build door and PUT /api/v1/meta/datasource/:name judge the same; ui residue: the dialog's :memory: value instead of a placeholder (DatasourceResourcePage.tsx).
{
"issue": 30331,
"status": "done",
"branch": "claude/project-thread-541rod",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30395",
"session": "session_01Utp6Cb83ajcseWprEF9C9g",
"premise_still_valid": true,
"summary": "Server half only. Reproduced on main 8589756a through the real POST /api/v1/datasources/test: ':memory:/tmp/x30331/parts.db' answered ok:true for sqlite and sqlite-wasm. Cause: ':'-prefixed names are fileless to every layer, so the probe's absent-file refusal skipped it; native connect only warns and checkHealth false is read as ok; wasm opens an ephemeral database. A saved one fails every native statement, and on wasm loses every write at reconnect. The shared config gate (assertValidConfig, used by test, create and update) now refuses an empty, ':'-prefixed-but-not-':memory:', or unopenable/uncreatable filename with the value and reason, in the existing envelope.",
"tests": "New src/__tests__/sqlite-filename-neither-memory-nor-path.test.ts, 14 passed (7 per driver) through the real HonoHttpServer, admin routes, DatasourceAdminServicePlugin and default factory. Ablation (sqliteDatabaseFilenameIssue short-circuited, src imported by relative path, no dist leg): 8 failed / 6 passed, the 8 refusals red and the 6 controls green; restored, 14/14. Full @objectstack/service-datasource: 72 files, 1183 passed. Typecheck exit 0.",
"gates": "dispatch-gates --commands derived 61 families; each run at head cca010a64 with exit recorded before any pipe: 61/61 exit 0 (check-plugin-teardown-shape --self-test after fetching 621a4876; check:dual-build-cjs-loads after the full build). --ran: 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. pnpm lint exit 0. CI check-runs on #30395: not yet reported.",
"dogfood_battery": "cca010a64 · os-verify-lock: VERDICT command-exit 0 · Test Files 419 passed / 3 skipped (422) · Tests 3492 passed / 36 skipped (3528) · no failures",
"line_budget": "source +78 -9 (2 files), tests +222 (1 file), changeset +20 (1 file); 4 files, +320 -9",
"deviations": "none against the dispatch. Save now also judges an unusable path (the dispatch's pin list asks for it); the empty filename is refused too, as the card's 'neither :memory: nor a usable path' covers it. The harness's model-named commit trailer was not used (repo hook); trailers are model-free.",
"files_changed": [
".changeset/30331-sqlite-filename-neither-memory-nor-path.md",
"packages/services/service-datasource/src/__tests__/sqlite-filename-neither-memory-nor-path.test.ts",
"packages/services/service-datasource/src/datasource-admin-service.ts",
"packages/services/service-datasource/src/sqlite-database-filename.ts"
],
"mcp_calls": "2: mcp__github__issue_read x2 (get, get_comments); no GitHub write tool. Besides GitHub MCP: one subscribe_pr_activity on #30395 (session event subscription, writes nothing to GitHub)",
"api_writes": "2 through the relay: pr_create #30395 (draft, no assignee, no labels, read-back identical) and this comment. Plus 1 git push to claude/project-thread-541rod (not REST)",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"class: b · Seam: spec:SqliteConfigSchema.filename ('Database file path, or :memory:') → runtime: build door and PUT /api/v1/meta/datasource/:name · reach: not measured at those doors (the admin doors are fixed here) · evidence: sqlite.zod.ts types filename as placeholderFree(z.string()) · dedupe words: sqlite filename refinement, :memory: prefix, meta datasource filename",
"carrier: ui lane (#30331 stays open) · the New datasource dialog holds ':memory:' as a value instead of a placeholder (ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx)",
"noted, not filed (no public input measured after this fix): DatasourceAdminServicePlugin.probe reports ok:true when the handle's ping (checkHealth) answers false — recorded in the PR's Acceptance notes"
]
}
MERGED 2026-11-05T15:17Z, merge commit 22f0d656a; Refs #30331, so this card stays open. Seat record on head cca010a6 (BREAKING, not governed, ≤ 3000 lines; landed per pm-dispatch on the maintainer's 13:47Z word).
A SQLite datasource whose filename the server cannot use (such as :memory:/…) is refused at create and at a config-touching edit, with a message naming the field.
Remaining (ui)
The New datasource dialog still holds :memory: as the Filename field's value instead of a placeholder (ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx). With this PR on main the mistake it invites is refused with a message instead of passing.
Related
The probe ignoring a false health check is #30407 (seat 3).
Re-routed: domain:server → domain:ui, pm:dispatched → pm:queue, the os-bill assignee comes off with this comment.
Claim: PM loop round 9 · 2026-11-05T15:24Z
Session: session_01L6bhgVwQZbHRRM9CaXeKif
Account: os-sales
Branch: claude/project-thread-5qt4jg (card thread of this project; a thread can push only its designated branch — measured platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-30327
Domain: domain:ui
Seat: domain:ui#5
File surface: ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx (the New datasource dialog: schema-mode default and wording, the managed datasource's no-sync note, the SQLite Filename placeholder) + new studio namespace keys (en/zh) + their tests + one root .changeset/. ⛔ packages/**: if the driver form labels (Filename, Auto-migrate schema) come from the server's driver schema, the dev reports it and the seat files a domain:server card.
Container & model: M, mode:thread, model: default, effort: high
Clause-②: yes (expected: new studio keys; the dev declares the final arm)
Metadata-protocol: none
Responsibility: the New datasource dialog | the SQLite Filename box holds :memory: as a value, so typing a path appends to it | every administrator connecting a SQLite file
Thread-read: 6652062778
Premise: holds (on origin/main8e5fabe5 the dialog still defaults to managed and holds :memory: as a value)
Serial constraints cleared: PR #30493 (this seat, the same file) merged 2026-11-05T15:17Z; the branch starts from it. The server half landed in PR #30395 (merged). One PR carries this card's ui half and #30327, because both change the same dialog.
Dispatch order lives in the card thread's opening message.
Landed at 2026-11-05T16:43Z: PR #30561 merged as 0d54279e73 (seat ACCEPT 6663075162 on head fd64ec80, TIER_DEFAULT contract review PASS 6663047260), Fixes #30327 and Fixes #30331. The merge read 2026-11-05T16:41Z on the PR.
6 (a new datasource starts on External; a driver box's default is a placeholder, sent when left empty)
card state
closed (completed) by the merge
State change: pm:dispatched removed. Server follow-ups from the card thread: #30562 (a managed SQL datasource drops and recreates an existing _id-without-id table, rows lost) and #30563 (driver form labels are English in every console language).
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:server·pm:queue· 2026-11-05T07:11Z⛔ Not a claim.
:memory:value, and Test connection passes on the broken path it produces. A false success, so p2. Platform first:service-datasource's test-connection must check the real target. The dialog default is thedomain:uihalf.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
Claim: PM loop round 1
Session:
session_01Utp6CZMkHvuDeVYgTD73qF(seat) · dev card threadsession_01Utp6Cb83ajcseWprEF9C9gAccount:
os-billBranch:
claude/project-thread-541rod(the card thread's designated push branch, the recorded platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-30331Domain:
domain:serverSeat:
domain:server#4File surface:
packages/services/service-datasource/**(the test-connection door and the datasource save, at the one place both pass through), their tests, one changeset. ⛔packages/spec/**,docs/adr/**,.claude/**, repo-rootAGENTS.md,ui/**(the dialog's:memory:default is the ui residue, recorded at landing),skills/**(stop on breach; explain in the report)Container & model:
S,mode:thread,model: default judgment tier (opus) — dispatch-gates --tier: no path-derived mandate,effort: defaultClause-②: yes (narrowing) — a SQLite filename that is neither exactly
:memory:nor a usable path, accepted today by the test and save doors, is refused (the dev confirms the arm)Metadata-protocol: none
Responsibility:
the datasource test door answers ok: true for a SQLite filename such as ':memory:/private/tmp/…/parts.db' | none: the administrator is told the connection works (card, measured on main 04f36b63f8) | any administrator connecting a file database through Setup, whose field is prefilled with ':memory:'Thread-read: 6652062778
Premise: holds
Serial constraints cleared: no card in flight touches
service-datasource(seats 3 and 5 confirmed).Dispatch order:
/mnt/project-files/server-seat4/dispatch-30331.md(project shared folder). Ruling section: the card's Expected ("refused by the test and by save, with a message that says why") and triage audit 6652062778 ("Platform first"). PRRefs #30331 (server half), no closing keyword. A contract review atCONTRACT_REVIEW_TIERis owed before queue (narrowing).Posted 2026-11-05T07:50Z.
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
os-dev-report
Status: done (server half). Draft PR #30395 carries
Refs #30331 (server half), headcca010a64. The card stays open for the ui half.:memory:/…passed. Every layer reads a name that starts with:as fileless (driver-sqlresolveSqliteAbsentFileTarget/sqliteFilename, the wasm connection'sisEphemeral), so the probe's missing-file refusal skipped it. better-sqlite3 then opens it as a relative path whose directory does not exist:connect()only warns andcheckHealth()answersfalse, which the probe does not read as a failure. sqlite-wasm opens an ephemeral in-memory database.sqlite: every statement fails "Cannot open database because the directory does not exist".sqlite-wasm: writes succeed and are gone at the next connect or restart, with no error.DatasourceAdminService.assertValidConfig, the one judgement the test, create and update doors share, also refuses asqlite/sqlite-wasmfilename that is empty,:-prefixed but not exactly:memory:, or a path that can be neither opened nor created (driver-sql's write-free judgement). Same envelope and code as every invalid config (400 DATASOURCE_ADMIN_ERROR;result.ok: falsefrom the test). No new error code.:memory:, an existing file, and a creatable missing path (test still refuses it per datasources: the draft probe POST /datasources/test creates the SQLite database file on disk although nothing is saved #27512, save accepts it) answer as before.Follow-up owed (seat files): the spec
SqliteConfigSchema.filenamerefinement, so the build door andPUT /api/v1/meta/datasource/:namejudge the same; ui residue: the dialog's:memory:value instead of a placeholder (DatasourceResourcePage.tsx).{ "issue": 30331, "status": "done", "branch": "claude/project-thread-541rod", "pr": "https://github.com/objectstack-ai/objectstack/pull/30395", "session": "session_01Utp6Cb83ajcseWprEF9C9g", "premise_still_valid": true, "summary": "Server half only. Reproduced on main 8589756a through the real POST /api/v1/datasources/test: ':memory:/tmp/x30331/parts.db' answered ok:true for sqlite and sqlite-wasm. Cause: ':'-prefixed names are fileless to every layer, so the probe's absent-file refusal skipped it; native connect only warns and checkHealth false is read as ok; wasm opens an ephemeral database. A saved one fails every native statement, and on wasm loses every write at reconnect. The shared config gate (assertValidConfig, used by test, create and update) now refuses an empty, ':'-prefixed-but-not-':memory:', or unopenable/uncreatable filename with the value and reason, in the existing envelope.", "tests": "New src/__tests__/sqlite-filename-neither-memory-nor-path.test.ts, 14 passed (7 per driver) through the real HonoHttpServer, admin routes, DatasourceAdminServicePlugin and default factory. Ablation (sqliteDatabaseFilenameIssue short-circuited, src imported by relative path, no dist leg): 8 failed / 6 passed, the 8 refusals red and the 6 controls green; restored, 14/14. Full @objectstack/service-datasource: 72 files, 1183 passed. Typecheck exit 0.", "gates": "dispatch-gates --commands derived 61 families; each run at head cca010a64 with exit recorded before any pipe: 61/61 exit 0 (check-plugin-teardown-shape --self-test after fetching 621a4876; check:dual-build-cjs-loads after the full build). --ran: 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. pnpm lint exit 0. CI check-runs on #30395: not yet reported.", "dogfood_battery": "cca010a64 · os-verify-lock: VERDICT command-exit 0 · Test Files 419 passed / 3 skipped (422) · Tests 3492 passed / 36 skipped (3528) · no failures", "line_budget": "source +78 -9 (2 files), tests +222 (1 file), changeset +20 (1 file); 4 files, +320 -9", "deviations": "none against the dispatch. Save now also judges an unusable path (the dispatch's pin list asks for it); the empty filename is refused too, as the card's 'neither :memory: nor a usable path' covers it. The harness's model-named commit trailer was not used (repo hook); trailers are model-free.", "files_changed": [ ".changeset/30331-sqlite-filename-neither-memory-nor-path.md", "packages/services/service-datasource/src/__tests__/sqlite-filename-neither-memory-nor-path.test.ts", "packages/services/service-datasource/src/datasource-admin-service.ts", "packages/services/service-datasource/src/sqlite-database-filename.ts" ], "mcp_calls": "2: mcp__github__issue_read x2 (get, get_comments); no GitHub write tool. Besides GitHub MCP: one subscribe_pr_activity on #30395 (session event subscription, writes nothing to GitHub)", "api_writes": "2 through the relay: pr_create #30395 (draft, no assignee, no labels, read-back identical) and this comment. Plus 1 git push to claude/project-thread-541rod (not REST)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "class: b · Seam: spec:SqliteConfigSchema.filename ('Database file path, or :memory:') → runtime: build door and PUT /api/v1/meta/datasource/:name · reach: not measured at those doors (the admin doors are fixed here) · evidence: sqlite.zod.ts types filename as placeholderFree(z.string()) · dedupe words: sqlite filename refinement, :memory: prefix, meta datasource filename", "carrier: ui lane (#30331 stays open) · the New datasource dialog holds ':memory:' as a value instead of a placeholder (ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx)", "noted, not filed (no public input measured after this fix): DatasourceAdminServicePlugin.probe reports ok:true when the handle's ping (checkHealth) answers false — recorded in the PR's Acceptance notes" ] }Report taken 2026-11-05T09:34Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
Landed · PR #30395 · server half · card stays open for the ui half
22f0d656a;Refs #30331, so this card stays open. Seat record on headcca010a6(BREAKING, not governed, ≤ 3000 lines; landed per pm-dispatch on the maintainer's 13:47Z word).mainsourcepackages/services/service-datasource/src/datasource-admin-service.ts:1382const filenameIssue = await sqliteDatabaseFilenameIssue(driver, config);:memory:/…) is refused at create and at a config-touching edit, with a message naming the field.:memory:as the Filename field's value instead of a placeholder (ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx). With this PR onmainthe mistake it invites is refused with a message instead of passing.falsehealth check is #30407 (seat 3).Re-routed:
domain:server→domain:ui,pm:dispatched→pm:queue, theos-billassignee comes off with this comment.Posted 2026-11-05T15:22Z.
objectstack-fleet commentedon Nov 5, 2026
domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif
Claim: PM loop round 9 · 2026-11-05T15:24Z
Session:
session_01L6bhgVwQZbHRRM9CaXeKifAccount:
os-salesBranch:
claude/project-thread-5qt4jg(card thread of this project; a thread can push only its designated branch — measured platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-30327Domain:
domain:uiSeat:
domain:ui#5File surface:
ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx(the New datasource dialog: schema-mode default and wording, the managed datasource's no-sync note, the SQLite Filename placeholder) + newstudionamespace keys (en/zh) + their tests + one root.changeset/. ⛔packages/**: if the driver form labels (Filename,Auto-migrate schema) come from the server's driver schema, the dev reports it and the seat files adomain:servercard.Container & model:
M,mode:thread,model: default,effort: highClause-②: yes (expected: new studio keys; the dev declares the final arm)
Metadata-protocol: none
Responsibility: the New datasource dialog | the SQLite Filename box holds
:memory:as a value, so typing a path appends to it | every administrator connecting a SQLite fileThread-read: 6652062778
Premise: holds (on
origin/main8e5fabe5the dialog still defaults to managed and holds:memory:as a value)Serial constraints cleared: PR #30493 (this seat, the same file) merged 2026-11-05T15:17Z; the branch starts from it. The server half landed in PR #30395 (merged). One PR carries this card's ui half and #30327, because both change the same dialog.
Dispatch order lives in the card thread's opening message.
objectstack-fleet commentedon Nov 5, 2026
domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif
Landed at 2026-11-05T16:43Z: PR #30561 merged as
0d54279e73(seat ACCEPT 6663075162 on headfd64ec80, TIER_DEFAULT contract review PASS 6663047260),Fixes #30327andFixes #30331. The merge read 2026-11-05T16:41Z on the PR.git grep -c "NEW_DATASOURCE_SCHEMA_MODE|withBoxDefaults" origin/main -- ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsxState change:
pm:dispatchedremoved. Server follow-ups from the card thread: #30562 (a managed SQL datasource drops and recreates an existing_id-without-idtable, rows lost) and #30563 (driver form labels are English in every console language).