Skip to content

cli: the organization-ownership refusal from os dev -d (non-SQLite) and from os start --database-auth-token / --database-driver still prints ceremony commands that plan another database (#31488 follow-up) #31547

Closed

Description

@objectstack-fleet

domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ

Filing gate: ① measured gaps from a landed card. These are the two out-of-scope findings in #31488's os-dev-report (6722447577, PR #31546), with the defect class #31488 fixed for os start -d / --home. ⛔ Not a claim.
Reader: server seat 5 (@objectstack/cli + @objectstack/runtime), from pm:queue.
Dedupe (open AND closed): os dev database flag ownership refusal ceremony database-url, start database-auth-token ownership refusal ceremony → #31488 only.
reach: operators upgrading a v17-shaped database through os dev -d with a non-SQLite URL, or through os start -d libsql://… --database-auth-token / --database-driver.
class: b · type: Bug
Grade: p3, self-graded by the server seat (Ruling-ref: 「定级你可以自己决定」). Both cases are narrower than #31488's.

维护者速读

#31488 修好了 os start -d / --home 时组织归属拒绝信息里打印的迁移命令没有指明数据库的问题。同类问题还剩两处:os dev -d 用非 SQLite 数据库时,打印的 --dev 命令仍不带数据库;os start 用 --database-auth-token 或 --database-driver 启动时,打印的命令带了 URL,但没带 token 或 driver。照着打印的命令执行,会规划到别的数据库,或者连不上数据库。

What is wrong (from the dev's reading on #31546, not measured)

  1. os dev -d with a non-SQLite URL, on a v17-shaped database. os dev leaves the ceremony to the operator for a non-SQLite database. The refusal's --dev commands name no database, so run verbatim they plan the project's default database.
  2. os start -d libsql://… --database-auth-token T, or --database-driver. After fix(cli,runtime): the ownership refusal from os start --home / -d names the database it refused #31546 the named commands carry the URL. They do not carry the token or driver that start passed to its child, so they cannot open the same database.

Expected

Related: #31488, PR #31546.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    pm:queueReady for the PM dispatch loop
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 8, 2026
  2. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ

    Claim: PM loop round 1 · 2026-11-08T14:47Z
    Session: session_01FEkQ5mbAyTfp7gbjowRA48 (card thread, dev) · seat session_01FEkQ5o8PE7ZtVjcor51wBZ
    Account: os-project-manager
    Branch: claude/project-thread-u74sqa
    Worktree: objectstack-issue-31547
    Domain: domain:server
    Seat: domain:server#5
    File surface: packages/runtime/src/organization-ownership-boot-guard.ts, the os dev / os start hand-off in packages/cli (channel from #31546), tests, root .changeset/
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: thread default
    Clause-②: no — expected: only the printed ceremony commands change; nothing accepted or refused changes; the dev confirms from the real diff and declares a widening arm if a published option or ceremony flag is added
    Metadata-protocol: none
    Responsibility: os dev / os start organization-ownership refusal (objectstack) | os dev -d (non-SQLite) and os start --database-auth-token / --database-driver print ceremony commands that plan or cannot open another database | operators upgrading such a database
    Thread-read: none
    Premise: holds per the #31488 dev's reading on PR #31546 (not measured); the dev measures red on main first
    Serial constraints cleared: cleared — #31546 (same files) merged; same thread

    Scope: Fixes #31547. Both cases name the refused database through #31546's channel and guard option; a token is never printed. Order: /mnt/project-files/pm-orders/server/order-31547.md. Summons: the maintainer's 「server 再开两个座位」「并发都是5」 (this project, 2026-11-07); grading per 「定级你可以自己决定」 is triage's here (graded on the card).

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 8, 2026
  4. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-project-manager · session_01FEkQ5mbAyTfp7gbjowRA48

    os-dev-report

    {
    "issue": 31547,
    "status": "done",
    "branch": "claude/project-thread-u74sqa",
    "pr": "#31581",
    "session": "session_01FEkQ5mbAyTfp7gbjowRA48",
    "premise_still_valid": true,
    "summary": "Premise held on 4d165ac and measured. os dev -d file:A.db printed Run 'os migrate organization-ownership --dev --out PLAN' with no database. A -d … --database-driver sqlite --database-auth-token T start printed commands without the driver or the token, and with the token unset its plan still ran (it wrote plan-connection-unset.json). Fix, through #31546's channel and guard option, with no second resolver. (1) dev.ts writes OS_INTERNAL_CEREMONY_DATABASE_URL with ceremonyDatabaseUrl(resolvedDb, { homeFlag: undefined }), so the --dev commands carry --database-url (a credential URL is still read from ${OS_DATABASE_URL:?…}). (2) The ceremony accepts only --database-url, but it reads OS_DATABASE_DRIVER and OS_DATABASE_AUTH_TOKEN from the environment, which is where both flags of start/dev land. So no flag is added (four axes in the PR). Instead, start.ts and dev.ts write two new internal channels, OS_INTERNAL_CEREMONY_DATABASE_DRIVER (the value) and OS_INTERNAL_CEREMONY_AUTH_TOKEN_FROM_FLAG (1, never the token). serve.ts spreads them into the new optional guard options databaseDriver / databaseAuthTokenFromFlag, and ceremonyCommand prefixes OS_DATABASE_DRIVER=KIND and OS_DATABASE_AUTH_TOKEN=\"${OS_DATABASE_AUTH_TOKEN:?export OS_DATABASE_AUTH_TOKEN as the database auth token this server was started with}\" with a note. The token never reaches the guard, and an unset export stops the shell. (3) os dev's own line for a non-SQLite database, and the line after a refused upgrade plan, spelled a bare os migrate organization-ownership --dev. Both now point at the two commands the guard's refusal names.",
    "tests": "Guard unit (packages/runtime/src/organization-ownership-boot-guard.test.ts): ⭐ driver prefix in every state, before the exported secret and before --dev; ⭐ token read as ${OS_DATABASE_AUTH_TOKEN:?…} with the note, alone or with a driver; ⭐ the printed plan runs through sh with os stubbed, sees driver+token+--dev --database-url file:A.db, and with the token unset exits non-zero with the message and empty stdout; CONTROL: neither option, commands as #31488. Channel unit: ⭐ driver by value, token only as '1', token text absent from env; parent-owned set/delete; ⭐ start.ts and dev.ts both write both channels. dev upgrade unit: ⭐ non-SQLite line and refused-plan line point at the refusal's commands (edited assertions). E2E: dev stale-column file (existing os dev --no-watch -d file:A.db run, no new spawn) ⭐ refusal names --dev --database-url file:A.db; start refusal file: new -d + --database-driver sqlite + --database-auth-token scenario, ⭐ exact commands, token absent from output; plan with token exported is of A.db (green on main too, so unstarred); ⭐ token unset stops the shell, no plan file. RED ON MAIN (4d165ac source, all packages built from it): guard 'Tests 3 failed | 27 passed (30)' (CONTROL green); cli unit 'Tests 5 failed | 15 passed (20)' ('writeCeremonyConnectionChannel is not a function', start source pin, both dev lines 'expected ... to contain the two commands the boot guard's re…'); e2e 'Tests 3 failed | 14 passed (17)', all #31488 cases and CONTROLs green, dev printed "Run 'os migrate organization-ownership --dev --out PLAN'". GREEN on head and again on the merged head after a full ./packages/** build: 30/30, 20/20, 17/17. ABLATIONS (scripts/ablation-replace.mjs, each 'ok restored: blob == HEAD … git diff HEAD is empty'): guard driver if (false && opts.databaseDriver) words += -> 'Tests 3 failed | 27 passed (30)', "expected '|tok-31547|migrate organization-owner…' to be 'turso|tok-31547|…'"; guard token if (false && opts.databaseAuthTokenFromFlag) words += -> 'Tests 2 failed | 28 passed (30)', 'expected +0 not to be +0' (shell no longer stops); dev hand-off through dist ("ABL31547D".length < 0, preflight 'marker present in 1 built file') -> dev file 'Tests 1 failed | 5 passed (6)'; start driver/token hand-off through dist ("ABL31547S".length > 0 ? {undefined…} : …, marker present in 1 built file) -> start file 'Tests 2 failed | 9 passed (11)'; restore leg cli rebuilt, preflight --absent both markers 'marker absent from all 904 built files', 'working tree clean against HEAD'. Typecheck runtime + cli (tsc + check:test-typecheck) exit 0 before and after the merge.",
    "gates": "Local on 25295c1 (origin/main 6ed533f merged; full pnpm --filter './packages/**' run build under os-verify-lock VERDICT command-exit 0): dispatch-gates --commands -> 72 families, exit codes captured before any pipe (record /mnt/project-files/pm-orders/server/31547-gates-ran.txt). 71 exit 0; check:test-source-alias exit 1 (the edited dev-organization-ownership-upgrade.test.ts reaches import('@objectstack/runtime') and import('@objectstack/service-datasource') through telemetry-datasource.ts), fixed in d2d0220 with two module-top side-effect imports, then exit 0, with check:cross-package-test-inputs, check:cli-test-child-env, check:undeclared-dep-imports, check:type-check-coverage re-run exit 0, that test 13/13 and cli typecheck exit 0. --ran on the record with codes: '72 derived, 72 run, 0 NOT-MEASURED, 0 UNRUN' (a DERIVED zero). eslint on the 11 touched .ts files exit 0. CI check-runs on #31581: the seat reads them.",
    "line_budget": "12 files, +378 / -21 per the PR (375/21 locally before the alias fix); source 5 files (+142/-12 before the 2-line test import fix), tests 6 files, changeset 1",
    "files_changed": [
    ".changeset/31547-ownership-refusal-names-dev-database-and-connection.md",
    "packages/cli/src/commands/dev.ts",
    "packages/cli/src/commands/serve.ts",
    "packages/cli/src/commands/start.ts",
    "packages/cli/src/utils/dev-organization-ownership-upgrade.ts",
    "packages/cli/src/utils/dev-organization-ownership-upgrade.test.ts",
    "packages/cli/src/utils/internal-ceremony-database-channel.ts",
    "packages/cli/src/utils/internal-ceremony-database-channel.test.ts",
    "packages/cli/test/dev-organization-ownership-stale-column.integration.test.ts",
    "packages/cli/test/start-organization-ownership-refusal.integration.test.ts",
    "packages/runtime/src/organization-ownership-boot-guard.ts",
    "packages/runtime/src/organization-ownership-boot-guard.test.ts"
    ],
    "deviations": [
    "Clause-②: the claim expected no; the real diff adds two optional members to @objectstack/runtime's published OrganizationOwnershipBootGuardOptions, so PR and changeset declare yes (widening), as the claim provided for (Metadata-protocol none, both packages patch).",
    "Scope: os dev's own manual line (non-SQLite database, and after a refused upgrade plan) is changed too: it spelled a bare os migrate organization-ownership --dev, the same defect on the same path; it now points at the guard's refusal. Two existing assertions in dev-organization-ownership-upgrade.test.ts were edited accordingly.",
    "The os dev end-to-end pin uses -d file:A.db (SQLite), the existing run; a non-SQLite e2e would need a database server. The non-SQLite text is pinned at unit level.",
    "The PR was opened without labels, as #31546 was (no labels named in the order)."
    ],
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "3 — mcp__github__pull_request_read x1 (#31581 get, read-back: draft, open, head d2d0220), mcp__github__issue_read x1 (#31547 get_comments: Claim 6722923834 names claude/project-thread-u74sqa), plus ToolSearch loads; no MCP write tool",
    "api_writes": "git push x1 (plain; the remote branch had been deleted on #31546's merge); relay pr_create via fleet-write/dispatch.mjs (#31581, 13967 bytes sent = stored, assignees none, no labels, draft); this os-dev-report comment via post-stamped on #31547",
    "open_questions": [],
    "security_findings": "none",
    "out_of_scope_findings": [
    "class: c · reach: a --database-auth-token beside a non-libSQL URL (ignored by the stack) still makes the printed commands require OS_DATABASE_AUTH_TOKEN; the rule follows the flag, not the driver · noted in the PR · carrier: PR #31581 · noted, not filed"
    ]
    }


    Generated by Claude Code

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

Metadata

Metadata

Labels

bugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions