Skip to content

docs(deployment): self-hosting's OS_DATABASE_URL guidance omits mysql:// — the one page a production deployer reads never offers a now-supported target #9053

Closed

Description

@os-project-manager

Filed unassigned by the dev seat implementing #9029 (ruling item 2 of #8739 — publishing MySQL's documented degradations as deployer-facing caveats). Duplicate-searched first, keyword over open and closed issues: the two near hits (#5820, #6265) are both standalone-stack runtime defects about scheme detection, both closed, neither about this page. No existing card.

Filed rather than fixed in PR #9052: that PR's dispatch fenced the content/docs/** sweep explicitly, and this is the inverse of the caveat work — an omitted capability claim, not an unqualified one.

Measured on origin/main @ 2ce1eb41b

content/docs/deployment/self-hosting.mdx:37, the OS_DATABASE_URL row of the "secrets you must pin" table:

Use `postgres://…`, `mongodb://…`, `libsql://…`, or a mounted `file:…` path

mysql:// is absent. The same row goes out of its way to qualify the other targets — Turso's optional install, and MongoDB's single-tenant restriction with a link to Drivers → Multi-tenancy — so the omission reads as deliberate exclusion rather than brevity.

Why this is worth a card

The maintainer's 2026-08-15 ruling on #8739 (comment 5302926756) declared MySQL a supported deployment target, on the explicit reasoning that the docs are the promise already made. self-hosting.mdx is the page that promise is least visible on, and it is the one a production deployer actually reads: its own description is "Run a compiled ObjectStack app on your own infrastructure … plus Compose with Postgres, Kubernetes, and the bare Node.js fallback."

Two consequences, and the second is the one that motivated filing:

  1. A deployer on the self-hosting path never learns MySQL is an option at all.
  2. Because they never meet it here, they also never meet its caveats here. PR docs(data-modeling): publish MySQL's two documented degradations as deployer-facing caveats #9052 publishes those caveats at the three sites where MySQL is offered (data-modeling/drivers.mdx, deployment/environment-variables.mdx, plugins/packages.mdx). This page is the fourth site — and the only one where the fix is to add the target, which is a capability claim rather than a caveat, and therefore outside that PR's scope.

Not claimed

Related


Generated by Claude Code

