From 8c1cab0b942cc2e66130885c71796263e977198f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 23:08:49 +0000 Subject: [PATCH 1/4] docs(spec): re-anchor the dead tracker citations in api/ to the commits that decided them Comment and docblock lines under packages/spec/src/api (rest-server.zod.ts excluded) that cited a tracker number answering 404 now cite the commit in this repository that decided what the line describes, and say so in words. Every file keeps its line count; no code token moves; string literals are left as tokens. Claude-Session: https://claude.ai/code/session_01CiCTczDo7tGhafXjf61dUJ Co-authored-by: Claude --- .../spec/src/api/apis-publish-gates.test.ts | 4 +- packages/spec/src/api/contract.test.ts | 2 +- packages/spec/src/api/contract.zod.ts | 2 +- .../spec/src/api/dataset-selection.test.ts | 2 +- packages/spec/src/api/discovery.test.ts | 10 ++-- packages/spec/src/api/discovery.zod.ts | 28 +++++----- packages/spec/src/api/dispatcher.zod.ts | 2 +- packages/spec/src/api/endpoint.test.ts | 2 +- .../spec/src/api/error-catalog-docs.test.ts | 2 +- .../spec/src/api/error-code-ledger.test.ts | 2 +- .../spec/src/api/error-code-ledger.zod.ts | 44 +++++++-------- packages/spec/src/api/errors.test.ts | 2 +- packages/spec/src/api/errors.zod.ts | 2 +- packages/spec/src/api/export.test.ts | 8 +-- packages/spec/src/api/metadata.test.ts | 4 +- packages/spec/src/api/metadata.zod.ts | 2 +- ...rest-api.handler-status-retirement.test.ts | 2 +- packages/spec/src/api/plugin-rest-api.zod.ts | 4 +- packages/spec/src/api/protocol.test.ts | 36 ++++++------- packages/spec/src/api/protocol.zod.ts | 54 +++++++++---------- packages/spec/src/api/rest-server.test.ts | 8 +-- packages/spec/src/api/validate-data.test.ts | 2 +- 22 files changed, 112 insertions(+), 112 deletions(-) diff --git a/packages/spec/src/api/apis-publish-gates.test.ts b/packages/spec/src/api/apis-publish-gates.test.ts index 3231b0e07b9..6eff8be56b1 100644 --- a/packages/spec/src/api/apis-publish-gates.test.ts +++ b/packages/spec/src/api/apis-publish-gates.test.ts @@ -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 @@ -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 diff --git a/packages/spec/src/api/contract.test.ts b/packages/spec/src/api/contract.test.ts index 5228f3b017a..7d3cffd9b52 100644 --- a/packages/spec/src/api/contract.test.ts +++ b/packages/spec/src/api/contract.test.ts @@ -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', () => { diff --git a/packages/spec/src/api/contract.zod.ts b/packages/spec/src/api/contract.zod.ts index 16f785fdf5c..6a7915f0a23 100644 --- a/packages/spec/src/api/contract.zod.ts +++ b/packages/spec/src/api/contract.zod.ts @@ -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 diff --git a/packages/spec/src/api/dataset-selection.test.ts b/packages/spec/src/api/dataset-selection.test.ts index 0ae442c1266..995e74ef57e 100644 --- a/packages/spec/src/api/dataset-selection.test.ts +++ b/packages/spec/src/api/dataset-selection.test.ts @@ -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> = [ diff --git a/packages/spec/src/api/discovery.test.ts b/packages/spec/src/api/discovery.test.ts index 91a9b15c3bb..59da9b3a4d0 100644 --- a/packages/spec/src/api/discovery.test.ts +++ b/packages/spec/src/api/discovery.test.ts @@ -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 @@ -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 @@ -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 @@ -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 = { production: 'production', sandbox: 'sandbox', diff --git a/packages/spec/src/api/discovery.zod.ts b/packages/spec/src/api/discovery.zod.ts index 1f32d5efe11..c88b6912c4c 100644 --- a/packages/spec/src/api/discovery.zod.ts +++ b/packages/spec/src/api/discovery.zod.ts @@ -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 @@ -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`, 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 @@ -508,8 +508,8 @@ export type DiscoveryEnvironment = z.input; * | `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) | * @@ -521,9 +521,9 @@ export type DiscoveryEnvironment = z.input; * `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 @@ -571,7 +571,7 @@ export type DiscoveryEnvironment = z.input; * "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`: adding a bucket to @@ -584,14 +584,14 @@ export type DiscoveryEnvironment = z.input; * 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> = { // 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', @@ -630,7 +630,7 @@ const NODE_ENV_TO_DISCOVERY_ENVIRONMENT: Readonly` 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 diff --git a/packages/spec/src/api/dispatcher.zod.ts b/packages/spec/src/api/dispatcher.zod.ts index 758f7855f6f..73932ed4c8d 100644 --- a/packages/spec/src/api/dispatcher.zod.ts +++ b/packages/spec/src/api/dispatcher.zod.ts @@ -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. * diff --git a/packages/spec/src/api/endpoint.test.ts b/packages/spec/src/api/endpoint.test.ts index c954472f9e9..7910c0e6733 100644 --- a/packages/spec/src/api/endpoint.test.ts +++ b/packages/spec/src/api/endpoint.test.ts @@ -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'` diff --git a/packages/spec/src/api/error-catalog-docs.test.ts b/packages/spec/src/api/error-catalog-docs.test.ts index 9487bf4f848..662c624211d 100644 --- a/packages/spec/src/api/error-catalog-docs.test.ts +++ b/packages/spec/src/api/error-catalog-docs.test.ts @@ -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 diff --git a/packages/spec/src/api/error-code-ledger.test.ts b/packages/spec/src/api/error-code-ledger.test.ts index b2d277e4282..2898b75ac5a 100644 --- a/packages/spec/src/api/error-code-ledger.test.ts +++ b/packages/spec/src/api/error-code-ledger.test.ts @@ -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'); }); diff --git a/packages/spec/src/api/error-code-ledger.zod.ts b/packages/spec/src/api/error-code-ledger.zod.ts index 1dba8559b53..c218f8929ca 100644 --- a/packages/spec/src/api/error-code-ledger.zod.ts +++ b/packages/spec/src/api/error-code-ledger.zod.ts @@ -105,7 +105,7 @@ * 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 — @@ -121,7 +121,7 @@ * 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 @@ -168,7 +168,7 @@ * 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 @@ -193,7 +193,7 @@ export const ERROR_CODE_LEDGER = { 'AMBIGUOUS_MATCH', // import row matched more than one record 'ANALYTICS_QUERY_FAILED', 'APPROVAL_ACTIONS_FAILED', - // [#8885] The eight rows below are the TEMPLATE-GENERATED members of the + // [commit 30b1c636a] The eight rows below are the TEMPLATE-GENERATED members of the // family whose literal-spelled siblings (`APPROVAL_RECALL_FAILED`, // `APPROVAL_ACTIONS_FAILED`, `APPROVAL_REQUEST_GET_FAILED`, // `APPROVAL_REQUEST_LIST_FAILED`) were already registered: the approvals @@ -295,7 +295,7 @@ export const ERROR_CODE_LEDGER = { 'SUGGESTION_DISMISS_FAILED', 'SUGGESTION_LIST_FAILED', 'SUMMARY_RECOMPUTE_FAILED', - // [#8885] `POST /approvals/requests/:id/remind` inside the reminder + // [commit 30b1c636a] `POST /approvals/requests/:id/remind` inside the reminder // cool-down window — `handleApprovalError` (`rest-server.ts`) maps // plugin-approvals' `THROTTLED: …` throw (`approval-service.ts`, // `remind()`) to 429 with this code on the wire. The spec contract @@ -426,7 +426,7 @@ export const ERROR_CODE_LEDGER = { // `errorFromThrown` (`action-execution.ts`). Reported by the #8087 // dispatcher-vocabulary gate. 'FLOW_FAILED', - // [#11504] the definition-level input-schema refusal: a node's static + // [commit f90e82024] the definition-level input-schema refusal: a node's static // `config` violates the `inputSchema` its own flow definition declares, so // the engine refused to dispatch — nothing ran, nothing was written, and // the result carries NO `status` (the #9378 never-dispatched class, beside @@ -443,7 +443,7 @@ export const ERROR_CODE_LEDGER = { // a node's config contradicts the schema the definition itself declares. // Not a VALIDATION_ERROR synonym: the REQUEST is well-formed — what fails // is the stored definition. Registered ahead of its producer by design - // (the #10413 → #10576 split shape, applied to #10025 → #11504): the + // (the #10413 → #10576 split shape, applied to #10025 → commit f90e82024): the // emitting half — `execute()`'s catch short-circuiting before // `retryExecution` in `@objectstack/service-automation` — is #10025's, // blocked on this row, and asserts this exact string by value. Registered @@ -488,7 +488,7 @@ export const ERROR_CODE_LEDGER = { // listed once per emitting package — provenance, not identity. 'WRITABLE_PACKAGE_REQUIRED', 'WRONG_PASSWORD', - // [#16649] ADR-0130 D4 — `resolveArtifactCollections` + // [commit 613bfbd3d] ADR-0130 D4 — `resolveArtifactCollections` // (`artifact-collections.ts`) refuses one collection key declared in the // ARRAY form by one source and the RECORD form by another inside the same // artifact; `refuse()` there stamps `code` + `status: 422`. Registered @@ -753,7 +753,7 @@ export const ERROR_CODE_LEDGER = { // seam and ahead of `stripSearchCompanion` and the realtime publish. // `UpdateHookResultNotWriteShapeError`, `verb-hook-result-shape.ts`. 'UPDATE_HOOK_RESULT_NOT_WRITE_SHAPE', - // [#14748] the ADR-0048 Phase 1 install-time namespace gate's refusal: a + // [commit 92b5d7f00] the ADR-0048 Phase 1 install-time namespace gate's refusal: a // package's `manifest.namespace` is already owned by an INSTALLED package // that is not a co-owner of it (ADR-0130 D1), so the install is refused up // front rather than allowed to half-apply and fail later at table @@ -765,7 +765,7 @@ export const ERROR_CODE_LEDGER = { // no artifact install SCOPE — which this gate, unlike the ADR-0130 D3 // object-name one, does not need — so an ordinary one-package install // reaches it, and the domain's terminal catch answers through - // `errorFromThrown`. #14474 gave the throw its ADR-0112 envelope (`code` + + // `errorFromThrown`. Commit df657d9df gave the throw its ADR-0112 envelope (`code` + // `status: 422`); until this row landed the door's #9106 narrowing demoted // the spelling onto the open `declaredCode` sibling and put the closed // member 422 derives (`VALIDATION_ERROR`) in `error.code`, so a caller @@ -819,7 +819,7 @@ export const ERROR_CODE_LEDGER = { // QUERY_OBJECT_MISMATCH one layer up. 'UPDATE_ID_MISMATCH', 'VALIDATION_FAILED', - // [#16649] ADR-0130 D3 — two packages delivered by ONE release artifact + // [commit 613bfbd3d] ADR-0130 D3 — two packages delivered by ONE release artifact // both claiming the same object name, refused by // `SchemaRegistry.installPackage` ahead of every mutation it makes and // therefore ahead of all DDL (`registry.ts`; `status: 422`; the literal @@ -847,7 +847,7 @@ export const ERROR_CODE_LEDGER = { 'ERR_BULK_RESULT_MISMATCH', 'FILTER_TOKEN_UNKNOWN', // filter references an unknown context token 'FILTER_TOKEN_UNRESOLVED', - // [#16649] The nine rows below are `door: 'none'` codes — raised while a + // [commit 613bfbd3d] The nine rows below are `door: 'none'` codes — raised while a // process is still assembling itself, or by a runner the CLI drives — // registered under the #16404 ruling (door or no door; see the header). // Each ships in this package's `dist/index.js` (measured), so its @@ -916,7 +916,7 @@ export const ERROR_CODE_LEDGER = { 'DELIVERY_NEVER_SENT', // [#8069] terminal delivery row with 0 attempts — a PARKED record of a delivery that could never be prepared, not one that failed. Redelivering it would be a FIRST send, and the row carries no HMAC signature because the secret that would have produced one is exactly what went missing, so it would go out unsigned (#7799). Distinct from DELIVERY_NOT_ELIGIBLE: that one says "wrong state, try when it settles"; this one says "never, fix the configuration instead" // "this delivery row's state does not permit the requested operation" — // ONE concept on TWO delivery surfaces of this package, deliberately - // sharing one spelling (PR #11858's contract-review PASS ruled option B; + // sharing one spelling (commit 1a47a5368's contract-review PASS ruled option B; // a second near-synonym code was rejected for the vocabulary sprawl // ADR-0112 exists to prevent). Stated per-surface because the two refuse // OPPOSITE halves of the state space — no single status predicate glosses @@ -931,11 +931,11 @@ export const ERROR_CODE_LEDGER = { // re-claimed the row mid-call — both `SqlHttpOutbox` and // `MemoryHttpOutbox` report that miss instead of a false success // (#11009). - // - `INotificationOutbox.ack` (`NotificationAckError`; #11453, #11859) + // - `INotificationOutbox.ack` (`NotificationAckError`; commits 1a47a5368, d9cf78eaa) // refuses a row that is not `in_flight` — an unclaimed `pending` row // (the ack-as-cancel trap) or an already-terminal one, because `ack` // records the outcome of a delivery the caller CLAIMED — AND, since - // #11859, an `in_flight` row no longer held by the claim being + // commit d9cf78eaa, an `in_flight` row no longer held by the claim being // completed: `ack` takes back the record `claim()` returned and the // compare-and-set binds its (`claimed_by`, `claimed_at`) credential, // so a claim lost to the `claimTtlMs` reap plus a re-claim (by ANY @@ -1117,7 +1117,7 @@ export const ERROR_CODE_LEDGER = { 'NOT_OVERRIDABLE', 'SUGGESTION_NOT_FOUND', 'SUGGESTION_STATE', // suggestion exists but is not in a confirmable/dismissable state - // [#19307] The data door's duplicate-name refusal on `sys_permission_set` + // [commit 8f6d83147] The data door's duplicate-name refusal on `sys_permission_set` // — `PermissionSetNameConflictError` (`errors.ts`), thrown by the // ADR-0094 D3 write-through middleware's insert leg // (`permission-set-projection.ts`) when a set with that machine name @@ -1157,7 +1157,7 @@ export const ERROR_CODE_LEDGER = { 'INVALID_REQUEST', ], '@objectstack/organizations': [ - // [#16649] The walled-posture membership-policy gate (#16130, ADR-0132): + // [commit 613bfbd3d] The walled-posture membership-policy gate (#16130, ADR-0132): // `assertWalledMembershipPolicyDeclared` (`membership-policy-gate.ts`) // throws `WalledMembershipPolicyError` — this code as `code` via the // exported `MEMBERSHIP_POLICY_ERROR_CODE`, no `status` — when a walled @@ -1178,7 +1178,7 @@ export const ERROR_CODE_LEDGER = { ], '@objectstack/driver-memory': [ // [#13254] Provenance for the in-memory driver's uniqueness refusal, which - // #13197 (field-level `unique`) and #13239 (declared `indexes[]` entries) + // commit 56c093c4d (field-level `unique`) and #13239 (declared `indexes[]` entries) // made real: a colliding write is REFUSED rather than landed. Stamped in // ONE place for both declaration surfaces — `conflictRefusal` // (`packages/drivers/driver-memory/src/memory-unique-constraint.ts`), @@ -1201,7 +1201,7 @@ export const ERROR_CODE_LEDGER = { // admission rule checks WHO emits, so an unlisted emitter is invisible to // every gate the repo has. 'UNIQUE_VIOLATION', - // [#16649] The in-memory driver's tenancy refusal — + // [commit 613bfbd3d] The in-memory driver's tenancy refusal — // `MemoryMultiTenantUnsupportedError` (`memory-tenancy-guard.ts`) carries // this code as `code` via the exported `MULTI_TENANT_UNSUPPORTED_CODE`, // no `status`; thrown by `assertSingleTenantPosture` and @@ -1219,7 +1219,7 @@ export const ERROR_CODE_LEDGER = { 'MEMORY_MULTI_TENANT_UNSUPPORTED', ], '@objectstack/driver-mongodb': [ - // [#16649] The MongoDB driver's tenancy refusal — + // [commit 613bfbd3d] The MongoDB driver's tenancy refusal — // `MongoDBMultiTenantUnsupportedError` (`mongodb-tenancy-guard.ts`) // carries this code as `code` via the exported // `MULTI_TENANT_UNSUPPORTED_CODE`, no `status`; thrown by @@ -1250,12 +1250,12 @@ export const ERROR_CODE_LEDGER = { // that": the request is well-formed and nothing faulted. // // Registered from the start — not left driver-local, as - // `MULTI_TENANT_UNSUPPORTED_CODE` was until #16649 — because it IS + // `MULTI_TENANT_UNSUPPORTED_CODE` was until commit 613bfbd3d — because it IS // wire-reachable: publishing a drafted object calls // `engine.syncObjectSchema` → `SqlDriver.syncSchema` → the DDL gate, on a // server already serving HTTP. That is the exact test #8035 applied when // it UNregistered `MONGODB_MULTI_TENANT_UNSUPPORTED` for failing it — a - // removal #16649 reversed under #16404; the test now decides only what a + // removal commit 613bfbd3d reversed under #16404; the test now decides only what a // door answers with, never whether a shipped code is registered. // Producer: `packages/drivers/driver-sql/src/dialect-emission-refusal.ts`. 'SQL_DIALECT_EMISSION_UNSUPPORTED', diff --git a/packages/spec/src/api/errors.test.ts b/packages/spec/src/api/errors.test.ts index 155846e720c..c6070f502f9 100644 --- a/packages/spec/src/api/errors.test.ts +++ b/packages/spec/src/api/errors.test.ts @@ -144,7 +144,7 @@ describe('EnhancedApiErrorSchema', () => { expect(error.documentation).toContain('objectstack.dev'); }); - // [#9934] Same field, same semantics as `ApiErrorSchema.userMessage` — the + // [commit 79c46da90] Same field, same semantics as `ApiErrorSchema.userMessage` — the // producer-side user-facing marking of the objectui#5210 ruling. it('carries a producer-marked `userMessage` verbatim, and stays absent when unmarked', () => { const marked = EnhancedApiErrorSchema.parse({ diff --git a/packages/spec/src/api/errors.zod.ts b/packages/spec/src/api/errors.zod.ts index cb2f18b70b8..085c27940cc 100644 --- a/packages/spec/src/api/errors.zod.ts +++ b/packages/spec/src/api/errors.zod.ts @@ -387,7 +387,7 @@ export const EnhancedApiErrorSchema = lazySchema(() => z.object({ * The producer's user-facing refusal text, verbatim — the same field, with * the same semantics, as `ApiErrorSchema.userMessage` (`contract.zod.ts`, * which carries the full rationale): the producer-side opt-in that marks a - * refusal message as addressed to the END USER (#9934, maintainer ruling + * refusal message as addressed to the END USER (commit 79c46da90, maintainer ruling * 2026-08-19 on objectui#5210). Present exactly when the producer opted in * at throw time; absent means consumers keep their generic substitution * (#3821 preserved by construction). Status-agnostic; never replaces diff --git a/packages/spec/src/api/export.test.ts b/packages/spec/src/api/export.test.ts index 7ac19ac1c38..2097ac94f9c 100644 --- a/packages/spec/src/api/export.test.ts +++ b/packages/spec/src/api/export.test.ts @@ -244,7 +244,7 @@ describe('ExportImportTemplateSchema', () => { }); // ========================================== -// Import Request — runAutomations declared default (#6704) +// Import Request — runAutomations declared default (commit c3f491626) // ========================================== /** @@ -257,9 +257,9 @@ describe('ExportImportTemplateSchema', () => { * `POST /data/:object/import` decides on — lives in * `packages/rest/src/import-run-automations-agreement.test.ts`, because only * that package can reach both the schema and `prepareImportRequest`. Neither - * half alone is the fact #6704 is about: the fact is the AGREEMENT. + * half alone is the fact commit c3f491626 pins: the fact is the AGREEMENT. * - * Before #6704 the two disagreed on exactly one input — the omitted key — and + * Before commit c3f491626 the two disagreed on exactly one input — the omitted key — and * that is the case a reader should look at first. */ describe('ImportRequestSchema — runAutomations declared default (#6704)', () => { @@ -302,7 +302,7 @@ describe('ImportRequestSchema — runAutomations declared default (#6704)', () = }); /** - * `mappingName` declared on the contract (#10330). + * `mappingName` declared on the contract (commit b9e9227e3). * * The wire accepted it long before the schema declared it: both import routes * read `body.mappingName` off the raw body in `prepareImportRequest` diff --git a/packages/spec/src/api/metadata.test.ts b/packages/spec/src/api/metadata.test.ts index ef91a2522bb..c1b75b85e38 100644 --- a/packages/spec/src/api/metadata.test.ts +++ b/packages/spec/src/api/metadata.test.ts @@ -532,7 +532,7 @@ describe('MetadataBulkResponseSchema', () => { }); // ========================================== -// 5. Overlay / Customization — REMOVED (#13135, ADR-0049; see metadata.zod.ts §5) +// 5. Overlay / Customization — REMOVED (commit 9e0ba21a1, ADR-0049; see metadata.zod.ts §5) // ========================================== // ========================================== @@ -994,7 +994,7 @@ describe('Cross-Framework Metadata API Contracts', () => { }); // (The `…/overlay` and `…/effective` route cases were removed with the - // section-5 contracts — #13135, ADR-0049: no adapter ever served those + // section-5 contracts — commit 9e0ba21a1, ADR-0049: no adapter ever served those // paths, so the cases pinned an API that did not exist.) describe('GET /api/meta/:type/:name/dependencies — Get dependencies', () => { diff --git a/packages/spec/src/api/metadata.zod.ts b/packages/spec/src/api/metadata.zod.ts index b888735ea12..4935a217628 100644 --- a/packages/spec/src/api/metadata.zod.ts +++ b/packages/spec/src/api/metadata.zod.ts @@ -194,7 +194,7 @@ export const MetadataBulkResponseSchema = lazySchema(() => BaseResponseSchema.ex // // The section-5 contracts (`MetadataOverlayResponseSchema`, // `MetadataOverlaySaveRequestSchema`, `MetadataEffectiveResponseSchema`) were -// REMOVED per ADR-0049 enforce-or-remove (#13135, re-charter of #12057): +// REMOVED per ADR-0049 enforce-or-remove (commit 9e0ba21a1, re-charter of #12057): // they declared REST contracts for the paper metadata-customization protocol // — `GET/PUT …/overlay`, `GET …/effective` — endpoints NO adapter ever // served (measured: no route spelling exists in packages/rest or diff --git a/packages/spec/src/api/plugin-rest-api.handler-status-retirement.test.ts b/packages/spec/src/api/plugin-rest-api.handler-status-retirement.test.ts index bd3d30eccb9..34f6db454d7 100644 --- a/packages/spec/src/api/plugin-rest-api.handler-status-retirement.test.ts +++ b/packages/spec/src/api/plugin-rest-api.handler-status-retirement.test.ts @@ -53,7 +53,7 @@ import { // `kernel/Manifest:loading` precedent). The D3 semantic entry // `rest-api-endpoint-handler-status-retired` carries the prescription. // -// On the assertion set (the #8586 / #11846 precedent): a schema refusal +// On the assertion set (the #8586 / commit 0c2334f6c precedent): a schema refusal // raises a `ZodError` whose issues carry `code` and `path` but no ADR-0112 // `status` — that envelope belongs to the API error surface. So these pins // assert the strongest set this surface really has: refusal, the issue diff --git a/packages/spec/src/api/plugin-rest-api.zod.ts b/packages/spec/src/api/plugin-rest-api.zod.ts index f7e5236c4fc..158eb30fd9d 100644 --- a/packages/spec/src/api/plugin-rest-api.zod.ts +++ b/packages/spec/src/api/plugin-rest-api.zod.ts @@ -36,7 +36,7 @@ import { retiredKey } from '../shared/retired-key'; * // 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'; @@ -1166,7 +1166,7 @@ export const DEFAULT_NOTIFICATION_ROUTES: RestApiRouteRegistration = { category: 'notification', public: false, summary: 'List notifications', - // NOT "paginated" (#6361). The route answers the newest `limit` rows and + // NOT "paginated" (commit 90bbf2510). The route answers the newest `limit` rows and // stops; there is no continuation token on either half of the contract // since `cursor` was removed in protocol 17. The catalog is a // machine-readable surface (Route & surface ownership rule 4), so a diff --git a/packages/spec/src/api/protocol.test.ts b/packages/spec/src/api/protocol.test.ts index 10a68d2fc96..8c9d6129809 100644 --- a/packages/spec/src/api/protocol.test.ts +++ b/packages/spec/src/api/protocol.test.ts @@ -14,7 +14,7 @@ import { CreateManyDataResponseSchema, UpdateManyDataRequestSchema, DeleteManyDataRequestSchema, - // View-management schemas removed with the retired ViewProtocol (#6239, v17) + // View-management schemas removed with the retired ViewProtocol (commit f549a0d4a, v17) // Permissions CheckPermissionRequestSchema, CheckPermissionResponseSchema, @@ -283,9 +283,9 @@ describe('ObjectStack Protocol', () => { }); /** - * [#6361] `GET /api/v1/notifications` declares no pagination — on either half. + * [commit 90bbf2510] `GET /api/v1/notifications` declares no pagination — on either half. * - * Maintainer ruling 2026-08-07 (Option A), ruled jointly with #6363: one + * Maintainer ruling 2026-08-07 (Option A), ruled jointly with the `unreadCount` fix (commit 17d095413): one * capability's two halves are never half-deleted. `cursor` was declared on the * request AND the response and honoured on neither, and `limit` declared a * `.default(20)` no request path has ever applied (the server windows at 50). @@ -341,7 +341,7 @@ describe('ObjectStack Protocol', () => { const parsedEmpty = ListNotificationsRequestSchema.parse({}); expect(Object.prototype.hasOwnProperty.call(parsedEmpty, 'limit')).toBe(false); expect(ListNotificationsRequestSchema.parse({ limit: 7 }).limit).toBe(7); - // The response half keeps exactly #6363's landed business, and gains nothing. + // The response half keeps exactly what commit 17d095413 landed (`unreadCount`), and gains nothing. expect(ListNotificationsResponseSchema.safeParse({ notifications: [], unreadCount: 0 }).success).toBe(true); }); @@ -1653,7 +1653,7 @@ describe('meta-read request schemas declare organizationId (#9726 — declared = }); describe('meta-read request schemas declare the draft-visibility switches (#9741 — declared = enforced)', () => { - // Maintainer ruling 2026-08-18 (#9741): declare `previewDrafts` / `state` + // Maintainer ruling 2026-08-18 (commit 2a29caa53): declare `previewDrafts` / `state` // exactly where the implementation enforces them, and record `environmentId` // as transport-level — OUT of the request shape by decision. The // implementation's inline parameter types are the measure: @@ -1737,7 +1737,7 @@ describe('meta-read request schemas declare the draft-visibility switches (#9741 }); describe('environmentId stays OUT of the meta-read request shape — by decision, not omission (#9741)', () => { - // Maintainer ruling 2026-08-18 (#9741): `environmentId` is the + // Maintainer ruling 2026-08-18 (commit 2a29caa53): `environmentId` is the // TRANSPORT-level multi-kernel routing key. The REST layer resolves the // target kernel from it BEFORE the protocol call, the implementation's // parameter types never read it off the request, and these schemas record @@ -1865,7 +1865,7 @@ describe('PublishMetaItemRequestSchema mirrors the implementation parameter type it('does not declare environmentId — transport-level by the #9741 ruling, stripped and shape-absent', () => { // Same regression guard as the meta-read block above: if someone declares // the member, the parse stops stripping it and this test names the ruling - // they are overturning (2026-08-18 on #9741: `environmentId` is the + // they are overturning (2026-08-18, commit 2a29caa53: `environmentId` is the // multi-kernel ROUTING key; `packages/rest` layers it on top via // `TransportScopedMetaRequest`). const result = PublishMetaItemRequestSchema.safeParse({ ...base, environmentId: 'env_alpha' }); @@ -1890,7 +1890,7 @@ describe('PublishMetaItemRequestSchema mirrors the implementation parameter type describe('MetadataProtocol declares publishMetaItem (#11006)', () => { // Type-level pins (compiled by the spec test typecheck, the - // translation-typegen.test.ts pattern — same as the #9740 block above). + // translation-typegen.test.ts pattern — same as the getMetaItemLayered block above, commit 11b779e0f). // Before this declaration the cast at the REST call site carried // MEMBER-EXISTENCE weight (deleting it answered TS2339, not TS2353), so a // request literal there was typed by nothing. These pins are what turns @@ -1916,7 +1916,7 @@ describe('MetadataProtocol declares publishMetaItem (#11006)', () => { // declaration any key sailed through the `(p as any)` cast. const good: PublishMetaItemRequest = { type: 'view', name: 'account_list', packageId: 'pkg_crm' }; expect(good.type).toBe('view'); - // @ts-expect-error `environmentId` is transport-level (#9741) — not a declared request member. + // @ts-expect-error `environmentId` is transport-level (commit 2a29caa53) — not a declared request member. const withEnv: PublishMetaItemRequest = { type: 'view', name: 'account_list', environmentId: 'env_a' }; expect(withEnv.name).toBe('account_list'); // @ts-expect-error an undeclared (here: misspelt) key is refused at the call shape. @@ -1929,8 +1929,8 @@ import { AuditMetaItemRequestSchema, AuditMetaItemResponseSchema } from './proto import type { AuditMetaItemRequest, AuditMetaItemResponse } from './protocol.zod'; describe('AuditMetaItemRequestSchema mirrors the implementation parameter type (#11678)', () => { - // The audit door was a step BEHIND the half-declared publish door #11006 - // adjudicated: NEITHER side was declared, and the REST call site reached the + // The audit door was a step BEHIND the half-declared publish door (closed by + // commit cccbe51bf): NEITHER side was declared, and the REST call site reached the // verb through `(p as any)` twice (guard + call). The measure is the // implementation's parameter type in `@objectstack/metadata-protocol` — // `{ type, name, organizationId?: string | null, limit?: number }` — and the @@ -2046,7 +2046,7 @@ describe('AuditMetaItemResponseSchema declares the compliance-trail body (#11678 describe('MetadataProtocol declares auditMetaItem (#11678)', () => { // Type-level pins (compiled by the spec test typecheck, the - // translation-typegen.test.ts pattern — same as the #9740 and #11006 blocks + // translation-typegen.test.ts pattern — same as the getMetaItemLayered (commit 11b779e0f) and publishMetaItem (commit cccbe51bf) blocks // above). Before this declaration the casts at the REST call site carried // MEMBER-EXISTENCE weight (TS2339, not TS2353), so the request literal // there was typed by nothing. These pins are what turns red if the member @@ -2067,7 +2067,7 @@ describe('MetadataProtocol declares auditMetaItem (#11678)', () => { it('refuses an undeclared key at the member call shape', () => { const good: AuditMetaItemRequest = { type: 'view', name: 'account_list', organizationId: null }; expect(good.type).toBe('view'); - // @ts-expect-error `environmentId` is transport-level (#9741) — not a declared request member (and #8747 removed it from this door's wire payload entirely). + // @ts-expect-error `environmentId` is transport-level (commit 2a29caa53) — not a declared request member (and #8747 removed it from this door's wire payload entirely). const withEnv: AuditMetaItemRequest = { type: 'view', name: 'account_list', environmentId: 'env_a' }; expect(withEnv.name).toBe('account_list'); // @ts-expect-error an undeclared (here: misspelt) key is refused at the call shape. @@ -2244,7 +2244,7 @@ describe('MetadataProtocol declares historyMetaItem (#12005)', () => { it('refuses an undeclared key at the member call shape', () => { const good: HistoryMetaItemRequest = { type: 'view', name: 'account_list', sinceSeq: 3, limit: 50 }; expect(good.type).toBe('view'); - // @ts-expect-error `environmentId` is transport-level (#9741) — not a declared request member (the REST door's spread of it rides the TransportScopedMetaRequest wrapper, never this shape). + // @ts-expect-error `environmentId` is transport-level (commit 2a29caa53) — not a declared request member (the REST door's spread of it rides the TransportScopedMetaRequest wrapper, never this shape). const withEnv: HistoryMetaItemRequest = { type: 'view', name: 'account_list', environmentId: 'env_a' }; expect(withEnv.name).toBe('account_list'); // @ts-expect-error an undeclared (here: misspelt) key is refused at the call shape. @@ -2322,7 +2322,7 @@ describe('DeleteMetaItemRequestSchema declares the contract members the reset do // the reset door DOES spread `environmentId` into its outgoing payload, // and that member rides `packages/rest`'s `TransportScopedMetaRequest` // envelope — never this schema. If someone declares it, this test names - // the ruling they are overturning (2026-08-18 on #9741). + // the ruling they are overturning (2026-08-18, commit 2a29caa53). const result = DeleteMetaItemRequestSchema.safeParse({ ...base, environmentId: 'env_alpha' }); expect(result.success).toBe(true); if (result.success) { @@ -2358,7 +2358,7 @@ describe('MetadataProtocol.deleteMetaItem types against the caught-up request sc dropStorage: true, }; expect(good.type).toBe('view'); - // @ts-expect-error `environmentId` is transport-level (#9741) — not a declared request member; the REST door layers it on via TransportScopedMetaRequest. + // @ts-expect-error `environmentId` is transport-level (commit 2a29caa53) — not a declared request member; the REST door layers it on via TransportScopedMetaRequest. const withEnv: DeleteMetaItemRequest = { type: 'view', name: 'account_list', environmentId: 'env_a' }; expect(withEnv.name).toBe('account_list'); // @ts-expect-error an undeclared (here: misspelt) key is refused at the call shape. @@ -2485,7 +2485,7 @@ describe('SaveMetaItemRequestSchema declares the contract members the save door // outgoing payload, and that member rides `packages/rest`'s // `TransportScopedMetaRequest` envelope — never this schema. If someone // declares it, this test names the ruling they are overturning - // (2026-08-18 on #9741). + // (2026-08-18, commit 2a29caa53). const result = SaveMetaItemRequestSchema.safeParse({ ...base, environmentId: 'env_alpha' }); expect(result.success).toBe(true); if (result.success) { @@ -2540,7 +2540,7 @@ describe('MetadataProtocol.saveMetaItem types against the caught-up request sche writeFace: 'meta-dispatch', }; expect(good.type).toBe('view'); - // @ts-expect-error `environmentId` is transport-level (#9741) — not a declared request member; the REST door layers it on via TransportScopedMetaRequest. + // @ts-expect-error `environmentId` is transport-level (commit 2a29caa53) — not a declared request member; the REST door layers it on via TransportScopedMetaRequest. const withEnv: SaveMetaItemRequest = { type: 'view', name: 'account_list', environmentId: 'env_a' }; expect(withEnv.name).toBe('account_list'); // @ts-expect-error `source` is implementation-internal provenance — no producer on this contract sends it, and the REST layer never reads it off the wire. diff --git a/packages/spec/src/api/protocol.zod.ts b/packages/spec/src/api/protocol.zod.ts index 1795c74e649..9ac510ab36b 100644 --- a/packages/spec/src/api/protocol.zod.ts +++ b/packages/spec/src/api/protocol.zod.ts @@ -223,7 +223,7 @@ export const GetMetaTypesResponseSchema = lazySchema(() => z.object({ * Get all items of a specific metadata type * * **`environmentId` is deliberately NOT a member here — or on any meta-read - * request schema** (maintainer ruling 2026-08-18, #9741). It is the + * request schema** (maintainer ruling 2026-08-18, commit 2a29caa53). It is the * TRANSPORT-level multi-kernel routing key: the REST layer resolves the target * kernel from it *before* the protocol call, and the implementation's own * parameter types (`@objectstack/metadata-protocol`) never read it off the @@ -582,8 +582,8 @@ export const RuntimeAuthoringIssueSchema = lazySchema(() => z.object({ * * Declared member for member against the implementation's parameter type in * `@objectstack/metadata-protocol` and the REST save door's actual sends — a - * declared-surface catch-up, not a new capability (#12004, the #11006 - * maintainer-ruled pattern, 2026-08-22 option B, carried one door over + * declared-surface catch-up, not a new capability (#12004, the maintainer-ruled + * pattern of commit cccbe51bf, 2026-08-22 option B, carried one door over * exactly as #11679/PR #12003 carried it to the reset twin). `saveMetaItem` * is a REQUIRED protocol member, so this was the sharpest instance of the * request-shape gap: the schema declared 3 of the ~11 members the door @@ -593,7 +593,7 @@ export const RuntimeAuthoringIssueSchema = lazySchema(() => z.object({ * Every member below already ships and is read and enforced by the * implementation. * - * `name` carries the enforced item-name grammar (#12194 — lowercase + * `name` carries the enforced item-name grammar (commit 311433f6b — lowercase * snake_case segments, optionally dot-qualified; `shared/identifiers.zod.ts` * is the single source). The implementation refuses an off-grammar name at * the door with `400 INVALID_REQUEST`, so declared = enforced. The read and @@ -604,7 +604,7 @@ export const RuntimeAuthoringIssueSchema = lazySchema(() => z.object({ * deliberately NOT declared: * * - `environmentId` — the TRANSPORT-level multi-kernel routing key, OUT of - * protocol request shapes by the #9741 maintainer ruling (2026-08-18): + * protocol request shapes by the maintainer ruling of 2026-08-18 (commit 2a29caa53): * `resolveProtocol(environmentId)` has already selected the target kernel * before this method is entered, and `packages/rest` layers that one * member on top of the declared shape via its `TransportScopedMetaRequest` @@ -787,7 +787,7 @@ export const SaveMetaItemResponseSchema = lazySchema(() => z.object({ * (with `?mode=draft`) stages a body, and this verb promotes the pending * DRAFT overlay to the live `active` row. Mirrors the implementation's * parameter type in `@objectstack/metadata-protocol` member for member — a - * declared-surface catch-up, not a new capability (#11006, maintainer ruling + * declared-surface catch-up, not a new capability (commit cccbe51bf, maintainer ruling * 2026-08-22: option B, closing the half-declared door #7294 left — the * response side was declared there while the request and the interface member * were not). The verb and every member here already ship and are enforced. @@ -796,7 +796,7 @@ export const SaveMetaItemResponseSchema = lazySchema(() => z.object({ * deliberately NOT declared: * * - `environmentId` — the TRANSPORT-level multi-kernel routing key, OUT of - * protocol request shapes by the #9741 maintainer ruling (2026-08-18): + * protocol request shapes by the maintainer ruling of 2026-08-18 (commit 2a29caa53): * `resolveProtocol(environmentId)` has already selected the target kernel * before this method is entered, and `packages/rest` layers that one member * on top of the declared shape via its `TransportScopedMetaRequest` wrapper, @@ -1255,8 +1255,8 @@ export const PublishPackageDraftsResponseSchema = lazySchema(() => z.object({ * * Declared member for member against the implementation's parameter type in * `@objectstack/metadata-protocol` and the REST reset door's actual sends — a - * declared-surface catch-up, not a new capability (#11679, the #11006 - * maintainer-ruled pattern): every member here already ships and is enforced. + * declared-surface catch-up, not a new capability (#11679, the maintainer-ruled + * pattern of commit cccbe51bf): every member here already ships and is enforced. * The member existed on `MetadataProtocol` all along; the request schema * declared 2 of the 8 members the reset door sends, so the door's call site * had to stay behind an `as any` cast (removing it surfaced `TS2353` on the @@ -1264,7 +1264,7 @@ export const PublishPackageDraftsResponseSchema = lazySchema(() => z.object({ * * One wire member is deliberately NOT declared: `environmentId`, the * transport-level multi-kernel routing key, OUT of protocol request shapes by - * the #9741 maintainer ruling (2026-08-18) — `resolveProtocol(environmentId)` + * the maintainer ruling of 2026-08-18 (commit 2a29caa53) — `resolveProtocol(environmentId)` * selects the target kernel before this method is entered, the implementation * never reads it off the request, and `packages/rest` layers it on via its * `TransportScopedMetaRequest` wrapper. @@ -1401,12 +1401,12 @@ export const DeleteMetaItemResponseSchema = lazySchema(() => z.object({ * allowed and denied) that Studio's 审计日志 / Audit log tab renders. Mirrors * the implementation's parameter type in `@objectstack/metadata-protocol` * member for member — a declared-surface catch-up, not a new capability - * (the #11006 maintainer-ruled pattern, 2026-08-22 option B, carried one door + * (the maintainer-ruled pattern of commit cccbe51bf, 2026-08-22 option B, carried one door * over): the verb and every member here already ship and are enforced. * * `environmentId` is deliberately NOT declared — the transport-level - * multi-kernel routing key is OUT of protocol request shapes by the #9741 - * maintainer ruling (2026-08-18): `resolveProtocol(environmentId)` selects the + * multi-kernel routing key is OUT of protocol request shapes by the + * maintainer ruling (2026-08-18, commit 2a29caa53): `resolveProtocol(environmentId)` selects the * target kernel before this method is entered, and the implementation never * reads it off the request (the REST audit door stopped sending it when #8747 * scoped the read). @@ -1500,14 +1500,14 @@ export const AuditMetaItemResponseSchema = lazySchema(() => z.object({ * the `sys_metadata_history` events (every overlay put/delete, ADR-0008 §2.4) * that Studio's History tab renders as a timeline. Mirrors the * implementation's parameter type in `@objectstack/metadata-protocol` member - * for member — a declared-surface catch-up, not a new capability (the #11006 - * maintainer-ruled pattern, 2026-08-22 option B, carried one door over + * for member — a declared-surface catch-up, not a new capability (the maintainer-ruled + * pattern of commit cccbe51bf, 2026-08-22 option B, carried one door over * exactly as #11678 carried it to the audit twin): the verb and every member * here already ship and are enforced. * * `environmentId` is deliberately NOT declared — the transport-level - * multi-kernel routing key is OUT of protocol request shapes by the #9741 - * maintainer ruling (2026-08-18): `resolveProtocol(environmentId)` selects + * multi-kernel routing key is OUT of protocol request shapes by the + * maintainer ruling (2026-08-18, commit 2a29caa53): `resolveProtocol(environmentId)` selects * the target kernel before this method is entered, and the implementation * never declares or reads it off the request. Unlike the audit twin (whose * door stopped sending it when #8747 scoped the read), the REST history door @@ -2089,7 +2089,7 @@ export const ValidateDataIssueSchema = lazySchema(() => z.object({ })); /** - * Validate Data Request (#6037 — #4633 ruling D) + * Validate Data Request (commit 18189983d — #4633 ruling D) * * Ask for the write path's verdict on candidate rows WITHOUT writing them. * @@ -2499,7 +2499,7 @@ export { // `ListViews` / `GetView` / `CreateView` / `UpdateView` / `DeleteView` — // five methods and their ten Request/Response schemas — were REMOVED per -// ADR-0049 enforce-or-remove (#6239, protocol 17, maintainer ruling +// ADR-0049 enforce-or-remove (commit f549a0d4a, protocol 17, maintainer ruling // 2026-08-07). Route 3 of the retirement playbook: not one of the ten was a // KEY on an authorable shape, nothing parsed them, and no route could reach the // methods, so there is no tombstone to write and no source or `sys_metadata` @@ -2722,8 +2722,8 @@ export const NotificationSchema = lazySchema(() => z.object({ // `cursor` was declared on BOTH halves of `GET /api/v1/notifications` and // honoured on neither, and `limit` declared a default the server has never -// applied. Both are removed per the maintainer ruling of 2026-08-07 (#6361, -// Option A), ruled together with #6363 as one capability's two halves — a +// applied. Both are removed per the maintainer ruling of 2026-08-07 (commit 90bbf2510, +// Option A), ruled together with the `unreadCount` fix (commit 17d095413) as one capability's two halves — a // pagination capability is never half-deleted. // // ## What the route actually does @@ -2759,7 +2759,7 @@ export const NotificationSchema = lazySchema(() => z.object({ // service CLAMPS an out-of-range limit (`Math.min(Math.max(limit ?? 50, 1), // 200)`); it does not refuse one. A constraint here would declare a rejection // the wire does not perform — the same declared-not-enforced defect in the -// opposite direction. ADR-0049, #6361. +// opposite direction. ADR-0049, commit 90bbf2510. /** * One prescription, two rejection sites — the `cursor` key was declared on both @@ -3500,7 +3500,7 @@ export interface DataProtocol { deleteData(request: DeleteDataRequest): Promise; /** - * Validate-only (#6037 — #4633 ruling D): the write path's verdict on + * Validate-only (commit 18189983d — #4633 ruling D): the write path's verdict on * candidate rows, with nothing persisted. * * Declared optional because it is additive to a shipped contract, not @@ -3539,7 +3539,7 @@ export interface MetadataProtocol { * a body, this makes it live). Declared optional like its `deleteMetaItem` * / `getMetaItemLayered` siblings: additive to a shipped contract, with the * implementation (`@objectstack/metadata-protocol`) predating the - * declaration. #11006 (maintainer ruling 2026-08-22, option B) promotes + * declaration. Commit cccbe51bf (maintainer ruling 2026-08-22, option B) promotes * what was an ADR-0076 D9 server-only extension into a declared optional * member, closing the half-declared door #7294 left: the response side was * declared there while the request and this member were not — so the @@ -3573,7 +3573,7 @@ export interface MetadataProtocol { * `getMetaItemLayered` siblings: additive to a shipped contract, with the * implementation (`@objectstack/metadata-protocol`) predating the * declaration. Promotes what was an ADR-0076 D9 server-only extension into - * a declared optional member (the #11006 maintainer-ruled pattern, + * a declared optional member (the maintainer-ruled pattern of commit cccbe51bf, * 2026-08-22 option B, carried one door over) — before this, the REST audit * door reached the verb through a runtime cast and its request literal was * compiled against nothing. A host without the verb is CONFORMING: the REST @@ -3590,7 +3590,7 @@ export interface MetadataProtocol { * `getMetaItemLayered` siblings: additive to a shipped contract, with the * implementation (`@objectstack/metadata-protocol`) predating the * declaration. Promotes what was an ADR-0076 D9 server-only extension into - * a declared optional member (the #11006 maintainer-ruled pattern, + * a declared optional member (the maintainer-ruled pattern of commit cccbe51bf, * 2026-08-22 option B, carried one door over exactly as #11678 carried it * to the audit twin) — before this, the REST history door reached the verb * through a runtime cast and its request literal was compiled against @@ -3627,7 +3627,7 @@ export interface PackageProtocol { // `ViewProtocol` (`listViews` / `getView` / `createView` / `updateView` / // `deleteView`) was REMOVED at protocol 17 — see the "View Management -// Operations — RETIRED" note above (#6239). No host implemented it and no route +// Operations — RETIRED" note above (commit f549a0d4a). No host implemented it and no route // reached it; view read/write is `MetadataProtocol` (`getMetaItem` / // `saveMetaItem` / `deleteMetaItem` with `type: 'view'`) plus `getUiView`. diff --git a/packages/spec/src/api/rest-server.test.ts b/packages/spec/src/api/rest-server.test.ts index d83ec5039a8..60da8e49725 100644 --- a/packages/spec/src/api/rest-server.test.ts +++ b/packages/spec/src/api/rest-server.test.ts @@ -195,7 +195,7 @@ describe('CrudOperation', () => { }); }); -// `CrudEndpointPatternSchema` tests were removed with the schema (#14691, ADR-0049 +// `CrudEndpointPatternSchema` tests were removed with the schema (commit b3a63d32c, ADR-0049 // enforce-or-remove): its only consumer, `crud.patterns`, is tombstoned below. describe('CrudEndpointsConfigSchema', () => { @@ -203,7 +203,7 @@ describe('CrudEndpointsConfigSchema', () => { const config = CrudEndpointsConfigSchema.parse({}); expect(config.dataPrefix).toBe('/data'); - // `objectParamStyle` is a tombstone since #14691: the parsed output carries + // `objectParamStyle` is a tombstone since commit b3a63d32c: the parsed output carries // no default for it any more. expect(config).not.toHaveProperty('objectParamStyle'); }); @@ -263,7 +263,7 @@ describe('MetadataEndpointsConfigSchema', () => { expect(config.prefix).toBe('/meta'); expect(config.enableCache).toBe(true); - // `cacheTtl` is a tombstone since #14691: no default is materialized. + // `cacheTtl` is a tombstone since commit b3a63d32c: no default is materialized. expect(config).not.toHaveProperty('cacheTtl'); }); @@ -368,7 +368,7 @@ describe('BatchEndpointsConfigSchema', () => { expect(config.maxBatchSize).toBe(200); expect(config.enableBatchEndpoint).toBe(true); - // `defaultAtomic` is a tombstone since #14691: no default is materialized. + // `defaultAtomic` is a tombstone since commit b3a63d32c: no default is materialized. expect(config).not.toHaveProperty('defaultAtomic'); }); diff --git a/packages/spec/src/api/validate-data.test.ts b/packages/spec/src/api/validate-data.test.ts index 122e54cb9da..9376f9c556c 100644 --- a/packages/spec/src/api/validate-data.test.ts +++ b/packages/spec/src/api/validate-data.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// [#6037 / #4633 ruling D] The validate-only DataProtocol contract. +// [commit 18189983d / #4633 ruling D] The validate-only DataProtocol contract. // // The ruling carried two clauses aimed squarely at this contract, and both are // pinned here because both are the kind that a later edit could quietly undo: From 22a00c42d39ddd825bcd09e69b525d9c5ab975d1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 23:09:28 +0000 Subject: [PATCH 2/4] docs(spec): name the contract review, not the commit, as the reviewer of the shared ack/redeliver spelling Claude-Session: https://claude.ai/code/session_01CiCTczDo7tGhafXjf61dUJ Co-authored-by: Claude --- packages/spec/src/api/error-code-ledger.zod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/spec/src/api/error-code-ledger.zod.ts b/packages/spec/src/api/error-code-ledger.zod.ts index c218f8929ca..d8156cd87b6 100644 --- a/packages/spec/src/api/error-code-ledger.zod.ts +++ b/packages/spec/src/api/error-code-ledger.zod.ts @@ -916,7 +916,7 @@ export const ERROR_CODE_LEDGER = { 'DELIVERY_NEVER_SENT', // [#8069] terminal delivery row with 0 attempts — a PARKED record of a delivery that could never be prepared, not one that failed. Redelivering it would be a FIRST send, and the row carries no HMAC signature because the secret that would have produced one is exactly what went missing, so it would go out unsigned (#7799). Distinct from DELIVERY_NOT_ELIGIBLE: that one says "wrong state, try when it settles"; this one says "never, fix the configuration instead" // "this delivery row's state does not permit the requested operation" — // ONE concept on TWO delivery surfaces of this package, deliberately - // sharing one spelling (commit 1a47a5368's contract-review PASS ruled option B; + // sharing one spelling (the contract review that passed commit 1a47a5368 ruled option B; // a second near-synonym code was rejected for the vocabulary sprawl // ADR-0112 exists to prevent). Stated per-surface because the two refuse // OPPOSITE halves of the state space — no single status predicate glosses From 4574d199d524bd85c8409da9e19f46e6b5a4e738 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 23:16:10 +0000 Subject: [PATCH 3/4] chore(changeset): @objectstack/spec patch for the re-anchored api/ provenance comments The rewritten docblocks ship: src/**/*.zod.ts is in files[], and the comments reach dist .d.ts and .js. Claude-Session: https://claude.ai/code/session_01CiCTczDo7tGhafXjf61dUJ Co-authored-by: Claude --- .changeset/spec-api-provenance-anchors.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .changeset/spec-api-provenance-anchors.md diff --git a/.changeset/spec-api-provenance-anchors.md b/.changeset/spec-api-provenance-anchors.md new file mode 100644 index 00000000000..f1366745395 --- /dev/null +++ b/.changeset/spec-api-provenance-anchors.md @@ -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. From 24d9fba6853632e578426586682669ebfb9d253a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 23:32:54 +0000 Subject: [PATCH 4/4] docs(references): regenerate the three api reference pages the rewritten docblocks project into Generated by `check:generated --fix` (gen:docs only, the one artifact it proved stale); five lines, each the same substitution as its source line. Claude-Session: https://claude.ai/code/session_01CiCTczDo7tGhafXjf61dUJ Co-authored-by: Claude --- content/docs/references/api/dispatcher.mdx | 2 +- content/docs/references/api/error-code-ledger.mdx | 6 +++--- content/docs/references/api/plugin-rest-api.mdx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content/docs/references/api/dispatcher.mdx b/content/docs/references/api/dispatcher.mdx index a4dcbe884a3..719e0c759cd 100644 --- a/content/docs/references/api/dispatcher.mdx +++ b/content/docs/references/api/dispatcher.mdx @@ -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. diff --git a/content/docs/references/api/error-code-ledger.mdx b/content/docs/references/api/error-code-ledger.mdx index 1c348888e5c..c6214a26199 100644 --- a/content/docs/references/api/error-code-ledger.mdx +++ b/content/docs/references/api/error-code-ledger.mdx @@ -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 — @@ -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 @@ -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 diff --git a/content/docs/references/api/plugin-rest-api.mdx b/content/docs/references/api/plugin-rest-api.mdx index 07d3fca8fff..5381d9f5fb6 100644 --- a/content/docs/references/api/plugin-rest-api.mdx +++ b/content/docs/references/api/plugin-rest-api.mdx @@ -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';