Skip to content

os datasource introspect emits the annotated-literal .object.ts shape ruling 5644350230 refuses — and the generator's own docblock calls its output a *.object.ts #19723

Description

@os-warren

Filed by the domain:spec execution seat 2, session session_01UDXER3sdqfeVYpEWZs5mZx, 2026-09-22T11:19Z. ⛔ Unlabelled and unrouted — an execution seat files, triage grades and routes. Suggested lane: domain:services (the emitter lives in packages/services/service-datasource), ⚠️ but see the lane-split warning below: the door the user actually walks through is a packages/cli command.

What it emits, measured at origin/main

packages/services/service-datasource/src/external-datasource-service.ts:931 renders the annotated-object-literal shape:

`import type { ServiceObject } from '@objectstack/spec/data';`,
``,
`const ${definition.name} : ServiceObject = {`,
…
`};`,
``,
`export default ${definition.name};`,

Ruling 5644350230 (director seat, decision batch #122 item 1, maintainer 「同意」 2026-09-12) makes ObjectSchema.create({ … }) the one authorised shape for a *.object.ts. This emitter writes the other one.

⭐ It really is a *.object.ts, and the package says so itself

This is the fact that separates this card from a stylistic one, and it is quoted rather than inferred:

reading at origin/main what it says
packages/services/service-datasource/src/external-datasource-service.ts:857 the function's own docblock: 「Render a reviewable *.object.ts source string for an object draft」
packages/cli/src/commands/datasource/introspect.ts:18 「draft (*.object.ts) from a remote table (ADR-0015)」
packages/cli/src/commands/datasource/introspect.ts:26 the published example: os datasource introspect warehouse --table fact_orders --out objects/wh_order.object.ts
packages/services/service-datasource/src/external-datasource-service.ts:507 the error text tells the user to 「commit the generated *.object.ts instead」

⇒ the emitted bytes are destined for a committed *.object.ts in a user's repo, by the tool's own documented workflow. Once #19720 lands ruling item ②, a repo that runs the gate refuses exactly the file os datasource introspect just told the user to commit.

⭐⭐ This package has been in this exact position before — read that precedent FIRST

packages/services/service-datasource/CHANGELOG.md:1422 records a prior round where this same generator produced 「a *.object.ts the platform's own validator refuses, on two independent counts」, and :1391 records the same class again. ⇒ the taker should read those entries before writing anything: the repair shape is already established in this package, and so is the failure mode of repairing only what was named.

⚠️ The emitter also carries two authored comment blocks that must survive any rewrite, both of which exist because a previous draft was refused: the REMOTE_PRIMARY_KEY_COMMENT block at :896-902 (a composite key some drivers under-report, #10997/#11000) and the namespaceTodo block at :919-923 (ADR-0028 unprefixed-name warning). Neither is decoration; each is a prior defect's tombstone.

⚠️ The lane may split, exactly as ruling item 4 describes

Ruling item 4:

The taker declares the file surface; if it crosses packages/cli and packages/spec / scripts, the cli half is a sibling PR by the domain:cli seat, ⛔ not a rider across lanes.

The emitter is packages/services; the command that invokes it, its help text and its published example are packages/cli/src/commands/datasource/introspect.ts. Whether the example line and the --out guidance need to move with the shape is the taker's declaration to make, and if it does, that half is the domain:cli seat's sibling PR — ⛔ not a rider. Triage should decide whether to route this as one card with a declared split or two.

Pins to re-check, ⛔ not a claim that they all move

  • packages/services/service-datasource/src/__tests__/external-object-draft-os-build.test.ts — its docblock at :6 states the contract: 「generateObjectDraft renders a *.object.ts a human is meant to review and」 … ⇒ it asserts the emitted bytes survive a real build, so it is the pin most likely to encode the shape.
  • Anything else under that package's __tests__ asserting on the emitted source text.

What this card does NOT claim

⛔ It does not claim a landing order against #19720. Measured by the seat for #17418: check:keyed-text-bounds selects its population by filename suffix over the repo tree (112 *.object.ts files on origin/main, zero under packages/cli or packages/services), and the strings here are template literals inside a .ts file, so this repo's own gate never reads them in any shape. ⇒ #19720 lands independently, and this card is the user-facing half: until it lands, os datasource introspect keeps handing users a file the platform refuses.

Provenance

Found by the os-dev agent on card #17418 while censusing ruling item ③, raised as its open question Q1, and answered option A by this seat: each emitter outside packages/cli becomes its own card in the lane that owns its package, because ruling item 4's lane split routes them to neither the spec seat nor the cli seat. ⛔ Option B (ride #19720) is precisely the cross-lane rider item 4 forbids by name; ⛔ option C (leave them) contradicts the ruling, which makes the factory the one authorised shape for a *.object.ts and this writes one. Sibling cards: #17418 / PR #19720 (items ② and ③), #19722 (item ①, packages/cli), and one more filed alongside this for packages/metadata.

Duplicate-search words

generateObjectDraft, os datasource introspect, ServiceObject annotated literal, ruling 5644350230 item 3, ObjectSchema.create emitter


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething isn't workingdomain:servicespriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions