Skip to content

TypeScriptSerializer emits an annotated object literal although packages/metadata's own README says it is for ObjectSchema.create() #19724

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:engine (packages/metadata* is that lane's by the domain table).

⭐ The package's own README already states the contract this code breaks

This is the strongest reading on the card, and it is a declared ≠ enforced finding that stands whether or not ruling 5644350230 reaches this site. Both lines at origin/main:

reading text
packages/metadata/README.md:77 TypeScriptSerializer.ts/.js module exports (for ObjectSchema.create(), defineView(), etc.)」
packages/metadata/src/serializers/typescript-serializer.ts:22-24 emits import type { ServiceObject } from '@objectstack/spec/data'; then export const metadata: ServiceObject = ${jsonStr}; then export default metadata;

⇒ the README says this serializer exists for the factory shape. It emits the annotated object literal instead, and it has never emitted a create() call. Nothing in the package reconciles the two.

Ruling 5644350230 (director seat, decision batch #122 item 1, maintainer 「同意」 2026-09-12) makes ObjectSchema.create({ … }) the one authorised shape for a *.object.ts, so the ruling and the README point the same way.

⛔ The sequencing question the taker must settle FIRST — the seat did NOT measure this

NOT MEASURED by this seat: whether TypeScriptSerializer's output ever lands in a file named *.object.ts. The seat traced the registration (metadata-manager.ts:572/:575 bind it under the typescript and javascript formats; index.ts:53 re-exports it, so it is also public API of a published package) but found no filename or write path in metadata-manager.ts — no writeFile, no extension ledger entry tying this serializer's output to a name. ⛔ That absence is a reading with an unstated reach, not a finding.

⇒ the taker answers this before writing code, because it decides the card's own scope:

  • Does any caller write this serializer's output to a *.object.ts? If yes, the ruling reaches it directly and the conversion is mandatory.
  • If no, the ruling does not reach it — but the README contradiction above still does, and the fix is then either the emitter or the README line, ⛔ not silence. Say which, with the reading.

⚠️ A third possibility the taker should not skip past: serialize<T> annotates every item as ServiceObject regardless of the metadata kind it was handed, so a serialized view or sharing rule is emitted carrying an object's type annotation. Whether that is in scope here or its own card is triage's call — ⛔ this card does not widen itself to claim it.

⭐ The round-trip coupling — deserialize reads back what serialize writes

typescript-serializer.ts:31-56 parses by finding export const (or export default), then the first { after it, then brace-matching with a hand-rolled string-literal tracker. Under the current shape that brace is the literal's own opening brace.

⚠️ Under ObjectSchema.create({ … }) the first { after export const is still the literal's opening brace — so the scan probably does not throw, and that is the hazard, not the safety: it would silently return the inner literal and drop the factory wrapper on every round trip. ⇒ a conversion that changes only serialize must be tested through deserialize, and the error text at :45-48 (which names the two accepted export patterns verbatim) re-read against whatever shape ships. ⛔ Do not assume the parser is shape-agnostic because it does not crash.

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. Sibling cards: #17418 / PR #19720 (items ② and ③), #19722 (item ①, packages/cli), and one filed alongside this for packages/services/service-datasource.

⛔ No landing-order dependency on #19720: check:keyed-text-bounds selects by filename suffix over this repo's tree (112 *.object.ts on origin/main, zero under packages/metadata), and these are template literals inside a .ts file, so this repo's gate never reads them in any shape.

Duplicate-search words

TypeScriptSerializer, metadata serializer ServiceObject, serialize deserialize round trip, 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

No one assigned

    Labels

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:enginepm:queuepriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions