Ruled: 5644350230 · letter A · 2026-09-12T07:02Z — director seat, decision batch #122 item 1, maintainer 「同意」.
Items ② and ③ LANDED on main in PR #19720 (merge commit 42339e2f48, one parent, 2026-09-22T13:07Z); ⛔ this card stays open because the body opens 「Part of」, so item ① keeps a carrier.
Blocked-by: #19722
⛔ Item ① (packages/cli/src/commands/init.ts TEMPLATES + content/docs/deployment/cli.mdx:1323, and generate.ts which the ruling under-names) is the cli half, and ruling item 4 makes it a sibling PR by the domain:cli seat, ⛔ not a rider across lanes. ⇒ nothing here is dispatchable by the domain:spec seat until #19722 lands.
Filed by the #16195 implementer, per that card's instruction to file this finding (unlabelled, for triage) if the "is the factory shape this repo's settled authorised shape" question could be read clearly while doing that card. It could not be resolved outright, but concrete published evidence on both sides was found, which is what follows.
Measured on origin/main d57611dfd3
The gate only reads the factory shape. check:keyed-text-bounds recognises ObjectSchema.create({ … }) (CREATE_CALL regex in scripts/check-keyed-text-bounds.mjs) — every one of the 112 *.object.ts files it currently parses is that shape.
os init's own emitter writes the other shape, a plain annotated object literal — documented explicitly in content/docs/deployment/cli.mdx:1323: "Creates a typed TypeScript file using Data.ServiceObject, UI.View, Automation.Flow, etc." Confirmed live by generating a template (TEMPLATES in packages/cli/src/commands/init.ts):
import * as Data from '@objectstack/spec/data';
const myAppItem: Data.ServiceObject = {
name: 'my_app_item',
fields: { … },
sharingModel: 'private',
};
export default myAppItem;
Evidence gathered this round, both directions
For the factory shape as "the" pattern:
content/docs/data-modeling/schema-design.mdx:11-19 — published, user-facing: "Every object definition follows this pattern:" followed by an ObjectSchema.create({…}) example. Not phrased as "one option" — phrased as the pattern.
packages/create-objectstack's own bundled template (packages/create-objectstack/src/templates/blank/src/objects/note.object.ts) — a second, independent official scaffolder (npx create-objectstack, the standalone entry point) — also emits the factory shape.
- Every ADR code example found this round that shows an object declaration (
docs/adr/0007, 0066, 0100, 0103) uses the factory shape.
For the literal shape as intentional, not accidental:
content/docs/deployment/cli.mdx:1323 documents os init/os g emitting the Data.*-typed literal as the described, current behaviour of a still-maintained, still-documented command — not flagged anywhere as deprecated or as a shape migration in progress.
packages/cli/src/commands/init.ts's TEMPLATES is actively synced for version-policy correctness (scripts/sync-scaffold-emission-policy.mjs, which keeps create-objectstack's bundled template's pnpm/typescript ranges in lockstep with it) — i.e. it is treated as a maintained source of truth for scaffolding, not legacy code nobody touches.
What was not found
No ADR, ledger, or ruling comment titled or framed as "which shape may a .object.ts declaration take" — nothing that resolves the disagreement one way or the other. The evidence above shows the disagreement is real, documented on both sides, and not a one-file fluke — not which side should win.
Why this deserves its own answer (from #16195, adopted here)
The second is not merely a cleanup: it would mean the repo's own gate and the repo's own scaffolder currently disagree about how an object file may be written, which is a question worth answering deliberately rather than as a side effect.
Two live resolutions, at least:
- teach
check:keyed-text-bounds (and any other .object.ts-shape-sensitive tooling) the plain-literal declaration shape, so a scaffolded object file is judged rather than refused; or
- change
os init's emitter (TEMPLATES / writeTemplateSrcFiles) to emit the factory shape, matching create-objectstack, schema-design.mdx, and every gate-readable example in the tree.
Neither is this card's to choose. Not scoped further — routing and domain assignment are triage's.
Generated by Claude Code
Ruled: 5644350230 · letter A · 2026-09-12T07:02Z — director seat, decision batch #122 item 1, maintainer 「同意」.
Items ② and ③ LANDED on
mainin PR #19720 (merge commit42339e2f48, one parent, 2026-09-22T13:07Z); ⛔ this card stays open because the body opens 「Part of」, so item ① keeps a carrier.Blocked-by: #19722
⛔ Item ① (
packages/cli/src/commands/init.tsTEMPLATES+content/docs/deployment/cli.mdx:1323, andgenerate.tswhich the ruling under-names) is the cli half, and ruling item 4 makes it a sibling PR by thedomain:cliseat, ⛔ not a rider across lanes. ⇒ nothing here is dispatchable by thedomain:specseat until #19722 lands.Filed by the #16195 implementer, per that card's instruction to file this finding (unlabelled, for triage) if the "is the factory shape this repo's settled authorised shape" question could be read clearly while doing that card. It could not be resolved outright, but concrete published evidence on both sides was found, which is what follows.
Measured on
origin/maind57611dfd3The gate only reads the factory shape.
check:keyed-text-boundsrecognisesObjectSchema.create({ … })(CREATE_CALLregex inscripts/check-keyed-text-bounds.mjs) — every one of the 112*.object.tsfiles it currently parses is that shape.os init's own emitter writes the other shape, a plain annotated object literal — documented explicitly incontent/docs/deployment/cli.mdx:1323: "Creates a typed TypeScript file usingData.ServiceObject,UI.View,Automation.Flow, etc." Confirmed live by generating a template (TEMPLATESinpackages/cli/src/commands/init.ts):Evidence gathered this round, both directions
For the factory shape as "the" pattern:
content/docs/data-modeling/schema-design.mdx:11-19— published, user-facing: "Every object definition follows this pattern:" followed by anObjectSchema.create({…})example. Not phrased as "one option" — phrased as the pattern.packages/create-objectstack's own bundled template (packages/create-objectstack/src/templates/blank/src/objects/note.object.ts) — a second, independent official scaffolder (npx create-objectstack, the standalone entry point) — also emits the factory shape.docs/adr/0007,0066,0100,0103) uses the factory shape.For the literal shape as intentional, not accidental:
content/docs/deployment/cli.mdx:1323documentsos init/os gemitting theData.*-typed literal as the described, current behaviour of a still-maintained, still-documented command — not flagged anywhere as deprecated or as a shape migration in progress.packages/cli/src/commands/init.ts'sTEMPLATESis actively synced for version-policy correctness (scripts/sync-scaffold-emission-policy.mjs, which keepscreate-objectstack's bundled template'spnpm/typescriptranges in lockstep with it) — i.e. it is treated as a maintained source of truth for scaffolding, not legacy code nobody touches.What was not found
No ADR, ledger, or ruling comment titled or framed as "which shape may a
.object.tsdeclaration take" — nothing that resolves the disagreement one way or the other. The evidence above shows the disagreement is real, documented on both sides, and not a one-file fluke — not which side should win.Why this deserves its own answer (from #16195, adopted here)
Two live resolutions, at least:
check:keyed-text-bounds(and any other.object.ts-shape-sensitive tooling) the plain-literal declaration shape, so a scaffolded object file is judged rather than refused; oros init's emitter (TEMPLATES/writeTemplateSrcFiles) to emit the factory shape, matchingcreate-objectstack,schema-design.mdx, and every gate-readable example in the tree.Neither is this card's to choose. Not scoped further — routing and domain assignment are triage's.
Generated by Claude Code