Skip to content

Commit 6cc8dcd

Browse files
docs(spec): record that the record-stage manifest type is deliberately an index signature, and the runtime schema is the contract (#20191)
Fixes #19324 Clause-②: no Ruling-ref: 5805795339 (batch #218 item 4, letter 丙). This PR carries out ruling item 1. It adds one docblock on `RecordStagePackageBodySchema`, at its `ZodRawShape` cast, and one beside `AssembledInstalledPackageSchema.manifest`. Both record the four points the ruling names. ⛔ No type change, ⛔ no schema change. Ruling item 2 holds: the client gap pin stays, and only its comment text moves. Per ruling item 3, the card is done when this lands. ## What changed - **`packages/spec/src/stack.zod.ts`, `RecordStagePackageBodySchema`** - Its published docblock gains a section, "Its published type is deliberately an index signature", which carries all four points. - The internal note above the declaration now says what the `as unknown as z.ZodObject(z.ZodRawShape)` cast costs, and that the cast emits nothing. - **`packages/spec/src/api/package-api-assembled.zod.ts`, `AssembledInstalledPackageSchema`** - The docblock ends with a new section, "`manifest`'s published type is deliberately an index signature", directly above the `manifest` line. It replaces the old one-paragraph pointer. - Since `c23cfb346a` the assembled declarations live in this file, not in `package-api.zod.ts`. - **`packages/client/src/return-type-precision.test.ts`** - The two comments that cited `packages/spec/src/stack.zod.ts:1283` now cite `RecordStagePackageBodySchema` by name. - They no longer say the gap is this card's to close: it is the accepted static contract, and the pin reddens the day the body is typed precisely. - Comment text only. No assertion, no `@ts-expect-error` and no binding moved. - **`packages/client/src/index.ts`, `ObjectStackClient.packages.list`** (patch round 2, `a2be2ff440`) - The TSDoc paragraph that called the asymmetry "a KNOWN GAP rather than a design", tracked on #19324 and citing `stack.zod.ts:1283`, is rewritten to the settled reading. The index signature is the accepted static contract (letter 丙), the runtime Zod schema is the enforced one so a row is narrowed by parsing, and A2 is recorded beside `RecordStagePackageBodySchema`. - Comment text only: every changed line of the file is a docblock line. Nothing in the `automation` namespace is touched. - **`.changeset/19324-record-stage-index-signature-docblock.md`**: `@objectstack/spec` patch and `@objectstack/client` patch (`b9b0d32d2f`). ## Which of the four points were already there Read at `3bd28e2b2e`, before the edit. | Ruling item 1 point | `RecordStagePackageBodySchema` | `AssembledInstalledPackageSchema` | |---|---|---| | ① the published type is deliberately an index signature | Partial. Only an internal "ANNOTATED structurally" comment, which the published `.d.ts` drops, pointing up the file. | Partial. "The body half is deliberately typed Record(string, unknown)". No consequence stated, and not called the accepted contract. | | ② the runtime Zod schema is the enforced contract | Absent at this site. It was said only in `AssembledPackageBodySchema`'s internal note. | Present in substance: "a wrong-shaped body is refused exactly as it is there". Kept, restated in the new section. | | ③ why (TS7056 / #14513) | Pointer only, in the unpublished comment. | Pointer only, and it named `AssembledPackageBodySchema` rather than the schema `manifest` is built from. | | ④ A2 is the precise form | Absent | Absent | ## Premise re-measured against the BUILT declarations Spec built at `3bd28e2b2e` (lock verdict `command-exit 0`). - `dist/api-assembled/index.d.ts` and `.d.mts` declare `manifest` as `z.ZodType` of Record(string, unknown) on both sides. - `dist/index.d.ts` and `.d.mts` declare `RecordStagePackageBodySchema` the same way, at line 23236. - A probe program ran tsc 6.0.3 (strict, NodeNext) through the package `exports`. `--listFiles` shows 9 spec `dist` files and 0 spec `src` files. - **Readings, exit 0 (all five compile):** - R1: `InstalledPackage` assigns to `AssembledInstalledPackage`. - R2: the whole union assigns to the assembled arm. - R3: any object assigns to the manifest. - R4: `string extends keyof` the manifest (an index signature). - R5: a `{ bogus: 1, objects: 'not-an-array' }` manifest compiles against the union. - **Lit controls, exit 2, TS2322 twice:** the reverse assignment, and a string manifest. - **Runtime control:** `InstalledPackageAtEitherStageSchema.safeParse` answers true for a valid authoring row, and false for the bogus row, both on the union and on the assembled arm. - The same readings hold at head `17f1e3d41c` after the edit, so the types did not move. ## The TS7056 reading behind the "why", re-measured after the split M1 is the decision round's reading at `d1ca8741dd`. This PR re-ran it at `3bd28e2b2e`. - **Mutation:** drop the artifact and record stages' structural annotations and the `ZodRawShape` cast. - **Result:** spec build exit 1 with exactly one error, `src/api/package-api-assembled.zod.ts(222,14): error TS7056`. Line 222 is `PackageApiContracts`. - **How:** through `scripts/ablation-replace.mjs`, with each anchor hitting 1 then 0, and blob `3c09282f16` → `ac2e5f6b0b` → `7823e5e634`. - **Restore proven:** blob == HEAD `3c09282f16`, `git diff HEAD` empty, `git status --porcelain` empty. The #14513 history was read from commit `7085f90531`. It covers TS7056 on the inferred type, and a named alias that turned `stack.zod` into a shared chunk. That chunk added 42,622 definition lines to the `qa/http-conformance` type-check program and pushed it past the then 4096 MB ceiling. The docblock says plainly that the named-alias reading is inherited for the record stage and was not re-measured. A2's cost is quoted with its commit (`d1ca8741dd`), as is the fact that it was not measured on the http-conformance program. ## One bounded fix in the same docblock The `AssembledInstalledPackageSchema` docblock said the assembled stage was "built from `AssembledPackageBodySchema`". That has been false since #19373. The row's `manifest` is `RecordStagePackageBodySchema`, which extends the artifact stage, and the artifact stage is `ManifestSchema.extend({ ...assembledPackageBodyShape(), … })`. It now reads "built from the same body shape as `AssembledPackageBodySchema` … at the record stage the next section describes". This was the decision round's own carrier note (comment 5800545221), and it names this PR. Same docblock, same class (the text beside `manifest` misdescribing its declaration), inside the claimed file surface, with no new gate. ## Changeset, not `skip-changeset`: the edit ships Measured on the rebuilt `dist` at `17f1e3d41c`: | probe | files | |---|---| | new `RecordStagePackageBodySchema` section heading | `dist/index.d.ts`, `dist/index.d.mts` | | new `AssembledInstalledPackageSchema` section heading | `dist/api-assembled/index.d.ts`, `dist/api-assembled/index.d.mts` | | lit control: an existing line of the `RecordStagePackageBodySchema` docblock | the same 2 files | | the replaced site-2 sentence | 0 | | the internal cast note (not TSDoc) | 0, dropped from `dist` as expected | Both edited files also ship as source, because `@objectstack/spec`'s `files[]` carries `src/**/*.zod.ts`. So the edit is published and takes a `patch` changeset, carrying `Clause-②: no`. `packages/client` publishes only `dist`, `README.md` and `CHANGELOG.md`, so its test-file comment ships nothing. The `packages.list` paragraph does ship: measured on the rebuilt client `dist` at `b9b0d32d2f`, the new phrase is in `index.d.ts`, `index.d.mts`, `index.js` and `index.mjs`. 'Tracked as #19324' and `stack.zod.ts:1283` are in 0 files, and the lit control, the unchanged `Array.isArray` warning, is in the same 4 files. So the changeset also carries `@objectstack/client`: patch (`b9b0d32d2f`). ## Verification The head is `b9b0d32d2f`. `packages/spec` did not move between `17f1e3d41c` and `b9b0d32d2f` (`git diff` on it is empty), so the spec readings below, taken at `17f1e3d41c`, hold at the head. The client and gate readings were re-taken at `b9b0d32d2f`. - **`@objectstack/spec` build:** exit 0. `pnpm --filter @objectstack/spec check:generated`: all 15 generated artifacts up to date. - **`@objectstack/spec` typecheck:** exit 0 (`tsc`, scripts and test layer). - **`@objectstack/spec` tests, targeted:** - 16 files / 613 tests in `--project local` and 7 files / 99 tests in `--project repo`, all passed. - The set: every test on the edited declarations (`package-api`, `stack-json-stage-package-body`, `assembled-package-body`, `api-entry-graph.pin`, `split-entries`), the tests that read `stack.zod.ts` as text, and every spec test that walks and reads source files. - ⊘ NOT MEASURED locally: the full spec suite. It passed the 560 s foreground ceiling with no verdict (exit 124). CI runs it. - **`@objectstack/client`** (at `b9b0d32d2f`): build exit 0 (`check-dts-emitted` 1/1). - typecheck exit 0, with `check:test-typecheck` OK at 0 files / 0 errors / 0 pinned. Its test program compiles `return-type-precision.test.ts` (`--listFiles`: 1 hit, against `spec/dist/api-assembled`). - tests: 50 files / 635 passed. - **Cross-package tests on the assembled row:** `runtime` `packages-read-delete-response-conformance` 17 passed, `objectql` `registry-package-manifest-serializable` 16 passed. - **`node scripts/pm/dispatch-gates.mjs --ran`** (re-derived and re-run at `b9b0d32d2f`; the new path added no family): 85 families derived. 83 run, every one exit 0. - ⊘ NOT MEASURED: `check:dual-build-cjs-loads`, which exits 3 until every workspace package is built. - ⊘ UNRUN: `check:type-check-debt`, which re-measures `tsc` per ledger entry over the whole built workspace. The only test-file edit is comment text, and the client test layer holds 0 errors. - CI runs both. - **ESLint, narrowed to the 4 changed `.ts` files** (at `b9b0d32d2f`): - Scope: `--print-config` applies 6 rules to `index.ts` and 5 to each of the other three. `--format json` reports 4 files, 0 errors, 0 warnings. - Why untouched files cannot change: `eslint.config.mjs` never enables type-aware linting (no `parserOptions.project`), so this diff cannot move the verdict on any other file. ## Acceptance notes - **`.changeset/17536-client-packages-read-doors-either-stage.md` still calls the gap "tracked as #19324" and cites `stack.zod.ts:1283`.** - It is a foreign changeset, and `check-empty-changeset` rule 2 forbids editing it. - This PR's changeset states the settled reading instead, for the same release text. - **Not merged with `main`.** `origin/main` is at `560b724c95`, 10 commits past the base, and none touches the five changed paths (empty `git diff --stat` on them). CI validates the merge ref. _Body corrected by `domain:spec` seat 2 after patch round 2 (`b9b0d32d2f`), from the dev's reported deviations: the client paragraph, the client changeset line, the stale Acceptance note removed, and the verification anchor._ --- _Generated by [Claude Code](https://claude.ai/code/session_01QcAS3qiYYZNezaxZxaUdMV)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0bd1126 commit 6cc8dcd

5 files changed

Lines changed: 127 additions & 29 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
'@objectstack/spec': patch
3+
'@objectstack/client': patch
4+
---
5+
6+
`RecordStagePackageBodySchema`, `AssembledInstalledPackageSchema` and `ObjectStackClient.packages.list` now say, in their published docblocks, that `manifest`'s static type is deliberately an index signature and that the runtime schema is the enforced contract (#19324)
7+
8+
Clause-②: no
9+
10+
`AssembledInstalledPackage['manifest']` is `RecordStagePackageBodySchema`, declared `z.ZodType<Record<string, unknown>, Record<string, unknown>>`. So its published type is an index signature: an authoring-stage `InstalledPackage` assigns to `AssembledInstalledPackage`, and a row whose `manifest` belongs to neither stage type-checks as an `InstalledPackageAtEitherStage`. The maintainer ruled that this is the accepted static contract (#19324, letter 丙). The three declarations now say so where a TypeScript reader meets them:
11+
12+
- **The runtime schema is the enforced contract.** `InstalledPackageAtEitherStageSchema.safeParse()` refuses a `manifest` that belongs to neither stage. Tell the two stages apart by parsing, never by the static type.
13+
- **Why the type is not inferred.** `tsc` refuses to print the whole metadata vocabulary into the declarations that embed it (TS7056). Dropping the record and artifact stages' annotations and the `ZodRawShape` cast fails the declaration build with TS7056 at `PackageApiContracts`. A named alias would turn `stack.zod` into a shared declaration chunk, the heap failure #14513 recorded.
14+
- **The precise form, if the schema depth ever allows it,** is the one #19324 measured as A2, with its cost recorded at `RecordStagePackageBodySchema`.
15+
16+
**`@objectstack/client`**: the `packages.list` TSDoc used to call this asymmetry "a KNOWN GAP rather than a design", tracked on #19324, and cited a `stack.zod.ts` line number. It now calls it the accepted static contract, cites `RecordStagePackageBodySchema` by name, and keeps its advice unchanged: narrow a row by parsing it with a `@objectstack/spec` schema, and never by `Array.isArray(pkg.manifest.objects)`.
17+
18+
This settles what the `@objectstack/client` read-door changeset (#17536) calls "a known gap, tracked as #19324". The gap is not closing under #19324: it is the accepted static contract, and the client pin that records it stays.
19+
20+
⛔ No behaviour changes. No type, schema, accept set, authorable key or export moves. Only TSDoc and source comments change, and they ship:
21+
22+
- `@objectstack/spec`'s published `files[]` carries `dist`, where the TSDoc is emitted into the `.d.ts` / `.d.mts` declarations, and `src/**/*.zod.ts`, so both edited files also ship as source.
23+
- `@objectstack/client`'s published `files[]` carries `dist`, where the rewritten paragraph lands in `index.d.ts`, `index.d.mts`, `index.js` and `index.mjs`.

‎packages/client/src/index.ts‎

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,14 +2513,19 @@ export class ObjectStackClient {
25132513
* as either stage, which is the right answer for it — the key such a guess
25142514
* would read is not there.)
25152515
*
2516-
* ⚠️ The RUNTIME half is the strict one, and the asymmetry is a KNOWN GAP
2517-
* rather than a design: `InstalledPackageAtEitherStageSchema.safeParse()`
2518-
* refuses a `manifest` belonging to neither stage, while that same row
2519-
* COMPILES against this declaration. Tracked as #19324, whose root cause is
2520-
* the deliberate `z.ZodType<Record<string, unknown>, …>` annotation at
2521-
* `packages/spec/src/stack.zod.ts:1283` (#14513 — TS7056 and a
2522-
* declaration-chunk ceiling); ⛔ not something this declaration can fix, and
2523-
* ⛔ not a licence to relax either runtime branch to match the type.
2516+
* ⚠️ The RUNTIME half is the strict one, and the asymmetry is the ACCEPTED
2517+
* static contract, not a gap waiting to close:
2518+
* `InstalledPackageAtEitherStageSchema.safeParse()` refuses a `manifest`
2519+
* belonging to neither stage, while that same row COMPILES against this
2520+
* declaration. The index signature comes from the deliberate
2521+
* `z.ZodType<Record<string, unknown>, …>` annotation on
2522+
* `RecordStagePackageBodySchema` in `@objectstack/spec` (the #14513 pattern —
2523+
* TS7056 and a declaration-chunk ceiling), and the maintainer ruled on
2524+
* #19324 (letter 丙) to keep it: the runtime Zod schema is the enforced
2525+
* contract, so narrow by parsing, as above. The precise form, A2, is
2526+
* recorded beside `RecordStagePackageBodySchema` for the day the schema
2527+
* depth allows it. ⛔ Not something this declaration can fix, and ⛔ not a
2528+
* licence to relax either runtime branch to match the type.
25242529
*/
25252530
list: async (filters?: { status?: string; type?: string; enabled?: boolean }): Promise<{ packages: InstalledPackageAtEitherStage[]; total: number }> => {
25262531
const route = this.getRoute('packages');

‎packages/client/src/return-type-precision.test.ts‎

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -686,14 +686,17 @@ declare const assembledRow: AssembledInstalledPackage;
686686
*
687687
* ⛔ It does NOT measure object-shaped tolerance, and at this head there is
688688
* some: on the assembled branch `manifest` is declared `Record<string, unknown>`
689-
* (the deliberate annotation at `packages/spec/src/stack.zod.ts:1283`, #14513),
690-
* so an object `manifest` belonging to NEITHER stage compiles against these
691-
* members. The runtime is the half that is correct —
689+
* (the deliberate annotation on `RecordStagePackageBodySchema` in
690+
* `packages/spec/src/stack.zod.ts`, the #14513 pattern), so an object
691+
* `manifest` belonging to NEITHER stage compiles against these members. The
692+
* runtime is the half that is correct —
692693
* `InstalledPackageAtEitherStageSchema.safeParse()` refuses that same row, and
693694
* that refusal is pinned beside its producer in
694695
* `packages/runtime/src/domains/packages-read-delete-response-conformance.test.ts`.
695-
* The type-level gap is #19324's to close; the third pin below records it as the
696-
* behaviour it is, so the day it closes this file says so.
696+
* The type-level gap is the accepted static contract: #19324 was ruled (letter
697+
* 丙) to record it at `RecordStagePackageBodySchema` rather than close it. The
698+
* third pin below records it as the behaviour it is, so the day the body is
699+
* typed precisely this file says so.
697700
*
698701
* ## Ablation, measured rather than asserted
699702
*
@@ -761,16 +764,20 @@ export function installedPackageEitherStagePins17536(): void {
761764
// ⛔ NOT a guarantee — a measurement, written down so it cannot change in
762765
// silence. `AssembledInstalledPackage['manifest']` is
763766
// `Record<string, unknown>` (from the deliberate
764-
// `z.ZodType<Record<string, unknown>, …>` annotation at
765-
// `packages/spec/src/stack.zod.ts:1283`, #14513 — TS7056 and a
766-
// declaration-chunk ceiling), so the assembled branch admits ANY object and
767-
// the assignment below COMPILES at this head. Measured with `tsc` against the
768-
// published declarations; the runtime disagrees and is the correct half:
767+
// `z.ZodType<Record<string, unknown>, …>` annotation on
768+
// `RecordStagePackageBodySchema` in `packages/spec/src/stack.zod.ts`, the
769+
// #14513 pattern — TS7056 and a declaration-chunk ceiling), so the
770+
// assembled branch admits ANY object and the assignment below COMPILES at
771+
// this head. Measured with `tsc` against the published declarations; the
772+
// runtime disagrees and is the correct half:
769773
// `InstalledPackageAtEitherStageSchema.safeParse()` answers `success: false`
770-
// for this very row.
774+
// for this very row. #19324 was ruled (letter 丙) to keep this as the
775+
// accepted static contract, so this pin stays until the body is typed
776+
// precisely.
771777
//
772-
// ⚠️ There is deliberately no `@ts-expect-error` here. The day #19324 types
773-
// the assembled body, tsc reds on THIS line — and that red is the
778+
// ⚠️ There is deliberately no `@ts-expect-error` here. The day the assembled
779+
// body is typed precisely (the A2 form recorded at
780+
// `RecordStagePackageBodySchema`), tsc reds on THIS line — and that red is the
774781
// notification this pin exists to deliver: read it as "the gap closed", then
775782
// delete this block and tighten the `manifest` guidance on
776783
// `ObjectStackClient.packages.list` in `index.ts`, which sends callers

‎packages/spec/src/api/package-api-assembled.zod.ts‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,9 @@ import {
7979
* C and was REJECTED by name: a union AT THE KEY makes neither stage checkable,
8080
* which is the tolerate-at-the-consumer shape Prime Directive #12 refuses. So
8181
* `ManifestSchema` is untouched here — still `strictObject`, still globs — and
82-
* the assembled stage gets its own name, built from `AssembledPackageBodySchema`
83-
* (#14242's own declaration) rather than a second transcription of it.
84-
*
85-
* The body half is deliberately typed `Record<string, unknown>`; the reason is
86-
* recorded at `AssembledPackageBodySchema` and is not repeated here. The RUNTIME
87-
* schema still carries the manifest's every field plus every collection's full
88-
* declaration, so a wrong-shaped body is refused exactly as it is there.
82+
* the assembled stage gets its own name, built from the same body shape as
83+
* `AssembledPackageBodySchema` (#14242's own declaration) rather than a second
84+
* transcription of it, at the record stage the next section describes.
8985
*
9086
* ## The row's manifest is the RECORD stage, not the assembled one
9187
*
@@ -124,6 +120,24 @@ import {
124120
* members that need the treatment is MEASURED, never hand-picked — pinned
125121
* key-by-key in `./package-api.test.ts`, so a new collection with no JSON form
126122
* reddens there, naming itself.
123+
*
124+
* ## `manifest`'s published type is deliberately an index signature
125+
*
126+
* `RecordStagePackageBodySchema` is declared `z.ZodType<Record<string,
127+
* unknown>, Record<string, unknown>>`, so this row's `manifest` publishes as an
128+
* index signature: an authoring-stage `InstalledPackage` assigns to
129+
* `AssembledInstalledPackage`, and at the type level this arm absorbs the
130+
* authoring arm of {@link InstalledPackageAtEitherStageSchema}. That is the
131+
* accepted static contract — the maintainer ruling on #19324 (letter 丙) — not
132+
* a gap to tighten in passing. The RUNTIME schema is the enforced contract: it
133+
* still carries the manifest's every field plus every collection's full
134+
* declaration, so `.parse()` refuses a wrong-shaped body — tell the two stages
135+
* apart by parsing, never by the static type. It is not inferred because `tsc`
136+
* refuses to print the whole metadata vocabulary into the declarations that
137+
* embed it (TS7056; #14513 measured it on the assembled body, and on this
138+
* stage it fires at `PackageApiContracts` below). The precise form, if the
139+
* schema depth ever allows it, is A2 — the reasons and A2's measured cost are
140+
* recorded once, at `RecordStagePackageBodySchema` in `../stack.zod`.
127141
*/
128142
export const AssembledInstalledPackageSchema = lazySchema(() => InstalledPackageSchema.extend({
129143
manifest: RecordStagePackageBodySchema.describe('The ASSEMBLED package body this row carries, at the stage the registry records it'),

‎packages/spec/src/stack.zod.ts‎

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1450,8 +1450,57 @@ export type ArtifactStagePackageBodyParsed = z.infer<typeof ArtifactStagePackage
14501450
* ⛔ Never widen this to `z.unknown()` to make a row fit. A row that parses
14511451
* through neither this stage nor the authoring one is a producer defect, and
14521452
* this is the declaration that has to keep saying so.
1453+
*
1454+
* ## Its published type is deliberately an index signature
1455+
*
1456+
* This schema is declared `z.ZodType<Record<string, unknown>, Record<string,
1457+
* unknown>>`, so the published type of a record-stage body is an index
1458+
* signature: any object assigns to it. It is the `manifest` of
1459+
* `AssembledInstalledPackageSchema` (`@objectstack/spec/api-assembled`), so an
1460+
* authoring-stage `InstalledPackage` assigns to `AssembledInstalledPackage`,
1461+
* and a row whose `manifest` belongs to neither stage type-checks as an
1462+
* `InstalledPackageAtEitherStage`. That is the accepted static contract — the
1463+
* maintainer ruling on #19324 (letter 丙) — not a gap to tighten in passing.
1464+
*
1465+
* The RUNTIME schema is the enforced contract. It carries the manifest's every
1466+
* field, every collection's full declaration and the two lowered members
1467+
* above, so `.parse()` refuses a wrong-shaped body member by member. Narrow a
1468+
* record-stage body by parsing it, never by trusting its static type.
1469+
*
1470+
* Why not inferred: the body is the whole metadata vocabulary, and `tsc`
1471+
* refuses to print it into the declarations that embed it — TS7056, 「The
1472+
* inferred type of this node exceeds the maximum length the compiler will
1473+
* serialize」. #14513 measured that on the assembled body; for this stage,
1474+
* dropping this annotation, the artifact stage's and the cast below fails the
1475+
* declaration build with TS7056 at `PackageApiContracts` (measured on #19324
1476+
* at `d1ca8741dd` and again at `3bd28e2b2e`). Why not a named type: #14513
1477+
* measured that an alias declared in this module turns `stack.zod` into a
1478+
* shared declaration chunk its embedders import, and recorded the heap failure
1479+
* that followed beside {@link AssembledPackageBodySchema}; for this stage that
1480+
* reading is inherited, not re-measured.
1481+
*
1482+
* The precise form, if the schema depth ever allows it, is the one #19324
1483+
* measured as A2: infer this stage and the artifact stage (drop both
1484+
* annotations and the cast), and give compact `typeof`-based annotations to
1485+
* the four declarations that embed the body — `PackageApiContracts`,
1486+
* `InstalledPackageAtEitherStageSchema`, `ListInstalledPackagesResponseSchema`
1487+
* and `GetInstalledPackageResponseSchema`. At `d1ca8741dd` it built, turned
1488+
* all five of the gap's measured type readings into compile errors, and left
1489+
* the runtime bundles byte-identical. Its cost is declaration size: +20,209
1490+
* lines in the then `./api` entry (one expansion of this stage) and +44,342 in
1491+
* the root entry (this stage and the artifact stage). The heaviest type-check
1492+
* program under CI's heap ceiling, `qa/http-conformance`'s, was not measured
1493+
* under it.
1494+
*/
1495+
/*
1496+
* ANNOTATED structurally — see the note on the artifact stage above, and the
1497+
* section of this docblock on the published type for what that costs a
1498+
* consumer. The `as unknown as z.ZodObject<z.ZodRawShape>` cast below is that
1499+
* annotation's price: the artifact stage's declared type no longer says it is
1500+
* an object, so `.extend()` is reached through a cast. The cast is type-only
1501+
* and emits nothing; at runtime `.extend()` runs on the artifact stage's
1502+
* object schema.
14531503
*/
1454-
/* ANNOTATED structurally — see the note on the artifact stage above. */
14551504
export const RecordStagePackageBodySchema: z.ZodType<Record<string, unknown>, Record<string, unknown>> =
14561505
lazySchema(() =>
14571506
(ArtifactStagePackageBodySchema as unknown as z.ZodObject<z.ZodRawShape>).extend({

0 commit comments

Comments
 (0)