From 78f711b9e6d69c29c8d10446a7125172550b0374 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 18:04:08 +0000 Subject: [PATCH 1/2] docs(spec): Rule #3 of implement-objectos names real @objectstack/spec exports RequestEnvelope and ResponseEnvelope are named in prose but neither is an export of the package. Rule #3 now names the real validation surface. --- packages/spec/prompts/implement-objectos.md | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/spec/prompts/implement-objectos.md b/packages/spec/prompts/implement-objectos.md index 7790bf2679..2f7502f3ef 100644 --- a/packages/spec/prompts/implement-objectos.md +++ b/packages/spec/prompts/implement-objectos.md @@ -38,8 +38,30 @@ in the qualified schemas (`TenantSecurityPolicySchema`, `PermissionSetSchema`). ### Rule #3: API Gateway Contract The HTTP/Gateway layer must perform strict request/response validation using `api/contract.zod.ts` and `api/endpoint.zod.ts`. -- Incoming requests -> Validate `RequestEnvelope` -- Outgoing responses -> Wrap in `ResponseEnvelope` +- **Incoming requests** -> validate the body against the schema the operation + declares. There is no single request envelope, by design: `StandardApiContracts` + maps each standard operation to its `input` — `create` to `CreateRequestSchema`, + `update` to `UpdateRequestSchema`, `get` and `delete` to `IdRequestSchema`, the + `bulk*` family to `BulkRequestSchema`, `list` to `QuerySchema` (that one from + `@objectstack/spec/data`). The route's own shape — method, path, mappings — is + `ApiEndpointSchema` in `api/endpoint.zod.ts`. +- **Outgoing responses** -> emit the one declared envelope. `BaseResponseSchema` + is its skeleton (`success`, `error`, `meta`); each response type adds its own + `data` on top of it — `SingleRecordResponseSchema`, `ListRecordResponseSchema`, + `BulkResponseSchema`, `DeleteResponseSchema` — and `StandardApiContracts` names + the `output` for the operation you served. +```typescript +import { + StandardApiContracts, + BaseResponseSchema, + envelopeViolations, +} from '@objectstack/spec/api'; +``` +`BaseResponseSchema.safeParse` alone does NOT prove a body is envelope-conformant: +it is a plain object schema, so it strips unknown keys, and it accepts +`{ success: true }` carrying no payload at all. Gate what you emit with +`envelopeViolations(body)` — it returns every way the body departs from the +declared envelope, and an empty array means conformant. ### Rule #4: Event Driven Architecture System state changes (User created, Schema changed) MUST emit events defined in `EventSchema`. From 26b33cfc90feb87e3272a0de917b4fb125b2b950 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 18:18:29 +0000 Subject: [PATCH 2/2] chore(changeset): patch for the Rule #3 prose fix --- .../implement-objectos-rule3-real-exports.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .changeset/implement-objectos-rule3-real-exports.md diff --git a/.changeset/implement-objectos-rule3-real-exports.md b/.changeset/implement-objectos-rule3-real-exports.md new file mode 100644 index 0000000000..4b7ce749e1 --- /dev/null +++ b/.changeset/implement-objectos-rule3-real-exports.md @@ -0,0 +1,33 @@ +--- +"@objectstack/spec": patch +--- + +docs(spec): `implement-objectos.md` Rule #3 names real exports instead of `RequestEnvelope` / `ResponseEnvelope` (#9614) + +The published runtime-kernel prompt told an implementing agent to "validate +`RequestEnvelope`" and "wrap in `ResponseEnvelope`". Neither has ever been an +export of `@objectstack/spec` — measured across all 16 published +`api-surface/*.json` entries — and `ResponseEnvelopeConfig*` is a config shape, +not the envelope, so it was not a drop-in referent. + +Rule #3 now describes the validation surface the package actually has: + +- **Requests**: there is no single request envelope by design. + `StandardApiContracts` maps each standard operation to its `input` + (`CreateRequestSchema`, `UpdateRequestSchema`, `IdRequestSchema`, + `BulkRequestSchema`, and `QuerySchema` for `list`), and `ApiEndpointSchema` + carries the route's own shape — which is what makes `api/endpoint.zod.ts`, a + file the rule already cited, actually reachable from it. +- **Responses**: `BaseResponseSchema` is the envelope skeleton that each + response type extends with its own `data`, and the rule now carries the + warning the schema's own docstring makes: `safeParse` alone does not prove + conformance, because the schema strips unknown keys and accepts a payloadless + `{ success: true }`. `envelopeViolations(body)` is the conformance check. + +The referents also move from prose into a fenced `import`, so +`check:published-readme-exports` resolves them from now on — the blind spot that +let the two fabricated names ship (prose symbols match neither an import clause +nor a member call site) no longer covers this rule. + +No schema, no runtime behaviour and no authorable surface changes; the published +prompt text does.