Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/spec-api-provenance-anchors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@objectstack/spec': patch
---

Provenance comments in `api/` were re-anchored

Comment and docblock lines under `src/api` (all but `rest-server.zod.ts`) that
cited tracker numbers which no longer resolve on GitHub now cite the commit in
this repository's history that decided the matter, and say in their own words
what was decided. Comments only: no type, schema, export or runtime behaviour
changes.
2 changes: 1 addition & 1 deletion content/docs/references/api/dispatcher.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The dispatcher is the central routing component that:
4. Serves prefixes registered by the kernel services above. Plugins that need
a code handler mount it imperatively on the `http.server` service (resolve
it from the plugin context on `kernel:ready`) — the manifest's
`contributes.routes` key was removed in @objectstack/spec 17 (#10726):
`contributes.routes` key was removed in @objectstack/spec 17 (commit bc56e1881):
nothing ever read it, and authoring it is now a tsc error and a parse
error carrying that prescription.

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

EVERY published package's `src/**` is held to this mechanically — #16649
EVERY published package's `src/**` is held to this mechanically — commit 44c917a47
widened the rule from `packages/spec/src/**` alone, which is all #16449
could afford to measure. `check:dispatcher-error-vocabulary` refuses to
classify a stamp site under one as anything but `foreign-vocabulary` (a
Expand Down Expand Up @@ -172,7 +172,7 @@ host boot matching is not wire vocabulary.
boot refusal that ships in `dist` is owed a row, so the codes left out or
retired on the "not wire vocabulary" reasoning were registrations owed
under the ruling, not re-argued per card — #16449 registered the nine
measured on its tree, and #16649 the fourteen `boot-refusal` rows
measured on its tree, and commit 613bfbd3d the fourteen `boot-refusal` rows
`dispatcher-error-vocabulary.ts` still carried, among them
`MONGODB_MULTI_TENANT_UNSUPPORTED` itself, back under
`@objectstack/driver-mongodb` with the #8035 removal reversed on the
Expand Down
2 changes: 1 addition & 1 deletion content/docs/references/api/plugin-rest-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Architecture Alignment:
// registered by plugin-hono-server; `examples/app-showcase`'s
// recalc-endpoint is a real consumer of this exact shape). The worked
// manifest example that used to sit here declared `contributes.routes`,
// which was removed in @objectstack/spec 17 (#10726): nothing ever read
// which was removed in @objectstack/spec 17 (commit bc56e1881): nothing ever read
// it, so every route it showed parsed cleanly and served nothing.
class RestApiPlugin {
name = 'rest_api';
Expand Down
4 changes: 2 additions & 2 deletions packages/spec/src/api/apis-publish-gates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ describe('[#5111] the flip — a well-formed `apis:` publishes', () => {
expect(() => defineStack({ manifest, apis: [validObjectEndpoint, validFlowEndpoint] })).not.toThrow();
});

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

// [#10338] `target` is optional in the VOCABULARY (an `object_operation`
// [commit d2619fd0c] `target` is optional in the VOCABULARY (an `object_operation`
// author no longer writes a dead string), so omission now reaches this gate
// instead of dying as a Zod `invalid_type` — and the gate is what holds the
// requirement for `type: 'flow'`. The issue path is asserted too: the author
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/api/contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('ApiErrorSchema', () => {
expect(error.details).toBeDefined();
});

// [#9934] The producer-side user-facing marking (objectui#5210 ruling):
// [commit 79c46da90] The producer-side user-facing marking (objectui#5210 ruling):
// presence is the producer's opt-in, absence keeps the consumer's generic
// substitution (#3821 preserved by construction).
it('carries a producer-marked `userMessage` verbatim', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/api/contract.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const ApiErrorSchema = lazySchema(() => z.object({
message: z.string().describe('Readable error message'),
/**
* The producer's user-facing refusal text, verbatim — the producer-side
* opt-in channel for "this exact text is addressed to the END USER" (#9934;
* opt-in channel for "this exact text is addressed to the END USER" (commit 79c46da90;
* maintainer ruling 2026-08-19 on objectui#5210, option 1).
*
* ## The problem it solves
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/api/dataset-selection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ describe('#17551 §5 — a valid selection still passes, and the parse adds noth
});

it('every in-repo selection specimen still passes', () => {
// The same leniency sweep #17058 ran at the door, re-run against the WHOLE
// The same leniency sweep commit 94c930248 ran at the door, re-run against the WHOLE
// schema: if any in-repo caller had been relying on the four undoored
// members going unparsed, this is where it shows.
const specimens: Array<Record<string, unknown>> = [
Expand Down
10 changes: 5 additions & 5 deletions packages/spec/src/api/discovery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,7 @@ describe('[#4828] resolveDiscoveryEnvironment (decision 4 — enum, not passthro
}
});

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

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

it('rejects a fold table that misses a member — the exhaustiveness gate itself', () => {
// ⚠️ This assertion is made by `tsc`, not by vitest, and that is the point.
// A RUNTIME exhaustiveness test cannot see the defect #6287 reported: the
// A RUNTIME exhaustiveness test cannot see the defect commit 84c86fb45 repaired: the
// fallback and three declared rows all produce `'development'`, so calling
// `resolveDiscoveryEnvironment('preview')` returned an identical answer
// whether a row existed or the `??` invented one. Such a test would have
Expand All @@ -1350,12 +1350,12 @@ describe('[#6287] the fold table is total over EnvironmentType', () => {
// exported, and exporting it to satisfy a test would put a private
// lookup on this package's public surface. That edit is a deliberate,
// visible change to a line whose own comment forbids it, not the silent
// drift #6287 was about — the drift was a member that nobody had to
// drift commit 84c86fb45 closed — the drift was a member that nobody had to
// touch anything to omit.
// `packages/spec`'s test layer IS type-checked (`tsconfig.test.json`, named
// in the `typecheck` script since #5286) and this file carries no entry in
// `test-typecheck-debt.json`, so the directive is live, not phantom.
// @ts-expect-error [#6287] `trial` has no fold — a partial table must not type-check.
// @ts-expect-error [commit 84c86fb45] `trial` has no fold — a partial table must not type-check.
const missingTrial: Record<EnvironmentType, DiscoveryEnvironment> = {
production: 'production',
sandbox: 'sandbox',
Expand Down
28 changes: 14 additions & 14 deletions packages/spec/src/api/discovery.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ export const ApiRoutesSchema = lazySchema(() => z.object({
* ADR-0015 §6.2: tables / draft / import / refresh-catalog / validate) are
* mounted.
*
* Declared by #6633 (route B toward #6306): the SDK's
* Declared by #6633 (route B toward the single API base that commit fec784863 gave the direct-mount routes): the SDK's
* `datasources.external.*` methods hard-coded `/api/v1/datasources` with no
* discovery mechanism at all, so any deployment on a non-default base
* (`apiPath`, or a programmatic `basePath`/`version`) had the whole family
Expand Down Expand Up @@ -419,16 +419,16 @@ export const ApiRoutesSchema = lazySchema(() => z.object({
* stays HERE, in the one open-source module that reads it:
* `NODE_ENV_TO_DISCOVERY_ENVIRONMENT` is typed
* `Record<EnvironmentType, DiscoveryEnvironment>`, which is what makes the fold
* provably total over the taxonomy rather than total by inspection (#6287).
* provably total over the taxonomy rather than total by inspection (commit 84c86fb45).
*
* Its relation to the 3-member `DiscoveryEnvironmentSchema` below is a strict
* subset: `resolveDiscoveryEnvironment` folds `test` → `development` and
* `staging` / `preview` / `trial` → `sandbox` (#4828, #6287), and the subset is
* `staging` / `preview` / `trial` → `sandbox` (#4828, commit 84c86fb45), and the subset is
* pinned in `discovery-environment-subset.pin.test.ts` (#5676).
*
* ⚠️ Adding a member here is a decision about the fold table too: a new bucket
* does not compile until it says which of the three coarse postures it
* advertises — on purpose, because before #6287 `preview` and `trial` reached
* advertises — on purpose, because before commit 84c86fb45 `preview` and `trial` reached
* `development` through a `??` fallback instead of a decision (#5673).
*/
export const EnvironmentTypeSchema = lazySchema(() => z
Expand Down Expand Up @@ -508,8 +508,8 @@ export type DiscoveryEnvironment = z.input<typeof DiscoveryEnvironmentSchema>;
* | `development`, `dev` | `development` | exact / short spelling |
* | `test` | `development` | ephemeral developer-class run (vitest/CI), not a provisioned pre-production copy |
* | `staging` | `sandbox` | pre-production and production-LIKE; certainly not `production`, and `sandbox` is the enum's pre-production member |
* | `preview` | `sandbox` | a PROVISIONED environment (own database, hostname, plan tier, per-environment RBAC), not a developer's machine — same class as `staging` (#6287) |
* | `trial` | `sandbox` | a provisioned environment holding an evaluating customer's real business data; developer-class would understate it (#6287) |
* | `preview` | `sandbox` | a PROVISIONED environment (own database, hostname, plan tier, per-environment RBAC), not a developer's machine — same class as `staging` (commit 84c86fb45) |
* | `trial` | `sandbox` | a provisioned environment holding an evaluating customer's real business data; developer-class would understate it (commit 84c86fb45) |
* | 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) |
* | anything else | `development` | an unrecognised spelling is a GUESS, and this function never claims `production` on a guess (#4828) |
*
Expand All @@ -521,9 +521,9 @@ export type DiscoveryEnvironment = z.input<typeof DiscoveryEnvironmentSchema>;
* `production`: `environment` is machine-readable, and a client may skip
* production warnings or loosen a destructive action's confirmation on it.
*
* ## `preview` and `trial` are a THIRD case — declared, not absent, not a guess (#6287)
* ## `preview` and `trial` are a THIRD case — declared, not absent, not a guess (commit 84c86fb45)
*
* Until #6287 those two reached `development` through the `??` fallback rather
* Until commit 84c86fb45 those two reached `development` through the `??` fallback rather
* than through a decision, so this table declared five of the seven
* `EnvironmentTypeSchema` members and let the other two fall off the end. That
* is the same shape the two rows above exist to separate: the fallback answers
Expand Down Expand Up @@ -571,7 +571,7 @@ export type DiscoveryEnvironment = z.input<typeof DiscoveryEnvironmentSchema>;
* "anything else" the two producers would have drifted again on exactly that
* input — the drift this consolidation exists to end.
*
* ## The taxonomy half of this table is EXHAUSTIVE, and tsc keeps it so (#6287)
* ## The taxonomy half of this table is EXHAUSTIVE, and tsc keeps it so (commit 84c86fb45)
*
* The seven `EnvironmentTypeSchema` rows are grouped behind a
* `satisfies Record<EnvironmentType, DiscoveryEnvironment>`: adding a bucket to
Expand All @@ -584,14 +584,14 @@ export type DiscoveryEnvironment = z.input<typeof DiscoveryEnvironmentSchema>;
* one cannot see this defect: the fallback and three of the seven rows all
* produce `'development'`, so calling `resolveDiscoveryEnvironment` returns an
* indistinguishable answer whether a row exists or the `??` invented it. A
* runtime exhaustiveness test would have passed on the exact state #6287
* reported. `tsc` compares the KEY SET, which is the actual claim. The negative
* runtime exhaustiveness test would have passed on the exact state commit 84c86fb45
* repaired. `tsc` compares the KEY SET, which is the actual claim. The negative
* control for it lives in `discovery.test.ts`.
*/
const NODE_ENV_TO_DISCOVERY_ENVIRONMENT: Readonly<Record<string, DiscoveryEnvironment>> = {
// The seven declared `EnvironmentTypeSchema` buckets. The `satisfies` is the
// gate described above: every member must appear, and nothing that is not a
// member may (#6287).
// member may (commit 84c86fb45).
...({
production: 'production',
sandbox: 'sandbox',
Expand Down Expand Up @@ -630,7 +630,7 @@ const NODE_ENV_TO_DISCOVERY_ENVIRONMENT: Readonly<Record<string, DiscoveryEnviro
export function resolveDiscoveryEnvironment(raw?: string | null): DiscoveryEnvironment {
const spelling = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
if (spelling === '') return 'production';
// [#6287] The fallback's ONE remaining job: a spelling that is not a declared
// [commit 84c86fb45] The fallback's ONE remaining job: a spelling that is not a declared
// `EnvironmentType` member and not an operator shorthand — `qa`, `uat`, a
// typo. It no longer silently answers for members of our own taxonomy; the
// table above is total over them and `tsc` keeps it that way, so a future
Expand Down Expand Up @@ -667,7 +667,7 @@ export function resolveDiscoveryEnvironment(raw?: string | null): DiscoveryEnvir
// under this package's `tsconfig.json`: a bogus `dev: 'nope'` reports TS2322
// as a literal and is silent under `Object.assign`.
//
// ⚠️ It is NOT the #6287 `satisfies Record<EnvironmentType,
// ⚠️ It is NOT commit 84c86fb45's `satisfies Record<EnvironmentType,
// DiscoveryEnvironment>` gate above that would be lost. `satisfies` applies
// to the literal, not to the assignment, so under that spelling a missing
// bucket still reports TS1360. Losing the value check silently is reason
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/api/dispatcher.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { CoreServiceName, ServiceCriticalitySchema } from '../system/core-servic
* 4. Serves prefixes registered by the kernel services above. Plugins that need
* a code handler mount it imperatively on the `http.server` service (resolve
* it from the plugin context on `kernel:ready`) — the manifest's
* `contributes.routes` key was removed in @objectstack/spec 17 (#10726):
* `contributes.routes` key was removed in @objectstack/spec 17 (commit bc56e1881):
* nothing ever read it, and authoring it is now a tsc error and a parse
* error carrying that prescription.
*
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/api/endpoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe('ApiEndpointSchema', () => {
expect(endpoint.name).toBe('get_customers');
});

// [#10338] `target` is OPTIONAL in the vocabulary: for `object_operation` no
// [commit d2619fd0c] `target` is OPTIONAL in the vocabulary: for `object_operation` no
// consumer reads it (the executor, the OpenAPI enrichment and the publish
// gate all branch on `objectParams` alone), so the author is no longer
// forced to write a dead string. The per-type requirement for `type: 'flow'`
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/api/error-catalog-docs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { deriveWireFace } from '../../../../scripts/check-error-status-conforman
*
* - **A translated code is not on the wire.** `DuplicateRecordError` declares
* `code = 'DUPLICATE_RECORD'`, and the REST door translates that envelope at
* the boundary, so every route answers `UNIQUE_VIOLATION` (#14723). The enum
* the boundary, so every route answers `UNIQUE_VIOLATION` (the 2026-09-03 ruling, landed in commit 65846bc46). The enum
* keeps the in-process spelling; the wire never carries it. Demanding a
* `### \`DUPLICATE_RECORD\`` heading on a page that documents the wire is
* demanding the page publish a code no client can ever receive — which is
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/api/error-code-ledger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ describe('ErrorCode (standard ∪ registered)', () => {
// Domain-prefixed, none re-spells a standard member — registered plainly, no waiver.
expect(standardSynonymOf(code), `${code} needs no waiver`).toBeUndefined();
}
// The card's ninth, `NAMESPACE_CONFLICT`, was already a row (#14748) — the
// The card's ninth, `NAMESPACE_CONFLICT`, was already a row (commit 92b5d7f00) — the
// one doored code of the batch, whose wire already carries it.
expect(ERROR_CODE_LEDGER['@objectstack/objectql']).toContain('NAMESPACE_CONFLICT');
});
Expand Down
Loading
Loading