An operation does not carry a return shape on its own — a client can only derive one for the rows an
operation reads back if that operation declares a projection. Without one, the generator in
packages/ecosy-sapedb falls back to row: Record<string, unknown>, honestly
labelled rather than guessed at.
fixtures/ledger.schema.json is the project's own worked fixture, and it declares five
operations — orders.place, orders.pay, orders.get,
payments.of_order, entries.of_account. None of the five declares a
projection. The two writes (orders.place, orders.pay)
correctly have no row to project — an insert and a batch answer with key,
changed and count, not rows. The other three all read
(get, scan, scan) and all three are the operations where a
projection would matter, and all three skip it.
grep -c '"projection"' fixtures/ledger.schema.json in
packages/ecosy-sapedb returns 0, against 23 occurrences of
"name" in the same file — the field exists as a naming convention throughout the schema,
projection is simply never one of the keys used.tests/typecheck/ledger.d.ts is generated from that fixture and shows the consequence
directly, for each of the three reads: row: Record<string, unknown>, with
"The schema does not describe documents, so the shape of this row is genuinely not known here."
— the generator's own comment, reproduced verbatim in the output every time this path is taken.projection is a real, wired field, not a documented-but-unbuilt one:
grep -rl projection under packages/ecosy-sapedb (excluding
node_modules) matches src/types/index.ts, src/commander/index.ts
and src/client/index.ts, plus their compiled dist/ counterparts. The fixture
not using it is a choice made in the fixture, not a missing capability.Does it lose data, break a promise on a public surface, or stop somebody installing and running? No. The fixture works exactly as documented — untyped rows are a real, supported answer, not a defect in the protocol. What is wrong is pedagogical: the one example most client authors will copy demonstrates the path SAPE-13's shape rule warns against, at every read operation it has.
Defer. Fixing it means changing the shape of a published example fixture — deciding
what each of the three reads' documents actually look like and writing three projections
that are honest about them — which is example content, not a protocol change, and nothing currently
depends on the fixture staying untyped.
projection blocks added to one JSON
file, and the generated .d.ts follows automatically. No wire format changes, no client
changes, no migration.