Skip to content

fix(service-datasource): a runtime managed datasource syncs its bound objects' tables on create and after a restart - #27748

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-2wg1a8
Oct 29, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-2wg1a8

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:server#3 · os-elon-musk · session_016WV4czbMpdApCUbUuNyHt7

Fixes #27701

What changes

  • registerPool (packages/services/service-datasource/src/datasource-admin-plugin.ts) now opens a runtime datasource's pool with objects: the names of the objects bound to it in the engine registry. The connect's existing sync loop gives them their tables. This covers the admin create, the boot rehydration, and a peer replica's convergence on a new datasource, which all go through registerPool.
  • ⛔ The objects are passed only when the datasource is managed. Its mode is read with resolveDatasourceSchemaMode, the same read the driver factory uses. An external or validate-only datasource passes none and never gets DDL (triage ruling 6506923793).
  • The registry read that listObjectsBoundTo already did is lifted into one local helper, objectsBoundTo, which both readers call. listObjectsBoundTo's answer is byte-for-byte the same.
  • Neither datasource-connection-service.ts (open PR fix(service-datasource): a plugin-driver datasource connected or reconnected through the connection service keeps the engine's floor #27715) nor objectql/src/engine.ts is touched.

Why

A code object bound to a Setup-created managed datasource never got its table. Boot's schema sync skipped it, because the driver did not exist yet. registerPool then called connect(record, { context }) with no objects, so the sync loop had nothing to sync. The datasource answered ok, and every read of the object was a 500 (Postgres 42P01), the same after a restart.

Verification

New pin: src/__tests__/runtime-datasource-bound-object-storage.test.ts. It uses the real DatasourceAdminServicePlugin through init() and start(), a real ObjectQL engine on the objectql and data slots, and the real default driver factory over SQLite files.

Case origin/main plugin this PR
on create, the bound object's table exists and the object reads red green
after a restart, the rehydrated pool creates a missing table and the object reads red green
control: an object bound to another datasource is not synced red green
⛔ schemaMode: external: the pool opens, nothing is synced green green
⛔ schemaMode: validate-only: the pool opens, nothing is synced green green

Ablations, each restored afterwards:

  • Dropping the objects argument turns the 3 positive cases red.
  • Forcing the managed gate open turns both negative cases red (syncObjectSchema called 2 times).

Local readings at 6f773675:

  • @objectstack/service-datasource test: 62 files, 1016/1016 passed. typecheck: exit 0.
  • dispatch-gates --commands: 59 families derived, 58 exit 0. pnpm check:dual-build-cjs-loads exited 3, so it is NOT MEASURED (it needs a whole-tree build; CI runs it).
  • dispatch-gates --ran: 59 accounted for.
  • pnpm lint: exit 0.

Clause-②: no
Metadata-protocol: none

Acceptance notes

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes.
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: n/a.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_016WV4czbMpdApCUbUuNyHt7

…s bound objects' tables

registerPool opened a Setup-created datasource's pool with no objects, so a
code object bound to it never got its table, on create or after a restart,
and every read of it was a 500. The connect now carries the objects bound to
the datasource when it is managed, read from the engine registry through the
same helper listObjectsBoundTo uses. An external or validate-only datasource
passes none and never gets DDL.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4czbMpdApCUbUuNyHt7
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/service-datasource, touching 2 documentable anchor(s).

5 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/api/wire-format.mdx (via /api/v1/meta/object/:name (route, a path literal in a comment in DatasourceAdminServicePlugin))
  • content/docs/data-modeling/external-datasources.mdx (via DatasourceAdminServicePlugin (symbol, a top-level class))
  • content/docs/protocol/kernel/http-protocol.mdx (via /api/v1/meta/object/:name (route, a path literal in a comment in DatasourceAdminServicePlugin))
  • content/docs/protocol/objectql/state-machine.mdx (via /api/v1/meta/object/:name (route, a path literal in a comment in DatasourceAdminServicePlugin))
  • content/docs/ui/forms.mdx (via /api/v1/meta/object/:name (route, a path literal in a comment in DatasourceAdminServicePlugin))

⛔ 2 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v17/17-1.mdx (via /api/v1/meta/object/:name (route, a path literal in a comment in DatasourceAdminServicePlugin))
  • content/docs/releases/v17/17-7.mdx (via /api/v1/meta/object/:name (route, a path literal in a comment in DatasourceAdminServicePlugin))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see

Coarse fallback — 2 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 81d00a4ed938eb896859630498fc59d91183cf71 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 326cad2e311bb62c995f15597eea96e3647efc74 — the merge of head 6f7736751e98b1ff5ed6634fca470bec6f02c94a into base 81d00a4ed938eb896859630498fc59d91183cf71, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 326cad2e311bb62c995f15597eea96e3647efc74 && git checkout 326cad2e311bb62c995f15597eea96e3647efc74
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 81d00a4ed938eb896859630498fc59d91183cf71 6f7736751e98b1ff5ed6634fca470bec6f02c94a && git checkout -B drift-repro 81d00a4ed938eb896859630498fc59d91183cf71 && git merge --no-ff 6f7736751e98b1ff5ed6634fca470bec6f02c94a

node scripts/docs-audit/affected-docs.mjs --json 81d00a4ed938eb896859630498fc59d91183cf71

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 81d00a4ed938eb896859630498fc59d91183cf71 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

Seat ACCEPT · PR #27748 · head 6f7736751e98b1ff5ed6634fca470bec6f02c94a · 2026-10-29T22:30Z

维护者速读

  • 改了什么: 在 Setup 里新建的「托管」数据源,打开连接时会给绑定到它的代码对象建表(新建时、重启后都会);外部/只校验模式的数据源仍然不做任何 DDL。
  • 为什么改: 之前这类对象从来没有表,数据源显示正常,但每次读都 500,重启也不好。
  • 风险与回滚: 只改 service-datasource 的 registerPool 一处,复用既有的同步循环;回滚 = revert 本 PR。
  • 先看: packages/services/service-datasource/src/datasource-admin-plugin.ts 的 registerPool 与 objectsBoundTo。
  • 两分钟验证: pnpm --filter @objectstack/service-datasource exec vitest run src/__tests__/runtime-datasource-bound-object-storage.test.ts,5 个用例全绿。
  • 需要你做的: 无,席位按本任期落地授权落地。

席位核对

ACCEPT

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 29, 2026 22:31
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 29, 2026 22:31
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 6d9419b Oct 29, 2026
49 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-2wg1a8 branch October 29, 2026 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

1 participant