Activity

  1. os-project-manager commented on Aug 16, 2026

    @os-project-manager
    CollaboratorAuthor

    Finding first-touch grading: promoted → pm:queue (finding removed); lands in content/docs/deployment/self-hosting.mdx:37 (the OS_DATABASE_URL row) ⇒ domain:devx; type Task (an omission, not a false statement — nothing on the page is wrong).

    Rationale: the maintainer's 2026-08-15 ruling on #8739 declared MySQL a supported deployment target on the explicit reasoning that the docs are the promise — a supported target missing from the one page a production deployer reads is the direct residue of that ruling, so promotion needs no new decision. Wording is the dev's call per the card (add mysql://… to the row with a caveat pointer at minimum; whether the page also grows a Compose example is optional and may be declared out of scope in the PR).

    Serial note: PR #9052 (in flight, #9029) publishes the MySQL caveats at three other sites and does not touch this file — no same-file conflict; dev should link the landed caveat anchors from this row, so dispatch preferably after #9052 merges (soft ordering, not a block).

    Size/model suggestion: S; sonnet.

    本评论来自分诊座位(scheduled fire ~08:09Z 2026-08-16,session session_015RsmSaKJXEy45yxFRnC2KA)。


    Generated by Claude Code

  2. os-project-manager commented on Aug 16, 2026

    @os-project-manager
    CollaboratorAuthor

    Claiming this card.

    • Session: session_011RB4waLuNbdruCo6X9oobm
    • Branch: claude/issue-9053-self-hosting-mysql-url
    • Worktree cut from origin/main @ 2cb69c31c

    Re-read the comments before the first edit: the only prior comment is the triage seat's first-touch grading (session_015RsmSaKJXEy45yxFRnC2KA), which is a grading note, not a dev claim. No earlier dev claim with a different session ID exists, so proceeding.

    Scope as dispatched: add mysql:// to self-hosting.mdx's OS_DATABASE_URL row in the shape the row already uses for the other targets, and point at the caveats PR #9052 landed in data-modeling/drivers.mdx rather than restating them. No sweep of content/docs/** — #9029's fence stands; any further page with the same gap gets filed as its own unassigned issue.


    Generated by Claude Code

  3. os-project-manager commented on Aug 16, 2026

    @os-project-manager
    CollaboratorAuthor
    {
      "issue": 9053,
      "status": "done",
      "branch": "claude/issue-9053-self-hosting-mysql-url",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/9076",
      "premise_still_valid": true,
      "summary": "The premise held on current main: the OS_DATABASE_URL row of content/docs/deployment/self-hosting.mdx was still at line 37 on 2cb69c31c and still listed only postgres://, mongodb://, libsql:// and file:. Added mysql://... to the row's 'Use ...' list next to postgres:// (same SqlDriver), followed by a one-sentence caveat pointer in the shape the row already uses for MongoDB's single-tenant restriction, linking to /docs/data-modeling/drivers#mysql-dialect-caveats. The pointer's wording is character-identical to the one PR #9052 landed on the sibling deployment page (environment-variables.mdx), so the two cannot drift into two divergent statements of the same caveat -- the substance stays in drivers.mdx. Verified against what #9052 actually landed (2a20b99ad) rather than what the card expected: the heading it created says THREE caveats, not two (the pre-existing upsert conflict-target limit plus the two new ones), so the pointer says three. On the card's mysql2:// question the check changed the answer's basis: mysql2:// is genuinely accepted by the runtime (detectDriverFromUrl in packages/runtime/src/standalone-stack.ts matches /^mysql2?://i), and drivers.mdx's URL -> Driver Inference Table at line 49 does list it as a scheme -- but the table naming 'mysql | mysql2' in the card's description is the Supported Drivers table's OS_DATABASE_DRIVER-value column, not schemes. It is still deliberately not listed here, because this row names one canonical scheme per target and never spells an alias (postgres:// not postgresql:///pg://, mongodb:// not mongodb+srv://, libsql:// not the *.turso.io http form, file: not sqlite:); adding it would make MySQL the only target on the page with enumerated aliases. Docs prose only, 1 insertion 1 deletion in one file. No sweep -- #9029's fence stands, and the one adjacent gap met while verifying my own pointer's destination was filed, not fixed.",
      "tests": "No unit tests apply -- this is a one-row docs prose change touching no source, config or driver behaviour, so the verification is the gate union, not a test suite. Gate families derived AFTER the diff was final, not recalled: `node scripts/pm/dispatch-gates.mjs content/docs/deployment/self-hosting.mdx` -> check:docs-audit-scope, check:docs-redirects, check:role-word (all lint.yml). Ran that union plus two the derivation did not place but the diff plainly implicates -- check:doc-anchors (the edit adds a #fragment link) and check:nul-bytes (any edit owes it). All five green at the final commit 9d1c23539 (`git rev-parse --short HEAD` at the run), on a clean tree (`git status --porcelain` empty). Real output: check:docs-audit-scope -> 'docs-accuracy-audit scope is in sync with content/docs/: 178 hand-written doc(s).' + 'release-owned pages are in scope and read-only: 9 page(s)'; check:docs-redirects -> 'check-docs-redirects: OK (apps/docs/redirects.mjs: 92 entries -- 89 page destination(s) resolved against content/docs, 3 wildcard, 0 outside the /docs route space, 98 chain probe(s) matched)'; check:role-word -> 'check-role-word: OK (43 baselined file(s), no new occurrences).'; check:doc-anchors -> 'check-doc-anchors: 240 internal #fragment link(s) across 396 source file(s) all resolve to a real heading' -- this is the one that actually proves the new link resolves #mysql-dialect-caveats to a real heading; check:nul-bytes -> 'OK (scanned 5960 text file(s) -- 5960 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).' plus a targeted grep -naP over the edited file, clean. One process note worth flagging: check:doc-anchors first failed with ERR_MODULE_NOT_FOUND because I had not yet run pnpm install in the fresh worktree -- a false red, not a finding; it went green after install, and the four other gates were unaffected. The page-path half of the new link (/docs/data-modeling/drivers) belongs to the `Check Documentation Links` job, which runs lychee and is CI's; locally the target file's existence is confirmed and #9052 already landed the identical path from two other files through that gate. CI gate conclusions are still in_progress at report time -- reporting at draft-PR time per the dispatch contract rather than waiting.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #9075: content/docs/deployment/environment-variables.mdx:50's OS_DATABASE_URL row omits mysql:// (and mysql2://) from its example scheme list, one row above the OS_DATABASE_DRIVER row where #9052 already added the MySQL caveat pointer. Filed unassigned, labelled `documentation` + `finding` with no pm:queue and no domain:* label, because that list is explicitly an `e.g.` list and states nothing untrue -- unlike self-hosting.mdx's closed 'Use ...' instruction. Met only while verifying where my own pointer sends a deployer (self-hosting.mdx links that page as 'the full catalog'), not from a sweep; duplicate-searched first, no existing card."
      ]
    }

    Labels on PR #9076 read back after bots settled, not merely written: documentation, size/xs, skip-changeset. PR is a draft with base main, head 9d1c2353968f9c8cabc873740ffbf54d687a84fc, unqueued — the merge queue is yours to arm. Worktree torn down unforced (git worktree remove exit 0); the other agents' worktrees are untouched.


    Generated by Claude Code

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

Metadata

Metadata

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions