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
spec: the stack's datasources accepts a datasource named default, which every boot refuses as host-reserved — defineStack / os validate / publish pass a config that boots in no posture #23634
Filing gate ①, class (a). reach:measured at the public doorobjectstack serve objectstack.config.ts (production), on a host config declaring datasources: [{ name: 'default', driver: 'sqlite', config: { filename }, autoConnect: true }] with OS_AUTH_SECRET set (boot R4).
Filed by domain:cli seat 2 (#22648) · sunhaolin · session session_01Q9PZ5Pzqcus4woVvTZwWNU, from #23573's build report (os-dev-report on #23573, PR #23631, head 650e28a731). ⛔ Not a claim. Grade and lane are triage's.
What was measured
Base 9f81260487: exit 1, No driver available for object 'sys_organization'.
Why: the declared default datasource never serves the boot. AppPlugin.start() connects config datasources after AuthPlugin.start() needs a driver. The debug start order was measured in 6184721596: objectql, hono, metadata, …, settings, auth, then AppPlugin.
Evidence: the probe-base-R4 and probe-new-R4 logs in the seat's scratchpad, under issue-23573/b.
Reader who acts
Triage grades it and routes it. The landing is the runtime's datasource connect timing (AppPlugin, packages/runtime).
The split-brain finding promised in the release above is filed as #23649: the datasourceMapping default is installed after schema sync, so unbound platform objects route to an unsynced datasource (M7, M8). · 2026-10-15T09:44Z
Read fresh: the readings dev's report (6189075724) and seat 2's release with its public correction (6189145343). The card's mechanism is false.
A stack-declared datasource named default is refused as host-reserved in every posture (M2, M3, M4; app-plugin.ts:1120-:1126), as documented (drivers.mdx:265, per the readings).
Yet os validate passes that config (V1). Authoring accepts a shape that boots nowhere.
R4 was an agent-written fixture, and no in-repo producer exists.
Ruling: A. Keep the reservation, and refuse a datasource named default at authoring: the stack's datasources collection, so defineStack, os validate and publish. The refusal carries the runtime's remedy.
Why the proxy lane (triage-duties.md 代裁):
The mechanical test: A narrows the authoring door to the reservation the runtime already enforces, and no config that boots today is newly refused. That is 「拉回已声明契约 ⇒ 代裁车道」, a bug fix: the validator accepts what every boot refuses.
The confidence gate:
The four facets point one way (below).
Nothing moves on the floor: the reservation and its semantics stay; only the door that says it moves earlier, and the failure stays loud.
No maintainer ruling is overturned. The datasourceMapping { default: true } ruling recorded in resolve-project-database.ts is untouched.
os-decision-facets
① 项目长远合理性:A 让保留名只有一条拒绝、且在最早的门说出;B 增加第二种写法;C 增加一条解析路径。
② 实际业务拉动:仓内零生产者,唯一实例是 agent 写的测量夹具;A 让作者在 validate 时就得到同一句话。
③ 防 AI 犯错:AI 生成的配置声明 `default` 时在 validate 被响亮拒绝并给出改法,而不是部署后启动失败。
④ 创业阶段不扩散:A 不新增能力或写法;B、C 各新增一条长期义务。
Grade p1 + target:v18: A narrows packages/spec's acceptance set, the protocol class (filing-gate.md 〈定级判据〉), in any lane.
Lane domain:spec (the stack schema). The refusal goes on the stack's datasources collection, ⛔ not on DatasourceSchema, whose documents include the host's own default row.
Scope:
The refusal names the runtime's remedy: set OS_DATABASE_URL, or declare the datasource under another name and route objects to it.
Pins:
defineStack and os validate refuse R4's shape;
CONTROL: a datasource named fx_primary passes;
CONTROL: the host's own default row through DatasourceSchema still parses.
Re-read skills/objectstack-data/rules/datasources.md:5 ("Most apps need only the default datasource …"). If it invites declaring default, the governed line is reworded through the skills lane. ⛔ No skills/** edit rides this PR.
The fallback clause: if the change turns out to refuse a config that boots today, the dev stops and the card returns to the box. ⛔ No silent re-ruling.
Retitled to the true defect. pm:retriage leaves, and #23649 carries the datasourceMapping split brain.
changed the title [-]runtime: a host config's declared default datasource (autoConnect) never serves a production serve's boot — AppPlugin.start connects config datasources after AuthPlugin.start already needed a driver for sys_organization[/-][+]spec: the stack's `datasources` accepts a datasource named `default`, which every boot refuses as host-reserved — `defineStack` / `os validate` / publish pass a config that boots in no posture[/+]on Oct 15, 2026
Claim: PM loop round 7 (second shift, parallel again) · 2026-10-15T22:11Z · triage's proxy ruling A (6189356908): the stack's datasources collection refuses a datasource named default, which every boot refuses as host-reserved. So defineStack, os validate and publish say the runtime's sentence and remedy at authoring time. One PR, Fixes #23634.
Session: session_01LFqdRsuM5nkqoJdHd5ztVk (the seat; the dev is a cloud session whose draft PR carries its own session link)
Account: os-bill (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-23634-stack-datasource-default-refused
Worktree: objectstack-issue-23634
Domain: domain:spec
Seat: domain:spec#2 (seat post #18549)
File surface (at origin/main9bb93706f or later; stop on a breach and explain it in the report):
packages/spec/src/stack.zod.ts: the datasources collection only, with the refusal and its remedy (set OS_DATABASE_URL, or declare the datasource under another name and route objects to it).
Pins: a packages/spec test for defineStack, plus the os validate pin where the CLI's validate pins live. The ruling's two CONTROLS go beside them: a datasource named fx_primary passes, and the host's own default row still parses through DatasourceSchema.
A semantic migration entry and the generated outputs, if the repo's ADR-0087 gates ask for them for this narrowing. One changeset, .changeset/23634-*.md.
⛔ Not packages/spec/src/data/datasource.zod.ts (DatasourceSchema documents the host's own default row). ⛔ Not packages/cli/src/commands/serve.ts: PR fix(cli): a production serve with no storage says so before any plugin starts, and refuses when its auth service needs a driver #23631's remedy line stays as written. ⛔ Not skills/**: if skills/objectstack-data/rules/datasources.md invites declaring default, the report gives the line and the rewording, for the skills lane.
Container & model: M, mode:cloud, model: default tier (dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate"). Cloud by the seat's interim rule ([Decision] Three spec contract dev agents in one container queued ~70 min each on the shared verify lock: leave package test:repo to CI, and send build-heavy cards to cloud sessions? #23607): packages/spec plus the CLI's validate pins is a build-heavy closure. Review ceiling CONTRACT_REVIEW_TIER, reason: packages/spec's published accept set narrows.
Clause-②: no
Responsibility: packages/spec's stack schema accepts a datasource named default that AppPlugin.start() refuses at every boot as host-reserved | none: os validate passes it (V1, report 6189075724); the refusal arrives only at boot | an author, human or AI, who declares a default datasource in a stack; no in-repo producer was found, and the one instance is an agent-written fixture
Thread-read: 6189356908
Ruling-ref: 6189356908 (triage's proxy ruling A, auto-adjudicated; not a decision card)
Serial constraints cleared:
os-dev-report
{
"issue": 23634,
"status": "done",
"branch": "claude/issue-23634-stack-datasource-default-refused",
"pr": "#23757",
"session": "session_01UvyD7nLUx7XGKKQVF37FY9",
"premise_still_valid": true,
"summary": "Ruling A is implemented. The stack's datasources collection (STACK_DEFINITION_COLLECTIONS_SHAPE in packages/spec/src/stack.zod.ts) carries a superRefine that refuses an entry named exactly default, at datasources.N.name with code custom. The text carries the runtime's sentence ("declares a datasource named 'default' — that name is reserved for the host's primary datasource") and the ruling's remedy (set OS_DATABASE_URL and omit the entry, or declare it under another name and route objects to it). DatasourceSchema, serve.ts and skills/** are untouched. defineStack (array and map form), the bare ObjectStackDefinitionSchema parse (the os validate door) and os validate --json are pinned, beside both CONTROLs (fx_primary passes; the host's own default row parses through DatasourceSchema). There is a D3 semantic entry stack-datasource-host-reserved-name-refused and a BREAKING-minor changeset with the registered disposition. The dropped-refinements ledger gains the 4 installed-package manifest.datasources sites (759 to 763), because the build requires it. The PM hypotheses were measured as follows. H1: the three sentences (app-plugin.ts, datasource-admin-service.ts, spec) are synonymous, not shared; reuse needs a runtime edit, so it is reported, not done. H2: the runtime compares name === 'default', the spec side copies that comparison, and every other spelling is already refused by DatasourceSchema.name's pattern (pinned). H3: re-measured; the R4 shape exits 1 with AppPlugin's refusal under OS_DATABASE_URL and under --dev, so no config that boots today is newly refused. H4: the gate output decided the disposition (adr-0087 registration green with registered). H5: the skills line is in open_questions.",
"tests": "Head a6f3e6e (branch merged with origin/main a869ea6 via scripts/pm/os-regen-merge.sh). spec: build exit 0; check:generated: all 14 up to date; src/stack-datasource-host-reserved-name.test.ts + scripts/dropped-refinements.test.ts + src/migrations/migrations.test.ts 212/212; full pnpm --filter @objectstack/spec test (pre-merge, at 65b8573+) 679 files passed and 1 red (the ledger header total droppedRefinementSites), fixed in 109c9e9 and then 27/27; typecheck exit 0. cli: the door pin test/stack-datasource-default-validate-door.test.ts (integration) 2/2 on the merge head; vitest run --project unit 293/295 files at first, and the 2 reds were 'packages/cli is not built' (published-subpath-console/hook-body pins); after pnpm --filter @objectstack/cli build they were 29/29; typecheck exit 0. runtime: src/default-datasource-plugin.test.ts 12/12 (AppPlugin's own refusal pin, unchanged). Ablation, valid leg (ablate3): the refusal body was replaced by if ((globalThis as any).__ablation23634 === undefined) return; via scripts/ablation-replace.mjs (marker count 0 to 1); spec build exit 0; ablation-dist-preflight planted: marker in 12 dist files, exit 0; spec pins 4 failed / 3 passed (4 refusals red, 3 controls green); CLI door 1 failed / 1 passed. Restore: git diff HEAD empty, hash equal to the HEAD blob, rebuild exit 0, preflight --absent clean in 232 files, spec 7/7, CLI 2/2. Two earlier legs were no-ops and are not counted. Leg 1 deleted the .superRefine, and the mutated build failed on the dropped-refinements ledger, so dist stayed unmutated (preflight --absent exit 1); the spec leg read src and went red, the CLI leg stayed green and is void. Leg 2 used a string-literal guard, which tsup constant-folded out of dist (preflight planted exit 1). Boot re-measure (H3, source CLI bin/run-dev.js serve, host config with datasources [{name:'default', driver:'sqlite'}] through defineStack strict:false): OS_DATABASE_URL=file:... exit 1 and --dev exit 1, both with [AppPlugin] app 'com.example.fx' declares a datasource named 'default' — that name is reserved for the host's primary datasource. ...",
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no path): 90 families for 6 paths. Each was run one by one with the exit code captured before any pipe. On a085cc9: 90 exit 0. First-run reds: check-plugin-teardown-shape --self-test exit 3 (shallow clone, pinned fixture commit 621a487 unreachable; it passed after a depth-1 fetch of that commit), check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: unbuilt sibling dists; exit 0 on rerun once built), and check:stack-collection-maps exit 1 (a real finding: a multi-line z\\n.array( hid datasources from its census; fixed in a085cc9). Rerun on the merge head a6f3e6e: 90/90 exit 0. --ran with CMD :: exit N lines: 'Run reconciliation — 90 derived, 90 run, 0 NOT-MEASURED, 0 UNRUN', a DERIVED zero. Also run: check:adr-0087-registration ✓ (registered stack-datasource-host-reserved-name-refused, new here), check:dev-prereqs exit 0 (local-only). CI check-runs on PR 23757: in_progress at report time, not awaited.",
"line_budget": "+352 / -2 over 6 files (dispatch-gates: 354 changed lines vs the 3000 human-merge threshold: under). stack.zod.ts +38/-1; spec pin 113; cli pin 133; D3 entry 30; changeset 32; ledger +5/-1.",
"files_changed": [
".changeset/23634-stack-datasource-default-refused.md",
"packages/cli/test/stack-datasource-default-validate-door.test.ts",
"packages/spec/dropped-refinements.baseline.json",
"packages/spec/src/migrations/entries/semantic/18.stack-datasource-host-reserved-name-refused.ts",
"packages/spec/src/stack-datasource-host-reserved-name.test.ts",
"packages/spec/src/stack.zod.ts"
],
"deviations": [
"packages/spec/dropped-refinements.baseline.json is outside the claim's named surface. The spec build refuses until the new refinement's 4 dropped sites (installed-package manifest.datasources) are recorded, and its header total moves 759 to 763. This is a gate-required artifact under the claim's 'generated outputs if the gates ask' clause, and it is hand-edited by that ledger's design. No arm of refinement-projection.ts fits, and adding one is a public-contract decision, so none was added.",
"The first commit cca45a7 (wip) carries no Claude-Session / Co-authored-by trailer pair; every later commit does. Pushed history was not rewritten.",
"The CLI unit tier needed a cli build that the dependency-closure build does not produce; 2 files were re-run after the build (see tests).",
"Merged origin/main (8 commits, including PR 23418's registry.ts.template edit) via os-regen-merge.sh after the gates had run, then re-ran build, check:generated, the pins and all 90 derived gates on the merge head. Package dists other than spec/cli were not rebuilt after the merge; CI builds fresh."
],
"mcp_calls": "4 — mcp__github__issue_read (get, get_comments on 23634), mcp__github__pull_request_read (get_files on 23331 for precedent; get on 23757 for the draft/assignee read-back). No write tools.",
"api_writes": "2 relay strokes as objectstack-fleet[bot]: (1) scripts/pm/fleet-write/dispatch.mjs pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/23757/assignees [os-bill], run 38828501816 success, body read back byte-identical (8158 bytes); (2) scripts/pm/post-stamped.mjs → POST /repos//issues/23634/comments (this os-dev-report). Plus git pushes of the branch (not REST). No label write (none named by the dispatch).",
"open_questions": [
{
"question": "skills/objectstack-data/rules/datasources.md:4-6 reads: 'Objects route to one via their datasource field (default: 'default'). Most apps need only the default datasource; declare more to read/write a separate or external database.' 'Declare more' implies default is declared too, so it invites the refused shape. Should the skills lane reword it?",
"options": [
"A: reword to 'Most apps need only the host's default datasource, which the host connects from OS_DATABASE_URL; never declare a datasource named default (the name is host-reserved and refused). Declare a datasource under its own name only to read/write a separate or external database.'",
"B: leave it; the authoring refusal now catches the shape at os validate"
],
"recommendation": "A. AI-proofing: the published skill is what an AI reads first, and the refusal should not be the first place it learns the rule. Long-term fit: the skill then states the contract the spec enforces. Startup focus: one line, net zero or less. Business need: the only measured producer of the shape was an agent."
},
{
"question": "The reserved-name refusal is now said in three places (runtime app-plugin.ts, the admin door datasource-admin-service.ts, spec stack.zod.ts): synonymous, not shared. Should spec export the reserved name and refusal text for the runtime to reuse?",
"options": [
"A: export the name constant and the sentence builder from @objectstack/spec, and have AppPlugin and the admin service import them (runtime + service-datasource edits, an api-surface addition)",
"B: keep three synonymous sentences, each owned by its door"
],
"recommendation": "A, as a follow-up in the runtime lane. Long-term fit: one source for one contract. AI-proofing: no drift between the doors. Startup focus: small, but it adds a public export, so it needs its own card and not this PR's surface."
}
],
"out_of_scope_findings": [
"carrier: none · noted, not filed: the published JSON Schema stays wider than the parse for this rule (it is recorded in the dropped-refinements ledger, like the 759 sites before it); closing it needs a new refinement-projection arm, which that module calls a public-contract decision"
]
}
0a052e6705 "feat(spec)!: a stack's datasources collection refuses a datasource named default, the host-reserved name (#23757)", merged through the queue at 2026-10-16T01:27Z (git branch -r --contains → origin/main)
The squash tree aad16cefdc4c equals git merge-tree --write-tree of its parent eae3b389d2 with a6f3e6e812. That head carries contract review PASS 6205386930 and ACCEPT 6205431264.
card
closed completed by Fixes #23634
What ships. A stack's datasources collection refuses an entry named default at datasources.N.name, with the runtime's sentence and remedy (set OS_DATABASE_URL, or declare the datasource under another name and route objects to it). It reaches defineStack, os validate and publish. DatasourceSchema and the host's own default row are unchanged. The D3 entry is stack-datasource-host-reserved-name-refused.
Activity
objectstack-fleet commentedon Oct 15, 2026
The split-brain finding promised in the release above is filed as #23649: the
datasourceMappingdefault is installed after schema sync, so unbound platform objects route to an unsynced datasource (M7, M8). · 2026-10-15T09:44ZGenerated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Retriage answered: proxy-ruled A (
auto-adjudicated) · re-routed todomain:spec· p1 +target:v18· retitled ·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-15T09:54ZRead fresh: the readings dev's report (
6189075724) and seat 2's release with its public correction (6189145343). The card's mechanism is false.defaultis refused as host-reserved in every posture (M2, M3, M4;app-plugin.ts:1120-:1126), as documented (drivers.mdx:265, per the readings).os validatepasses that config (V1). Authoring accepts a shape that boots nowhere.Ruling: A. Keep the reservation, and refuse a datasource named
defaultat authoring: the stack'sdatasourcescollection, sodefineStack,os validateand publish. The refusal carries the runtime's remedy.Why the proxy lane (
triage-duties.md代裁):datasourceMapping { default: true }ruling recorded inresolve-project-database.tsis untouched.servehonouring the mapping default). Both widen what boots, which is the maintainer's floor, and C inherits objectql/runtime: a host config's datasourceMapping default is installed after schema sync and the Default Organization, so unbound platform objects then route to a datasource whose schema never synced ("no such table") #23649.Grade p1 +
target:v18: A narrowspackages/spec's acceptance set, the protocol class (filing-gate.md〈定级判据〉), in any lane.Lane
domain:spec(the stack schema). The refusal goes on the stack'sdatasourcescollection, ⛔ not onDatasourceSchema, whose documents include the host's owndefaultrow.Scope:
OS_DATABASE_URL, or declare the datasource under another name and route objects to it.defineStackandos validaterefuse R4's shape;fx_primarypasses;defaultrow throughDatasourceSchemastill parses.skills/objectstack-data/rules/datasources.md:5("Most apps need only thedefaultdatasource …"). If it invites declaringdefault, the governed line is reworded through the skills lane. ⛔ Noskills/**edit rides this PR.serve.tsstays as written.Retitled to the true defect.
pm:retriageleaves, and #23649 carries thedatasourceMappingsplit brain.[-]runtime: a host config's declared default datasource (autoConnect) never serves a production serve's boot — AppPlugin.start connects config datasources after AuthPlugin.start already needed a driver for sys_organization[/-][+]spec: the stack's `datasources` accepts a datasource named `default`, which every boot refuses as host-reserved — `defineStack` / `os validate` / publish pass a config that boots in no posture[/+]objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 7 (second shift, parallel again) · 2026-10-15T22:11Z · triage's proxy ruling A (
6189356908): the stack'sdatasourcescollection refuses a datasource nameddefault, which every boot refuses as host-reserved. SodefineStack,os validateand publish say the runtime's sentence and remedy at authoring time. One PR,Fixes #23634.Session:
session_01LFqdRsuM5nkqoJdHd5ztVk(the seat; the dev is a cloud session whose draft PR carries its own session link)Account:
os-bill(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23634-stack-datasource-default-refusedWorktree:
objectstack-issue-23634Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface (at
origin/main9bb93706for later; stop on a breach and explain it in the report):packages/spec/src/stack.zod.ts: thedatasourcescollection only, with the refusal and its remedy (setOS_DATABASE_URL, or declare the datasource under another name and route objects to it).packages/spectest fordefineStack, plus theos validatepin where the CLI's validate pins live. The ruling's two CONTROLS go beside them: a datasource namedfx_primarypasses, and the host's owndefaultrow still parses throughDatasourceSchema..changeset/23634-*.md.packages/spec/src/data/datasource.zod.ts(DatasourceSchemadocuments the host's owndefaultrow). ⛔ Notpackages/cli/src/commands/serve.ts: PR fix(cli): a production serve with no storage says so before any plugin starts, and refuses when its auth service needs a driver #23631's remedy line stays as written. ⛔ Notskills/**: ifskills/objectstack-data/rules/datasources.mdinvites declaringdefault, the report gives the line and the rewording, for the skills lane.Container & model:
M,mode:cloud,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate"). Cloud by the seat's interim rule ([Decision] Three spec contract dev agents in one container queued ~70 min each on the shared verify lock: leave packagetest:repoto CI, and send build-heavy cards to cloud sessions? #23607):packages/specplus the CLI's validate pins is a build-heavy closure. Review ceilingCONTRACT_REVIEW_TIER, reason:packages/spec's published accept set narrows.Clause-②: no
Responsibility:
packages/spec's stack schema accepts a datasource nameddefaultthatAppPlugin.start()refuses at every boot as host-reserved | none:os validatepasses it (V1, report6189075724); the refusal arrives only at boot | an author, human or AI, who declares adefaultdatasource in a stack; no in-repo producer was found, and the one instance is an agent-written fixtureThread-read: 6189356908
Ruling-ref: 6189356908 (triage's proxy ruling A,
auto-adjudicated; not a decision card)Serial constraints cleared:
batch 3in this seat's session. In flight from this seat: spec:PageTypeSchemasayshomeis "the platform-level landing page" andutilitya "floating utility panel", but the landing is the first navigation item and both types render as ordinary inline pages #23610's objectui half (cloud) and spec(conversions): eight ADR-0087 D2 conversions stay on the 18 load path after #23487 — five families each need a ruling before they can retire #23543 F3, dispatched in the same act on a disjoint surface (flow nodes and conversions).stack.zod.ts,datasource.zod.tsor the CLI's validate. PR feat(spec)!: a page declares nothing the console does not honour — isDefault only on a bound record page, a closed template set, regions its template places #23708 holds the ui generated shards only. Draft PR feat(lint)!: the two page component rules run on the runtime publish door (ruling B) #23418 editsregistry.ts.template: if this PR adds a migration entry, the later lander mergesmainand regenerates throughscripts/pm/os-regen-merge.sh.objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23634,
"status": "done",
"branch": "claude/issue-23634-stack-datasource-default-refused",
"pr": "#23757",
"session": "session_01UvyD7nLUx7XGKKQVF37FY9",
"premise_still_valid": true,
"summary": "Ruling A is implemented. The stack's
datasourcescollection (STACK_DEFINITION_COLLECTIONS_SHAPE in packages/spec/src/stack.zod.ts) carries a superRefine that refuses an entry named exactlydefault, at datasources.N.name with code custom. The text carries the runtime's sentence ("declares a datasource named 'default' — that name is reserved for the host's primary datasource") and the ruling's remedy (set OS_DATABASE_URL and omit the entry, or declare it under another name and route objects to it). DatasourceSchema, serve.ts and skills/** are untouched. defineStack (array and map form), the bare ObjectStackDefinitionSchema parse (the os validate door) and os validate --json are pinned, beside both CONTROLs (fx_primary passes; the host's owndefaultrow parses through DatasourceSchema). There is a D3 semantic entrystack-datasource-host-reserved-name-refusedand a BREAKING-minor changeset with theregistereddisposition. The dropped-refinements ledger gains the 4 installed-package manifest.datasources sites (759 to 763), because the build requires it. The PM hypotheses were measured as follows. H1: the three sentences (app-plugin.ts, datasource-admin-service.ts, spec) are synonymous, not shared; reuse needs a runtime edit, so it is reported, not done. H2: the runtime comparesname === 'default', the spec side copies that comparison, and every other spelling is already refused by DatasourceSchema.name's pattern (pinned). H3: re-measured; the R4 shape exits 1 with AppPlugin's refusal under OS_DATABASE_URL and under --dev, so no config that boots today is newly refused. H4: the gate output decided the disposition (adr-0087 registration green withregistered). H5: the skills line is in open_questions.","tests": "Head a6f3e6e (branch merged with origin/main a869ea6 via scripts/pm/os-regen-merge.sh). spec: build exit 0; check:generated: all 14 up to date; src/stack-datasource-host-reserved-name.test.ts + scripts/dropped-refinements.test.ts + src/migrations/migrations.test.ts 212/212; full
pnpm --filter @objectstack/spec test(pre-merge, at 65b8573+) 679 files passed and 1 red (the ledger header total droppedRefinementSites), fixed in 109c9e9 and then 27/27; typecheck exit 0. cli: the door pin test/stack-datasource-default-validate-door.test.ts (integration) 2/2 on the merge head;vitest run --project unit293/295 files at first, and the 2 reds were 'packages/cli is not built' (published-subpath-console/hook-body pins); afterpnpm --filter @objectstack/cli buildthey were 29/29; typecheck exit 0. runtime: src/default-datasource-plugin.test.ts 12/12 (AppPlugin's own refusal pin, unchanged). Ablation, valid leg (ablate3): the refusal body was replaced byif ((globalThis as any).__ablation23634 === undefined) return;via scripts/ablation-replace.mjs (marker count 0 to 1); spec build exit 0; ablation-dist-preflight planted: marker in 12 dist files, exit 0; spec pins 4 failed / 3 passed (4 refusals red, 3 controls green); CLI door 1 failed / 1 passed. Restore: git diff HEAD empty, hash equal to the HEAD blob, rebuild exit 0, preflight --absent clean in 232 files, spec 7/7, CLI 2/2. Two earlier legs were no-ops and are not counted. Leg 1 deleted the .superRefine, and the mutated build failed on the dropped-refinements ledger, so dist stayed unmutated (preflight --absent exit 1); the spec leg read src and went red, the CLI leg stayed green and is void. Leg 2 used a string-literal guard, which tsup constant-folded out of dist (preflight planted exit 1). Boot re-measure (H3, source CLI bin/run-dev.js serve, host config with datasources [{name:'default', driver:'sqlite'}] through defineStack strict:false): OS_DATABASE_URL=file:... exit 1 and --dev exit 1, both with[AppPlugin] app 'com.example.fx' declares a datasource named 'default' — that name is reserved for the host's primary datasource. ...","gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no path): 90 families for 6 paths. Each was run one by one with the exit code captured before any pipe. On a085cc9: 90 exit 0. First-run reds: check-plugin-teardown-shape --self-test exit 3 (shallow clone, pinned fixture commit 621a487 unreachable; it passed after a depth-1 fetch of that commit), check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: unbuilt sibling dists; exit 0 on rerun once built), and check:stack-collection-maps exit 1 (a real finding: a multi-line
z\\n.array(hid datasources from its census; fixed in a085cc9). Rerun on the merge head a6f3e6e: 90/90 exit 0. --ran withCMD :: exit Nlines: 'Run reconciliation — 90 derived, 90 run, 0 NOT-MEASURED, 0 UNRUN', a DERIVED zero. Also run: check:adr-0087-registration ✓ (registered stack-datasource-host-reserved-name-refused, new here), check:dev-prereqs exit 0 (local-only). CI check-runs on PR 23757: in_progress at report time, not awaited.","line_budget": "+352 / -2 over 6 files (dispatch-gates: 354 changed lines vs the 3000 human-merge threshold: under). stack.zod.ts +38/-1; spec pin 113; cli pin 133; D3 entry 30; changeset 32; ledger +5/-1.",
"files_changed": [
".changeset/23634-stack-datasource-default-refused.md",
"packages/cli/test/stack-datasource-default-validate-door.test.ts",
"packages/spec/dropped-refinements.baseline.json",
"packages/spec/src/migrations/entries/semantic/18.stack-datasource-host-reserved-name-refused.ts",
"packages/spec/src/stack-datasource-host-reserved-name.test.ts",
"packages/spec/src/stack.zod.ts"
],
"deviations": [
"packages/spec/dropped-refinements.baseline.json is outside the claim's named surface. The spec build refuses until the new refinement's 4 dropped sites (installed-package manifest.datasources) are recorded, and its header total moves 759 to 763. This is a gate-required artifact under the claim's 'generated outputs if the gates ask' clause, and it is hand-edited by that ledger's design. No arm of refinement-projection.ts fits, and adding one is a public-contract decision, so none was added.",
"The first commit cca45a7 (wip) carries no Claude-Session / Co-authored-by trailer pair; every later commit does. Pushed history was not rewritten.",
"The CLI unit tier needed a cli build that the dependency-closure build does not produce; 2 files were re-run after the build (see tests).",
"Merged origin/main (8 commits, including PR 23418's registry.ts.template edit) via os-regen-merge.sh after the gates had run, then re-ran build, check:generated, the pins and all 90 derived gates on the merge head. Package dists other than spec/cli were not rebuilt after the merge; CI builds fresh."
],
"mcp_calls": "4 — mcp__github__issue_read (get, get_comments on 23634), mcp__github__pull_request_read (get_files on 23331 for precedent; get on 23757 for the draft/assignee read-back). No write tools.",
"api_writes": "2 relay strokes as objectstack-fleet[bot]: (1) scripts/pm/fleet-write/dispatch.mjs pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/23757/assignees [os-bill], run 38828501816 success, body read back byte-identical (8158 bytes); (2) scripts/pm/post-stamped.mjs → POST /repos//issues/23634/comments (this os-dev-report). Plus git pushes of the branch (not REST). No label write (none named by the dispatch).",
"open_questions": [
{
"question": "skills/objectstack-data/rules/datasources.md:4-6 reads: 'Objects route to one via their
datasourcefield (default:'default'). Most apps need only thedefaultdatasource; declare more to read/write a separate or external database.' 'Declare more' impliesdefaultis declared too, so it invites the refused shape. Should the skills lane reword it?","options": [
"A: reword to 'Most apps need only the host's
defaultdatasource, which the host connects fromOS_DATABASE_URL; never declare a datasource nameddefault(the name is host-reserved and refused). Declare a datasource under its own name only to read/write a separate or external database.'","B: leave it; the authoring refusal now catches the shape at os validate"
],
"recommendation": "A. AI-proofing: the published skill is what an AI reads first, and the refusal should not be the first place it learns the rule. Long-term fit: the skill then states the contract the spec enforces. Startup focus: one line, net zero or less. Business need: the only measured producer of the shape was an agent."
},
{
"question": "The reserved-name refusal is now said in three places (runtime app-plugin.ts, the admin door datasource-admin-service.ts, spec stack.zod.ts): synonymous, not shared. Should spec export the reserved name and refusal text for the runtime to reuse?",
"options": [
"A: export the name constant and the sentence builder from @objectstack/spec, and have AppPlugin and the admin service import them (runtime + service-datasource edits, an api-surface addition)",
"B: keep three synonymous sentences, each owned by its door"
],
"recommendation": "A, as a follow-up in the runtime lane. Long-term fit: one source for one contract. AI-proofing: no drift between the doors. Startup focus: small, but it adds a public export, so it needs its own card and not this PR's surface."
}
],
"out_of_scope_findings": [
"carrier: none · noted, not filed: the published JSON Schema stays wider than the parse for this rule (it is recorded in the dropped-refinements ledger, like the 759 sites before it); closing it needs a new refinement-projection arm, which that module calls a public-contract decision"
]
}
objectstack-fleet commentedon Oct 16, 2026
Landing record, PR #23757 ·
domain:specseat 2 (#18549) · sessionsession_01LFqdRsuM5nkqoJdHd5ztVk· 2026-10-16T01:28Zorigin/main0a052e6705"feat(spec)!: a stack's datasources collection refuses a datasource named default, the host-reserved name (#23757)", merged through the queue at 2026-10-16T01:27Z (git branch -r --contains→origin/main)gh-readonly-queue/main/*ref names #23757aad16cefdc4cequalsgit merge-tree --write-treeof its parenteae3b389d2witha6f3e6e812. That head carries contract review PASS6205386930and ACCEPT6205431264.completedbyFixes #23634What ships. A stack's
datasourcescollection refuses an entry nameddefaultatdatasources.N.name, with the runtime's sentence and remedy (setOS_DATABASE_URL, or declare the datasource under another name and route objects to it). It reachesdefineStack,os validateand publish.DatasourceSchemaand the host's owndefaultrow are unchanged. The D3 entry isstack-datasource-host-reserved-name-refused.Follow-ups.
skills/objectstack-data/rules/datasources.md:4-6) is skills(objectstack-data):rules/datasources.mdreads as an invitation to declare a datasource nameddefault, which the stack now refuses as host-reserved #23768 (domain:skills, Tier H). ItsBlocked-by: #23757is now cleared.