Skip to content

Commit 5cf58eb

Browse files
docs(spec): re-anchor the dead tracker citations in api/ to the commits that decided them (stage 2) (#20342)
Part of #20234 Clause-②: no ## What changed This is stage 2 of the staged sweep. It covers `packages/spec/src/api/**` and nothing else, and it leaves out `packages/spec/src/api/rest-server.zod.ts`, which seat 2's #20295 claim holds. Later stages cover the other areas, so this PR says `Part of`. Every comment or docblock site in scope that cited a tracker number answering 404 has been rewritten in ruling C+D's form C (comment 5749154545 on #19123). That is **107 sites on 105 lines in 22 files, covering 30 numbers**. Each rewritten line now cites the commit in `origin/main` history that decided what the line describes, and it says in its own words what that commit decided. No ADR or ruling-record file in `docs/adr/` or `scripts/adr-anchors/` names any of the 32 dead numbers, so every anchor is a commit. Nothing was dropped: every number in scope had a deciding commit. One more comment site is left on purpose, because its number belongs to another repository (see Acceptance notes). Only comments changed. Every source file keeps its line count (112 lines out, 112 in), so no line citation into these files moves. Seven of those 112 lines carry no number; they are the second half of a sentence that had to be reflowed. No code token moves (see the guard below). The 34 string-literal sites that carry a dead number are tokens, so they are left as they were and listed below. **No citation number is added.** Every tracker number on an added line was already on the line it replaces. No PR number stands beside a sha. Two more kinds of file change, both mechanical: - **Regenerated reference pages.** Five of the rewritten docblock lines project into `content/docs/references/api/` (`dispatcher.mdx`, `error-code-ledger.mdx`, `plugin-rest-api.mdx`). `check:docs` proved those three pages stale, and `pnpm --filter @objectstack/spec check:generated --fix` regenerated only them. The diff is five lines, each the same substitution as its source line. - **A `patch` changeset** for `@objectstack/spec` (see Changeset below). ## Census: `api/`, before and after **Instrument.** This is stage 1's instrument. It sends REST `GET /repos/objectstack-ai/objectstack/issues/N` without following redirects, for every distinct in-repo number cited in `packages/spec/src/api`. The population is: - the citation gate's own `CITATION_RE`, kept when the qualifier is none, `objectstack`, `objectstack-ai/objectstack`, `framework`, `pre-` or `post-`; - N of 100 or more; - excluding the ordinal heads the gate declares, and `summon`. Each site is classified by the TypeScript parser as a line comment, a docblock or a string. **Controls.** The lit controls were `#16862`, `#16847` and `#17698`. The dead controls were `#16714`, `#16715` and `#16697`. They were probed at the start, after every 100 numbers and at the end, which is 5 checkpoints per run. They read 15 of 15 lit (200) and 15 of 15 dead (404) in both runs. | reading | tree | numbers probed | 200 | 404 | 301 or other | dead sites, all of `api/` | in scope | `rest-server.zod.ts` | in-scope lines | in-scope files | dead numbers in scope | |---|---|---|---|---|---|---|---|---|---|---|---| | before | base `21ab41041`, probed 2026-09-27T22:56Z to 22:58Z | 351 | 319 | 32 | 0 | **153** | 142 | 11 | 140 | 23 | 31 | | after | head `22a00c42d`, probed 2026-09-27T23:10Z to 23:12Z; `.ts` sources identical at the final head | 334 | 319 | 15 | 0 | **46** | 35 | 11 | 35 | 9 | 14 | **Before, in scope, by class.** 34 non-test docblock sites and 30 non-test line comments. 7 test docblock sites and 37 test line comments. 33 test string sites (describe and it titles). 1 non-test string. **After, in scope.** 34 string sites and 1 comment site remain. The comment site is `export-job-family-retirement.test.ts:25`, which names an objectui PR (see Acceptance notes). The head probe found no number newly dead since the base probe: 319 numbers answer 200 in both runs. PR #20226's area table read `api` 153 at an earlier base, and this census reads the same 153 at `21ab41041`. Of those, 11 sites sit in `rest-server.zod.ts` (`#14369` twice and `#14691` nine times, all comments). They wait for #20295 to land. `pre-#N` spellings do occur in `api/`: the at-tier review measured 15 sites on 15 lines in 13 files at the head, for example `discovery.zod.ts:913` `pre-#4828`. All 15 numbers answer 200, so the gate's blind spot for that spelling (#20330) hides no dead site in this stage. _(Corrected by the `domain:spec` seat 4 at 2026-09-28T00:48Z, from the at-tier review record 5861396181. The draft said that no such spelling occurs.)_ ## Per-number table The counts are in-scope sites and files. `rewritten / left` gives comment sites rewritten and string sites left. Every anchor was read in its diff or message, not only in its subject: it is the commit that made the change the line now describes, never a later refactor or a commit that merely mentions the number. | number | sites / files | rewritten / left | anchor: what it decided | |---|---|---|---| | `#6037` | 5/2 | 3/2 | `18189983d`: declares `DataProtocol.validateData`, the validate-only operation, under #4633 ruling D | | `#6239` | 4/2 | 3/1 | `f549a0d4a`: retires `ViewProtocol` and its ten request/response schemas (ADR-0049, route 3) | | `#6287` | 18/2 | 17/1 | `84c86fb45`: `preview` and `trial` fold to `sandbox` by declaration, and the fold table is typed total over `EnvironmentType` | | `#6306` | 1/1 | 1/0 | `fec784863`: the direct-mount routes read the one API base | | `#6361` | 5/3 | 4/1 | `90bbf2510`: the notification-list `cursor` is retired on both halves (maintainer ruling 2026-08-07, Option A) | | `#6363` | 3/2 | 3/0 | `17d095413`: `unreadCount` counts the whole inbox, not the window | | `#6704` | 4/1 | 3/1 | `c3f491626`: `runAutomations` declares the default the import route applies, with the agreement pin | | `#8885` | 2/1 | 2/0 | `30b1c636a`: registers the nine REST wire codes that sweep found | | `#9740` | 3/1 | 2/1 | `11b779e0f`: declares `getMetaItemLayered`. The two cross-references to its test block now name the block by member | | `#9741` | 23/2 | 16/7 | `2a29caa53`: records the 2026-08-18 maintainer ruling. `previewDrafts` and `state` are declared, and `environmentId` stays transport-level | | `#9934` | 4/4 | 4/0 | `79c46da90`: the producer-side `userMessage` channel | | `#10264` (objectui) | 1/1 | 0/0 | not this repository's number: see Acceptance notes | | `#10330` | 3/1 | 1/2 | `b9e9227e3`: declares `mappingName` on `ImportRequestSchema` | | `#10338` | 4/2 | 3/1 | `d2619fd0c`: `ApiEndpoint.target` is optional, and the publish gate holds the flow requirement | | `#10726` | 2/2 | 2/0 | `bc56e1881`: retires `contributes.routes`, ruled Option B (stage 1's anchor too) | | `#11006` | 12/2 | 10/2 | `cccbe51bf`: declares `publishMetaItem` under the 2026-08-22 maintainer ruling, option B | | `#11453` | 1/1 | 1/0 | `1a47a5368`: `ack()` refuses a row that is not `in_flight` | | `#11504` | 4/2 | 2/2 | `f90e82024`: registers `FLOW_INPUT_SCHEMA_INVALID`, the contract half (stage 1's anchor too) | | `#11846` | 1/1 | 1/0 | `0c2334f6c`: the preview-mode retirement, whose test states the same assertion-set reasoning (stage 1's anchor too) | | `#11858` (a PR) | 1/1 | 1/0 | `1a47a5368`, its squash commit: `ack()` takes the shared `DELIVERY_NOT_ELIGIBLE` spelling | | `#11859` | 2/1 | 2/0 | `d9cf78eaa`: `ack()` binds the claim credential in its compare-and-set | | `#12194` | 1/1 | 1/0 | `311433f6b`: declares the item-name grammar and refuses it loudly at the publish door | | `#13135` | 3/2 | 3/0 | `9e0ba21a1`: retires the paper metadata-customization protocol (stage 1's anchor too) | | `#13197` | 1/1 | 1/0 | `56c093c4d`: the in-memory driver enforces field-level `unique` | | `#14474` | 1/1 | 1/0 | `df657d9df`: the install-time namespace conflict refusal carries an ADR-0112 envelope | | `#14691` | 16/1 | 4/12 | `b3a63d32c`: retires the ten inert `RestServerConfig` keys. All 16 sites are in `rest-server.test.ts`; the 9 in `rest-server.zod.ts` are out of scope | | `#14723` | 1/1 | 1/0 | `65846bc46`: lands the 2026-09-03 maintainer ruling, so a unique-constraint refusal has one wire spelling, `UNIQUE_VIOLATION`, on every route | | `#14748` | 2/2 | 2/0 | `92b5d7f00`: registers `NAMESPACE_CONFLICT` (its diff wrote the row this line glosses) | | `#16649` | 12/2 | 11/1 | `613bfbd3d` for 9 sites: registers the fourteen remaining `door: 'none'` codes. `44c917a47` for 2 sites: widens the vocabulary gate's face to every published package and retires `boot-refusal` (each of its diffs wrote the line it now anchors) | | `#17058` | 1/1 | 1/0 | `94c930248`: parses the dataset-query selection at the door, with its leniency sweep | | `#19307` | 1/1 | 1/0 | `8f6d83147`: the `sys_permission_set` duplicate-name refusal carries `UNIQUE_VIOLATION` | Every cited sha resolves to exactly one commit (`git rev-parse --disambiguate`, count 1), and every one is an ancestor of the base (`merge-base --is-ancestor`, exit 0). That is 30 distinct shas. Two wordings to check, both true of their commit: - `error-code-ledger.zod.ts:919`: 「the contract review that passed commit 1a47a53 ruled option B」. The review record sat on PR #11858, which answers 404 today. The line keeps that review's ruling as stated before and names the commit that landed it. - `discovery.zod.ts:291`: 「route B toward the single API base that commit fec7848 gave the direct-mount routes」. #6633 is live and stays, and the dead goal it pointed at is now named by the commit that delivered it. ## The 34 string sites left as tokens - **Test titles (33 sites).** `protocol.test.ts` 12, `rest-server.test.ts` 12, `export.test.ts` 3, `error-code-ledger.test.ts` 2, `validate-data.test.ts` 2, and 1 each in `discovery.test.ts` and `endpoint.test.ts`. - **Non-test string (1 site).** `error-code-ledger.zod.ts:1692`, the `reason` of the `FLOW_INPUT_SCHEMA_INVALID` row in the exported `PROVENANCE_WAIVERS` table (it cites `#11504`). It ships in the package as data. The one reader, `scripts/check-error-code-provenance.ts`, checks the table and never prints a `reason` to an author. So it is neither a comment nor author-shown text in the form D sense, and it is not rewritten here. No author-shown text was found in `api/`: nothing here is #20233's form D. ## Mechanical guard: no code token moves The check is a comments-stripped token comparison, base `21ab41041` against head `22a00c42d` (the later commits add only the changeset and the regenerated pages). It uses the TypeScript parser's leaf tokens, so template literals are scanned in context, and it excludes JSDoc nodes. It ran over all 22 touched `.ts` files. - Real run: 88,201 base tokens, **0 files with a token change** (exit 0). - Comment-insertion control: 0 files changed, as expected (exit 0). - Positive control (a declaration appended): 1 file reads DIFFER (exit 1). - Positive control (one digit changed inside a `rest-server.test.ts` test-title string): 1 file reads DIFFER (exit 1). ## Changeset This change ships bytes, so a `patch` changeset for `@objectstack/spec` is included. It says only that the provenance comments were re-anchored. Measured on the built package: 8 of the touched sources are `src/**/*.zod.ts`, which `files[]` ships verbatim. The rewritten docblocks also reach `dist`: `2a29caa53`, `cccbe51bf`, `84c86fb45`, `613bfbd3d` and `90bbf2510` each appear in 1 declaration file, and `613bfbd3d` and `79c46da90` each appear in 6 bundled `.js` files. The positive control, a pre-existing `protocol.zod.ts` docblock sentence, appears in `dist/api/index.d.ts`. ## Gates (head `24d9fba68`) - **Citation judging pass, run as CI runs it:** `pnpm check:issue-citations && node scripts/check-issue-citations.mjs` exits 0. The self-test passes 73 cases in 7 batteries. The live run judged 13 citations across 8 files, and all 13 resolve. These are the live numbers left on changed lines, such as #4633, #4828, #12004, #11679 and #16404. - **Doc authoring:** `pnpm check:doc-authoring` exits 0. - **Derived gates:** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at the final head derived 111 families, and all 111 exit 0. `--ran` reports 111 run, 0 NOT MEASURED, 0 unrun, and exits 0. - At the earlier head, before the reference pages were regenerated, the list held 87 families. `check:docs` exited 1 there; that is what proved the three pages stale. - Four gates (`check:doc-formula-expressions`, `check:dual-build-cjs-loads`, `check:lean-entry-closure`, `check:type-check-debt`) first exited 3, PREREQUISITE NOT MET. They exit 0 after a full `turbo run build` of `./packages/*` (71 tasks, exit 0, under the shared verify lock). - **Build, tests, typecheck and lint:** - `pnpm --filter @objectstack/spec build` exits 0. - `vitest run --maxWorkers=2 src/api` in `packages/spec`: 47 files and 1,518 tests pass. That covers all 13 touched test files. - The three spec script suites that read `api/` source text (`check-error-code-provenance`, `file-description`, `schema-index`) pass: 3 files, 144 tests. - `pnpm --filter @objectstack/spec typecheck` exits 0, including `check:test-typecheck` (53 files, 255 errors, 142 pinned signatures held). - `eslint --no-inline-config --format json` over the 22 touched `.ts` files: 22 files, 0 errors, 0 warnings. All 22 are in eslint's own population (`isPathIgnored` false for each). The config never enables type-aware linting, so a comment edit here cannot move the verdict on any untouched file. The repo-wide `pnpm lint` is CI's run. ## Acceptance notes - **The objectui PR number.** `export-job-family-retirement.test.ts:25` reads 「objectui retired its side first (objectui#10247, merged as objectui PR #10264)」. The number belongs to objectui's board, but the citation grammar reads `objectui PR #10264` as a bare number of this repository, so the census counts it as dead here (it is 404 on this board). `objectstack-ai/objectui` answers 403 to this session, on both REST and the web page, so whether that PR is live is NOT MEASURED. The line is left unchanged. This is the same grammar family as #20330's `pre-` / `post-` blind spot, a qualifier the grammar does not recognise, and it is named there, not filed. - **Base.** The branch is 2 commits behind `origin/main` (`d3958bac6`, read at 2026-09-28). Neither commit touches `packages/spec/src/api` or `content/docs/references/api`, and a no-driver `merge-tree` of the head onto `d3958bac6` exits 0. So there was no merge. - **#20295's branch.** It edits `rest-server.test.ts` too, in hunks at base lines 114 to 136, 152 to 185 and 663 to 679. This PR's four comment edits there are at lines 198, 206, 266 and 371. A no-driver `merge-tree` of this head with that branch's head `2e575f156` exits 0. - **Surface.** The regenerated reference pages under `content/docs/references/api/` are the one set of files outside `packages/spec/src/api/**` besides the changeset. They are generator output projected from the rewritten docblocks, and the required `TypeScript Type Check` job reds without them. --- _Generated by [Claude Code](https://claude.ai/code/session_01CiCTczDo7tGhafXjf61dUJ)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent c74de10 commit 5cf58eb

26 files changed

Lines changed: 128 additions & 117 deletions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
Provenance comments in `api/` were re-anchored
6+
7+
Comment and docblock lines under `src/api` (all but `rest-server.zod.ts`) that
8+
cited tracker numbers which no longer resolve on GitHub now cite the commit in
9+
this repository's history that decided the matter, and say in their own words
10+
what was decided. Comments only: no type, schema, export or runtime behaviour
11+
changes.

‎content/docs/references/api/dispatcher.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ The dispatcher is the central routing component that:
1717
4. Serves prefixes registered by the kernel services above. Plugins that need
1818
a code handler mount it imperatively on the `http.server` service (resolve
1919
it from the plugin context on `kernel:ready`) — the manifest's
20-
`contributes.routes` key was removed in @objectstack/spec 17 (#10726):
20+
`contributes.routes` key was removed in @objectstack/spec 17 (commit bc56e1881):
2121
nothing ever read it, and authoring it is now a tsc error and a parse
2222
error carrying that prescription.
2323

‎content/docs/references/api/error-code-ledger.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ absent here is a protocol gap, not a tier question.
109109
ONE shape, no second list: a `door: 'none'` code is a row like any other —
110110
the string under the package that stamps it, and a comment that states its
111111
`status` and the reachability reading ("no HTTP door on this tree; the
112-
thrown value is the boundary"). Until #16649 the dispatcher vocabulary
112+
thrown value is the boundary"). Until commit 44c917a47 the dispatcher vocabulary
113113
(`packages/runtime/src/dispatcher-error-vocabulary.ts`) carried a
114114
`boot-refusal` verdict that recorded that same reachability for the codes
115115
NOT yet registered; it is RETIRED, because the gate below now refuses it —
@@ -125,7 +125,7 @@ it, `error.code` carries the specific code instead of the status-derived
125125
member plus `declaredCode`. The `declaredCode` demotion (#9106) stays for
126126
genuinely unknown / third-party spellings only.
127127

128-
EVERY published package's `src/**` is held to this mechanically — #16649
128+
EVERY published package's `src/**` is held to this mechanically — commit 44c917a47
129129
widened the rule from `packages/spec/src/**` alone, which is all #16449
130130
could afford to measure. `check:dispatcher-error-vocabulary` refuses to
131131
classify a stamp site under one as anything but `foreign-vocabulary` (a
@@ -172,7 +172,7 @@ host boot matching is not wire vocabulary.
172172
boot refusal that ships in `dist` is owed a row, so the codes left out or
173173
retired on the "not wire vocabulary" reasoning were registrations owed
174174
under the ruling, not re-argued per card — #16449 registered the nine
175-
measured on its tree, and #16649 the fourteen `boot-refusal` rows
175+
measured on its tree, and commit 613bfbd3d the fourteen `boot-refusal` rows
176176
`dispatcher-error-vocabulary.ts` still carried, among them
177177
`MONGODB_MULTI_TENANT_UNSUPPORTED` itself, back under
178178
`@objectstack/driver-mongodb` with the #8035 removal reversed on the

‎content/docs/references/api/plugin-rest-api.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Architecture Alignment:
3535
// registered by plugin-hono-server; `examples/app-showcase`'s
3636
// recalc-endpoint is a real consumer of this exact shape). The worked
3737
// manifest example that used to sit here declared `contributes.routes`,
38-
// which was removed in @objectstack/spec 17 (#10726): nothing ever read
38+
// which was removed in @objectstack/spec 17 (commit bc56e1881): nothing ever read
3939
// it, so every route it showed parsed cleanly and served nothing.
4040
class RestApiPlugin {
4141
name = 'rest_api';

‎packages/spec/src/api/apis-publish-gates.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ describe('[#5111] the flip — a well-formed `apis:` publishes', () => {
9999
expect(() => defineStack({ manifest, apis: [validObjectEndpoint, validFlowEndpoint] })).not.toThrow();
100100
});
101101

102-
// [#10338] The acceptance half of the ruling that made `target` optional:
102+
// [commit d2619fd0c] The acceptance half of the ruling that made `target` optional:
103103
// an `object_operation` endpoint is addressed by `objectParams.object` /
104104
// `.operation`, and NO consumer reads `target` for that type (executor,
105105
// OpenAPI enrichment and this gate all branch on `objectParams` alone) — so
@@ -312,7 +312,7 @@ describe('[#5111] gate (a) — the supported subset (mirrors `planEndpointTarget
312312
expect(message).toMatch(/names no target flow/);
313313
});
314314

315-
// [#10338] `target` is optional in the VOCABULARY (an `object_operation`
315+
// [commit d2619fd0c] `target` is optional in the VOCABULARY (an `object_operation`
316316
// author no longer writes a dead string), so omission now reaches this gate
317317
// instead of dying as a Zod `invalid_type` — and the gate is what holds the
318318
// requirement for `type: 'flow'`. The issue path is asserted too: the author

‎packages/spec/src/api/contract.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('ApiErrorSchema', () => {
4646
expect(error.details).toBeDefined();
4747
});
4848

49-
// [#9934] The producer-side user-facing marking (objectui#5210 ruling):
49+
// [commit 79c46da90] The producer-side user-facing marking (objectui#5210 ruling):
5050
// presence is the producer's opt-in, absence keeps the consumer's generic
5151
// substitution (#3821 preserved by construction).
5252
it('carries a producer-marked `userMessage` verbatim', () => {

‎packages/spec/src/api/contract.zod.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const ApiErrorSchema = lazySchema(() => z.object({
5151
message: z.string().describe('Readable error message'),
5252
/**
5353
* The producer's user-facing refusal text, verbatim — the producer-side
54-
* opt-in channel for "this exact text is addressed to the END USER" (#9934;
54+
* opt-in channel for "this exact text is addressed to the END USER" (commit 79c46da90;
5555
* maintainer ruling 2026-08-19 on objectui#5210, option 1).
5656
*
5757
* ## The problem it solves

‎packages/spec/src/api/dataset-selection.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ describe('#17551 §5 — a valid selection still passes, and the parse adds noth
283283
});
284284

285285
it('every in-repo selection specimen still passes', () => {
286-
// The same leniency sweep #17058 ran at the door, re-run against the WHOLE
286+
// The same leniency sweep commit 94c930248 ran at the door, re-run against the WHOLE
287287
// schema: if any in-repo caller had been relying on the four undoored
288288
// members going unparsed, this is where it shows.
289289
const specimens: Array<Record<string, unknown>> = [

‎packages/spec/src/api/discovery.test.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ describe('[#4828] resolveDiscoveryEnvironment (decision 4 — enum, not passthro
12411241
}
12421242
});
12431243

1244-
// [#6287] `preview` was one of this fixture's three examples until the fold
1244+
// [commit 84c86fb45] `preview` was one of this fixture's three examples until the fold
12451245
// table grew a row for it. The RULE is unchanged and still pinned — an
12461246
// unrecognised spelling never claims production — but `preview` is no longer
12471247
// an example of one: it is a declared `EnvironmentTypeSchema` member with a
@@ -1272,7 +1272,7 @@ describe('[#4828] resolveDiscoveryEnvironment (decision 4 — enum, not passthro
12721272
});
12731273

12741274
/**
1275-
* [#6287] Every `EnvironmentType` member folds by DECLARATION, not by fallback.
1275+
* [commit 84c86fb45] Every `EnvironmentType` member folds by DECLARATION, not by fallback.
12761276
*
12771277
* Before this, five of the seven members had a row in the fold table and
12781278
* `preview` / `trial` fell through `?? 'development'` — a fold nobody had
@@ -1330,7 +1330,7 @@ describe('[#6287] the fold table is total over EnvironmentType', () => {
13301330

13311331
it('rejects a fold table that misses a member — the exhaustiveness gate itself', () => {
13321332
// ⚠️ This assertion is made by `tsc`, not by vitest, and that is the point.
1333-
// A RUNTIME exhaustiveness test cannot see the defect #6287 reported: the
1333+
// A RUNTIME exhaustiveness test cannot see the defect commit 84c86fb45 repaired: the
13341334
// fallback and three declared rows all produce `'development'`, so calling
13351335
// `resolveDiscoveryEnvironment('preview')` returned an identical answer
13361336
// whether a row existed or the `??` invented one. Such a test would have
@@ -1350,12 +1350,12 @@ describe('[#6287] the fold table is total over EnvironmentType', () => {
13501350
// exported, and exporting it to satisfy a test would put a private
13511351
// lookup on this package's public surface. That edit is a deliberate,
13521352
// visible change to a line whose own comment forbids it, not the silent
1353-
// drift #6287 was about — the drift was a member that nobody had to
1353+
// drift commit 84c86fb45 closed — the drift was a member that nobody had to
13541354
// touch anything to omit.
13551355
// `packages/spec`'s test layer IS type-checked (`tsconfig.test.json`, named
13561356
// in the `typecheck` script since #5286) and this file carries no entry in
13571357
// `test-typecheck-debt.json`, so the directive is live, not phantom.
1358-
// @ts-expect-error [#6287] `trial` has no fold — a partial table must not type-check.
1358+
// @ts-expect-error [commit 84c86fb45] `trial` has no fold — a partial table must not type-check.
13591359
const missingTrial: Record<EnvironmentType, DiscoveryEnvironment> = {
13601360
production: 'production',
13611361
sandbox: 'sandbox',

‎packages/spec/src/api/discovery.zod.ts‎

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ export const ApiRoutesSchema = lazySchema(() => z.object({
288288
* ADR-0015 §6.2: tables / draft / import / refresh-catalog / validate) are
289289
* mounted.
290290
*
291-
* Declared by #6633 (route B toward #6306): the SDK's
291+
* Declared by #6633 (route B toward the single API base that commit fec784863 gave the direct-mount routes): the SDK's
292292
* `datasources.external.*` methods hard-coded `/api/v1/datasources` with no
293293
* discovery mechanism at all, so any deployment on a non-default base
294294
* (`apiPath`, or a programmatic `basePath`/`version`) had the whole family
@@ -419,16 +419,16 @@ export const ApiRoutesSchema = lazySchema(() => z.object({
419419
* stays HERE, in the one open-source module that reads it:
420420
* `NODE_ENV_TO_DISCOVERY_ENVIRONMENT` is typed
421421
* `Record<EnvironmentType, DiscoveryEnvironment>`, which is what makes the fold
422-
* provably total over the taxonomy rather than total by inspection (#6287).
422+
* provably total over the taxonomy rather than total by inspection (commit 84c86fb45).
423423
*
424424
* Its relation to the 3-member `DiscoveryEnvironmentSchema` below is a strict
425425
* subset: `resolveDiscoveryEnvironment` folds `test` → `development` and
426-
* `staging` / `preview` / `trial` → `sandbox` (#4828, #6287), and the subset is
426+
* `staging` / `preview` / `trial` → `sandbox` (#4828, commit 84c86fb45), and the subset is
427427
* pinned in `discovery-environment-subset.pin.test.ts` (#5676).
428428
*
429429
* ⚠️ Adding a member here is a decision about the fold table too: a new bucket
430430
* does not compile until it says which of the three coarse postures it
431-
* advertises — on purpose, because before #6287 `preview` and `trial` reached
431+
* advertises — on purpose, because before commit 84c86fb45 `preview` and `trial` reached
432432
* `development` through a `??` fallback instead of a decision (#5673).
433433
*/
434434
export const EnvironmentTypeSchema = lazySchema(() => z
@@ -508,8 +508,8 @@ export type DiscoveryEnvironment = z.input<typeof DiscoveryEnvironmentSchema>;
508508
* | `development`, `dev` | `development` | exact / short spelling |
509509
* | `test` | `development` | ephemeral developer-class run (vitest/CI), not a provisioned pre-production copy |
510510
* | `staging` | `sandbox` | pre-production and production-LIKE; certainly not `production`, and `sandbox` is the enum's pre-production member |
511-
* | `preview` | `sandbox` | a PROVISIONED environment (own database, hostname, plan tier, per-environment RBAC), not a developer's machine — same class as `staging` (#6287) |
512-
* | `trial` | `sandbox` | a provisioned environment holding an evaluating customer's real business data; developer-class would understate it (#6287) |
511+
* | `preview` | `sandbox` | a PROVISIONED environment (own database, hostname, plan tier, per-environment RBAC), not a developer's machine — same class as `staging` (commit 84c86fb45) |
512+
* | `trial` | `sandbox` | a provisioned environment holding an evaluating customer's real business data; developer-class would understate it (commit 84c86fb45) |
513513
* | unset / blank | `production` | the host declined to say; every other reader of that absence already says `production`, and of the two ways to be wrong, calling a real production deployment `development` is the dangerous one (#5673, #5936) |
514514
* | anything else | `development` | an unrecognised spelling is a GUESS, and this function never claims `production` on a guess (#4828) |
515515
*
@@ -521,9 +521,9 @@ export type DiscoveryEnvironment = z.input<typeof DiscoveryEnvironmentSchema>;
521521
* `production`: `environment` is machine-readable, and a client may skip
522522
* production warnings or loosen a destructive action's confirmation on it.
523523
*
524-
* ## `preview` and `trial` are a THIRD case — declared, not absent, not a guess (#6287)
524+
* ## `preview` and `trial` are a THIRD case — declared, not absent, not a guess (commit 84c86fb45)
525525
*
526-
* Until #6287 those two reached `development` through the `??` fallback rather
526+
* Until commit 84c86fb45 those two reached `development` through the `??` fallback rather
527527
* than through a decision, so this table declared five of the seven
528528
* `EnvironmentTypeSchema` members and let the other two fall off the end. That
529529
* is the same shape the two rows above exist to separate: the fallback answers
@@ -571,7 +571,7 @@ export type DiscoveryEnvironment = z.input<typeof DiscoveryEnvironmentSchema>;
571571
* "anything else" the two producers would have drifted again on exactly that
572572
* input — the drift this consolidation exists to end.
573573
*
574-
* ## The taxonomy half of this table is EXHAUSTIVE, and tsc keeps it so (#6287)
574+
* ## The taxonomy half of this table is EXHAUSTIVE, and tsc keeps it so (commit 84c86fb45)
575575
*
576576
* The seven `EnvironmentTypeSchema` rows are grouped behind a
577577
* `satisfies Record<EnvironmentType, DiscoveryEnvironment>`: adding a bucket to
@@ -584,14 +584,14 @@ export type DiscoveryEnvironment = z.input<typeof DiscoveryEnvironmentSchema>;
584584
* one cannot see this defect: the fallback and three of the seven rows all
585585
* produce `'development'`, so calling `resolveDiscoveryEnvironment` returns an
586586
* indistinguishable answer whether a row exists or the `??` invented it. A
587-
* runtime exhaustiveness test would have passed on the exact state #6287
588-
* reported. `tsc` compares the KEY SET, which is the actual claim. The negative
587+
* runtime exhaustiveness test would have passed on the exact state commit 84c86fb45
588+
* repaired. `tsc` compares the KEY SET, which is the actual claim. The negative
589589
* control for it lives in `discovery.test.ts`.
590590
*/
591591
const NODE_ENV_TO_DISCOVERY_ENVIRONMENT: Readonly<Record<string, DiscoveryEnvironment>> = {
592592
// The seven declared `EnvironmentTypeSchema` buckets. The `satisfies` is the
593593
// gate described above: every member must appear, and nothing that is not a
594-
// member may (#6287).
594+
// member may (commit 84c86fb45).
595595
...({
596596
production: 'production',
597597
sandbox: 'sandbox',
@@ -630,7 +630,7 @@ const NODE_ENV_TO_DISCOVERY_ENVIRONMENT: Readonly<Record<string, DiscoveryEnviro
630630
export function resolveDiscoveryEnvironment(raw?: string | null): DiscoveryEnvironment {
631631
const spelling = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
632632
if (spelling === '') return 'production';
633-
// [#6287] The fallback's ONE remaining job: a spelling that is not a declared
633+
// [commit 84c86fb45] The fallback's ONE remaining job: a spelling that is not a declared
634634
// `EnvironmentType` member and not an operator shorthand — `qa`, `uat`, a
635635
// typo. It no longer silently answers for members of our own taxonomy; the
636636
// table above is total over them and `tsc` keeps it that way, so a future
@@ -667,7 +667,7 @@ export function resolveDiscoveryEnvironment(raw?: string | null): DiscoveryEnvir
667667
// under this package's `tsconfig.json`: a bogus `dev: 'nope'` reports TS2322
668668
// as a literal and is silent under `Object.assign`.
669669
//
670-
// ⚠️ It is NOT the #6287 `satisfies Record<EnvironmentType,
670+
// ⚠️ It is NOT commit 84c86fb45's `satisfies Record<EnvironmentType,
671671
// DiscoveryEnvironment>` gate above that would be lost. `satisfies` applies
672672
// to the literal, not to the assignment, so under that spelling a missing
673673
// bucket still reports TS1360. Losing the value check silently is reason

0 commit comments

Comments
 (0)