From 6afec4532a276b96222df6d6db4c08dbaded8369 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <50353452+hotlong@users.noreply.github.com> Date: Tue, 29 Sep 2026 18:47:17 +0800 Subject: [PATCH 1/3] wip(rest): mechanical first pass of the dead-citation re-anchor (review pending) Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289 Co-authored-by: Claude --- .changeset/rest-provenance-anchors.md | 11 ++ .../src/analytics-fault-user-message.test.ts | 6 +- .../direct-mount-base-follows-apipath.test.ts | 4 +- ...ry-advertised-direct-mounts.parity.test.ts | 6 +- .../src/discovery-schema-conformance.test.ts | 2 +- ...error-response-sandbox-arm-message.test.ts | 8 +- ...esponse-structured-arm-door-parity.test.ts | 16 +- packages/rest/src/error-response.ts | 44 ++--- ...cctx-authz-input-seam-reachability.test.ts | 2 +- .../rest/src/execctx-consumer-census.test.ts | 6 +- ...al-datasource-envelope.conformance.test.ts | 4 +- ...ernal-datasource-routes-auth-guard.test.ts | 22 +-- .../rest/src/external-datasource-routes.ts | 24 +-- ...external-datasource-validate-scope.test.ts | 4 +- packages/rest/src/import-coerce.ts | 2 +- .../rest/src/import-dryrun-parity.test.ts | 2 +- .../rest/src/import-job-integration.test.ts | 4 +- .../import-run-automations-agreement.test.ts | 10 +- ...-runner-historical-readonly-insert.test.ts | 2 +- ...import-runner-unique-violation-row.test.ts | 2 +- packages/rest/src/import-runner.ts | 10 +- packages/rest/src/index.ts | 2 +- packages/rest/src/log.ts | 2 +- packages/rest/src/meta-501-envelope.test.ts | 8 +- .../rest/src/meta-audience-plural.test.ts | 2 +- ...und-save-and-reset-capability-gate.test.ts | 4 +- .../meta-compound-save-force-parity.test.ts | 20 +-- .../meta-compound-save-mode-parity.test.ts | 26 +-- .../rest/src/meta-item-layered-route.test.ts | 2 +- packages/rest/src/meta-object-fls.test.ts | 4 +- packages/rest/src/meta-plural-i18n.test.ts | 8 +- .../src/meta-publish-package-scope.test.ts | 4 +- .../rest/src/meta-published-overlay.test.ts | 6 +- .../src/meta-route-registration-order.test.ts | 4 +- .../src/meta-state-route-doc-spelling.test.ts | 2 +- .../meta-unknown-type-read-refusal.test.ts | 4 +- ...-write-door-capability-enumeration.test.ts | 10 +- ...oor-16019-raw-statement-fault-code.test.ts | 2 +- ...ge-door-execctx-fault-reachability.test.ts | 30 ++-- .../src/package-door-user-message.test.ts | 2 +- ...package-routes-coded-error-mapping.test.ts | 2 +- packages/rest/src/package-routes.ts | 6 +- packages/rest/src/query-multiplicity.ts | 6 +- .../rest-14078-invalid-date-total-arm.test.ts | 2 +- .../src/rest-4xx-message-truncation.test.ts | 2 +- .../src/rest-5xx-status-passthrough.test.ts | 2 +- .../src/rest-api-derivation-gates.test.ts | 4 +- .../src/rest-api-plugin-slot-lookups.test.ts | 2 +- packages/rest/src/rest-api-plugin.ts | 2 +- .../src/rest-approvals-wire-codes.test.ts | 6 +- .../src/rest-duplicate-record-arm.test.ts | 6 +- .../src/rest-exec-ctx-principal-kind.test.ts | 6 +- ...st-field-visibility-fault-envelope.test.ts | 4 +- .../src/rest-hook-refusal-code-parity.test.ts | 2 +- .../rest-hook-refusal-message-parity.test.ts | 10 +- .../rest-hook-script-fault-envelope.test.ts | 2 +- packages/rest/src/rest-route-ledger.ts | 10 +- .../src/rest-sandbox-declared-status.test.ts | 8 +- ...server-meta-org-scope-url-spelling.test.ts | 8 +- .../rest-server-meta-read-org-scope.test.ts | 12 +- ...r-meta-references-refusal-envelope.test.ts | 2 +- .../rest-server-meta-write-org-scope.test.ts | 2 +- .../rest-server-query-multiplicity.test.ts | 2 +- packages/rest/src/rest-server.ts | 168 +++++++++--------- ...st-share-user-message-bypass-exits.test.ts | 4 +- .../rest/src/rest-share-user-message.test.ts | 4 +- .../rest-sub-config-parse-not-cast.test.ts | 18 +- .../src/rest-thrown-code-vocabulary.test.ts | 6 +- .../rest-user-facing-refusal-marking.test.ts | 4 +- ...-response-internal-fields.tripwire.test.ts | 2 +- packages/rest/src/rest.test.ts | 2 +- ...ui-view-route-identity.measurement.test.ts | 4 +- .../ui-view-route-tenancy.measurement.test.ts | 8 +- 73 files changed, 336 insertions(+), 325 deletions(-) create mode 100644 .changeset/rest-provenance-anchors.md diff --git a/.changeset/rest-provenance-anchors.md b/.changeset/rest-provenance-anchors.md new file mode 100644 index 00000000000..41679c5a768 --- /dev/null +++ b/.changeset/rest-provenance-anchors.md @@ -0,0 +1,11 @@ +--- +'@objectstack/rest': patch +--- + +Provenance comments in `@objectstack/rest` were re-anchored + +Comment and docblock lines under `src/` 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 route, error code, refusal text, type, export or runtime behaviour +changes. diff --git a/packages/rest/src/analytics-fault-user-message.test.ts b/packages/rest/src/analytics-fault-user-message.test.ts index 01e75fa1ac7..fea6527d2ea 100644 --- a/packages/rest/src/analytics-fault-user-message.test.ts +++ b/packages/rest/src/analytics-fault-user-message.test.ts @@ -24,7 +24,7 @@ * ①b — the arm that re-dresses `classifiedRefusalAnswer`'s body with * `...refusalFields` — IS the arm the card measured, and it does carry the mark * because that body comes from `resolveErrorResponse`, whose arms already ride - * it (`withDeclaredUserMessage`, #9934). §5 pins ①b as untouched, so the two + * it (`withDeclaredUserMessage`, commit 79c46da90). §5 pins ①b as untouched, so the two * classified arms are not flattened into one story in either direction. * * What ①, ③a and ③b have in common is that none of them holds a classified body @@ -43,7 +43,7 @@ * 1. `classifyDataError` (`error-response.ts`), whose only caller is the * exported `mapDataError`, which IS `withDeclaredUserMessage(error, * classifyDataError(…))`. That door already carries the mark, applied one - * layer OUT and branch-agnostically over every arm — the shape #9934 chose + * layer OUT and branch-agnostically over every arm — the shape commit 79c46da90 chose * deliberately, and the reason the shared body-builder carries no mark of * its own. * 2. this route's ③a. @@ -323,7 +323,7 @@ describe('[#12710] §4 both doors carry the same producer mark for the same thro const flat = dataDoor(c.error()); // POSITIVE CONTROL — without this the analytics assertion below could pass // for the wrong reason (two doors agreeing the mark does not belong on - // this terminal). #9934 rules that it does; `/data` is where that ruling + // this terminal). Commit 79c46da90 rules that it does; `/data` is where that ruling // already lives. expect( flat.body.userMessage, diff --git a/packages/rest/src/direct-mount-base-follows-apipath.test.ts b/packages/rest/src/direct-mount-base-follows-apipath.test.ts index 89d23f7e964..6faa6336268 100644 --- a/packages/rest/src/direct-mount-base-follows-apipath.test.ts +++ b/packages/rest/src/direct-mount-base-follows-apipath.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// [#6306] ONE API base for the whole REST surface — pinned end to end through +// [commit fec784863] ONE API base for the whole REST surface — pinned end to end through // the plugin that composes it in production. // // The defect this replaces: `RestServer.getApiBasePath()` answers @@ -13,7 +13,7 @@ // `/api/v1` (`packages.*` ×4, `datasources/:name/external/*` ×5). Those 9 // were also absent from `{apiPath}/openapi.json` (71 paths vs 79), because // that document is filtered to this server's base — the filter is what made -// the split visible (#5822 / PR #6303). +// the split visible (#5822 / commit 465c5fc14). // // What is pinned here, and at which level. This file drives // `createRestApiPlugin(config).start(ctx)` — the real composition — over a diff --git a/packages/rest/src/discovery-advertised-direct-mounts.parity.test.ts b/packages/rest/src/discovery-advertised-direct-mounts.parity.test.ts index 71571ecec19..12e975e1077 100644 --- a/packages/rest/src/discovery-advertised-direct-mounts.parity.test.ts +++ b/packages/rest/src/discovery-advertised-direct-mounts.parity.test.ts @@ -17,7 +17,7 @@ // chain together against the live surface, so ANY future change that moves // only one side goes red here: move the mount without the advertisement (or // vice versa) and the advertised URL stops resolving in the handler table. -// #6306 was the first such move and it landed with no edit in this file — +// Commit fec784863 was the first such move and it landed with no edit in this file — // which is the property working, not the pin missing it. // // The non-default-base case is the load-bearing one: it drives the @@ -25,7 +25,7 @@ // convention. Note the level this file measures at — it calls // `mountAndRecordDirectRoutes` directly, so `versionedBase` is its own // parameter and the projection is pinned independently of WHO chooses that -// base. Since #6306 the production chooser is `RestServer.getApiBasePath()` +// base. Since commit fec784863 the production chooser is `RestServer.getApiBasePath()` // (so `apiPath` deployments mount and advertise under `{apiPath}`); that // wiring — plugin config in, mounted+advertised+documented URLs out — is // pinned end to end in `direct-mount-base-follows-apipath.test.ts`. @@ -219,7 +219,7 @@ describe('[#6633] /discovery advertises the direct-mount surfaces where they are // The mount base is an input here, deliberately decoupled from the // RestServer's own base: that is what proves the advertisement is read // off the recorded mounts rather than re-derived from config. It is also - // what kept advertisement and mount inseparable across #6306's move. + // what kept advertisement and mount inseparable across commit fec784863's move. const { table } = boot({ versionedBase: '/backend/api/v9' }); const discovery = await readDiscovery(table); diff --git a/packages/rest/src/discovery-schema-conformance.test.ts b/packages/rest/src/discovery-schema-conformance.test.ts index 4309f15ece0..4c353e1c23e 100644 --- a/packages/rest/src/discovery-schema-conformance.test.ts +++ b/packages/rest/src/discovery-schema-conformance.test.ts @@ -341,7 +341,7 @@ describe('[#4828] the REST /discovery live shape conforms to DiscoverySchema', ( // SEGMENT (`'v1'` by default) — the string the caller had just typed to reach // the endpoint. `DiscoverySchema` declares `version` under "System Identity" // next to `name` and `environment`, and the #10993 ruling (reaffirmed by - // #11235/#11242) settled that as the SERVING ARTIFACT's version. + // Commit 376c70f98/commit 98ea3443f) settled that as the SERVING ARTIFACT's version. // // Every assertion below pins PROVENANCE, never a literal version string: the // wire answer is compared against the producer's own answer, or against a diff --git a/packages/rest/src/error-response-sandbox-arm-message.test.ts b/packages/rest/src/error-response-sandbox-arm-message.test.ts index 6e4b40c0cd9..52f31681c0b 100644 --- a/packages/rest/src/error-response-sandbox-arm-message.test.ts +++ b/packages/rest/src/error-response-sandbox-arm-message.test.ts @@ -36,7 +36,7 @@ * §3 the non-sandbox control: a plain producer on the same codes keeps * `error.message` byte for byte — the two-read rule is a read of a field * the sandbox populated, never a strip of the wrapper off `.message`; - * §4 CONVERGED (#15071, maintainer ruling 2026-09-04 / batch #27, option B): + * §4 CONVERGED (commit cf6e0a193, maintainer ruling 2026-09-04 / batch #27, option B): * a sandboxed CRASH carrying a declared code reaches the unwrap door's * sanitised `500 UNCLASSIFIED_FAULT` whatever code it declares — the * terminal moved above the arms (`isSandboxCrash`). This section was the @@ -63,7 +63,7 @@ const HERE = dirname(fileURLToPath(import.meta.url)); /** * The classification's own source, read once: §4-derivation and §6 both scan it - * — one re-derives the arm list from the tree (the #15071 ruling's execution + * — one re-derives the arm list from the tree (the commit cf6e0a193 ruling's execution * constraint), the other guards the sentence rule. Same package, so the read * does not escape it (AGENTS.md → cross-package test inputs). */ @@ -233,8 +233,8 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out }); /** - * FLIPPED by #15071, deliberately and in that card's PR, from - * `ACCEPTED DIVERGENCE` to `CONVERGED` — the same discipline PR #15065 used + * FLIPPED by commit cf6e0a193, deliberately and in that card's PR, from + * `ACCEPTED DIVERGENCE` to `CONVERGED` — the same discipline commit 1c7adc73d used * on its own §4 one file over. ⛔ The section is not DELETED: it is the only * thing that would notice the divergence coming back, and what changes is * its verdict, not its existence. diff --git a/packages/rest/src/error-response-structured-arm-door-parity.test.ts b/packages/rest/src/error-response-structured-arm-door-parity.test.ts index 67d34001b97..942276bc8be 100644 --- a/packages/rest/src/error-response-structured-arm-door-parity.test.ts +++ b/packages/rest/src/error-response-structured-arm-door-parity.test.ts @@ -524,7 +524,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { }); /** - * [#15071] The crash sibling of the case above — CONVERGED where the + * [commit cf6e0a193] The crash sibling of the case above — CONVERGED where the * producer declared no status, and named as a DIVERGENCE where it did. * * The maintainer ruling (2026-09-04, batch #27, option B) moved the @@ -565,8 +565,8 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { /** * FLIPPED by #17273, deliberately and in that card's PR, from - * `ACCEPTED DIVERGENCE (#15071 widens it)` to `CONVERGED` — the same - * discipline #14704 used on the sentence case above and #15071 used on + * `ACCEPTED DIVERGENCE (commit cf6e0a193 widens it)` to `CONVERGED` — the same + * discipline #14704 used on the sentence case above and commit cf6e0a193 used on * `error-response-sandbox-arm-message.test.ts` §4. ⛔ The case is not * DELETED: it is the only thing that would notice the divergence coming * back, and what changes is its verdict, not its existence. @@ -574,7 +574,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { * ## What the old verdict bought, and why it had to change * * `ACCEPTED DIVERGENCE` bought "the next reader knows this is - * unconverged" — never "nothing is wrong here". #15071 could not take + * unconverged" — never "nothing is wrong here". Commit cf6e0a193 could not take * this shape because closing it means moving the STATUS * `resolveErrorResponse`'s passthrough decided, the #11588-fenced * contract question, so it recorded the boundary IN the pin and had the @@ -587,7 +587,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { * `500`, the declared `DELETE_RESTRICTED` → the catalog's * `INTERNAL_ERROR`, and the runner's `hook 'guard' threw: TypeError: …` * debug wrapper → the generic sentence. Nothing is added to the body. - * The single door is byte-identical to what #15071 left. + * The single door is byte-identical to what commit cf6e0a193 left. */ it('CONVERGED (#17273): a sandboxed CRASH that DECLARED a 4xx status is the fault terminal at both doors', () => { const err: any = new Error("hook 'guard' threw: TypeError: x is not a function"); @@ -597,7 +597,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { err.object = 'account'; const bulk = bulkDoor(err, 'account'); const single = singleDoor(err, 'account'); - // The single door: what #15071 ruled — a crash is a fault. + // The single door: what commit cf6e0a193 ruled — a crash is a fault. expect(single.status).toBe(500); expect(single.body.code).toBe('INTERNAL_ERROR'); expect(String(single.body.error)).not.toContain('threw:'); @@ -621,7 +621,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { * The crash terminal in `resolveErrorResponse` is deliberately not * band-scoped: scoping it to 4xx would have converged the shape above * while minting a NEW divergence one band over — the single door has - * answered `500 INTERNAL_ERROR` for this error since #15071, and the + * answered `500 INTERNAL_ERROR` for this error since commit cf6e0a193, and the * bulk door's 5xx arm would have kept `503` with the declared code. * * ⛔ This is NOT a narrowing of the 5xx arm's unconditional prose-drop @@ -651,7 +651,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { * the flip moved. An implementation that degraded every SANDBOX-origin * error to the fault terminal would turn both cases above green while * deleting the whole sandbox-refusal surface on the bulk door — - * #15071's ruling fences exactly that: *"Ordinary declared refusals (a + * Commit cf6e0a193's ruling fences exactly that: *"Ordinary declared refusals (a * hook that throws a business error carrying a code, no crash) are * **untouched** — only the crash branch moves."* * diff --git a/packages/rest/src/error-response.ts b/packages/rest/src/error-response.ts index 450da14fd0f..f7445c937a6 100644 --- a/packages/rest/src/error-response.ts +++ b/packages/rest/src/error-response.ts @@ -4,7 +4,7 @@ * How a thrown thing becomes an HTTP answer — ADR-0112's concern, at the REST * boundary. * - * [#8850] Moved here from `rest-server.ts`, where this code sat at module level + * [commit 8664a2c99] Moved here from `rest-server.ts`, where this code sat at module level * ahead of the `RestServer` class for historical rather than structural * reasons: none of it reads class state, and the class body is not its subject. * The move is a MOVE — every function below is byte-identical to the version @@ -312,7 +312,7 @@ export function sandboxBusinessMessage(error: any): string | undefined { * ## ⛔ What this deliberately does NOT decide * * Fault classification. A sandboxed **CRASH** (#7543) no longer reaches this - * function at all: #15071 put {@link isSandboxCrash} ABOVE the code-gated arms + * function at all: commit cf6e0a193 put {@link isSandboxCrash} ABOVE the code-gated arms * in {@link classifyDataError}, so a crashed body is answered by * {@link UNCLASSIFIED_FAULT} whatever code it declared, and the other door * declines the consult for a sandbox producer outright (the section above). @@ -324,7 +324,7 @@ export function sandboxBusinessMessage(error: any): string | undefined { * * ⚠️ CONVERGED was the no-declared-status case only until #17273: a crash that * DECLARED a status used to leave {@link resolveErrorResponse} at that status, - * wrapper and all, through a passthrough #15071 did not touch. That door now + * wrapper and all, through a passthrough commit cf6e0a193 did not touch. That door now * asks the SAME {@link isSandboxCrash} gate before its passthrough, so the * question has one answer at both doors for every band — flipped from ACCEPTED * DIVERGENCE to CONVERGED in @@ -486,7 +486,7 @@ export function declaredHttpStatus(error: any): number | undefined { * any case; a number in the field callers branch on is the loudest possible * violation of a closed vocabulary. All four flat arms now ask ONE question. * - * [#10345] Five arms, since the sandbox unwrap door joined them. It emitted no + * [commit cad8b42f0] Five arms, since the sandbox unwrap door joined them. It emitted no * `code` at all, so #9232 found nothing there to narrow and left it out — and * an exit that never speaks the vocabulary is the one a vocabulary sweep * cannot see. `rest-thrown-code-vocabulary.test.ts`'s `ARMS` table enumerates @@ -670,7 +670,7 @@ function missingRelationIsObject(raw: string, object: string | undefined): boole * not permitted …" — trips the `'' … not` substring check and * returns a misleading 404. * - * [#9934] The exported face is a WRAPPER: classification happens in + * [commit 79c46da90] The exported face is a WRAPPER: classification happens in * {@link classifyDataError} below (this docblock's subject, byte-for-byte the * old `mapDataError`), and the wrapper then rides the producer's declared * `userMessage` onto whatever body classification chose — see @@ -682,7 +682,7 @@ export function mapDataError(error: any, object?: string): { status: number; bod } /** - * [#9934] Carry a producer-marked user-facing refusal text onto a classified + * [commit 79c46da90] Carry a producer-marked user-facing refusal text onto a classified * wire body — the REST door's half of the objectui#5210 ruling (producer-side * opt-in; the console render half is objectui's). * @@ -800,7 +800,7 @@ function isSandboxOrigin(error: any): boolean { } /** - * [#15071] Did a sandboxed body CRASH — as opposed to reporting a refusal? + * [commit cf6e0a193] Did a sandboxed body CRASH — as opposed to reporting a refusal? * * The two reads {@link sandboxBusinessMessage} already makes, asked from the * other side: a sandbox origin ({@link isSandboxOrigin}) whose unwrapped @@ -873,7 +873,7 @@ function fiveXxArmDisplacesDeclared4xx( } /** - * [#14389 / #14723] Is this thrown value the ENGINE's unique-violation + * [#14389 / commit 65846bc46] Is this thrown value the ENGINE's unique-violation * envelope — `@objectstack/objectql`'s `DuplicateRecordError`? * * Gated on the envelope, name AND code, not on the code alone: a hook that @@ -975,7 +975,7 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { * not. ⛔ So "the code is new there" is the wrong way round; the withheld value * is the change. * - * ## One wire spelling on the route — the rows too (#14723) + * ## One wire spelling on the route — the rows too (commit 65846bc46) * * The #14541 contract review (condition 2) disclosed a fork this file's "one * condition, one wire code" framing did not cover: the DOORS answered a @@ -987,7 +987,7 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { * `POST /data/:object/import` said `UNIQUE_VIOLATION` while a row on the SAME * route said `DUPLICATE_RECORD`. * - * Maintainer ruling (2026-09-03, #14723): a unique-constraint refusal has ONE + * Maintainer ruling (2026-09-03, commit 65846bc46): a unique-constraint refusal has ONE * wire spelling on every route, `UNIQUE_VIOLATION` — the standard-catalog * member the published protocol docs give for the 409 constraint-violation * body. The row derivations now apply the same mapping this arm applies, keyed @@ -1274,7 +1274,7 @@ function structuredCodeAnswer( } function classifyDataError(error: any, object?: string): { status: number; body: Record } { - // [#15071] A sandboxed CRASH is a fault before it is anything else — above + // [commit cf6e0a193] A sandboxed CRASH is a fault before it is anything else — above // the arms, because the arms are asked before the unwrap door that used to // hold this terminal. Maintainer ruling 2026-09-04 (batch #27), option B: // a crash "reaches the unwrap door's sanitised 500 whatever code it @@ -1319,7 +1319,7 @@ function classifyDataError(error: any, object?: string): { status: number; body: // The full wrapper still reaches server logs via the callers' // "[REST] Unhandled error" logging and the BodyRunner's own error log. // - // [#10345] The `code` the producer declared rides too — via + // [commit cad8b42f0] The `code` the producer declared rides too — via // {@link thrownCodeFields}, the same one definition the three arms around // it use. This branch used to omit `code` unconditionally, and that // omission is what the card measured: a QuickJS hook throwing @@ -1375,13 +1375,13 @@ function classifyDataError(error: any, object?: string): { status: number; body: // `TypeError: not a function` is an internal fault rather than a // business message — {@link isScriptFaultMessage}. "Deliberately FIRST: // a crash outranks everything else about the error, including a stray - // declared `status`" is unchanged as a rule; [#15071] moved the gate + // declared `status`" is unchanged as a rule; [commit cf6e0a193] moved the gate // that applies it to the TOP of this function ({@link isSandboxCrash}), // because the code-gated arms above are asked before this door and were // answering a crash with a business status and the wrapper prose. So // this branch keeps its meaning and loses its guard — the guard did not // disappear, it out-ranks more of the file than it used to. - // [#9967] A body that NAMES its own HTTP status is asking to be served + // [commit 8f266f1cd] A body that NAMES its own HTTP status is asking to be served // with it — the same #7867 rule `domains/actions.ts` applies on the // custom-action route. The QuickJS side-channel carries a body-thrown // error's declared `status` out of the VM onto `SandboxError.status`, @@ -1395,7 +1395,7 @@ function classifyDataError(error: any, object?: string): { status: number; body: // pins (`hook-error-format.dogfood.test.ts`) require. const declared = declaredHttpStatus(error); if (declared === undefined || declared < 500) { - // [#10345] `status` is resolved BEFORE the code fields are asked + // [commit cad8b42f0] `status` is resolved BEFORE the code fields are asked // for, and handed to {@link thrownCodeFields} as the fallback, so // an unregistered spelling demotes against the status the client // actually receives rather than against a default — the #9232 §5 @@ -1483,7 +1483,7 @@ function classifyDataError(error: any, object?: string): { status: number; body: // The `code` rides along on {@link declaresServerFault}, the criterion // `@objectstack/types` already owns for "this producer DECLARED a // server fault" (`status >= 500` *and* a non-empty string `code`; PR - // #6122, pinned by `error-leak.test.ts`, read by the analytics route + // Commit 64cd01082, pinned by `error-leak.test.ts`, read by the analytics route // here and by `runtime`'s dispatcher). Inside this branch its status // half is already true, so what it adds is the `code` half — and it // adds it as a TESTED predicate rather than a fourth open-coded @@ -2048,7 +2048,7 @@ export function sendDeclaredFault( * [#9098] Emits through {@link sendDeclaredFault}, so `FIELD_VISIBILITY_UNRESOLVED` * is now checked against the closed ADR-0112 vocabulary at COMPILE time. It was * this call — an object literal handed to an `error: any` parameter — that put - * an unregistered code on the wire for as long as it did (#8885 registered it; + * an unregistered code on the wire for as long as it did (commit 30b1c636a registered it; * this makes the next one impossible rather than merely findable). The wire * answer is unchanged: 503, `code`, and the #5437-withheld prose. */ @@ -2100,10 +2100,10 @@ function logWithheldServerFault( */ function resolveErrorResponse(error: any, object?: string): { status: number; body: Record } { // [#17273] A sandboxed body that CRASHED is a fault before it is anything - // else — the SAME terminal ordering #15071 gave {@link classifyDataError}, + // else — the SAME terminal ordering commit cf6e0a193 gave {@link classifyDataError}, // asked here so the ruling reaches the other door too. // - // #15071 converged the single `/data` door and named the residue rather + // Commit cf6e0a193 converged the single `/data` door and named the residue rather // than rediscovering it: {@link isSandboxCrash} went ABOVE that function's // code-gated arms, so a crashed body reaches {@link UNCLASSIFIED_FAULT} // whatever it declared — while THIS door kept answering the declared @@ -2113,7 +2113,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // answers, decided by which route caught it — and the one this door gave // put the runner's `TypeError: …` text on the wire at a business status. // - // The ruling that decides it is #15071's, quoted on {@link isSandboxCrash} + // The ruling that decides it is commit cf6e0a193's, quoted on {@link isSandboxCrash} // and NOT restated here: *"A declared code is the author's statement about // the failure mode they **handled**. A crash … is not that mode, so it is // classified as a fault"*, against *"an internal stack-shaped sentence at a @@ -2277,8 +2277,8 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // {@link thrownCodeFields}. This arm's old gate was bare truthiness, so // it also admitted a non-string `code`; that limb is gone with the // narrowing, and the flat arms now ask one question (five of them since - // #10345 brought the sandbox unwrap door into the vocabulary). - // [#9934] Both passthrough arms ride a producer-declared `userMessage` + // Commit cad8b42f0 brought the sandbox unwrap door into the vocabulary). + // [commit 79c46da90] Both passthrough arms ride a producer-declared `userMessage` // onto the body, the same rule as the exported `mapDataError` wrapper — // see {@link withDeclaredUserMessage}. On the 5xx arm the PROSE is // still withheld (#5437); the marked channel is authored user text, not diff --git a/packages/rest/src/execctx-authz-input-seam-reachability.test.ts b/packages/rest/src/execctx-authz-input-seam-reachability.test.ts index ddc4357afb7..ce8cfe0e558 100644 --- a/packages/rest/src/execctx-authz-input-seam-reachability.test.ts +++ b/packages/rest/src/execctx-authz-input-seam-reachability.test.ts @@ -591,7 +591,7 @@ describe('[#13906] §2 — the Layer 0 ex-member refusal, and what a failed post const captured = await drive(mount(serverWith(viaKernelManager(kernel))), { 'x-api-key': RAW_EXMEMBER_KEY }); expect(captured.status).toBe(503); // ⭐ And it answers as an OUTAGE, not as a permission denial — the - // distinction #13279 ruled on and this repair reuses rather than reinvents. + // distinction commit 6a180e42d ruled on and this repair reuses rather than reinvents. expect(captured.body?.success).not.toBe(true); }); diff --git a/packages/rest/src/execctx-consumer-census.test.ts b/packages/rest/src/execctx-consumer-census.test.ts index b3cf0e68047..86661827637 100644 --- a/packages/rest/src/execctx-consumer-census.test.ts +++ b/packages/rest/src/execctx-consumer-census.test.ts @@ -58,7 +58,7 @@ import { fileURLToPath } from 'node:url'; import { dirname, resolve } from 'node:path'; import { ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_STATUS, - // [#13279] §8 drives the real loud failure rather than a stand-in, so the + // [commit 6a180e42d] §8 drives the real loud failure rather than a stand-in, so the // propagation it observes is the one production raises. AuthzStoreUnavailableError, AUTHZ_STORE_UNAVAILABLE_STATUS, } from '@objectstack/core'; @@ -82,7 +82,7 @@ type Handler = (req: any, res: any) => any; * Every `this.resolveExecCtx(environmentId, req)` invocation, with the line it * sits on and whether it carries its OWN `.catch(…)`. * - * [#13279] The catch ARGUMENT changed: a caught site passes + * [commit 6a180e42d] The catch ARGUMENT changed: a caught site passes * `rethrowAuthzStoreUnavailable` instead of `() => undefined`, so a * permission-store outage is re-raised rather than degraded into a refusal. * The detection below keys on `.catch(` and is deliberately spelling-agnostic, @@ -698,7 +698,7 @@ describe('[#13160] §6 the boundary of this census', () => { // `package-door-execctx-fault-reading.test.ts` (PR #13153) — // fail-CLOSED, two ablation legs, both rival readings falsified. // ⛔ Recorded as DEFERRED to that file, never as "assumed closed". - // [#13279] The catch argument is now `rethrowAuthzStoreUnavailable` + // [commit 6a180e42d] The catch argument is now `rethrowAuthzStoreUnavailable` // (was `() => undefined`): a permission-store OUTAGE must reach the // door as the 503 it is instead of being laundered into a 401/403. // This grep tracks the wrapper's CURRENT spelling — the site is still diff --git a/packages/rest/src/external-datasource-envelope.conformance.test.ts b/packages/rest/src/external-datasource-envelope.conformance.test.ts index 6d94bc83b58..b20461c8afb 100644 --- a/packages/rest/src/external-datasource-envelope.conformance.test.ts +++ b/packages/rest/src/external-datasource-envelope.conformance.test.ts @@ -51,9 +51,9 @@ interface Captured { * would read the 401 body instead of the arm it names, and this file would * silently stop measuring what it exists to measure. * - * [#9901/#10255] …and an ENTITLED one: every route now also requires a + * [#9901/commit 6ce58a735] …and an ENTITLED one: every route now also requires a * capability (`manage_platform_settings` on the reads — `validate` among them - * since the 2026-08-20 #10255 ruling — `manage_metadata` on the writes), so + * since the 2026-08-20 commit 6ce58a735 ruling — `manage_metadata` on the writes), so * this stub holds both. Same reasoning one step further — a * resolver carrying an identity but no grants would turn every case below into * a reading of the 403 body. Holding both rather than one per case is diff --git a/packages/rest/src/external-datasource-routes-auth-guard.test.ts b/packages/rest/src/external-datasource-routes-auth-guard.test.ts index c15d83cb075..f8c764dc9f0 100644 --- a/packages/rest/src/external-datasource-routes-auth-guard.test.ts +++ b/packages/rest/src/external-datasource-routes-auth-guard.test.ts @@ -3,7 +3,7 @@ /** * [#9686] The `/api/v1/datasources/:name/external/*` federation family requires * an authenticated caller — on every route, read and write alike — and - * [#9901/#10255] a CAPABILITY above that on every route. + * [#9901/commit 6ce58a735] a CAPABILITY above that on every route. * * ## What this pins, and why it is driven through the real plugin * @@ -56,10 +56,10 @@ * here, which is what makes the read/write split falsifiable rather than * merely written down. * - * [#10255] `POST /external/validate` was the one route the #9901 ruling did + * [commit 6ce58a735] `POST /external/validate` was the one route the #9901 ruling did * not name: no admin twin, no metadata created, so it kept the #9686 * authentication floor — pinned here as an explicit `capability: null` row so - * that gating it later had to change the table. That later card is #10255, + * that gating it later had to change the table. That later card is commit 6ce58a735, * ruled 2026-08-20 (verbatim: 「同意你的意见。」, accepting option A): validate * takes the READ capability, because validation drives the same live * remote-schema introspection the read twins gate and reports on it. The row @@ -102,14 +102,14 @@ type Handler = (req: any, res: any) => any; * runtime-origin federated object, the refresh rewrites the cached catalog * snapshot. Both are asserted to be unreachable without an identity. * - * [#10255] There is no `capability: null` row any more: `POST + * [commit 6ce58a735] There is no `capability: null` row any more: `POST * /external/validate` carried one — spelled as an explicit `null` rather than * omitted, so that a later edit gating it had to change this table — and the - * 2026-08-20 #10255 ruling is that later edit: validate is a read + * 2026-08-20 commit 6ce58a735 ruling is that later edit: validate is a read * (validation drives the same live remote introspection the read twins * gate), so its row now carries `READ_CAPABILITY` like its two read siblings. * - * [#10537] The validate row's `call` is the SCOPED composition + * [commit e634ecf6a] The validate row's `call` is the SCOPED composition * (`validateDatasource`), which is what the route dispatches to since the * fan-out fix; the fixture keeps a `validateAll` spy beside it precisely so a * regression to the whole-farm sweep is visible here rather than silent. @@ -179,7 +179,7 @@ function federationServiceSpies() { generateObjectDraft: vi.fn(async () => ({ name: 'customers' })), importObject: vi.fn(async () => ({ name: 'customers' })), refreshCatalog: vi.fn(async () => ({ tables: {} })), - // [#10537] `POST /external/validate` dispatches to the SCOPED composition + // [commit e634ecf6a] `POST /external/validate` dispatches to the SCOPED composition // now. The whole-farm `validateAll` stays in the set, spied and never // expected to run: "the service never ran" then means the method the // route actually reaches, and a regression to the sweep shows up as a @@ -414,7 +414,7 @@ describe('[#9686] the same boot still serves an entitled caller', () => { describe('[#9901] the family requires a capability above authentication', () => { it('refuses an authenticated caller holding NOTHING on all five routes — 403 PERMISSION_DENIED, before the service', async () => { - // [#10255] Five, not four: `POST /external/validate` joined the ruled set + // [commit 6ce58a735] Five, not four: `POST /external/validate` joined the ruled set // on 2026-08-20, so there is no `capability: null` row left to filter out // and this loop runs the whole family. const { table, service, lookups } = await bootFederation({ @@ -483,10 +483,10 @@ describe('[#9901] the family requires a capability above authentication', () => it('[#10255] POST /external/validate requires the READ capability — the authentication-floor era is over', async () => { // This case is the previous pin FLIPPED, deliberately. Until the - // 2026-08-20 #10255 ruling it asserted the exact opposite — an + // 2026-08-20 commit 6ce58a735 ruling it asserted the exact opposite — an // authenticated caller holding nothing was SERVED here while refused the // other four — because #9901's ruling did not name this route. The ruling - // that changed it is recorded on #10255 (option A): validation drives + // that changed it is recorded on commit 6ce58a735 (option A): validation drives // the same live remote-schema introspection the read twins gate, so // validate is a read and answers to the read capability. const { table, service } = await bootFederation({ @@ -521,7 +521,7 @@ describe('[#9901] the family requires a capability above authentication', () => expect(statusCode).toBe(validate.ok); expect(body?.success).toBe(true); expect(service.validateDatasource).toHaveBeenCalledWith(DS); - // [#10537] …and the served request did NOT fan out across every datasource. + // [commit e634ecf6a] …and the served request did NOT fan out across every datasource. expect(service.validateAll).not.toHaveBeenCalled(); }); diff --git a/packages/rest/src/external-datasource-routes.ts b/packages/rest/src/external-datasource-routes.ts index fcf23f90816..5dda26ab0ed 100644 --- a/packages/rest/src/external-datasource-routes.ts +++ b/packages/rest/src/external-datasource-routes.ts @@ -73,7 +73,7 @@ import { mountDirectRoutes, type DirectMountedRoute } from './direct-mount.js'; * is not a second envelope flag, so it belongs inside `data` rather than being * dropped. * - * [#10537] `POST /validate` does URL-SCOPED WORK. It used to call + * [commit e634ecf6a] `POST /validate` does URL-SCOPED WORK. It used to call * `validateAll()` — every federated object on every federated datasource, each * validation driving a live `introspect(datasource)` — and then keep only the * rows matching `:name`. The rows were right; the work was not scoped, so one @@ -126,7 +126,7 @@ export interface ExternalDatasourceRoutesOptions { /** * [#9901] The capability the federation family's READ routes require: * `GET /external/tables`, `POST /external/tables/:remote/draft` and - * [#10255] `POST /external/validate`. + * [commit 6ce58a735] `POST /external/validate`. * * It is `manage_platform_settings` because the first two routes are the * DECLARED TWINS of `GET /:name/remote-tables` and `POST /:name/object-draft` @@ -139,10 +139,10 @@ export interface ExternalDatasourceRoutesOptions { * Maintainer ruling, 2026-08-20 (verbatim: 「其他接受你的建议。」): the * federation family is NOT deliberately the lower-privilege door. * - * [#10255] `validate` has no admin twin to converge with, so #9901 left it on + * [commit 6ce58a735] `validate` has no admin twin to converge with, so #9901 left it on * the #9686 authentication floor and filed the question instead of deciding * it. The follow-up ruling (maintainer, 2026-08-20, verbatim: - * 「同意你的意见。」, accepting option A on #10255) converged it here: what + * 「同意你的意见。」, accepting option A on commit 6ce58a735) converged it here: what * validation does is drive the SAME live remote-schema introspection the * two read twins gate (`introspect` per datasource, in * `service-datasource/src/external-datasource-service.ts`), and its report — @@ -150,7 +150,7 @@ export interface ExternalDatasourceRoutesOptions { * unreachable remotes — is a read of the same federation surface. One family, * one door-type: reads here, writes on {@link FEDERATION_WRITE_CAPABILITY}. * - * [#10537] The reasoning is unchanged by the scoping fix and was never about + * [commit e634ecf6a] The reasoning is unchanged by the scoping fix and was never about * the sweep's WIDTH: it is the same introspection whether one datasource is * read or all of them, so `validate` answers to the read capability either way. */ @@ -225,7 +225,7 @@ export function registerExternalDatasourceRoutes( * `503` which services a deployment has wired, and — for the two routes that * write — so the refusal provably precedes the write rather than following it. * - * ## [#9901/#10255] …and a CAPABILITY above it, on every route + * ## [#9901/commit 6ce58a735] …and a CAPABILITY above it, on every route * * #9686 left this family gated on authentication alone and pointed the * capability question at #9593, which answered it for the admin half only. @@ -271,13 +271,13 @@ export function registerExternalDatasourceRoutes( * — since `isSystem` is never resolved from inbound HTTP — one no wire caller * could ever take, so it would be unfalsifiable divergence from the twin. * - * ## [#10255] `validate` joined the reads; the `'authenticated'` kind retired + * ## [commit 6ce58a735] `validate` joined the reads; the `'authenticated'` kind retired * * #9901's ruling enumerated four routes, so `POST /external/validate` — no * twin on the admin spelling, no metadata created — kept the #9686 * authentication floor under its own explicit kind: an un-ruled route * silently inheriting a neighbour's gate would have read as ruled. The - * question was filed as #10255 and ruled on 2026-08-20: validate takes the + * question was filed as commit 6ce58a735 and ruled on 2026-08-20: validate takes the * READ capability (see {@link FEDERATION_READ_CAPABILITY}'s note for why it * is a read). With every route now ruled, the `'authenticated'` kind would * be a door no route walks through, so it is REMOVED rather than kept — a @@ -341,7 +341,7 @@ export function registerExternalDatasourceRoutes( }; /** - * [#10537] The scoped validation the `POST /validate` route needs: validate + * [commit e634ecf6a] The scoped validation the `POST /validate` route needs: validate * the federated objects bound to ONE datasource, composed service-side from * the same primitives the whole-farm sweep uses (`listObjects` → filter → * `validateObject`). @@ -362,7 +362,7 @@ export function registerExternalDatasourceRoutes( * * A wired service with no scoped spelling could be served by falling back to * `validateAll()` and post-filtering — which is precisely the behaviour - * #10537 removed. A silent fallback would leave the fan-out reachable, on a + * Commit e634ecf6a removed. A silent fallback would leave the fan-out reachable, on a * path no test drives, for exactly the deployments nobody is looking at. So * absence takes the same 503 arm every other route here takes when the * service cannot serve it: loud, and already the declared shape of "this @@ -494,12 +494,12 @@ export function registerExternalDatasourceRoutes( }, }, - // Validate the federated objects on this datasource. [#10255] A 'read': + // Validate the federated objects on this datasource. [commit 6ce58a735] A 'read': // validation drives the same live remote-schema introspection the two // read twins gate, so it answers to the same capability (ruled 2026-08-20; // the constant's doc carries the reasoning). // - // [#10537] The work is scoped by the CALL, not by a filter over a + // [commit e634ecf6a] The work is scoped by the CALL, not by a filter over a // whole-farm sweep: `validateDatasource(:name)` introspects the named // datasource's remote and no other. The response is unchanged — the rows // the post-filter used to keep are exactly the rows this returns (see diff --git a/packages/rest/src/external-datasource-validate-scope.test.ts b/packages/rest/src/external-datasource-validate-scope.test.ts index 56d9f499dc7..fe03cb5a5b8 100644 --- a/packages/rest/src/external-datasource-validate-scope.test.ts +++ b/packages/rest/src/external-datasource-validate-scope.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#10537] `POST /datasources/:name/external/validate` does URL-SCOPED WORK. + * [commit e634ecf6a] `POST /datasources/:name/external/validate` does URL-SCOPED WORK. * * ## The defect this file measures * @@ -82,7 +82,7 @@ const OBJECTS = [ { name: 'local_thing', datasource: 'default', fields: { id: { type: 'text' } } }, ]; -/** An entitled caller — the capability gate (#9901/#10255) is not this file's subject. */ +/** An entitled caller — the capability gate (#9901/commit 6ce58a735) is not this file's subject. */ const CREDENTIALED = async () => ({ userId: 'u_validate_scope', systemPermissions: ['manage_platform_settings'], diff --git a/packages/rest/src/import-coerce.ts b/packages/rest/src/import-coerce.ts index 4d5fb196925..abdd17abc6f 100644 --- a/packages/rest/src/import-coerce.ts +++ b/packages/rest/src/import-coerce.ts @@ -695,7 +695,7 @@ export async function coerceFieldValue( // // Ruling D (maintainer, 2026-08-06) retired the mirror rather than growing it: // the dry run now ASKS for the verdict through `DataProtocol.validateData` -// (#6037), which runs the same `validateRecord` / `evaluateValidationRules` +// (commit 18189983d), which runs the same `validateRecord` / `evaluateValidationRules` // `insert()` runs, under the deployment's own ADR-0104 posture. See // `import-runner.ts`'s dry-run branch. Every verdict these two produced is // re-asserted through that route in `import-dryrun-parity.test.ts` — retiring diff --git a/packages/rest/src/import-dryrun-parity.test.ts b/packages/rest/src/import-dryrun-parity.test.ts index a1d834b0576..11d017a41fc 100644 --- a/packages/rest/src/import-dryrun-parity.test.ts +++ b/packages/rest/src/import-dryrun-parity.test.ts @@ -12,7 +12,7 @@ * with `VALIDATION_FAILED`. * * Ruling D (maintainer, 2026-08-06) replaced prediction with the verdict - * itself: the dry run asks `DataProtocol.validateData` (#6037 / PR #6474), + * itself: the dry run asks `DataProtocol.validateData` (commit 18189983d / commit 18189983d), * which runs the same `validateRecord` / `evaluateValidationRules` `insert()` * runs. So this file never pins the dry run's output ALONE — every case runs * BOTH halves against one live engine and asserts they agree. A test that diff --git a/packages/rest/src/import-job-integration.test.ts b/packages/rest/src/import-job-integration.test.ts index 99dcccae6d7..89b4f850a87 100644 --- a/packages/rest/src/import-job-integration.test.ts +++ b/packages/rest/src/import-job-integration.test.ts @@ -25,7 +25,7 @@ import { ObjectQL } from '@objectstack/objectql'; import { SqlDriver } from '@objectstack/driver-sql'; import { ObjectStackProtocolImplementation } from '@objectstack/metadata-protocol'; import { SysImportJob } from '@objectstack/platform-objects/audit'; -// #6535: the ONE definition of the async-import row ceiling. The pin below reads it +// Commit a92b1793c: the ONE definition of the async-import row ceiling. The pin below reads it // from here so that moving it is observable at the enforcement point. import { IMPORT_JOB_MAX_ROWS } from '@objectstack/spec/api'; import { RestServer } from './rest-server'; @@ -175,7 +175,7 @@ describe('async import job — real engine + protocol integration', () => { expect(results._json.results.find((r: any) => !r.ok)).toMatchObject({ field: 'score', code: 'invalid_number' }); }); - // #6535: the ceiling has ONE definition — the spec export — and rest is its only + // Commit a92b1793c: the ceiling has ONE definition — the spec export — and rest is its only // enforcer. So this case derives everything it knows about the ceiling from that // export: how big a payload must be to breach it, and the number the 413 copy is // required to name. Re-spelling 50_000 here would just move the duplicated literal diff --git a/packages/rest/src/import-run-automations-agreement.test.ts b/packages/rest/src/import-run-automations-agreement.test.ts index dab3ed1f302..9a3135046ec 100644 --- a/packages/rest/src/import-run-automations-agreement.test.ts +++ b/packages/rest/src/import-run-automations-agreement.test.ts @@ -2,7 +2,7 @@ /** * The declared default of `runAutomations` AGREES with the server's decision - * (#6704). + * (commit c3f491626). * * ## Why the agreement, and not either half * @@ -26,7 +26,7 @@ * * ## Behaviour is deliberately UNCHANGED * - * #6704 moved the DECLARATION to the runtime, never the runtime to the + * Commit c3f491626 moved the DECLARATION to the runtime, never the runtime to the * declaration: `packages/rest/src/import-prepare.ts` is untouched. The * `serverDecision` column below therefore reads identically before and after the * change, and the `declared` column is what moved. If a future edit "fixes" the @@ -68,7 +68,7 @@ const declared = (body: Record): boolean => describe('runAutomations — declared default agrees with the server (#6704)', () => { const cases: Array<{ label: string; body: Record; expected: boolean }> = [ - // THE case. Before #6704 this row was the divergence: declared `false`, + // THE case. Before commit c3f491626 this row was the divergence: declared `false`, // server `true`. Everything else in this file already agreed. { label: 'omitted', body: {}, expected: true }, { label: 'explicit true', body: { runAutomations: true }, expected: true }, @@ -86,7 +86,7 @@ describe('runAutomations — declared default agrees with the server (#6704)', ( } it('validating before sending cannot change the outcome', async () => { - // The concrete harm #6704 names: a client that parses its request through + // The concrete harm commit c3f491626 names: a client that parses its request through // the published schema and sends the PARSED object used to get the opposite // behaviour from one that sent the same body unvalidated. Drive both paths // through the server and require one answer. @@ -109,7 +109,7 @@ describe('runAutomations — declared default agrees with the server (#6704)', ( it('an omitted flag is the only input whose declaration ever moved', async () => { // Guards the reverse direction of the fix: the explicit spellings were - // already in agreement before #6704 and must not have been "fixed" into + // already in agreement before commit c3f491626 and must not have been "fixed" into // something else while the omitted case was corrected. expect(declared({ runAutomations: false })).toBe(false); expect(await serverDecision({ runAutomations: false })).toBe(false); diff --git a/packages/rest/src/import-runner-historical-readonly-insert.test.ts b/packages/rest/src/import-runner-historical-readonly-insert.test.ts index 43dd0fca080..09cc20d0d5d 100644 --- a/packages/rest/src/import-runner-historical-readonly-insert.test.ts +++ b/packages/rest/src/import-runner-historical-readonly-insert.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #6640 — the historical import, end to end, through the REAL write path. + * Commit 2ab1257c9 — the historical import, end to end, through the REAL write path. * * `runImport` with `treatAsHistorical: true` puts `preserveAudit: true` on the * write context (pinned next door in `import-runner-historical.test.ts`) and diff --git a/packages/rest/src/import-runner-unique-violation-row.test.ts b/packages/rest/src/import-runner-unique-violation-row.test.ts index 189e7da4b90..29df8508857 100644 --- a/packages/rest/src/import-runner-unique-violation-row.test.ts +++ b/packages/rest/src/import-runner-unique-violation-row.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14723] An import ROW reports a unique-constraint refusal as + * [commit 65846bc46] An import ROW reports a unique-constraint refusal as * `UNIQUE_VIOLATION` — the one wire spelling the route has. * * ## The fork this closes diff --git a/packages/rest/src/import-runner.ts b/packages/rest/src/import-runner.ts index 47f875f0dcd..96383a2b244 100644 --- a/packages/rest/src/import-runner.ts +++ b/packages/rest/src/import-runner.ts @@ -34,7 +34,7 @@ import { isEngineDuplicateRecordEnvelope } from './error-response.js'; * no verdict at all and the write answered `VALIDATION_FAILED`. * * So the dry-run branch below calls {@link ImportProtocolLike.validateData} - * (#6037) instead: the engine runs the same `validateRecord` / + * (commit 18189983d) instead: the engine runs the same `validateRecord` / * `evaluateValidationRules` `insert()` runs, under this deployment's own * ADR-0104 posture, and persists nothing. Agreement is by construction rather * than by a copy kept in step by hand. @@ -150,7 +150,7 @@ export interface ImportProtocolLike { */ insertManyData?(args: ImportProtocolRequest<{ object: string; records: any[] }>): Promise<{ outcomes: Array<{ ok: boolean; record?: any; error?: unknown }> }>; /** - * Validate-only (#6037 — #4633 ruling D). The write path's verdict on a + * Validate-only (commit 18189983d — #4633 ruling D). The write path's verdict on a * candidate row, with nothing persisted. The dry run routes through THIS * rather than re-deriving a verdict of its own. * @@ -325,14 +325,14 @@ export function sanitizeRowError(raw: unknown): string { * `code` therefore speaks one vocabulary across the whole row report: the * field-level catalog (ADR-0114) that `coerceRow`'s cell failures already use. * - * ## One wire spelling for a unique-constraint refusal (#14723) + * ## One wire spelling for a unique-constraint refusal (commit 65846bc46) * * The engine answers a driver's unique violation with its `DuplicateRecordError` * envelope (`code: 'DUPLICATE_RECORD'`, `status: 409`, the driver's error on * `cause`), and this report used to relay that code verbatim — while the * WHOLE-REQUEST failure on the very same `POST /data/:object/import` answered * `UNIQUE_VIOLATION` through `mapDataError`. Maintainer ruling (2026-09-03, - * #14723): one wire spelling on every route. So the engine's envelope is mapped + * Commit 65846bc46): one wire spelling on every route. So the engine's envelope is mapped * to `UNIQUE_VIOLATION` here, by the same predicate the whole-request arm uses * ({@link isEngineDuplicateRecordEnvelope}: registered code AND class name), * before the producer's own code is read. A field-level finding still wins @@ -518,7 +518,7 @@ export function runImport(opts: RunImportOptions): Promise { * * Runs on EVERY dry run, whatever `runAutomations` says. The write's * `beforeInsert` hooks fire before validation and could in principle derive - * a field this reports on — a boundary #6037 documents and deliberately does + * a field this reports on — a boundary commit 18189983d documents and deliberately does * not close, because firing user-authored hooks (mail, outbound calls, * writes to other objects) inside a preview is the retired `validateOnly` * defect in a new spelling. Gating on `!runAutomations` instead would leave diff --git a/packages/rest/src/index.ts b/packages/rest/src/index.ts index 79513b4a1c1..daa2a5ca510 100644 --- a/packages/rest/src/index.ts +++ b/packages/rest/src/index.ts @@ -49,7 +49,7 @@ export { buildFieldMetaMap } from './export-format.js'; export type { ExportFieldMeta } from './export-format.js'; // Query-parameter MULTIPLICITY — the repo's ONE rule for a single-valued -// parameter supplied more than once (#6307 / #6877), published so the doors +// parameter supplied more than once (commit 293476148 / #6877), published so the doors // OUTSIDE this package can answer it with that one implementation instead of a // second copy that drifts (#17672). `query-multiplicity.ts`'s header is the // authority on the rule; what belongs here is which half travels. diff --git a/packages/rest/src/log.ts b/packages/rest/src/log.ts index 3720e0a0775..0f30b4cac7f 100644 --- a/packages/rest/src/log.ts +++ b/packages/rest/src/log.ts @@ -3,7 +3,7 @@ /** * The package's console shim, in one place. * - * [#8850] Lifted out of `rest-server.ts` unchanged when the ADR-0112 + * [commit 8664a2c99] Lifted out of `rest-server.ts` unchanged when the ADR-0112 * error/fault-classification prologue moved to `error-response.ts`: both files * log through it, and the alternative — a second copy of the same two lines — * is the "two spellings of one thing" shape this repo pays for repeatedly. It diff --git a/packages/rest/src/meta-501-envelope.test.ts b/packages/rest/src/meta-501-envelope.test.ts index 602e4f639a3..b32369a7cca 100644 --- a/packages/rest/src/meta-501-envelope.test.ts +++ b/packages/rest/src/meta-501-envelope.test.ts @@ -19,8 +19,8 @@ * mechanism"), so it carried the sibling-key shape too — the card's table * sampled one of the twins, not both. * - * ⚠️ [#12195] The compound `PUT /meta/:type/:section/:name` in that table is - * RETIRED (#12176 stage 3). The row is kept because it is the historical + * ⚠️ [commit 7986d973f] The compound `PUT /meta/:type/:section/:name` in that table is + * RETIRED (commit 7986d973f stage 3). The row is kept because it is the historical * measurement this file exists to explain; the case that drove it is replaced * by a pin that the arity stays unmounted, so a re-mount cannot quietly * reintroduce a fourth envelope dialect. @@ -139,7 +139,7 @@ function boot() { migrateStored: () => drive('POST', MIGRATE_PATH, { params: {} }), singleSave: () => drive('PUT', SINGLE_PATH, { params: { type: 'object', name: 'account' } }), /** - * [#12195] The compound arity's REGISTRATION, not a call to it. + * [commit 7986d973f] The compound arity's REGISTRATION, not a call to it. * `route()` above THROWS on an unregistered path, so this reads * the route list directly. */ @@ -219,7 +219,7 @@ describe('#7035 — the `/meta` 501 refusals all speak the ADR-0112 envelope', ( await stack.reset(), await stack.singleSave(), ]; - // [#12195] THREE routes, not four: the compound `PUT` twin that used to + // [commit 7986d973f] THREE routes, not four: the compound `PUT` twin that used to // be the fourth is retired. expect(answers.map((a) => a.status)).toEqual([501, 501, 501]); expect(answers.map((a) => a.body?.error?.code)).toEqual([ diff --git a/packages/rest/src/meta-audience-plural.test.ts b/packages/rest/src/meta-audience-plural.test.ts index f2dfd8632eb..eeb62e4457a 100644 --- a/packages/rest/src/meta-audience-plural.test.ts +++ b/packages/rest/src/meta-audience-plural.test.ts @@ -134,7 +134,7 @@ describe('the same spelling sensitivity on the other per-type gates', () => { }); // --------------------------------------------------------------------------- -// [#6241] The same gate, one branch further in: the CACHED read path. +// [commit 83a3b1f2e] The same gate, one branch further in: the CACHED read path. // // Everything above tests a protocol double with no `getMetaItemCached`, so the // single-item read always fell through to the uncached branch — the branch that diff --git a/packages/rest/src/meta-compound-save-and-reset-capability-gate.test.ts b/packages/rest/src/meta-compound-save-and-reset-capability-gate.test.ts index 61fe4760e77..7c1e852b2a5 100644 --- a/packages/rest/src/meta-compound-save-and-reset-capability-gate.test.ts +++ b/packages/rest/src/meta-compound-save-and-reset-capability-gate.test.ts @@ -145,7 +145,7 @@ function boot(opts: BootOptions) { hasOverlay: () => overlays.has('account'), /** - * [#12195] The compound arity's REGISTRATIONS, not calls to them. These + * [commit 7986d973f] The compound arity's REGISTRATIONS, not calls to them. These * used to be `compoundGet()` / `compoundPut()`; the arity is retired, so * what is assertable now is that nothing is mounted there. */ @@ -172,7 +172,7 @@ describe('[#7019 / #12195] the compound-name arity is retired', () => { * object schema, edit a label, PUT it back) still deleted the fields the * caller was never allowed to see, through this door. * - * #12176 retired the arity, so the bypass is closed by removal instead of + * Commit 7986d973f retired the arity, so the bypass is closed by removal instead of * by a second gate. The pin inverts to match: what must stay true is that * the door is not mounted, because a re-mounted compound door arrives * UNGATED unless whoever mounts it re-derives #6603/#7019 — which is diff --git a/packages/rest/src/meta-compound-save-force-parity.test.ts b/packages/rest/src/meta-compound-save-force-parity.test.ts index c9d188afbf4..00e119c21ef 100644 --- a/packages/rest/src/meta-compound-save-force-parity.test.ts +++ b/packages/rest/src/meta-compound-save-force-parity.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#11095 → #12195] `?force=true` on the `/meta` save doors — a two-door parity + * [#11095 → commit 7986d973f] `?force=true` on the `/meta` save doors — a two-door parity * suite whose SECOND DOOR NO LONGER EXISTS. * * ## What this file is now, and why it was not deleted @@ -16,10 +16,10 @@ * do, got the identical refusal back, with nothing saying the parameter had * been ignored. #11095 closed it by threading the parameter. * - * #12176's maintainer ruling (2026-08-25) then retired compound metadata item - * names outright. Stage 1 (#12194) declared the item-name grammar and refuses + * Commit 7986d973f's maintainer ruling (2026-08-25) then retired compound metadata item + * names outright. Stage 1 (commit 311433f6b) declared the item-name grammar and refuses * every slash-bearing name at the publish door — BEFORE the destructive gate - * this file was written about — and stage 3 (#12195) un-mounts the arity. + * this file was written about — and stage 3 (commit 7986d973f) un-mounts the arity. * * ⛔ REWORKED rather than deleted. The guard worth keeping is against the arity * coming BACK: a re-mounted compound door is a door that reads neither `?force` @@ -33,7 +33,7 @@ * the remedy, honoured `?force=true`, the truthy table (§2); * 3. #6877's repeated-parameter guard is re-pinned on the surviving door (§3); * 4. the slash-bearing name a caller would once have spelled compound is - * pinned answering #12194's `400 INVALID_REQUEST` at the surviving door, + * pinned answering commit 311433f6b's `400 INVALID_REQUEST` at the surviving door, * with `?force` unable to acknowledge past it (§4). * * ⛔ Still not a precedent for the dispatcher: `@objectstack/runtime`'s @@ -274,7 +274,7 @@ function boot() { compoundFields: () => Object.keys(JSON.parse(rows.get('row_compound')!.metadata).fields ?? {}).sort(), singleFields: () => Object.keys(JSON.parse(rows.get('row_single')!.metadata).fields ?? {}).sort(), /** - * [#12195] The compound door's REGISTRATION, not a call to it. This + * [commit 7986d973f] The compound door's REGISTRATION, not a call to it. This * used to be `compoundPut()`; the arity is retired, so what is * assertable now is that nothing is mounted there. */ @@ -287,7 +287,7 @@ function boot() { singlePut: (query: Record = {}) => call(SINGLE_PATH, { type: 'object', name: SINGLE_NAME }, query), /** - * [#12195] The surviving door addressed with an ARBITRARY name — the + * [commit 7986d973f] The surviving door addressed with an ARBITRARY name — the * shape a caller now uses for a slash-bearing one (percent-encoded on * the wire, decoded by Hono before the handler runs). */ @@ -300,14 +300,14 @@ function boot() { const PUT_REMEDY = 're-submit with ?force=true to proceed.'; // ═══════════════════════════════════════════════════════════════════════════ -// 1. ⭐ [#12195] The compound door is GONE — the pin the removal owes +// 1. ⭐ [commit 7986d973f] The compound door is GONE — the pin the removal owes // ═══════════════════════════════════════════════════════════════════════════ describe('[#11095 / #12195] the compound-name `PUT` arity is retired', () => { /** * ⛔ REWORKED, not deleted — same reasoning as the `mode` suite next door. * #11095 threaded `?force` onto the compound door to close the fourth - * divergence on the pair; #12176 then retired the pair itself. The guard + * divergence on the pair; commit 7986d973f then retired the pair itself. The guard * worth keeping is against the arity coming BACK, because a re-mounted * compound door is a door that reads neither `?force` nor `?mode` unless * someone re-threads them — the divergence family this file documents. @@ -435,7 +435,7 @@ describe('[#11095 / #6877] a REPEATED `?force` is refused, never read as force-O }); // ═══════════════════════════════════════════════════════════════════════════ -// 4. ⭐ [#12194] A slash-bearing name is refused at the GRAMMAR gate, before +// 4. ⭐ [commit 311433f6b] A slash-bearing name is refused at the GRAMMAR gate, before // the destructive gate — and `?force` cannot acknowledge past it. // ═══════════════════════════════════════════════════════════════════════════ diff --git a/packages/rest/src/meta-compound-save-mode-parity.test.ts b/packages/rest/src/meta-compound-save-mode-parity.test.ts index 2a26dbc61e5..bcf3e82b241 100644 --- a/packages/rest/src/meta-compound-save-mode-parity.test.ts +++ b/packages/rest/src/meta-compound-save-mode-parity.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#11712 → #12195] `?mode=draft` on the `/meta` save doors — a two-door parity + * [#11712 → commit 7986d973f] `?mode=draft` on the `/meta` save doors — a two-door parity * suite whose SECOND DOOR NO LONGER EXISTS. * * ## What this file is now, and why it was not deleted @@ -23,9 +23,9 @@ * The caller asked for a staging buffer and got a publish, with a `200` and no * signal at the call site. * - * #12176's maintainer ruling (2026-08-25) retired compound metadata item names - * outright. Stage 1 (#12194) declared the item-name grammar and refuses every - * slash-bearing name at the publish door; stage 3 (#12195) un-mounts the arity. + * Commit 7986d973f's maintainer ruling (2026-08-25) retired compound metadata item names + * outright. Stage 1 (commit 311433f6b) declared the item-name grammar and refuses every + * slash-bearing name at the publish door; stage 3 (commit 7986d973f) un-mounts the arity. * So the divergence is not fixed — the door it needed is GONE. * * ⛔ The file is REWORKED rather than deleted, deliberately. "The divergence is @@ -39,7 +39,7 @@ * are unchanged; * 3. #6877's repeated-parameter guard is re-pinned on the surviving door (§3); * 4. the slash-bearing name a caller would once have spelled compound is - * pinned answering #12194's `400 INVALID_REQUEST` at the surviving door + * pinned answering commit 311433f6b's `400 INVALID_REQUEST` at the surviving door * (§4) — the capability that REPLACED the compound arity, and the case that * answered `200` + published-live before this retirement. * @@ -66,7 +66,7 @@ * `meta-compound-save-force-parity.test.ts` documents. The `200` save answer is * the protocol's own `{ success, version, seq, state, message }`. The `400` * from `refuseRepeatedQueryParams` is hand-built by the route and NESTED: - * `{ error: { code, message } }`. #12194's grammar refusal is the ADR-0112 + * `{ error: { code, message } }`. Commit 311433f6b's grammar refusal is the ADR-0112 * envelope with a TOP-LEVEL `code` (`INVALID_REQUEST`). */ @@ -272,7 +272,7 @@ function boot() { outcome: (name: string) => [labelOf(name, 'active'), labelOf(name, 'draft')] as const, singleOutcome: () => [labelOf(SINGLE_NAME, 'active'), labelOf(SINGLE_NAME, 'draft')] as const, /** - * [#12195] The compound door's REGISTRATION, not a call to it. This + * [commit 7986d973f] The compound door's REGISTRATION, not a call to it. This * used to be `compoundPut()`, driving `PUT COMPOUND_PATH`; the arity is * retired, so what is assertable now is that nothing is mounted there. */ @@ -285,7 +285,7 @@ function boot() { singlePut: (query: Record = {}) => call(SINGLE_PATH, { type: 'object', name: SINGLE_NAME }, query), /** - * [#12195] The surviving door addressed with an ARBITRARY name — the + * [commit 7986d973f] The surviving door addressed with an ARBITRARY name — the * shape a caller now uses for a slash-bearing one. Hono decodes `%2F` * before the handler runs, so the handler sees the raw name and this * helper hands it over directly, which is the same value. @@ -301,14 +301,14 @@ const STAGED = [LIVE_LABEL, SUBMITTED_LABEL]; const PUBLISHED = [SUBMITTED_LABEL, undefined]; // ═══════════════════════════════════════════════════════════════════════════ -// 1. ⭐ [#12195] The compound door is GONE — the pin the removal owes +// 1. ⭐ [commit 7986d973f] The compound door is GONE — the pin the removal owes // ═══════════════════════════════════════════════════════════════════════════ describe('[#11712 / #12195] the compound-name `PUT` arity is retired', () => { /** * ⛔ This file's original subject — "`?mode=draft` is honoured at one door - * and dropped at the other" — is DISSOLVED, not fixed. #12176 retired - * compound metadata item names; #12194 refuses every slash-bearing name at + * and dropped at the other" — is DISSOLVED, not fixed. Commit 7986d973f retired + * compound metadata item names; commit 311433f6b refuses every slash-bearing name at * the publish door; this stage un-mounts the arity that used to serve them. * * The pins are REWORKED rather than deleted, because "the divergence is @@ -447,7 +447,7 @@ describe('[#11712 / #6877] a REPEATED query parameter is refused, never read as }); // ═══════════════════════════════════════════════════════════════════════════ -// 4. ⭐ [#12194] A slash-bearing name is refused at the GRAMMAR gate — the +// 4. ⭐ [commit 311433f6b] A slash-bearing name is refused at the GRAMMAR gate — the // capability that replaced the compound door, pinned where callers meet it. // ═══════════════════════════════════════════════════════════════════════════ @@ -456,7 +456,7 @@ describe('[#12194 / #12195] a slash-bearing name is refused at the surviving doo * With the compound arity gone, `crm/task` reaches the single-segment door * percent-encoded (`%2F`) — the spelling the SDK now sends for every name, * and the one Hono decodes back to `crm/task` before the handler sees it. - * What answers is #12194's grammar refusal, with the ADR-0112 envelope. + * What answers is commit 311433f6b's grammar refusal, with the ADR-0112 envelope. * * This is the pin that makes the removal safe to read: the old compound * door answered `200` and published live for this exact input. diff --git a/packages/rest/src/meta-item-layered-route.test.ts b/packages/rest/src/meta-item-layered-route.test.ts index bb3b4a387d3..bc8b3fc3d8a 100644 --- a/packages/rest/src/meta-item-layered-route.test.ts +++ b/packages/rest/src/meta-item-layered-route.test.ts @@ -125,7 +125,7 @@ describe('#5882 GET /meta/:type/:name/layers — the declared layered resource', }); it('has no three-segment catch-all left to capture its path', async () => { - // [#12195] This used to be an ORDER pin. `/:type/:name` cannot match a + // [commit 7986d973f] This used to be an ORDER pin. `/:type/:name` cannot match a // 3-segment path, but `/:type/:section/:name` COULD — it would bind // section=, name="layers" and answer an ordinary metadata read // for an item called "layers". Under a first-match router, registration diff --git a/packages/rest/src/meta-object-fls.test.ts b/packages/rest/src/meta-object-fls.test.ts index 3a352e41797..e2290c2b8e2 100644 --- a/packages/rest/src/meta-object-fls.test.ts +++ b/packages/rest/src/meta-object-fls.test.ts @@ -164,7 +164,7 @@ const EXITS: ObjectSchemaMaskExit[] = [ { name: 'GET /meta/objects/:name?state=draft — uncached branch via the canonical PLURAL spelling', run: (testCase) => { - // #3984/#6241: the plural spelling is canonical, and a gate keyed on + // #3984/commit 83a3b1f2e: the plural spelling is canonical, and a gate keyed on // the raw `:type` param is a gate it walks past. Driving one row of // the table through it keeps that from being re-learned. const { rest } = boot({ testCase, cached: true }); @@ -200,7 +200,7 @@ const EXITS: ObjectSchemaMaskExit[] = [ ); }, }, - // [#12195] The compound-name read `GET /meta/:type/:section/:name` was the + // [commit 7986d973f] The compound-name read `GET /meta/:type/:section/:name` was the // fourth exit in this table until its arity was retired. Every name reaches // the single-item read above now, and that exit carries the same ADR-0106 // masking contract — so the removal costs this table no coverage, it costs diff --git a/packages/rest/src/meta-plural-i18n.test.ts b/packages/rest/src/meta-plural-i18n.test.ts index ae703aa17fb..436340d2caa 100644 --- a/packages/rest/src/meta-plural-i18n.test.ts +++ b/packages/rest/src/meta-plural-i18n.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #6349 — the `/meta` routes' PLURAL spelling gets the same i18n as the + * Commit 2443bb4c4 — the `/meta` routes' PLURAL spelling gets the same i18n as the * singular one. * * `translateMetaItem` / `translateMetaItems` decide "does this type translate" @@ -327,19 +327,19 @@ describe('#6349 §2 single item `GET /meta/:type/:name`', () => { }); // --------------------------------------------------------------------------- -// §3 — [#12195] the compound-name read is RETIRED +// §3 — [commit 7986d973f] the compound-name read is RETIRED // --------------------------------------------------------------------------- describe('#6349 §3 — the compound-name arity no longer exists', () => { /** * This section drove `GET /meta/:type/:section/:name` and asserted the * plural type spelling translated identically to the singular there. The - * arity is retired (#12176 stage 3), so the translation surface it covered + * arity is retired (commit 7986d973f stage 3), so the translation surface it covered * is served by §2's single-item read — which folds the type through the * same `canonicalMetaUrlType` and runs the same translator. * * What is left to pin is the absence, so a re-mounted compound arity cannot - * quietly reappear WITHOUT the plural fold (the #6349 defect: one spelling + * quietly reappear WITHOUT the plural fold (the commit 2443bb4c4 defect: one spelling * translated, the other not). */ it('mounts no compound `:section` arity to translate', () => { diff --git a/packages/rest/src/meta-publish-package-scope.test.ts b/packages/rest/src/meta-publish-package-scope.test.ts index 91cf251bab9..76039a1f054 100644 --- a/packages/rest/src/meta-publish-package-scope.test.ts +++ b/packages/rest/src/meta-publish-package-scope.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// #10063 — the draft→active promotion door could not state the package its +// Commit 9e04c3e35 — the draft→active promotion door could not state the package its // write belongs to, so #9612's package-closure narrowing never fired for the // one door that needed it most. // @@ -91,7 +91,7 @@ function mockRes() { /** * @param execCtx what `resolveExecCtx` resolves to for the request under test. - * The publish door gates on `manage_metadata` (#8919) BEFORE it reaches any + * The publish door gates on `manage_metadata` (commit b5378550e) BEFORE it reaches any * of this, so the capability is present in every case except the one that * deliberately withholds it — without it each case would 403 and pass for * the wrong reason. diff --git a/packages/rest/src/meta-published-overlay.test.ts b/packages/rest/src/meta-published-overlay.test.ts index b06920199a2..59b6afc87ac 100644 --- a/packages/rest/src/meta-published-overlay.test.ts +++ b/packages/rest/src/meta-published-overlay.test.ts @@ -358,7 +358,7 @@ describe('[#8278] REST `/meta/:type/:name/published` resolves from the published // registration than §1, so the overlay consult has to be on both or // the fix covers only one of the two doors this card puts in scope. // - // [#12194] The fixture used to be authored through `runtimePublish` — + // [commit 311433f6b] The fixture used to be authored through `runtimePublish` — // the item-name grammar now refuses a slash name at that door, and the // READ door deliberately stays open for pre-grammar residue rows. So // the row is seeded directly in the store, which is exactly what such @@ -377,7 +377,7 @@ describe('[#8278] REST `/meta/:type/:name/published` resolves from the published expect(Array.from(rows.values()).filter((r) => r.state === 'active')).toHaveLength(1); - // [#12195] Read through the SINGLE-SEGMENT door, which is where a + // [commit 7986d973f] Read through the SINGLE-SEGMENT door, which is where a // pre-grammar residue row is addressed now. This used to drive the // compound arity `GET /:type/:section/:name/published` with // `{ section: 'views', name: 'all_leads' }`, which the handler folded @@ -387,7 +387,7 @@ describe('[#8278] REST `/meta/:type/:name/published` resolves from the published // percent-encodes the name, `%2F` matches `/:type/:name/published` // (Hono does not split on an encoded slash — measured), and Hono decodes // the parameter back to `views/all_leads` before the handler runs. So - // the handler receives exactly the value passed below, and #12194's + // the handler receives exactly the value passed below, and commit 311433f6b's // "any stored junk name remains listable and clearable" still holds. const res = await callPublished( setup(protocol, metadata), diff --git a/packages/rest/src/meta-route-registration-order.test.ts b/packages/rest/src/meta-route-registration-order.test.ts index a6fd7b5f872..5beb5d16042 100644 --- a/packages/rest/src/meta-route-registration-order.test.ts +++ b/packages/rest/src/meta-route-registration-order.test.ts @@ -12,7 +12,7 @@ * * `GET /meta/:type` swallows every one-segment path — `diagnostics`, * `_drafts`, `types` — that is not registered ahead of it; * * `GET /meta/:type/:section/:name` swallowed every three-segment path — - * `/history`, `/audit`, `/diff`, `/published` — likewise. [#12195] That + * `/history`, `/audit`, `/diff`, `/published` — likewise. [commit 7986d973f] That * one is RETIRED with compound-name addressing, so the hazard is gone * rather than ordered around; the pin below inverted to match, because a * re-mount is how the hazard comes back and an order pin phrased against @@ -94,7 +94,7 @@ describe('/meta registration order', () => { } }); - // [#12195] The three compound arities are RETIRED, so the two pins that used + // [commit 7986d973f] The three compound arities are RETIRED, so the two pins that used // to live here — "every three-segment literal precedes the compound-name // catch-all" and "the FSM state read precedes the compound `/published` // twin" — no longer have a second route to order against. diff --git a/packages/rest/src/meta-state-route-doc-spelling.test.ts b/packages/rest/src/meta-state-route-doc-spelling.test.ts index b43f0ec83eb..9a8ffac7a7a 100644 --- a/packages/rest/src/meta-state-route-doc-spelling.test.ts +++ b/packages/rest/src/meta-state-route-doc-spelling.test.ts @@ -2,7 +2,7 @@ /** * The published prose that teaches the ADR-0020 D3.3 legal-next-state - * introspection route spells it the way the REST ledger does (#10178, #14561). + * introspection route spells it the way the REST ledger does (commit 38cf397ea, #14561). * * WHY THIS EXISTS (measured, not argued). #9180 step ② retired the plural * `/api/v1/meta/objects/:name/state/:field` registration and moved the SDK to diff --git a/packages/rest/src/meta-unknown-type-read-refusal.test.ts b/packages/rest/src/meta-unknown-type-read-refusal.test.ts index a76520234e5..a85eadbc3cc 100644 --- a/packages/rest/src/meta-unknown-type-read-refusal.test.ts +++ b/packages/rest/src/meta-unknown-type-read-refusal.test.ts @@ -20,7 +20,7 @@ // // * types in the static spelling contract (`sharing_rule`, `webhook`, // `objects`, `api`) — declared, addressable, frequently empty -// (`theme` was one of them until #10485 retired its carrier out of the +// (`theme` was one of them until commit 35ad101bc retired its carrier out of the // contract — it now earns the refusal, pinned below); // * live-only keys an ordinary `registerApp` produces (`data`, `kind`, // `package`, `policy`) — outside the static contract but ENUMERATED by @@ -184,7 +184,7 @@ describe('[#9488] a type that EXISTS and has no items still answers 200 with an it.each(['theme', 'themes'])( '[#10485] retired spelling %s is refused — it left the static contract with its carrier', async (type) => { - // Until #10485 both spellings answered 200-empty here. The + // Until commit 35ad101bc both spellings answered 200-empty here. The // retirement removed the `themes: 'theme'` fold, so a read now // gets the same ADR-0112 refusal an invented name does. const { rest } = setup(); diff --git a/packages/rest/src/meta-write-door-capability-enumeration.test.ts b/packages/rest/src/meta-write-door-capability-enumeration.test.ts index 076976ee6ee..5e9612e729e 100644 --- a/packages/rest/src/meta-write-door-capability-enumeration.test.ts +++ b/packages/rest/src/meta-write-door-capability-enumeration.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#8919] EVERY metadata write door on the REST `/meta` surface demands the + * [commit b5378550e] EVERY metadata write door on the REST `/meta` surface demands the * ADR-0066 D1 `manage_metadata` authoring capability. * * ## Why this is an enumeration and not two more assertions @@ -113,11 +113,11 @@ interface Door { /** * The metadata write doors, as registered by `registerMetadataEndpoints` — five - * of them since #12195 retired the compound-name save (the count is the table's + * of them since commit 7986d973f retired the compound-name save (the count is the table's * own length, never a number written in prose: it read "six" for as long as it - * took #12195 to remove an entry without touching this sentence). + * took commit 7986d973f to remove an entry without touching this sentence). * - * Four carried the gate before #8919 (`_migrate-stored` #4857-era, the single + * Four carried the gate before commit b5378550e (`_migrate-stored` #4857-era, the single * and compound saves #6603/#7019, the reset #7019); `publish` and `rollback` * are the two that card added. * @@ -156,7 +156,7 @@ const DOORS: readonly Door[] = [ protocolMethod: 'rollbackMetaItem', params: { type: 'object', name: 'account' }, body: { toVersion: 1 }, }, - // [#12195] `PUT /meta/:type/:section/:name — compound-name save` was + // [commit 7986d973f] `PUT /meta/:type/:section/:name — compound-name save` was // enumerated here until its arity was retired. It reached the same // `saveMetaItem` as the single-segment save above and carried the same // capability gate, so the door set loses a spelling, not a capability. diff --git a/packages/rest/src/package-door-16019-raw-statement-fault-code.test.ts b/packages/rest/src/package-door-16019-raw-statement-fault-code.test.ts index 5a4b6e86cdd..0881af34812 100644 --- a/packages/rest/src/package-door-16019-raw-statement-fault-code.test.ts +++ b/packages/rest/src/package-door-16019-raw-statement-fault-code.test.ts @@ -49,7 +49,7 @@ * * ⛔ Not a re-judgement of either catch: `declaresHttpAnswer`'s docblock * already says a declared 5xx is re-thrown too. The contract review of PR - * #16650 required the consequence to be NAMED and PINNED, nothing else. + * Commit 001a83b04 required the consequence to be NAMED and PINNED, nothing else. */ import { describe, it, expect, vi } from 'vitest'; diff --git a/packages/rest/src/package-door-execctx-fault-reachability.test.ts b/packages/rest/src/package-door-execctx-fault-reachability.test.ts index d9bb704da7e..b212eb63032 100644 --- a/packages/rest/src/package-door-execctx-fault-reachability.test.ts +++ b/packages/rest/src/package-door-execctx-fault-reachability.test.ts @@ -29,7 +29,7 @@ * anonymous floor decides: **401 `UNAUTHENTICATED`**, "Authentication is * required to access this endpoint." The caller may hold a valid session; * the fault is elsewhere. - * - `GRANTS LOST` (two classes, ⭐ both since repaired — #13279 and + * - `GRANTS LOST` (two classes, ⭐ both since repaired — commit 6a180e42d and * [#13476]) — identity survives and the CAPABILITY * aggregation is what faulted, so the door answered **403 `FORBIDDEN`**, * "Reading packages requires the `studio.access` or `setup.access` @@ -40,7 +40,7 @@ * inside `resolveAuthzContext` (`@objectstack/core`), one layer further * out. * - * ⭐ **[#13279] REPAIRED, and this file now pins the repair.** Maintainer + * ⭐ **[commit 6a180e42d] REPAIRED, and this file now pins the repair.** Maintainer * ruling 2026-08-30, verbatim 「第一批其余同意」: `tryFind` distinguishes * "no rows" from "the read failed", and a read failure fails LOUD. The * `PERMISSION_STORE_DOWN` class therefore answers **503 @@ -73,7 +73,7 @@ * any class — that zero was read against a WORKING instrument: section 1 * shows this same door answering **500 `INTERNAL_ERROR`** when the fault is * raised one layer later, by the package service. So "no 5xx" was a property - * of the degradation, not of the harness. ⭐ **[#13279] Now partitioned + * of the degradation, not of the harness. ⭐ **[commit 6a180e42d] Now partitioned * rather than zero**: the ruled permission-store class answers 503 on every * route, and every class the ruling did not reach still answers a refusal. * Section 3 asserts both halves, so the test still fails if a door goes @@ -90,11 +90,11 @@ * lets anything through. Section 4 measures this per class, against a * control that shows the witness CAN report a rejection. * - * ## What this file does, and no longer does not (#13279) + * ## What this file does, and no longer does not (commit 6a180e42d) * * As written for #13255 this file repaired nothing and asserted no verdict — * distinguishing "no context" from "resolution failed" was a behaviour change - * on a public door and out of that card's scope. #13279 RULED that change for + * on a public door and out of that card's scope. Commit 6a180e42d RULED that change for * the permission-store half, so the assertions covering it are now regression * pins on the repaired behaviour rather than measurements of a defect. * @@ -144,7 +144,7 @@ import { describe, it, expect } from 'vitest'; import { ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_STATUS, - // [#13279] The loud permission-store outage, and its brand predicate. + // [commit 6a180e42d] The loud permission-store outage, and its brand predicate. AUTHZ_STORE_UNAVAILABLE_CODE, AUTHZ_STORE_UNAVAILABLE_STATUS, isAuthzStoreUnavailableError, } from '@objectstack/core'; import type { RouteHandler } from '@objectstack/spec/contracts'; @@ -339,7 +339,7 @@ interface FaultClass { /** * `lost` — the whole execution context is gone. * `grants` — identity survives, the capability aggregation is empty. - * `loud` — [#13279] the resolution REFUSES rather than resolving at all. + * `loud` — [commit 6a180e42d] the resolution REFUSES rather than resolving at all. */ ctx: 'lost' | 'grants' | 'loud'; read: { status: number; code: string }; @@ -349,7 +349,7 @@ interface FaultClass { const DENY = { status: ANONYMOUS_DENY_STATUS, code: ANONYMOUS_DENY_CODE }; /** * The capability refusal. ⭐ [#13476] No fault CLASS carries this any more — the - * two that did are both repaired (#13279, #13476) — but it is deliberately kept + * two that did are both repaired (commit 6a180e42d, #13476) — but it is deliberately kept * rather than deleted: it is now the answer the INNOCENT shapes must keep, and * section 3's `UNRESOLVABLE vs UNWIRED` pin asserts it through this constant so * "what an unwired embedder gets" and "what a genuine capability denial gets" @@ -358,7 +358,7 @@ const DENY = { status: ANONYMOUS_DENY_STATUS, code: ANONYMOUS_DENY_CODE }; */ const FORBID = { status: 403, code: 'FORBIDDEN' }; /** - * [#13279] The LOUD cohort — a permission-store outage, answered as the outage + * [commit 6a180e42d] The LOUD cohort — a permission-store outage, answered as the outage * it is. Ruled 2026-08-30 (maintainer, verbatim 「第一批其余同意」): * `tryFind` distinguishes "no rows" from "the read failed", and a read failure * fails LOUD, so an outage can no longer be answered as a capability denial. @@ -420,7 +420,7 @@ const CLASSES: FaultClass[] = [ id: 'PERMISSION_STORE_DOWN', what: 'identity resolves, then every permission-store read throws', faulted: () => ({ ...healthy(), objectQLProvider: async () => qlDown() }), - // ⭐ [#13279] INVERTED IN PLACE, not re-baselined. Until the 2026-08-30 + // ⭐ [commit 6a180e42d] INVERTED IN PLACE, not re-baselined. Until the 2026-08-30 // ruling this row read `ctx: 'grants', read: FORBID, write: FORBID` — an // authenticated principal with an empty capability set, refused 403. That // was the DISGUISE the ruling reverses: the store that holds the @@ -435,11 +435,11 @@ const CLASSES: FaultClass[] = [ // read `ctx: 'grants', read: FORBID, write: FORBID` — an authenticated // administrator whose engine was simply GONE, told they lack a capability. // It was the LAST surviving member of the GRANTS-LOST disguise on this - // door: #13279 made a read that was ISSUED and threw fail loud, and this + // door: commit 6a180e42d made a read that was ISSUED and threw fail loud, and this // class never issues a read, so that ruling's landing point could not see // it. The engine seam now keeps "no engine is wired" and "the engine could // not be resolved" apart (`wiredEngineOrLoud`, `rest-server.ts`), so this - // class takes the SAME loud answer #13279 chose, for the same reason: + // class takes the SAME loud answer commit 6a180e42d chose, for the same reason: // nothing was read, so no capability judgement was ever reached. // // ⚠️ Its innocent twin is NOT here and must never be: an embedder that @@ -455,7 +455,7 @@ describe('[#13255] reachability — each production fault class, driven, with it // ---- the fault ------------------------------------------------------- const rest = serverWith(klass.faulted()); const req = { params: {}, headers: {}, method: 'POST', path: PUBLISH_PATH, ...(klass.req ?? {}) }; - // [#13279] The loud cohort never produces a context to inspect — that IS + // [commit 6a180e42d] The loud cohort never produces a context to inspect — that IS // the repair. The resolution REJECTS with the branded outage error instead // of fabricating an envelope that reports a capability set nobody read. if (klass.ctx === 'loud') { @@ -635,7 +635,7 @@ describe('[#13255] the private resolver FULFILS on every production fault class' // The PRIVATE resolver, read BEFORE the wrapper's `.catch` can act — so // this reads the supplier, not the net over it. const inner = (rest as any).resolveExecCtx(req.params?.environmentId, req); - // ⭐ [#13279] INVERTED IN PLACE for the loud cohort. This assertion used to + // ⭐ [commit 6a180e42d] INVERTED IN PLACE for the loud cohort. This assertion used to // read `'fulfilled'` for EVERY class, and that uniformity was the finding: // every fault reached the door as a value, so no fault could be told from a // verdict. A permission-store outage now REJECTS all the way out here — @@ -674,7 +674,7 @@ describe('[#13255] a server-side fault is indistinguishable from the denial it i }); it('⭐ [#13279] GRANTS LOST: a permission-store outage NO LONGER answers what "you hold nothing" answers', async () => { - // ⭐ THE INVERSION. This is the #13282 assertion the 2026-08-30 ruling + // ⭐ THE INVERSION. This is the commit 43028a8f8 assertion the 2026-08-30 ruling // reverses, inverted IN PLACE with its reason recorded — ⛔ not deleted and // ⛔ not re-baselined. It used to read: // diff --git a/packages/rest/src/package-door-user-message.test.ts b/packages/rest/src/package-door-user-message.test.ts index 921037bb461..18baafa9846 100644 --- a/packages/rest/src/package-door-user-message.test.ts +++ b/packages/rest/src/package-door-user-message.test.ts @@ -17,7 +17,7 @@ * ``` * * `resolveThrownHttpError` answers `userMessage` whenever the throw carried a - * non-empty string one (`declaredUserMessage`, #9934), so an author's + * non-empty string one (`declaredUserMessage`, commit 79c46da90), so an author's * deliberate, end-user-addressed refusal text sat in that local and was * dropped one line later. Nothing invalid shipped — `code`, `status` and * `message` were all correct — which is what made the loss silent: the mark diff --git a/packages/rest/src/package-routes-coded-error-mapping.test.ts b/packages/rest/src/package-routes-coded-error-mapping.test.ts index 08a2a2eb8f4..0d9efeb4402 100644 --- a/packages/rest/src/package-routes-coded-error-mapping.test.ts +++ b/packages/rest/src/package-routes-coded-error-mapping.test.ts @@ -62,7 +62,7 @@ * ⚠️ The block's OTHER reason for driving the gate here is stale as well. It * read: *"`GET /packages` is different BY DESIGN: both of its data sources sit * in their own inner `try { … } catch {}` … so nothing below it reaches the - * outer catch"*. #11063 and #11130 removed both inner catches — + * outer catch"*. #11063 and commit 851909530 removed both inner catches — * `package-routes.ts` now marks each read `NOT wrapped in a catch, * deliberately` — so those arms DO reach this outer catch, and are pinned in * `package-list-durable-read-refusal.test.ts` and diff --git a/packages/rest/src/package-routes.ts b/packages/rest/src/package-routes.ts index d15d572e681..0e0f45a5497 100644 --- a/packages/rest/src/package-routes.ts +++ b/packages/rest/src/package-routes.ts @@ -52,7 +52,7 @@ async function refusePackageRequest( req: any, res: any, ): Promise { - // [#13279] The gate's OWN net. `rethrowAuthzStoreUnavailable` keeps the + // [commit 6a180e42d] The gate's OWN net. `rethrowAuthzStoreUnavailable` keeps the // fail-closed default for every fault except a permission-store outage, which // must reach `handlePackageRouteError` and be answered as the 503 // `SERVICE_UNAVAILABLE` it is — never as a capability denial the caller could @@ -207,7 +207,7 @@ function sendThrownError(res: any, error: unknown): void { // adding one here would be a new rule at one door and would re-create the // divergence this closes. const declaredCode = demotedDeclaredCode(thrown); - // [#12502] The producer's user-facing refusal text (#9934), the SECOND + // [#12502] The producer's user-facing refusal text (commit 79c46da90), the SECOND // declared channel this writer was holding and dropping. A third spread into // the same object, and the three do not interact: `details` is structured // context, `declaredCode` is a code spelling, `userMessage` is prose a @@ -225,7 +225,7 @@ function sendThrownError(res: any, error: unknown): void { // obligation to re-derive and inventing one to match the sibling would be the // mistake, not the safe choice. Byte for byte the dispatcher twin's // expression (`errorFromThrown`, `packages/runtime/src/http-dispatcher.ts`), - // which serves this same path and has emitted the channel since #9934. + // which serves this same path and has emitted the channel since commit 79c46da90. // // ⚠️ NOT withheld on the sanitised 5xx above, and this one needs no judgement // call: the withhold rewrites a LOCAL `message` const, and diff --git a/packages/rest/src/query-multiplicity.ts b/packages/rest/src/query-multiplicity.ts index e6887a55579..d4169688681 100644 --- a/packages/rest/src/query-multiplicity.ts +++ b/packages/rest/src/query-multiplicity.ts @@ -55,7 +55,7 @@ import { RPC_QUERY_ALIAS_SLOTS } from '@objectstack/spec/data'; * site names the parameters it declares single-valued instead of gating "every * key in `req.query`". * - * #6307 landed the first copy of this rule in `package-routes.ts`, on the + * Commit 293476148 landed the first copy of this rule in `package-routes.ts`, on the * `?version=` of that registrar's package read/delete routes. Those routes are * gone (#14503 — the dispatcher's `/packages` domain is their single * implementation), so the rule has one home: here. @@ -93,7 +93,7 @@ export type SingleQueryRead = /** * Read a query parameter the route declares single-valued out of the shape the - * transport contract actually declares (#6307). + * transport contract actually declares (commit 293476148). * * See this module's header for why repetition is refused rather than resolved, * and why the rule counts occurrences instead of inspecting the value. @@ -130,7 +130,7 @@ export function repeatedQueryParamMessage(name: string, count: number): string { * position ADR-0112 declares and the one PR #7293 (#7035) just converged this * file's `/meta` 501 refusals onto. `VALIDATION_ERROR` is not a new code: it is * the standard catalog's member for 400 (`spec/src/api/errors.zod.ts`, - * `standardErrorCodeForHttpStatus(400)`), and the same code #6307 chose for + * `standardErrorCodeForHttpStatus(400)`), and the same code commit 293476148 chose for * this same condition on `/packages/:id`. Nothing in `packages/spec` moves. * * ## Why it also normalises diff --git a/packages/rest/src/rest-14078-invalid-date-total-arm.test.ts b/packages/rest/src/rest-14078-invalid-date-total-arm.test.ts index dc8b2d45ebe..1e3eab5dc3e 100644 --- a/packages/rest/src/rest-14078-invalid-date-total-arm.test.ts +++ b/packages/rest/src/rest-14078-invalid-date-total-arm.test.ts @@ -16,7 +16,7 @@ * * ## Reachability is measured, not argued * - * PR #14409 (landed `3ecb7dc1a`) drove both live client libraries: mysql2 + * Commit 3ecb7dc1a (landed `3ecb7dc1a`) drove both live client libraries: mysql2 * 3.23.1 returns a module constant literally named `INVALID_DATE` for a zero * `DATETIME`, and postgres-date 1.0.7 builds `new Date(NaN)` for every year in * 275760..294276 — a range Postgres itself stores. The maintainer ruled option diff --git a/packages/rest/src/rest-4xx-message-truncation.test.ts b/packages/rest/src/rest-4xx-message-truncation.test.ts index 8f67e395503..5780193dadb 100644 --- a/packages/rest/src/rest-4xx-message-truncation.test.ts +++ b/packages/rest/src/rest-4xx-message-truncation.test.ts @@ -263,7 +263,7 @@ async function callRoute(rest: any, method: string, path: string, req: Record/ failed spec * validation: ` prefix, with a `(+N more)` suffix for the remainder. * - * ⚠️ [#10888] That is no longer the form THIS route receives in production, and + * ⚠️ [commit d806081dd] That is no longer the form THIS route receives in production, and * the distinction is worth stating because the docblock used to imply otherwise. * `saveMetaItem` renders its findings clause per face: the `/meta` write doors * declare `writeFace: 'meta-envelope'` and get a short headline (count plus diff --git a/packages/rest/src/rest-5xx-status-passthrough.test.ts b/packages/rest/src/rest-5xx-status-passthrough.test.ts index 1b30f5496ed..8a250035a9f 100644 --- a/packages/rest/src/rest-5xx-status-passthrough.test.ts +++ b/packages/rest/src/rest-5xx-status-passthrough.test.ts @@ -29,7 +29,7 @@ // not just the status. // // The `code` half is spelled with `declaresServerFault` (`@objectstack/types`, -// PR #6122) — the criterion this repo already uses for "the producer declared a +// Commit 64cd01082) — the criterion this repo already uses for "the producer declared a // server fault" at the analytics route and in `runtime`'s dispatcher — rather // than a fourth open-coded truthiness check. // diff --git a/packages/rest/src/rest-api-derivation-gates.test.ts b/packages/rest/src/rest-api-derivation-gates.test.ts index 86a6117d831..89fe00d1baa 100644 --- a/packages/rest/src/rest-api-derivation-gates.test.ts +++ b/packages/rest/src/rest-api-derivation-gates.test.ts @@ -128,7 +128,7 @@ describe('REST gate — action alias normalization (#3391)', () => { const ro = { apiMethods: ['get', 'list'] }; expect(allowed(ro, 'query')).toBe(true); // query → list expect(allowed(ro, 'find')).toBe(true); // find → list - // [#6259] Was `allowed(ro, 'batch', …)` — the third alias this table + // [commit 6968885ef] Was `allowed(ro, 'batch', …)` — the third alias this table // claimed to normalize, and the only one no producer ever sends. Every // `enforceApiAccess` call site passes a canonical literal, and the // cross-object `POST /batch` route (rest-server.ts, `registerBatchEndpoints`) @@ -138,7 +138,7 @@ describe('REST gate — action alias normalization (#3391)', () => { expect(allowed(ro, 'bulk', { bulkChild: 'create' })).toBe(false); }); - // [#6259] The REST half of the absence pin. Stated as the fork it is: + // [commit 6968885ef] The REST half of the absence pin. Stated as the fork it is: // `batch` is not DENIED, it is unrecognized — and an unrecognized action is // ungated by `apiMethods` (custom actions never were). That is precisely why // a producer-less row could not be dismissed as harmless: while it existed, diff --git a/packages/rest/src/rest-api-plugin-slot-lookups.test.ts b/packages/rest/src/rest-api-plugin-slot-lookups.test.ts index a7343d25bfe..6b23dc7cd60 100644 --- a/packages/rest/src/rest-api-plugin-slot-lookups.test.ts +++ b/packages/rest/src/rest-api-plugin-slot-lookups.test.ts @@ -71,7 +71,7 @@ const captured = vi.hoisted(() => ({ ctorArgs: [] as unknown[][] })); // is the only expensive thing here, so it is the only thing suppressed, and // every other method the composition root calls stays the production one. That // matters beyond tidiness — the plugin also asks the instance for the API base -// (`getApiBasePath()`, #6306), and a hand-written stub that lists only the +// (`getApiBasePath()`, commit fec784863), and a hand-written stub that lists only the // methods the plugin happened to call the day it was written turns each new // collaborator call into a `TypeError` here, in a file about slot WIRING that // has no opinion on the base. Inheriting the contract keeps this test measuring diff --git a/packages/rest/src/rest-api-plugin.ts b/packages/rest/src/rest-api-plugin.ts index c1f241c9cad..d2d87b19acf 100644 --- a/packages/rest/src/rest-api-plugin.ts +++ b/packages/rest/src/rest-api-plugin.ts @@ -548,7 +548,7 @@ export function createRestApiPlugin(config: RestApiPluginConfig = {}): Plugin { // those are; the route-ledger conformance guard drives the same // function, so a registrar added there cannot slip past it. if (restServer) { - // [#6306] ONE base for the whole surface. This is the same + // [commit fec784863] ONE base for the whole surface. This is the same // value `registerRoutes()` mounted everything else under — // asked of the server that owns it, never recomputed here. // The old line was `${basePath}/${version}`, which is diff --git a/packages/rest/src/rest-approvals-wire-codes.test.ts b/packages/rest/src/rest-approvals-wire-codes.test.ts index eb6f0e9fd74..b2b8e34f2a0 100644 --- a/packages/rest/src/rest-approvals-wire-codes.test.ts +++ b/packages/rest/src/rest-approvals-wire-codes.test.ts @@ -1,10 +1,10 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#8885] The approvals routes' wire codes are REGISTERED vocabulary — pins + * [commit 30b1c636a] The approvals routes' wire codes are REGISTERED vocabulary — pins * for the population the card's sweep found. * - * The #8885 sweep measured 9 codes reaching the wire from `packages/rest` that + * The commit 30b1c636a sweep measured 9 codes reaching the wire from `packages/rest` that * were in neither `StandardErrorCode` nor `ERROR_CODE_LEDGER`, all in one * family and all with the same cause: the approvals route factories spell the * terminal 500 catch's code as a TEMPLATE @@ -29,7 +29,7 @@ * (single-occurrence `.replace('-', '_')` included), so a route name the * template would mangle into an invalid code also fails here. * [#14573] The file has since become the home for the approvals door's - * live-emission pins generally, not only the #8885 population: the + * live-emission pins generally, not only the commit 30b1c636a population: the * `FORBIDDEN` → 403 case below pins a row that is registered vocabulary and * whose emission was — contrary to that card's premise — already observed * elsewhere. See its own comment for where, and why it is pinned here too. diff --git a/packages/rest/src/rest-duplicate-record-arm.test.ts b/packages/rest/src/rest-duplicate-record-arm.test.ts index e2ff3651d42..17ce8daf682 100644 --- a/packages/rest/src/rest-duplicate-record-arm.test.ts +++ b/packages/rest/src/rest-duplicate-record-arm.test.ts @@ -106,7 +106,7 @@ const mysqlRaw = () => }); /** - * driver-memory (#13197): already an ADR-0112 envelope of its own — + * driver-memory (commit 56c093c4d): already an ADR-0112 envelope of its own — * `UNIQUE_VIOLATION` / 409 — whose sentence quotes the offending value as JSON. * Measured template, byte for byte (`memory-unique-constraint.ts`). */ @@ -237,7 +237,7 @@ describe('#14389 §1 — the engine\'s DUPLICATE_RECORD envelope answers 409 UNI ); // The envelope's OWN `developerMessage` addresses the in-process caller // of `engine.insert` ("attached as `cause`", and the in-process - // spelling beside the wire one — #14723) and `cause` never reaches + // spelling beside the wire one — commit 65846bc46) and `cause` never reaches // this wire — it is not relayed. expect(r.body.developerMessage).not.toBe(env.developerMessage); expect(String(r.body.developerMessage)).not.toContain('cause'); @@ -383,7 +383,7 @@ describe('#14389 §2 — a real insert conflict, real engine on real better-sqli describe('#14389 §3 — the envelope and the raw error it carries answer the same status / code / field / sentence', () => { // The raw error still reaches this boundary from engine-direct callers and - // from every write door that is not `insert` (#14390 is the `update` door), + // from every write door that is not `insert` (commit 9d7f7259f is the `update` door), // through the untouched `isUniqueViolationError` arm. For ONE conflict the // two must agree, or the platform gives two answers to one constraint // depending on whether the engine happened to envelope it. diff --git a/packages/rest/src/rest-exec-ctx-principal-kind.test.ts b/packages/rest/src/rest-exec-ctx-principal-kind.test.ts index 1ff0e3e6f23..c5a2161b719 100644 --- a/packages/rest/src/rest-exec-ctx-principal-kind.test.ts +++ b/packages/rest/src/rest-exec-ctx-principal-kind.test.ts @@ -82,7 +82,7 @@ const makeAuth = () => ({ const cookie = headers?.get?.('cookie'); if (cookie === 'admin') return { user: { id: 'admin1' } }; if (cookie === 'member') return { user: { id: 'member1' } }; - // [#6216] A session that DOES carry a bearer token, so the + // [commit f586f1a89] A session that DOES carry a bearer token, so the // `accessToken` pin below exercises a live branch of // `resolveAuthzContext` rather than an absent value. if (cookie === 'member-tok') { @@ -318,7 +318,7 @@ describe('#6216 — the REST face assembles through the SHARED assembler, output // `ExecutionContext.accessToken` reaches hooks as `session.accessToken` // (`objectql/engine.ts` buildSession, `spec/data/hook.zod.ts`), and the // runtime / MCP face has always carried it. This transport never has. - // #6216 makes that an explicit `accessToken: undefined` input at this + // Commit f586f1a89 makes that an explicit `accessToken: undefined` input at this // face rather than a silent gap — widening a published hook surface to // a second transport is a product decision, not a refactor. If REST // should carry it, this pin is the thing that must change, deliberately. @@ -333,7 +333,7 @@ describe('#6216 — the REST face assembles through the SHARED assembler, output describe('#7280 — the ADR-0069 gate posture is an ASSEMBLED field on this face', () => { // Before #7280 the gate reached the envelope through // `...(authGate ? { authGate } : {})` spread on AFTER assembly, behind an - // `as any` — outside the closed entry field set (#6216) by construction. + // `as any` — outside the closed entry field set (commit f586f1a89) by construction. // It is an assembler input now. These pins are on the WIRE, through the real // `computeExecCtx` pipeline: `rest-auth-gate.test.ts` hand-builds a context // and so proves only that `enforceAuth` reads the key, never that this face diff --git a/packages/rest/src/rest-field-visibility-fault-envelope.test.ts b/packages/rest/src/rest-field-visibility-fault-envelope.test.ts index ba3133102dc..e33a330d6a3 100644 --- a/packages/rest/src/rest-field-visibility-fault-envelope.test.ts +++ b/packages/rest/src/rest-field-visibility-fault-envelope.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#8885] ADR-0112 pins for the two wire codes the card measured, on the REST + * [commit 30b1c636a] ADR-0112 pins for the two wire codes the card measured, on the REST * emitters themselves. * * ## 1. `sendFieldVisibilityFault` — the ADR-0106 D6 tier-3 refusal @@ -24,7 +24,7 @@ * * ## 2. `mapDataError`'s comment-access branch — `RECORD_NOT_ACCESSIBLE` * - * #8885's table claimed this code is in NEITHER `StandardErrorCode` nor the + * Commit 30b1c636a's table claimed this code is in NEITHER `StandardErrorCode` nor the * ledger. That row was a measurement error: `RECORD_NOT_ACCESSIBLE` has been a * `StandardErrorCode` member (Authorization block, "Sharing rule restriction") * since before the card's own measured commit — the #4630 branch comment diff --git a/packages/rest/src/rest-hook-refusal-code-parity.test.ts b/packages/rest/src/rest-hook-refusal-code-parity.test.ts index ad3cb7ece8e..b8fc66f782f 100644 --- a/packages/rest/src/rest-hook-refusal-code-parity.test.ts +++ b/packages/rest/src/rest-hook-refusal-code-parity.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// [#10345] A sandboxed hook refusal keeps its ADR-0112 `code` on the +// [commit cad8b42f0] A sandboxed hook refusal keeps its ADR-0112 `code` on the // `/api/v1/data` write path — at 409 and 403 exactly as at 400. // // --------------------------------------------------------------------------- diff --git a/packages/rest/src/rest-hook-refusal-message-parity.test.ts b/packages/rest/src/rest-hook-refusal-message-parity.test.ts index 18f435322c4..0b738841b6b 100644 --- a/packages/rest/src/rest-hook-refusal-message-parity.test.ts +++ b/packages/rest/src/rest-hook-refusal-message-parity.test.ts @@ -415,7 +415,7 @@ describe('[#11588] #5437/#5582 and #5423 are exactly where they were', () => { // RED pre-fix, because the fixture is a SANDBOXED refusal: the `error` // assertion reads the defect exactly as §1 does, and only the // `userMessage` half is direction-insensitive. Moved here and the claim - // corrected rather than the prediction re-fitted — #9934's marked + // corrected rather than the prediction re-fitted — commit 79c46da90's marked // channel is orthogonal to the unwrap and must stay so, which is a // "must not move" and not a control. const err = sandboxRefusal('this record is frozen', { @@ -482,12 +482,12 @@ describe('[#11588] #5437/#5582 and #5423 are exactly where they were', () => { // door while `mapDataError` sanitised the same error to a `500`. #11588 stated // why it stopped there — "making the two agree means moving the STATUS the // passthrough decided, which is a contract question and not this card's" — and -// #15071 widened the population without being able to take that question +// Commit cf6e0a193 widened the population without being able to take that question // either, recording it a second time as an ACCEPTED DIVERGENCE one file over // (`error-response-structured-arm-door-parity.test.ts` §4). // // #17273 is the card that took it: `resolveErrorResponse` now asks the same -// `isSandboxCrash` gate #15071 put above `classifyDataError`'s arms, before its +// `isSandboxCrash` gate commit cf6e0a193 put above `classifyDataError`'s arms, before its // declared-status passthrough, so the two doors answer one crash one way. // // ⛔ INVERTED rather than DELETED, the discipline §8b above already applies: a @@ -512,7 +512,7 @@ describe('[#11588 → #17273] the crash-with-a-declared-4xx divergence, now CLOS expect(viaRoute.body.error).toBe(INTERNAL_ERROR_MESSAGE); expect(String(viaRoute.body.error)).not.toContain('threw:'); - // The `/data` door, unmoved since #7543/#15071 — the control that says + // The `/data` door, unmoved since #7543/commit cf6e0a193 — the control that says // the flip above is the route door meeting it, not both doors sliding. const viaData = mapDataError(withCrash()); expect(viaData.status).toBe(500); @@ -523,7 +523,7 @@ describe('[#11588 → #17273] the crash-with-a-declared-4xx divergence, now CLOS it('#17273 negative control: the same declared 4xx WITHOUT a crash keeps the passthrough, both status and sentence', () => { // One `innerMessage` apart from the case above. A refusal is not a - // crash, and #15071's ruling fences it explicitly — if this goes green + // crash, and commit cf6e0a193's ruling fences it explicitly — if this goes green // by answering 500, the fix above deleted the refusal surface instead // of moving the crash. const refusal = throughRouteDoor(sandboxRefusal('x', { status: 409 })); diff --git a/packages/rest/src/rest-hook-script-fault-envelope.test.ts b/packages/rest/src/rest-hook-script-fault-envelope.test.ts index f4fbda78f90..fc42178d4b3 100644 --- a/packages/rest/src/rest-hook-script-fault-envelope.test.ts +++ b/packages/rest/src/rest-hook-script-fault-envelope.test.ts @@ -325,7 +325,7 @@ describe('[#7543] a hook that deliberately refuses still speaks in its own words }); it('the refusal envelope carries no `code` when the hook declared none', () => { - // [#10345] Re-read, not rewritten to fit. This assertion always tested a + // [commit cad8b42f0] Re-read, not rewritten to fit. This assertion always tested a // producer that declares NO code, so it pins ADR-0112's "nothing is // invented for a half-declaration" and is green on both sides of that // card. What it never tested — and what the comment here used to claim diff --git a/packages/rest/src/rest-route-ledger.ts b/packages/rest/src/rest-route-ledger.ts index 3f88dc256b7..aaed1b45665 100644 --- a/packages/rest/src/rest-route-ledger.ts +++ b/packages/rest/src/rest-route-ledger.ts @@ -278,9 +278,9 @@ export const REST_ROUTE_LEDGER: readonly RestRouteLedgerEntry[] = [ // so the SDK guard (#3642) certified them off a DECLARATION while they died // at runtime. Both are `route-manager` mounts here now. // - // [#12195] The ordering constraint this note used to carry is DISCHARGED, + // [commit 7986d973f] The ordering constraint this note used to carry is DISCHARGED, // not merely unstated: the compound `/:type/:section/:name` arities are - // retired (stage 3 of #12176), and they were the three-segment catch-all + // retired (stage 3 of commit 7986d973f), and they were the three-segment catch-all // that every literal three-segment sibling had to be registered above. The // four-segment `/state/:field` collision with the compound `/published` // twin is gone with it. `meta-route-registration-order.test.ts` still pins @@ -292,11 +292,11 @@ export const REST_ROUTE_LEDGER: readonly RestRouteLedgerEntry[] = [ responseSchema: 'GetPublishedMetaItemResponseSchema', note: 'ADR-0033 published snapshot; 404s for a name that does not exist, which the pre-#7526 fall-through into the compound-name route structurally could not do (it answered a protection-envelope stub identical before publish and for a bogus name). [#12038 ruling 1C] the named schema is DELIBERATELY OPAQUE (`z.unknown()`): the route answers an arbitrary metadata item body, BARE on this surface (enveloped on the dispatcher twin) — never a union frozen against the type registry' }, - // [#12195] THREE ROWS RETIRED HERE — `GET /api/v1/meta/:type/:section/:name`, + // [commit 7986d973f] THREE ROWS RETIRED HERE — `GET /api/v1/meta/:type/:section/:name`, // `PUT` on the same path, and `GET …/:section/:name/published`. They were the // compound-name arities: `section` and `name` folded back into one // slash-bearing key the protocol layer treated as a single opaque string. - // Stage 1 (#12194) made every such name unwritable at the publish door, so + // Stage 1 (commit 311433f6b) made every such name unwritable at the publish door, so // the arities addressed only names that can no longer be created. // // No `client:` disposition moved to `absent` as a result: `meta.getItem`, @@ -305,7 +305,7 @@ export const REST_ROUTE_LEDGER: readonly RestRouteLedgerEntry[] = [ // name — it percent-encodes, and `%2F` matches the single-segment pattern // with the parameter decoded back to the stored spelling. That is what keeps // a pre-grammar residue row readable, writable and deletable after the - // removal, per #12194's "any stored junk name remains listable and + // removal, per commit 311433f6b's "any stored junk name remains listable and // clearable". // ── ui ──────────────────────────────────────────────────────────────────── diff --git a/packages/rest/src/rest-sandbox-declared-status.test.ts b/packages/rest/src/rest-sandbox-declared-status.test.ts index c7c7982a80d..4c825f85b9e 100644 --- a/packages/rest/src/rest-sandbox-declared-status.test.ts +++ b/packages/rest/src/rest-sandbox-declared-status.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// [#9967] A sandboxed hook body that DECLARES its own HTTP status is served +// [commit 8f266f1cd] A sandboxed hook body that DECLARES its own HTTP status is served // with it on `/api/v1/data` — the sandbox unwrap no longer outranks the // declared-status read. // @@ -26,11 +26,11 @@ // - a body that CRASHES (`isScriptFaultMessage`) stays the sanitised 500 — // even when the crash object carries a stray `status`; // - the envelope carries no `code` for a body that DECLARED none. -// ⚠️ [#10345] That third bullet used to read "the envelope still carries NO +// ⚠️ [commit cad8b42f0] That third bullet used to read "the envelope still carries NO // `code` field (old @objectstack/client builds prepend `code` to the // human-readable message)". Every fixture below declares no code, so what // the section actually pinned was ADR-0112's "invent nothing" half, and it -// is green on both sides of #10345. The blanket claim was the defect: a +// is green on both sides of commit cad8b42f0. The blanket claim was the defect: a // hook that DID declare a code lost it here. See `error-response.ts` for // why the client-compat rationale is retired. // @@ -94,7 +94,7 @@ describe('[#9967] mapDataError: a sandboxed body that declares a 4xx status keep // The unwrap branch's own contract (`object` rides; no `code` is // invented for a producer that declared none) is unchanged by the fix; // compared output-to-output so a field later added to BOTH envelopes - // (#9934's marking, #10345's declared `code`) keeps this green. + // (commit 79c46da90's marking, commit cad8b42f0's declared `code`) keeps this green. const declared = mapDataError(sandboxRefusal({ status: 403 }), 'showcase_task'); const undeclared = mapDataError(sandboxRefusal(), 'showcase_task'); diff --git a/packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts b/packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts index 38cb6ad5848..626e2f612b8 100644 --- a/packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts +++ b/packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// #10340 — the `/meta` doors decided ORGANIZATION SCOPE from the RAW url +// Commit 26f3588fb — the `/meta` doors decided ORGANIZATION SCOPE from the RAW url // spelling while storage folded it through the COMPLETE map. // // ── What was broken ─────────────────────────────────────────────────────── @@ -47,7 +47,7 @@ import { RestServer } from './rest-server.js'; const META = '/api/v1/meta'; const ORG = 'org_alpha'; -// The two measured members of the disagreement set (#10340's table, +// The two measured members of the disagreement set (commit 26f3588fb's table, // re-derived at head by execution): URL-only spellings of // `allowOrgOverride: true` types, invisible to the manifest map. const MEMBERS = [ @@ -202,7 +202,7 @@ describe('#10340 the /meta doors decide org scope on the FOLDED type, not the ra }); expect(requestFrom(b6.rollbackMetaItem).organizationId).toBe(ORG); - // [#12195] The compound-name GET and PUT were driven here too, + // [commit 7986d973f] The compound-name GET and PUT were driven here too, // as the doors most likely to be left org-BLIND while their // twins were fixed (#9454). Their arity is retired, so the // spelling map is exercised through the single-segment doors @@ -256,7 +256,7 @@ describe('#10340 the /meta doors decide org scope on the FOLDED type, not the ra }); it('⛔ leaves GET /meta/_drafts unfolded — it matches the draft row STORED type, by design', async () => { - // Deliberately NOT a site (#10340 records why): stored types are + // Deliberately NOT a site (commit 26f3588fb records why): stored types are // canonical because the protocol folds on save, so `?type=` is a // filter against stored rows, not a URL segment. Folding it would // be a behaviour change, not a repair. diff --git a/packages/rest/src/rest-server-meta-read-org-scope.test.ts b/packages/rest/src/rest-server-meta-read-org-scope.test.ts index 29955672a1d..b931a835a8b 100644 --- a/packages/rest/src/rest-server-meta-read-org-scope.test.ts +++ b/packages/rest/src/rest-server-meta-read-org-scope.test.ts @@ -595,7 +595,7 @@ describe('#13764 the history seams of this harness honour the org partition', () // fold happens, not about whether one happens. `getMetaDiagnostics` reads each // swept type through `getMetaItems({ type: t, organizationId })`. // -// ⚠️ [#14683, recorded by #15034] `getMetaItems` NOW APPLIES THE REGISTRY GATE +// ⚠️ [commit 96326040f, recorded by #15034] `getMetaItems` NOW APPLIES THE REGISTRY GATE // ITSELF, after folding the request type. This header used to say it applied // none and that the scope was therefore the caller's to decide per type; that // sentence is FALSE on today's tree. What that dissolved is the obstacle the @@ -629,7 +629,7 @@ describe('#13764 the history seams of this harness honour the org partition', () // `ctx?.tenantId` at the call site and that assertion, and only it, turns red." // MEASURED on the merged tree, that ablation now leaves this file GREEN IN FULL // (30/30 at that revision; the file has grown since) — `getMetaItems`' own gate -// re-folds the raw tenant id, phantom control included. Same fate as #14677's +// re-folds the raw tenant id, phantom control included. Same fate as commit a4e4d2d78's // ablation B, and for the same reason. // // ⇒ What this file DOES still discriminate is the organization being DROPPED: @@ -683,7 +683,7 @@ describe('#13753 GET /meta/diagnostics states the org partition on the ?type= ar }); it('a plural URL spelling is folded before the scope decision, not after', async () => { - // [#10340] The predicate is asked with `canonicalMetaUrlType(...)`, + // [commit 26f3588fb] The predicate is asked with `canonicalMetaUrlType(...)`, // never the raw segment: `declaresOrgOverride` answers `false` for // URL-only spellings, so an unfolded `views` would silently drop // back to env-wide and this case would report a clean tile again. @@ -711,7 +711,7 @@ describe('#13753 GET /meta/diagnostics states the org partition on the ?type= ar // would serve them again. ⚠️ [#15034] PREDICTED DIRECTION, // CORRECTED: replacing the predicate with `ctx?.tenantId` at the // call site no longer moves this count — `getMetaItems`' own gate - // (#14683) re-folds it. What still drives it to 2 is a read door + // (commit 96326040f) re-folds it. What still drives it to 2 is a read door // that reaches the store with the org unfolded, which is why the // control stays. const written = await b.put(NON_OVERRIDABLE, 'accounts'); @@ -796,7 +796,7 @@ describe('#13753 GET /meta/diagnostics states the org partition on the ?type= ar // the whole-registry sweep`, which asserted the OPPOSITE and // carried "if this reddens, read the card before making it green". // #15622 IS that card. It ruled the untyped arm forwards the - // caller's organization RAW, because since #14683 the callee folds + // caller's organization RAW, because since commit 96326040f the callee folds // per swept type inside its own loop — so one org id now expresses // exactly the per-type scope the old pin said it could not. The // assertion is INVERTED rather than deleted so the next reader sees @@ -974,7 +974,7 @@ describe('#13753 GET /meta/diagnostics states the org partition on the ?type= ar // on a non-overridable target (`object`, `flow`, `app` — the most common // delete there is) it would suppress the organization altogether and leave the // false clearance exactly where it was. Raw is nevertheless not an -// unconditional tenant: since #14683 `getMetaItems` applies +// unconditional tenant: since commit 96326040f `getMetaItems` applies // `organizationIdForMetaRead` to its OWN `request.type`, so the per-SOURCE // decision is the callee's. // diff --git a/packages/rest/src/rest-server-meta-references-refusal-envelope.test.ts b/packages/rest/src/rest-server-meta-references-refusal-envelope.test.ts index 181cfdc5791..419b153489e 100644 --- a/packages/rest/src/rest-server-meta-references-refusal-envelope.test.ts +++ b/packages/rest/src/rest-server-meta-references-refusal-envelope.test.ts @@ -294,7 +294,7 @@ describe('#15685 the /references door answers its two refusals in ONE envelope', // POPULATION, because "survives the bound" is meaningless without one. The // enforced ceiling on a metadata item name is the `maxLength` of the column // that stores it, not a `.max()` in `packages/spec`: the identifier schemas - // declare a floor and a grammar and deliberately no ceiling (#12144), and + // declare a floor and a grammar and deliberately no ceiling (commit 3a04b0125), and // the widest storing column is `sys_metadata.name` at 255 // (`packages/metadata-core/src/objects/sys-metadata.object.ts`; the // length-ceiling note on `SystemIdentifierSchema` is the authority). Both diff --git a/packages/rest/src/rest-server-meta-write-org-scope.test.ts b/packages/rest/src/rest-server-meta-write-org-scope.test.ts index 3429079073b..a4b632238d6 100644 --- a/packages/rest/src/rest-server-meta-write-org-scope.test.ts +++ b/packages/rest/src/rest-server-meta-write-org-scope.test.ts @@ -117,7 +117,7 @@ function boot(execCtx: any) { return { status: res.statusCode, body: res.json.mock.calls.at(-1)?.[0] }; }; - /** [#12195] Every mounted route, for absence sweeps. */ + /** [commit 7986d973f] Every mounted route, for absence sweeps. */ const routes = () => (rest as any).getRoutes(); return { ...calls, drive, routes }; diff --git a/packages/rest/src/rest-server-query-multiplicity.test.ts b/packages/rest/src/rest-server-query-multiplicity.test.ts index ebd57dee113..7bfd503f6fd 100644 --- a/packages/rest/src/rest-server-query-multiplicity.test.ts +++ b/packages/rest/src/rest-server-query-multiplicity.test.ts @@ -307,7 +307,7 @@ describe('#6877 §1 — a repeated single-valued parameter is refused, not resol expect(protocol.diffMetaItem).not.toHaveBeenCalled(); }); - // [#12195] The compound-name read `GET /meta/:type/:section/:name?package` + // [commit 7986d973f] The compound-name read `GET /meta/:type/:section/:name?package` // was pinned here until its arity was retired. The single-segment read // above carries the same `?package` refusal, and it is the door every name // reaches now. diff --git a/packages/rest/src/rest-server.ts b/packages/rest/src/rest-server.ts index cb57de8250e..ec47cff8991 100644 --- a/packages/rest/src/rest-server.ts +++ b/packages/rest/src/rest-server.ts @@ -2,7 +2,7 @@ import { IHttpServer, resolveAuthzContext, resolveLocalizationContext, isAuthGateAllowlisted, - // [#13279] Re-raise a permission-store OUTAGE through the fail-closed nets + // [commit 6a180e42d] Re-raise a permission-store OUTAGE through the fail-closed nets // below instead of degrading it into an anonymous/denied answer. rethrowAuthzStoreUnavailable, // [#13476] Raised HERE too, at the data-engine seam: an engine that cannot @@ -111,7 +111,7 @@ import { HistoryMetaItemRequestSchema, AuditMetaItemRequestSchema, } from '@objectstack/spec/api'; -// [#9741] Declared request shapes for the meta-read doors below — imported so +// [commit 2a29caa53] Declared request shapes for the meta-read doors below — imported so // each door's request literal is compiled against the spec contract instead of // being smuggled past it with `as any` (see `TransportScopedMetaRequest`). import type { @@ -147,7 +147,7 @@ import type { // runtime surprise on whichever arm a test happens to drive. import type { ErrorCode } from '@objectstack/spec/api'; // The async-import row ceiling has exactly one definition, in the spec, whose -// TSDoc is its public statement (#6535). rest is the only enforcer, so it reads +// TSDoc is its public statement (commit a92b1793c). rest is the only enforcer, so it reads // that export rather than re-declaring the literal beside a "mirrors spec" comment. import { IMPORT_JOB_MAX_ROWS } from '@objectstack/spec/api'; // [#10235] The per-column sortability projection the object read serves on its @@ -232,11 +232,11 @@ import { sendError as sendEnvelopeError } from '@objectstack/types'; export type RestProtocol = DataProtocol & MetadataProtocol; /** - * [#9741] Typed TRANSPORT envelope for the meta-read doors. + * [commit 2a29caa53] Typed TRANSPORT envelope for the meta-read doors. * * `environmentId` is the multi-kernel routing key, and it is OUT of the * protocol request shape **by explicit maintainer decision** (ruling recorded - * 2026-08-18 on #9741): `resolveProtocol(environmentId)` selects the target + * 2026-08-18 on commit 2a29caa53): `resolveProtocol(environmentId)` selects the target * kernel *before* the protocol call, and the implementation's parameter types * (`@objectstack/metadata-protocol`) never read it off the request — the spec * schemas (`protocol.zod.ts`) record the same exclusion schema-side. The doors @@ -248,7 +248,7 @@ export type RestProtocol = DataProtocol & MetadataProtocol; * error at the call site, not a cast-and-hope. Never add protocol members * here; a key that belongs to the request belongs in the spec schema. * - * [#9805] The same typing now covers the NON-door `getMetaItems` helper call + * [commit 45862a53d] The same typing now covers the NON-door `getMetaItems` helper call * sites in this file (the object, book, doc, view and dataset listings). Two * spellings those sites carry deliberately SURVIVE the tightening, because * retiring either would change behaviour rather than typing: @@ -279,7 +279,7 @@ type TransportScopedMetaRequest = R & { environmentId?: string }; * doors' transport key. * * - `environmentId` — identical to the meta case and covered by the same - * ruling (2026-08-18, #9741): `resolveProtocol(environmentId)` picks the + * ruling (2026-08-18, commit 2a29caa53): `resolveProtocol(environmentId)` picks the * target kernel BEFORE the call, `@objectstack/metadata-protocol`'s data * methods never read it off the request, and `protocol.zod.ts` records the * exclusion schema-side. The doors still spread it (long-standing wire @@ -363,7 +363,7 @@ import { } from './served-endpoints.js'; import { logError, logWarn } from './log.js'; -// [#8850] The ADR-0112 error/fault-classification prologue — how a thrown thing +// [commit 8664a2c99] The ADR-0112 error/fault-classification prologue — how a thrown thing // becomes an HTTP answer — was module-level code sitting ahead of this class for // historical reasons and now lives in its own module. A move, not a redesign: // same functions, same wire answers, and `mapDataError` re-exported below so the @@ -905,7 +905,7 @@ function importJobUndoable(row: any): boolean { * Ruled **B** by the maintainer (2026-09-02): every copy of this spelling * guards on `Number.isNaN(value.getTime())`, all five arms in ONE change, * because a guard on some arms and not others re-opens the drift the single - * spelling closed. Reachability is MEASURED, not assumed (#14409, landed + * spelling closed. Reachability is MEASURED, not assumed (commit 3ecb7dc1a, landed * `3ecb7dc1a`): mysql2 3.23.1 returns a module constant literally named * `INVALID_DATE` for a zero `DATETIME`, and postgres-date 1.0.7 builds * `new Date(NaN)` for every year in 275760..294276 — years Postgres itself @@ -1166,7 +1166,7 @@ type NormalizedRestServerConfig = { }; }; /** - * [#14691] Every key of `RouteGenerationConfigSchema` is a `retiredKey()` + * [commit b3a63d32c] Every key of `RouteGenerationConfigSchema` is a `retiredKey()` * tombstone (ADR-0049 enforce-or-remove — nothing here ever read * `includeObjects` / `excludeObjects` / `nameTransform` / `overrides`; the * #14369 census). The sub-object is still PARSED, so an authored key is @@ -1371,7 +1371,7 @@ export interface MountedRoute extends RouteEntry { * post-identity fault SHOULD discard identity; that is a behaviour change on a * public door and is deliberately left unruled here. * - * ⚠️ Absorbing here cannot weaken the #13279 loud path, but the reason is + * ⚠️ Absorbing here cannot weaken the commit 6a180e42d loud path, but the reason is * no longer "one construction site" — [#13476] added a SECOND one, at the * data-engine seam below ({@link wiredEngineOrLoud}). The invariant that * matters is narrower and is what this helper actually needs: no branded @@ -1423,7 +1423,7 @@ async function seamOrUndefined(call: () => T | PromiseLike): Promise { - // [#6349] Normalize HERE, not at the call sites. `isTranslatableMetaType` + // [commit 2443bb4c4] Normalize HERE, not at the call sites. `isTranslatableMetaType` // reads `TRANSLATABLE_METADATA_TYPES`, which is DERIVED from // `METADATA_DOCUMENT_TRANSLATORS`' keys — and those are singular-only, // matching `translateMetadataDocument`'s "Canonical metadata type string". The @@ -3612,7 +3612,7 @@ export class RestServer { // // This is #3984's family (per-type judgements seeing only the singular) // landing on the i18n predicate instead of on a gate. It folds at the - // HELPER rather than at the four call sites for the reason #6241 proved + // HELPER rather than at the four call sites for the reason commit 83a3b1f2e proved // the hard way: a normalization the callers own is one a later caller // forgets. The helper owns "does this type translate", so it owns the // spelling that question is asked in. `metaTypeSingular` leaves an @@ -3768,7 +3768,7 @@ export class RestServer { // same fold over the vetted `tenantId`), the one answer the runtime // dispatcher's layered read asks too. const layeredOrganizationId = metaReadGate.metaReadOrganizationId(req.params.type, layeredCtx); - // [#9741] This door never carried an `as any`, but `p: any` meant its + // [commit 2a29caa53] This door never carried an `as any`, but `p: any` meant its // request literal was never checked either — the same blind spot with // a different spelling. Typing the literal (spec shape + the // transport-level `environmentId`, see `TransportScopedMetaRequest`) @@ -3817,7 +3817,7 @@ export class RestServer { * call site can stand unconditionally at an exit that serves all types. * `metaType` must be the NORMALIZED type (`/meta/objects/x` is the canonical * plural spelling; a gate comparing the raw param is a gate the canonical - * spelling walks past — #3984 / #6241). + * spelling walks past — #3984 / commit 83a3b1f2e). * * The returned function REJECTS with {@link ObjectSchemaMaskEvaluationError} * on D6 tier 3 — the security service threw. Call sites answer 5xx via @@ -3886,7 +3886,7 @@ export class RestServer { * Translate a list of metadata documents using `translateMetaItem`. * * Normalizes the `:type` spelling for the same reason, and on the same - * terms, as {@link translateMetaItem} — see the note there (#6349). The + * terms, as {@link translateMetaItem} — see the note there (commit 2443bb4c4). The * list route is one of the three that hands this the raw path segment, and * splitting the fix (list normalized, single-item not) would trade one * missing translation for the far harder "the list is localized but the @@ -4242,14 +4242,14 @@ export class RestServer { delete: crud.operations?.delete ?? true, list: crud.operations?.list ?? true, }, - // `patterns` / `objectParamStyle` are tombstones since #14691 — + // `patterns` / `objectParamStyle` are tombstones since commit b3a63d32c — // refused by the parse above, never threaded. dataPrefix: crud.dataPrefix, }, metadata: { prefix: metadata.prefix, enableCache: metadata.enableCache, - // `cacheTtl` is a tombstone since #14691 (`enableCache` selects the + // `cacheTtl` is a tombstone since commit b3a63d32c (`enableCache` selects the // protocol's cached read path, which takes no TTL). // [ADR-0106 D8] Default ON — masking is the platform default and // ships with the current major. The key has a declared seat @@ -4272,7 +4272,7 @@ export class RestServer { // the `POST /_migrate-stored` door, which used to leave with // that switch — the compatibility cost the ruling priced. maintenance: metadata.endpoints?.maintenance ?? true, - // `schema` is a tombstone since #14691: it gated a route that + // `schema` is a tombstone since commit b3a63d32c: it gated a route that // does not exist. }, }, @@ -4284,13 +4284,13 @@ export class RestServer { createMany: batch.operations?.createMany ?? true, updateMany: batch.operations?.updateMany ?? true, deleteMany: batch.operations?.deleteMany ?? true, - // `upsertMany` is a tombstone since #14691: there is no upsertMany + // `upsertMany` is a tombstone since commit b3a63d32c: there is no upsertMany // route to gate (upsert is an operation type of the generic batch // endpoint). So is `defaultAtomic`: atomicity is the per-request // `options.atomic` (ADR-0119 D4). }, }, - // [#14691] Parsed for the refusal, threaded as nothing — every key of + // [commit b3a63d32c] Parsed for the refusal, threaded as nothing — every key of // the sub-object is a tombstone (see the type above). `routes` is kept // as a key so the normalized shape still has one seat per sub-object. routes: routes as Record, @@ -4300,7 +4300,7 @@ export class RestServer { /** * The full API base path — THE base for this deployment's REST surface. * - * [#6306] Public because it is the single source of truth, not merely a + * [commit fec784863] Public because it is the single source of truth, not merely a * convenience: `rest-api-plugin.ts` threads this very value into the * direct-mount registrars (`packages.*`, `datasources/:name/external/*`) * so those nine routes mount under the same prefix as everything the @@ -4525,7 +4525,7 @@ export class RestServer { // NOT overwritten here. `DiscoverySchema` declares the field // under "System Identity", grouped with `name` and // `environment` — the "what server is this" question, settled - // by the #10993 ruling and reaffirmed by #11235/#11242. + // by the #10993 ruling and reaffirmed by commit 376c70f98/commit 98ea3443f. // // This line used to read `discovery.version = // this.config.api.version`, which is a different fact @@ -4537,9 +4537,9 @@ export class RestServer { // carried no identity. // // It also masked the producer. `getDiscovery()` derives the - // value from `OS_RUNTIME_VERSION` (#11235) — the same stamp + // value from `OS_RUNTIME_VERSION` (commit 376c70f98) — the same stamp // `/health` and the runtime dispatcher's own `/discovery` - // read (#10993/#11242) — so after #11297 this overwrote a + // read (#10993/commit 98ea3443f) — so after #11297 this overwrote a // value that already AGREED with the other producer, turning // one answer back into two dialects of one field. // @@ -4624,7 +4624,7 @@ export class RestServer { // direct mounts (#5822): the advertised base is read off // the very route arrays the registrars iterated to mount, // so advertisement and mounting derive from one fact and - // cannot drift. Since #6306 those registrars mount at + // cannot drift. Since commit fec784863 those registrars mount at // this server's own `getApiBasePath()` — the single // base — so an `apiPath` deployment advertises // `{apiPath}/packages` and `{apiPath}/datasources`. @@ -5064,7 +5064,7 @@ export class RestServer { // lives where it is observable, in the mount // `${basePath}/${version}` -> `/api/v1`. The runtime version // is answered by `{basePath}/discovery` and `/health`, derived - // from `OS_RUNTIME_VERSION` (#10993/#11235/#11292). OpenAPI + // from `OS_RUNTIME_VERSION` (#10993/commit 376c70f98/#11292). OpenAPI // 3.1 defines this field as "the version of the OpenAPI // document (which is distinct from the OpenAPI Specification // version or the API implementation version)" — the document @@ -5291,8 +5291,8 @@ export class RestServer { * and the ruling that drew these four radii does not name it. Moving it * under a switch is a decision, not a tidy-up. * - * [#12195] The compound-name twins spelled `/:type/:section/:name` used to - * close that list. They are RETIRED (stage 3 of #12176): every item is + * [commit 7986d973f] The compound-name twins spelled `/:type/:section/:name` used to + * close that list. They are RETIRED (stage 3 of commit 7986d973f): every item is * addressed through the single-segment `/:type/:name`, with the name * percent-encoded by the caller. * @@ -5450,15 +5450,15 @@ export class RestServer { // `getMetaDiagnostics` reads each swept type through // `getMetaItems({ type: t, organizationId })`. // - // ⚠️ [#14683] `getMetaItems` NOW APPLIES THE REGISTRY GATE + // ⚠️ [commit 96326040f] `getMetaItems` NOW APPLIES THE REGISTRY GATE // ITSELF — `organizationIdForMetaRead(request.type, // request.organizationId)`, one statement after it folds the // type through `canonicalizeMetaRequestType`. That is the // ONE inner gate this call site now sits above; the sibling // gate in the same file guards `getMetaItem` (the singular - // overlay read, #14908), which this arm never reaches. + // overlay read, commit d5cbb44f3), which this arm never reaches. // - // ⛔ Until #14683 this comment said `getMetaItems` applied NO + // ⛔ Until commit 96326040f this comment said `getMetaItems` applied NO // registry gate of its own and the scope was therefore // decided HERE, per type, by the caller. That sentence is // FALSE on today's tree — do not reintroduce it, and do not @@ -5509,7 +5509,7 @@ export class RestServer { // a fan-out per overridable type plus a REST-side // re-aggregation of `total`/`stats`/`scannedTypes`. // - // ⚠️ #14683 DISSOLVED THAT OBSTACLE (#15034 recorded + // ⚠️ Commit 96326040f DISSOLVED THAT OBSTACLE (#15034 recorded // it, #15622 acted on it). `getMetaDiagnostics` does // not spend the organization once: it loops `for (const // t of targetTypes)` calling `getMetaItems({ type: t, @@ -5575,7 +5575,7 @@ export class RestServer { .catch(rethrowAuthzStoreUnavailable); const diagnosticsOrganizationId: string | undefined = diagnosticsType ? organizationIdForMetaRead( - // [#10340] FOLDED, not raw — see the PUT door's + // [commit 26f3588fb] FOLDED, not raw — see the PUT door's // org-scope comment for the measurement. The // protocol keeps receiving the caller's own // spelling (it normalises, and refuses an @@ -5872,7 +5872,7 @@ export class RestServer { const previewDrafts = typeof req.query?.preview === 'string' && req.query.preview.toLowerCase() === 'draft' && mayReadPendingDrafts(listCtx); - // [#9741] Typed against the spec request shape plus the + // [commit 2a29caa53] Typed against the spec request shape plus the // transport-level `environmentId` — the `as any` this // literal used to carry is retired now that the spec // declares `previewDrafts` (and `organizationId`, #9726). @@ -6016,7 +6016,7 @@ export class RestServer { // looks like its repair. // // ⭐ And RAW is not the unconditional tenant that - // predicate exists to prevent, because since #14683 + // predicate exists to prevent, because since commit 96326040f // `getMetaItems` applies it ITSELF, to its OWN // `request.type`, after the fold. The per-SOURCE-type // decision is already the callee's: an overridable @@ -6089,7 +6089,7 @@ export class RestServer { // [#5882] GET /meta/:type/:name/layers — the three-layer diagnostic // projection as its OWN resource. Registered BEFORE // /meta/:type/:name for the same first-match reason as - // /references above. [#12195] It also used to have to precede the + // /references above. [commit 7986d973f] It also used to have to precede the // compound `/:type/:section/:name`, which would otherwise capture // this path with section=, name="layers"; that catch-all is // retired, so only the /references-style reason remains. @@ -6113,7 +6113,7 @@ export class RestServer { // [ADR-0106 D2/D5] The dedicated path is its own // schema-serving outlet — it resolves the caller's // field-visibility posture exactly like the plain meta - // read does, with the NORMALIZED type (#3984 / #6241). + // read does, with the NORMALIZED type (#3984 / commit 83a3b1f2e). const layeredMetaType = RestServer.metaTypeSingular(req.params.type); let maskPosture: ObjectSchemaMaskPosture; try { @@ -6217,7 +6217,7 @@ export class RestServer { const environmentId = isScoped ? req.params?.environmentId : undefined; const p = await this.resolveProtocol(environmentId, req); - // [#3984 / #6241] Normalize the `:type` segment ONCE, + // [#3984 / commit 83a3b1f2e] Normalize the `:type` segment ONCE, // here at the top, and let every gate below read THIS // value. The route serves both spellings and Prime // Directive #3 makes the plural one canonical @@ -6226,7 +6226,7 @@ export class RestServer { // // #3984 ruled this shape for exactly that reason ("每个 // handler 顶部归一一次,后续所有闸门都用归一后的值"), and - // #6241 is why the ruling is written into the code + // Commit 83a3b1f2e is why the ruling is written into the code // rather than trusted to memory: eight days after // #3984 landed, the cache-branch condition below still // excluded `doc`/`book` by LITERAL comparison, so @@ -6369,7 +6369,7 @@ export class RestServer { // audience gate is per-caller, and a shared ETag would // leak gated content across viewers. // - // [#6241] That sentence was already here while the + // [commit 83a3b1f2e] That sentence was already here while the // exclusion beneath it compared the RAW param against // the literals `'doc'` / `'book'`, so the canonical // plural spelling took the cached branch and shipped @@ -6424,7 +6424,7 @@ export class RestServer { // #3, and an exclusion it could be spelled around would // not be an exclusion). The `doc` / `book` literals // that stood at the end of this condition had exactly - // that hole; #6241 closed it. + // that hole; commit 83a3b1f2e closed it. const isDashboardType = metaType === 'dashboard'; // ADR-0046 §6.7 — the two audience-gated types, excluded // from the cache so {@link metaItemReadGate} judges them. @@ -6471,7 +6471,7 @@ export class RestServer { const cacheI18n = await this.resolveI18nService(environmentId, req); const cacheLocale = this.extractLocale(req, cacheI18n); - // [#9741] Typed request — `as any` retired. The + // [commit 2a29caa53] Typed request — `as any` retired. The // cached read carries NO draft-visibility members // on purpose: this branch is unreachable when a // draft switch is ADMITTED (`previewDrafts` / @@ -6598,7 +6598,7 @@ export class RestServer { } else { // Non-cached version const packageId = req.query?.package || undefined; - // [#9741] Typed against the spec request shape — + // [commit 2a29caa53] Typed against the spec request shape — // the `as any` this literal used to carry is // retired now that the spec declares `state` and // `previewDrafts` (and `organizationId`, #9726). @@ -6941,7 +6941,7 @@ export class RestServer { // else the session's `activeOrganizationId`, which is the // very field the dispatcher twin reads. // - // [#10340] The type is FOLDED before the scope decision, + // [commit 26f3588fb] The type is FOLDED before the scope decision, // never the raw URL spelling. Storage folds `:type` // through `META_URL_TO_SINGULAR` — the COMPLETE map — // while `declaresOrgOverride` tolerates only the @@ -6967,7 +6967,7 @@ export class RestServer { // REQUEST SHAPE alone: the schema declared only // `{ type, name, item }`, and removing the cast surfaced // TS2353 on every other key. The literal is now compiled - // against the spec contract through the #9741 + // against the spec contract through the commit 2a29caa53 // `TransportScopedMetaRequest` wrapper — `environmentId` // is the transport-level routing key that wrapper layers // on, ⛔ never a protocol key; every other key here is @@ -6979,7 +6979,7 @@ export class RestServer { name: req.params.name, item, organizationId, - // [#10888] This door answers with an ADR-0112 error + // [commit d806081dd] This door answers with an ADR-0112 error // envelope that carries the refusal's `issues[]` // structurally beside the message (`sendError` threads a // top-level `issues`), so `saveMetaItem`'s 422 renders @@ -7130,7 +7130,7 @@ export class RestServer { // together. `ctx` is the capability gate's own // `resolveExecCtx` result, resolved above. const organizationId = organizationIdForMetaWrite( - // [#10340] FOLDED, not raw — see the PUT door's + // [commit 26f3588fb] FOLDED, not raw — see the PUT door's // org-scope comment for the measurement. canonicalMetaUrlType(req.params.type), ctx?.tenantId, ); @@ -7141,7 +7141,7 @@ export class RestServer { // on REQUEST SHAPE: the member was declared all along, but // the schema declared only `{ type, name }`, so removing the // cast surfaced TS2353 on six keys. The literal is now - // compiled against the spec contract through the #9741 + // compiled against the spec contract through the commit 2a29caa53 // `TransportScopedMetaRequest` wrapper — `environmentId` is // the transport-level routing key that wrapper layers on, // ⛔ never a protocol key; every other key here is checked @@ -7218,7 +7218,7 @@ export class RestServer { if (refuseNonAuthoringCaller(historyCtx, res, 'Reading a metadata item\'s version history')) return; const p = await this.resolveProtocol(environmentId, req); // The cast came off when `MetadataProtocol` declared - // `historyMetaItem` (#12005 — the #11006 pattern, exactly + // `historyMetaItem` (#12005 — the commit cccbe51bf pattern, exactly // as #11678 de-cast the audit twin below). The member is // declared OPTIONAL, so this truthiness guard is not just // feature detection: it is what narrows the member to @@ -7302,7 +7302,7 @@ export class RestServer { // `req`), the same result the audit twin and 40+ handlers // here already share. const historyOrganizationId = organizationIdForMetaRead( - // [#10340] FOLDED, not raw — see the PUT door's + // [commit 26f3588fb] FOLDED, not raw — see the PUT door's // org-scope comment for the measurement. canonicalMetaUrlType(req.params.type), historyCtx?.tenantId, ); @@ -7310,7 +7310,7 @@ export class RestServer { // reset door above, NOT as a plain `HistoryMetaItemRequest` // like the audit door below: this door still spreads the // transport-level `environmentId` (long-standing wire - // shape, deliberately unchanged — the #9741 ruling keeps + // shape, deliberately unchanged — the commit 2a29caa53 ruling keeps // it out of the protocol schema, and the implementation // never reads it), so the wrapper is what layers that one // member on. Every OTHER key is compiled against the spec @@ -7523,7 +7523,7 @@ export class RestServer { // (#20441), not a second resolution. // // The `(p as any)` casts this door carried came off when - // `MetadataProtocol` declared `auditMetaItem` (the #11006 + // `MetadataProtocol` declared `auditMetaItem` (the commit cccbe51bf // pattern, same as the publish door below): the literal is // now compiled against the spec contract, so an undeclared // key here is a compile error (TS2353) instead of a payload @@ -7561,7 +7561,7 @@ export class RestServer { handler: async (req: any, res: any) => { try { const environmentId = isScoped ? req.params?.environmentId : undefined; - // [#8919] Authoring capability gate — the SAME four lines the + // [commit b5378550e] Authoring capability gate — the SAME four lines the // `PUT` / `DELETE` / `_migrate-stored` doors carry, deliberately // not a second way of demanding the same capability. // @@ -7631,7 +7631,7 @@ export class RestServer { const body = (req.body && typeof req.body === 'object') ? req.body : {}; const message = typeof body.message === 'string' ? body.message : undefined; - // [#10063] Software-package binding for the PROMOTION — + // [commit 9e04c3e35] Software-package binding for the PROMOTION — // `?package=`, deliberately the SAME wire spelling and the // same normalisation the `PUT` door states it with a few // hundred lines up, not a second dialect for one value. @@ -7690,7 +7690,7 @@ export class RestServer { // save without scoping the publish is not a smaller change, // it is a broken one. // - // [#8919] The context is now the one the capability gate above + // [commit b5378550e] The context is now the one the capability gate above // already resolved, so the caller a publish is SCOPED to can // never drift from the caller it was AUTHORIZED against — the // same single-resolution shape the `PUT` door carries. @@ -7698,12 +7698,12 @@ export class RestServer { // handlers in this file (see the `/published` comment's seam // warning, which stands). const organizationId = organizationIdForMetaWrite( - // [#10340] FOLDED, not raw — see the PUT door's + // [commit 26f3588fb] FOLDED, not raw — see the PUT door's // org-scope comment for the measurement. canonicalMetaUrlType(req.params.type), ctx?.tenantId, ); // [#11145] The `(p as any)` cast this call carried came off - // when `MetadataProtocol` declared `publishMetaItem` (#11006, + // when `MetadataProtocol` declared `publishMetaItem` (commit cccbe51bf, // maintainer ruling 2026-08-22, option B). What the cast was // load-bearing FOR is recorded because it is counter-intuitive // and was measured, not assumed: deleting it while the member @@ -7715,12 +7715,12 @@ export class RestServer { // declaring the member could retire it; widening the // implementation's own request type in // `@objectstack/metadata-protocol` (which this package - // deliberately does not depend on) never could, and #10350 + // deliberately does not depend on) never could, and commit 490879ad0 // measured exactly that. // // What replaces it is the point of the exercise, not a // side effect: the literal below is compiled against the spec - // contract through the #9741 `TransportScopedMetaRequest` + // contract through the commit 2a29caa53 `TransportScopedMetaRequest` // wrapper, so an undeclared key here is a COMPILE ERROR // (`TS2353`, measured) instead of a payload member no contract // has ever seen. `environmentId` is the transport-level @@ -7762,7 +7762,7 @@ export class RestServer { handler: async (req: any, res: any) => { try { const environmentId = isScoped ? req.params?.environmentId : undefined; - // [#8919] Authoring capability gate — the same four lines as + // [commit b5378550e] Authoring capability gate — the same four lines as // the sibling doors, and the sharper half of this pair. // `rollbackMetaItem` restores a CALLER-SUPPLIED `toVersion` as // the new live row, so without this gate it is a mechanism for @@ -7845,10 +7845,10 @@ export class RestServer { // env-wide row — a write to a partition the caller never // named, audited as `null`. See the `PUT` door above. // - // [#8919] `ctx` is the one the capability gate above resolved, + // [commit b5378550e] `ctx` is the one the capability gate above resolved, // so scope and authorization read the same identity. const organizationId = organizationIdForMetaWrite( - // [#10340] FOLDED, not raw — see the PUT door's + // [commit 26f3588fb] FOLDED, not raw — see the PUT door's // org-scope comment for the measurement. canonicalMetaUrlType(req.params.type), ctx?.tenantId, ); @@ -8002,7 +8002,7 @@ export class RestServer { // `diffCtx` is the caller resolved at the head of this door // (#20378), not a second resolution. const diffOrganizationId = organizationIdForMetaRead( - // [#10340] FOLDED, not raw — see the PUT door's + // [commit 26f3588fb] FOLDED, not raw — see the PUT door's // org-scope comment for the measurement. canonicalMetaUrlType(req.params.type), diffCtx?.tenantId, ); @@ -8106,7 +8106,7 @@ export class RestServer { // boundary's accept set for `/meta/:type/...` is unchanged, which is // what the 2026-08-17 re-weigh (item 3) requires of this step. // - // [#12195] The four-segment collision this comment used to describe is + // [commit 7986d973f] The four-segment collision this comment used to describe is // GONE with the compound `/:type/:section/:name/published` twin. That // twin captured `/meta/object/x/state/published` as "the published // version of the compound name object/x/state", and only the literal @@ -8231,14 +8231,14 @@ export class RestServer { // after publish, identical for a name that does not exist: a route // that structurally could not 404. // - // ONE arity since #12195 (stage 3 of #12176's maintainer-ruled + // ONE arity since commit 7986d973f (stage 3 of commit 7986d973f's maintainer-ruled // retirement of compound-name addressing, 2026-08-25). This route used // to be mounted twice — the second registration was // `/:type/:section/:name/published`, folding `section` and `name` back // into one slash-bearing key so the SDK's // `getPublished('lead', 'views/all_leads')` could reach it. // - // Stage 1 (#12194) declared the item-name grammar and refuses every + // Stage 1 (commit 311433f6b) declared the item-name grammar and refuses every // slash-bearing name at the publish door, so no name reachable ONLY // through that arity can exist any more. What remains addressable is a // pre-grammar residue row, and it is reachable HERE: a percent-encoded @@ -8255,7 +8255,7 @@ export class RestServer { try { const environmentId = isScoped ? req.params?.environmentId : undefined; const type = String(req.params?.type ?? ''); - // [#12195] No `section` fold: this route has one arity. + // [commit 7986d973f] No `section` fold: this route has one arity. // A percent-encoded slash arrives already decoded here, // so a residue name reads exactly as it is stored. const name = String(req.params?.name ?? ''); @@ -8326,7 +8326,7 @@ export class RestServer { // read. [#14907] The CALLEE gates: `getMetaItemLayered` // resolves `organizationIdForMetaRead` AFTER its canonical // fold, so the tenant goes over RAW. ⛔ Pre-gating HERE, on - // the unfolded `:type`, would be the #10340 defect. ⛔ And + // the unfolded `:type`, would be the commit 26f3588fb defect. ⛔ And // the old "fail-open in the safe direction" reading is the // argument the predicate refutes: an org named on a type // the registry does not declare overridable resurrects the @@ -8454,7 +8454,7 @@ export class RestServer { }); return; } - // [#10340] FOLDED here too — the smaller second site + // [commit 26f3588fb] FOLDED here too — the smaller second site // of the same class. The layered consult above folds // internally (protocol boundary), but this fallback // reads the code/package registry, which stores @@ -8488,14 +8488,14 @@ export class RestServer { // ── RETIRED: the compound `/:type/:section/:name` arities ────────── // // `GET` and `PUT /meta/:type/:section/:name` were mounted here until - // #12195 (stage 3 of #12176's maintainer-ruled retirement of + // Commit 7986d973f (stage 3 of commit 7986d973f's maintainer-ruled retirement of // compound-name addressing, 2026-08-25). Both folded `section` and // `name` back into one slash-bearing key (`views/all_leads`) that the // protocol layer then treated as a single opaque string — the section // half was never stored, filtered or enumerated, so it was addressing // syntax and nothing else. // - // Stage 1 (#12194) declared the item-name grammar and refuses every + // Stage 1 (commit 311433f6b) declared the item-name grammar and refuses every // slash-bearing name at the publish door, which is what makes this a // removal of dead addressing rather than of a capability: no name // reachable only through these arities can be created any more. @@ -11131,7 +11131,7 @@ export class RestServer { const clientMsg = sandboxBusinessMessage(error) ?? msg; // ── [#12710] The producer's marked sentence, resolved once ─ - // #9934's `userMessage` channel is STATUS- and BRANCH-agnostic + // Commit 79c46da90's `userMessage` channel is STATUS- and BRANCH-agnostic // by construction: `withDeclaredUserMessage` applies it ONCE at // the `/data` door's exit, over whatever envelope classification // chose. This door has no such wrapper — it builds ①, ③a and ③b @@ -11909,7 +11909,7 @@ export class RestServer { : undefined; // [#12669] …and so does the sentence the producer addressed to // the CALLER. The flat `/data` door attaches it in - // `withDeclaredUserMessage` (`error-response.ts`, #9934) and + // `withDeclaredUserMessage` (`error-response.ts`, commit 79c46da90) and // the one classification asked above is already holding the // result; this family dropped it at the same re-dress, with the // same one-directional silence — an author's own remedy text @@ -13467,7 +13467,7 @@ export class RestServer { * * This is the load-bearing half of the mounted ⇒ advertised parity * (ADR-0076 D12): the registrars mount at whatever base the plugin threads - * in (since #6306 that is `getApiBasePath()`), the recorder keeps the + * in (since commit fec784863 that is `getApiBasePath()`), the recorder keeps the * very arrays they iterated to mount (#5822), and this method projects the * advertised `routes.packages` / `routes.datasources` out of those arrays. * One expression, two consumers — a future change that moves the mount diff --git a/packages/rest/src/rest-share-user-message-bypass-exits.test.ts b/packages/rest/src/rest-share-user-message-bypass-exits.test.ts index 3fc099624cd..af53507efdc 100644 --- a/packages/rest/src/rest-share-user-message-bypass-exits.test.ts +++ b/packages/rest/src/rest-share-user-message-bypass-exits.test.ts @@ -45,7 +45,7 @@ * * ⭐ The second row is the card's OPEN question, measured rather than assumed: * the prefix exit had no precedent of its own (the fault terminal has one — - * #9934 deliberately rides the mark onto fault terminals). The measurement + * Commit 79c46da90 deliberately rides the mark onto fault terminals). The measurement * answers it. `/data` carries the mark for that identical throw, on all five * prefixes (§3), so the two doors disagree and the exit is in. Had `/data` * omitted it there, the two doors would have AGREED and there would have been @@ -297,7 +297,7 @@ const FAULTS: Array<{ name: string; error: unknown; message: string }> = [ // ⭐ The row that shows the mark and the WITHHELD PROSE are two // different decisions: `sharingFaultMessage` replaces the QuickJS // wrapper with the generic sentence, and the author's own text still - // travels. #9934's argument, exercised rather than quoted. + // travels. Commit 79c46da90's argument, exercised rather than quoted. name: 'a sandboxed body on a declared 5xx — prose withheld, mark carried', error: sandboxRefusal('the share index is being rebuilt', { code: 'SHARE_INDEX_REBUILDING', status: 503, userMessage: RECOVERING, diff --git a/packages/rest/src/rest-share-user-message.test.ts b/packages/rest/src/rest-share-user-message.test.ts index df6cdfa107c..708337c68cd 100644 --- a/packages/rest/src/rest-share-user-message.test.ts +++ b/packages/rest/src/rest-share-user-message.test.ts @@ -11,7 +11,7 @@ * — the flat `/data` door's own classification — and re-dressed `status`, * `code`, the message and (since #12510) `declaredCode` into the nested * ADR-0112 D5 envelope (#8111). The classification's body was ALREADY carrying - * the producer's `userMessage`, attached by `withDeclaredUserMessage` (#9934), + * the producer's `userMessage`, attached by `withDeclaredUserMessage` (commit 79c46da90), * and it was dropped at the re-dress. * * Measured on `07e646565` before the repair, one producer driven through the @@ -302,7 +302,7 @@ const MARKED: Array<{ { // The sandbox limb with NO declared status: `classifyDataError`'s unwrap // door answers 400 and the nested envelope fills the required `code` - // from the catalog floor. The mark rides that arm too — #9934's rule is + // from the catalog floor. The mark rides that arm too — commit 79c46da90's rule is // branch-agnostic by construction. name: 'a sandboxed hook body with a sentence and NO declared status', error: sandboxRefusal('sharing is frozen until the access review closes', { diff --git a/packages/rest/src/rest-sub-config-parse-not-cast.test.ts b/packages/rest/src/rest-sub-config-parse-not-cast.test.ts index 0ea4c1be57c..cb4d7b9f3d8 100644 --- a/packages/rest/src/rest-sub-config-parse-not-cast.test.ts +++ b/packages/rest/src/rest-sub-config-parse-not-cast.test.ts @@ -44,7 +44,7 @@ * its key diff empty too and folded its `??` chain onto the parse; it keeps * the `.omit()`ed `requireAuth` tombstone, and is not this file's subject. * - * [#14691] Ten of the keys these pins originally exercised were RETIRED under + * [commit b3a63d32c] Ten of the keys these pins originally exercised were RETIRED under * ADR-0049 enforce-or-remove (the #14369 liveness census found them normalized * and never read): `crud.patterns` / `objectParamStyle`, `metadata.cacheTtl` / * `endpoints.schema`, `batch.operations.upsertMany` / `defaultAtomic`, and all @@ -141,7 +141,7 @@ describe('[#11984] §A RestServer construction runs the four sibling schemas', ( }); // `routes.nameTransform`, `crud.objectParamStyle` and `metadata.cacheTtl` used - // to be pinned here as "refuses the OUT-OF-CONTRACT value". Since #14691 the + // to be pinned here as "refuses the OUT-OF-CONTRACT value". Since commit b3a63d32c the // keys themselves are tombstones and EVERY value is refused — see §E. it('refuses a declared key written with the wrong type', () => { @@ -152,7 +152,7 @@ describe('[#11984] §A RestServer construction runs the four sibling schemas', ( // `crud.patterns` (an enum-keyed record) and `routes.overrides..operations` // (an exhaustive one) used to be pinned here for their key-by-key refusals. - // Both records are tombstones since #14691 — see §E. + // Both records are tombstones since commit b3a63d32c — see §E. it('lists every failing key of the sub-object in one refusal', () => { const message = refusal({ batch: { maxBatchSize: 0, enableBatchEndpoint: 'yes' as never } }); @@ -210,7 +210,7 @@ describe('[#11984] §B the refusal survives the plugin path', () => { }); it('rejects `createRestApiPlugin({ api: { routes: { nameTransform: "none" } } }).start()` — a #14691 tombstone, through the plugin path', async () => { - // Before #14691 this case drove `'snake_case'`, the out-of-enum value. + // Before commit b3a63d32c this case drove `'snake_case'`, the out-of-enum value. // The key is retired now, so its former DEFAULT is refused too, with the // prescription rather than the enum text. await expect( @@ -229,7 +229,7 @@ describe('[#11984] §C regression guards — the narrowing is exactly the declar expect(cfg.batch.maxBatchSize).toBe(200); expect(cfg.metadata.prefix).toBe('/meta'); expect(cfg.crud.dataPrefix).toBe('/data'); - // [#14691] the retired keys materialize NO default any more — the + // [commit b3a63d32c] the retired keys materialize NO default any more — the // normalized config simply does not carry them. expect(cfg.metadata).not.toHaveProperty('cacheTtl'); expect(cfg.crud).not.toHaveProperty('objectParamStyle'); @@ -245,7 +245,7 @@ describe('[#11984] §C regression guards — the narrowing is exactly the declar // The two enum read-backs (`routes.nameTransform`, `crud.objectParamStyle`) // and the "KEEPS a negative `metadata.cacheTtl`" bound used to live here. - // All three keys are tombstones since #14691, so those pins are reversed + // All three keys are tombstones since commit b3a63d32c, so those pins are reversed // in §E; the negative-TTL bound the card once argued about is moot — no // TTL of any sign is accepted. @@ -299,7 +299,7 @@ describe('[#11984] §D the four siblings consume the parsed output', () => { }); it('KEEPS a partial `batch.operations` and `metadata.endpoints` the same way', () => { - // [#14691] `upsertMany` and `schema` left both shapes: the three live + // [commit b3a63d32c] `upsertMany` and `schema` left both shapes: the three live // switches per block are exactly what the normalized config carries. expect(normalized({ batch: { operations: { deleteMany: false } } }).batch.operations).toEqual({ createMany: true, updateMany: true, deleteMany: false, @@ -318,11 +318,11 @@ describe('[#11984] §D the four siblings consume the parsed output', () => { }); // The `crud.patterns` preservation pin (and the `z.partialRecord` question it - // deferred to #14365) is gone with the key — #14691 retired the record. + // deferred to #14365) is gone with the key — commit b3a63d32c retired the record. }); // --------------------------------------------------------------------------- -// §E — [#14691] the retired keys are REFUSED at construction, with the +// §E — [commit b3a63d32c] the retired keys are REFUSED at construction, with the // prescription, whatever the value. These are the #11984 pins above, reversed: // the SERVER is still what is measured (the schema-level pins live in // `packages/spec`'s `rest-server.test.ts`), and `refusal()`'s `''`-on-success diff --git a/packages/rest/src/rest-thrown-code-vocabulary.test.ts b/packages/rest/src/rest-thrown-code-vocabulary.test.ts index 997afe04e99..cf8b41396e7 100644 --- a/packages/rest/src/rest-thrown-code-vocabulary.test.ts +++ b/packages/rest/src/rest-thrown-code-vocabulary.test.ts @@ -100,7 +100,7 @@ const thrownWithStatus = (status: number, code?: unknown) => const thrownWithStatusCode = (statusCode: number, code?: unknown) => Object.assign(new Error('boom'), { statusCode, ...(code !== undefined ? { code } : {}) }); /** - * [#10345] `runtime/src/sandbox/quickjs-runner.ts`'s `SandboxError`: the debug + * [commit cad8b42f0] `runtime/src/sandbox/quickjs-runner.ts`'s `SandboxError`: the debug * wrapper on `.message`, the business text on `.innerMessage`. Reaches the * unwrap door, which sits above the passthrough. */ @@ -119,7 +119,7 @@ const sandboxThrownWithStatus = (status: number, code?: unknown) => { * at a time because the defect this card measured was FOUR verbatim * passthroughs, and a fix that reached three of them would read as done. * - * [#10345] A FIFTH arm joined the list. The sandbox unwrap door emitted no + * [commit cad8b42f0] A FIFTH arm joined the list. The sandbox unwrap door emitted no * `code` at all, so #9232 had nothing to narrow there and left it out — and * "no code, ever" is exactly the shape a vocabulary sweep cannot see. It now * carries the producer's declared code like its four siblings, so it is @@ -155,7 +155,7 @@ const ARMS = [ status: 503, }, { - // [#10345] The sandbox unwrap — reached by `.innerMessage` plus a + // [commit cad8b42f0] The sandbox unwrap — reached by `.innerMessage` plus a // declared client-band status, and the ONLY arm whose body text is the // unwrapped business message rather than `error.message`. name: 'mapDataError sandbox unwrap 4xx (`.innerMessage`)', diff --git a/packages/rest/src/rest-user-facing-refusal-marking.test.ts b/packages/rest/src/rest-user-facing-refusal-marking.test.ts index 4c063e7b6a0..04c99ee5df6 100644 --- a/packages/rest/src/rest-user-facing-refusal-marking.test.ts +++ b/packages/rest/src/rest-user-facing-refusal-marking.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// [#9934] The producer-side user-facing marking, at the REST door — the +// [commit 79c46da90] The producer-side user-facing marking, at the REST door — the // producer half of the objectui#5210 ruling (maintainer, 2026-08-19, option 1). // // A hook refusal that declares `userMessage` on the thrown error carries that @@ -102,7 +102,7 @@ describe('[#9934] mapDataError: the marking carries the exact text; unmarked car it('rides the sandbox unwrap — a body hook refusal keeps its marking at 400', () => { // The shape `quickjs-runner` produces for a body's deliberate throw: - // `innerMessage` set (business message), plus the #9934 side-channel. + // `innerMessage` set (business message), plus the commit 79c46da90 side-channel. const err = Object.assign(new Error("hook 'close_guard' threw: Error: 删除被阻断"), { innerMessage: '删除被阻断', userMessage: USER_TEXT, diff --git a/packages/rest/src/rest-write-response-internal-fields.tripwire.test.ts b/packages/rest/src/rest-write-response-internal-fields.tripwire.test.ts index e845b66722f..24807238a5c 100644 --- a/packages/rest/src/rest-write-response-internal-fields.tripwire.test.ts +++ b/packages/rest/src/rest-write-response-internal-fields.tripwire.test.ts @@ -338,7 +338,7 @@ const DISPOSITIONS: Record = { 'DELETE /api/v1/meta/:type/:name': { kind: 'no-record-echo', why: 'Metadata plane: delete receipt.' }, 'POST /api/v1/meta/:type/:name/publish': { kind: 'no-record-echo', why: 'Metadata plane: publish receipt.' }, 'POST /api/v1/meta/:type/:name/rollback': { kind: 'no-record-echo', why: 'Metadata plane: rollback receipt.' }, - // [#12195] `PUT /api/v1/meta/:type/:section/:name` had a disposition here + // [commit 7986d973f] `PUT /api/v1/meta/:type/:section/:name` had a disposition here // until the compound-name arity was retired. Removed rather than kept: this // file's own stale-entry check treats a disposition for a route that no // longer exists as a defect, which is exactly the right reading. diff --git a/packages/rest/src/rest.test.ts b/packages/rest/src/rest.test.ts index 81442125596..b354c0f30ed 100644 --- a/packages/rest/src/rest.test.ts +++ b/packages/rest/src/rest.test.ts @@ -2559,7 +2559,7 @@ describe('mapDataError — schema/constraint envelopes', () => { expect(r.status).toBe(400); expect(r.body.error).toBe('制作基地被「项目主计划批次」引用(3 条),删除被阻断,请先解除引用'); expect(r.body.object).toBe('pm_base'); - // [#10345] No `code` because this producer DECLARED none — not because + // [commit cad8b42f0] No `code` because this producer DECLARED none — not because // the unwrap door withholds it. That door carries a declared code now; the // old "older bundled clients prepend any code to the message" rationale was // retired with the measurement in `error-response.ts`. What stays pinned diff --git a/packages/rest/src/ui-view-route-identity.measurement.test.ts b/packages/rest/src/ui-view-route-identity.measurement.test.ts index 49e916b0d82..7a390af1b91 100644 --- a/packages/rest/src/ui-view-route-identity.measurement.test.ts +++ b/packages/rest/src/ui-view-route-identity.measurement.test.ts @@ -20,14 +20,14 @@ * * ## The three questions, and why the second is the big one * - * #13160 / PR #13213's census drove every `resolveExecCtx` consumer in + * #13160 / commit 4801296e7's census drove every `resolveExecCtx` consumer in * `rest-server.ts` and found 52 of 52 bare sites refusing an absent context * with 401. This route surfaced there precisely because it is NOT a consumer — * the one metadata-touching route in the table that resolves no identity at * all. That census stopped at the seam and said so. This file continues past * it: * - * 1. §1-§2 — the seam, reproduced INDEPENDENTLY of #13213 (its own harness, + * 1. §1-§2 — the seam, reproduced INDEPENDENTLY of commit 4801296e7 (its own harness, * its own instrument), plus the exact argument object the seam hands the * producer. * 2. §3-§4 — ⭐ the half #13214 marks UNMEASURED: does `getUiView` apply diff --git a/packages/rest/src/ui-view-route-tenancy.measurement.test.ts b/packages/rest/src/ui-view-route-tenancy.measurement.test.ts index 8ce7ce334c2..d53ed04d2b6 100644 --- a/packages/rest/src/ui-view-route-tenancy.measurement.test.ts +++ b/packages/rest/src/ui-view-route-tenancy.measurement.test.ts @@ -23,7 +23,7 @@ * * ## Why it exists separately from `ui-view-route-identity.measurement.test.ts` * - * That file (PR #13244) settled the SINGLE-TENANT half and settled it hard: + * That file (commit 889ec5b42) settled the SINGLE-TENANT half and settled it hard: * this route resolves no identity at the REST seam, and `getUiView` applies no * authorization downstream because the seam hands it exactly `{ object, type }`. * ⛔ None of that is re-measured here. @@ -65,7 +65,7 @@ * * ## ⚠️ Constructor arity — the previous run's self-caught bug, mechanised * - * PR #13244 wrote a 27-argument call to the 20-parameter `RestServer` + * Commit 889ec5b42 wrote a 27-argument call to the 20-parameter `RestServer` * constructor. It RAN, while silently shifting three providers onto the wrong * parameters: a harness that executes can still be wrong at the reading level, * and a tenancy harness is exactly where that bites, because `kernelManager` @@ -132,7 +132,7 @@ const SCHEMA_A = { * Environment B — the environment an anonymous caller is trying to reach. * * Two `hidden` fields, deliberately of DIFFERENT kinds, because §3 measures the - * blast radius on the crossed path rather than inheriting #13244's + * blast radius on the crossed path rather than inheriting commit 889ec5b42's * single-tenant answer: * - `beta_secret` is hidden and NOT one of the producer's priority names; * - `status` is hidden and IS one of them (`name`, `title`, `label`, @@ -775,7 +775,7 @@ describe('[#13214] §3 what the response contains, on the owned path and on the // ⚠️ Read the history before the assertions: they were the other way // round two days ago, and that sequence is part of the record. // - // - #13244 measured this SINGLE-TENANT with ONE hidden field, which + // - commit 889ec5b42 measured this SINGLE-TENANT with ONE hidden field, which // happened not to be a priority name, saw it dropped, and reported // "hidden is dropped by declaration" — true of the field it drove, // false of the class. From 13338b11fa9499ac623c9a4fb24f971e4131ab12 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <50353452+hotlong@users.noreply.github.com> Date: Tue, 29 Sep 2026 18:51:27 +0800 Subject: [PATCH 2/3] wip(rest): mechanical pass for the remaining researched anchors, first review fixes Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289 Co-authored-by: Claude --- .../analytics-dataset-selection-door.test.ts | 6 +-- ...allowlist-fault-window.measurement.test.ts | 4 +- .../src/discovery-schema-conformance.test.ts | 4 +- ...-generic-passthrough-object-parity.test.ts | 10 ++-- ...error-response-sandbox-arm-message.test.ts | 12 ++--- ...esponse-structured-arm-door-parity.test.ts | 20 ++++---- packages/rest/src/error-response.ts | 46 ++++++++--------- ...cctx-authz-input-seam-reachability.test.ts | 2 +- .../rest/src/execctx-consumer-census.test.ts | 6 +-- ...al-datasource-envelope.conformance.test.ts | 4 +- ...external-datasource-validate-scope.test.ts | 2 +- .../rest/src/http-request-test-builder.ts | 4 +- .../rest/src/http-response-test-builder.ts | 4 +- .../rest/src/import-dryrun-parity.test.ts | 2 +- ...import-runner-unique-violation-row.test.ts | 2 +- .../meta-state-route-engine-outage.test.ts | 8 +-- .../src/objectql-slot-consumer-census.test.ts | 6 +-- ...oor-16019-raw-statement-fault-code.test.ts | 4 +- ...ge-door-execctx-fault-reachability.test.ts | 18 +++---- ...plugin-metadata-retired-fields.pin.test.ts | 2 +- .../src/plugin-type-closed-set.pin.test.ts | 2 +- .../rest-14078-invalid-date-total-arm.test.ts | 2 +- ...pi-config-defaults-follow-spec.pin.test.ts | 2 +- .../src/rest-approvals-wire-codes.test.ts | 8 +-- .../src/rest-config-parse-not-cast.test.ts | 8 +-- .../src/rest-duplicate-record-arm.test.ts | 2 +- .../src/rest-exec-ctx-principal-kind.test.ts | 2 +- .../rest-server-meta-read-org-scope.test.ts | 8 +-- packages/rest/src/rest-server.ts | 50 +++++++++---------- .../rest-sub-config-parse-not-cast.test.ts | 4 +- .../src/ui-view-environment-ownership.test.ts | 2 +- ...ui-view-route-identity.measurement.test.ts | 10 ++-- .../ui-view-route-tenancy.measurement.test.ts | 2 +- packages/rest/src/xlsx-test-loader.ts | 4 +- 34 files changed, 136 insertions(+), 136 deletions(-) diff --git a/packages/rest/src/analytics-dataset-selection-door.test.ts b/packages/rest/src/analytics-dataset-selection-door.test.ts index 42bb5ca1c11..0d786931772 100644 --- a/packages/rest/src/analytics-dataset-selection-door.test.ts +++ b/packages/rest/src/analytics-dataset-selection-door.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#17058] `POST /analytics/dataset/query` parses its `selection` AT THE DOOR. + * [commit 94c930248] `POST /analytics/dataset/query` parses its `selection` AT THE DOOR. * * The defect: the route checked only that `selection.measures` was a non-empty * array, so every other member reached `dataset-executor` unrefused — while the @@ -17,9 +17,9 @@ * one that matters most: a fully-loaded VALID selection still passes. A door * that refuses too much is a worse defect than the one being fixed. * - * ## [#17551, ruled] The half #17058 could not door + * ## [#17551, ruled] The half commit 94c930248 could not door * - * #17058 parsed a PROJECTION — the seven members whose declarations coincide + * Commit 94c930248 parsed a PROJECTION — the seven members whose declarations coincide * with `AnalyticsQuery`'s — and projected `runtimeFilter`, `dateGranularity`, * `compareTo` and `totals` AWAY, because `DatasetSelection` had no Zod schema * anywhere in the repo and authoring one in this consumer is the second diff --git a/packages/rest/src/auth-gate-allowlist-fault-window.measurement.test.ts b/packages/rest/src/auth-gate-allowlist-fault-window.measurement.test.ts index 050f45eb8cd..553c837cebc 100644 --- a/packages/rest/src/auth-gate-allowlist-fault-window.measurement.test.ts +++ b/packages/rest/src/auth-gate-allowlist-fault-window.measurement.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#15021] MEASUREMENT — does the #13906 fail-closed window also refuse the + * [commit cc238db8b] MEASUREMENT — does the #13906 fail-closed window also refuse the * ALLOW-LISTED remediation routes `isAuthGateAllowlisted` exists to keep * reachable? * @@ -530,7 +530,7 @@ describe('[#15021] §5 can a mounted route capture a CONCRETE remediation path?' // mounts (`plugin-auth`'s `/api/v1/auth/*`, `plugin-hono-server`'s // `/auth/me/*`) that never enter `computeExecCtx`. // - // ⚠️ If this goes RED, the reachability qualifier on #15021 is gone and the + // ⚠️ If this goes RED, the reachability qualifier on commit cc238db8b is gone and the // card's impact sentence has become true: a mounted route now answers a // remediation path, and §2 says every such answer is 503 for the duration // of a session-backend fault. ⛔ Do not relax this to make a new mount diff --git a/packages/rest/src/discovery-schema-conformance.test.ts b/packages/rest/src/discovery-schema-conformance.test.ts index 4c353e1c23e..5d453a28520 100644 --- a/packages/rest/src/discovery-schema-conformance.test.ts +++ b/packages/rest/src/discovery-schema-conformance.test.ts @@ -340,8 +340,8 @@ describe('[#4828] the REST /discovery live shape conforms to DiscoverySchema', ( // line after calling the producer, so the wire answer was the MOUNTED PATH // SEGMENT (`'v1'` by default) — the string the caller had just typed to reach // the endpoint. `DiscoverySchema` declares `version` under "System Identity" - // next to `name` and `environment`, and the #10993 ruling (reaffirmed by - // Commit 376c70f98/commit 98ea3443f) settled that as the SERVING ARTIFACT's version. + // next to `name` and `environment`, and the #10993 ruling (which commits + // 98ea3443f and 376c70f98 landed) settled that as the SERVING ARTIFACT's version. // // Every assertion below pins PROVENANCE, never a literal version string: the // wire answer is compared against the producer's own answer, or against a diff --git a/packages/rest/src/error-response-generic-passthrough-object-parity.test.ts b/packages/rest/src/error-response-generic-passthrough-object-parity.test.ts index 9e9a87c3848..de92e9fcd55 100644 --- a/packages/rest/src/error-response-generic-passthrough-object-parity.test.ts +++ b/packages/rest/src/error-response-generic-passthrough-object-parity.test.ts @@ -1,12 +1,12 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14725 — the GENERIC declared-status passthrough must answer one refusal + * Commit f5cc78b63 — the GENERIC declared-status passthrough must answer one refusal * with one body, on both REST error doors. * * ## What was measured, on `origin/main` @ `a12b15e394` * - * #14541 made the two doors agree for every error a BESPOKE arm classifies. + * Commit 6d178a408 made the two doors agree for every error a BESPOKE arm classifies. * They still disagreed for every error that reaches the GENERIC declared-status * passthrough, because the two copies of that one passthrough differed by * exactly one key: `classifyDataError`'s copy ends `...(object ? { object } : @@ -121,8 +121,8 @@ const singleDoor = (error: unknown, object?: string): Wire => mapDataError(error * * ⚠️ "Three siblings" is itself easy to over-read, so the measured limit: §3 * keys on `RECORD_LOCKED`, one of §1's OWN codes, so an arm for that code - * migrates §3 along with §1. Only §2 and #14541's §4 are independent of the - * codes below. #14541 §5's "every arm in the SHARED classification has a §1 + * migrates §3 along with §1. Only §2 and commit 6d178a408's §4 are independent of the + * codes below. Commit 6d178a408 §5's "every arm in the SHARED classification has a §1 * parity case" reddens when an arm ARRIVES, but goes green again as soon as its * author adds the parity case it asks for — it does not hold THIS file's §1 to * the passthrough. @@ -140,7 +140,7 @@ describe('#14725 — the generic declared-status passthrough carries `object` on // The card's own measurement. `DUPLICATE_RECORD` HAS a bespoke arm // keyed on `DuplicateRecordError`'s class/`name`; a bare property // write does not carry it, which is exactly the shape the card - // measured on the #14541 branch. + // measured on the commit 6d178a408 branch. { code: 'DUPLICATE_RECORD', status: 409, message: 'A record with this value already exists' }, { code: 'RECORD_LOCKED', status: 409, message: 'This record is frozen' }, // A 4xx from the other end of the band, so the pin is not a diff --git a/packages/rest/src/error-response-sandbox-arm-message.test.ts b/packages/rest/src/error-response-sandbox-arm-message.test.ts index 52f31681c0b..6621e9b8174 100644 --- a/packages/rest/src/error-response-sandbox-arm-message.test.ts +++ b/packages/rest/src/error-response-sandbox-arm-message.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14704 — the single-record `/data` door must not ship the QuickJS debug + * Commit 1c7adc73d — the single-record `/data` door must not ship the QuickJS debug * wrapper out of a declared-code structured arm. * * ## What was measured, on `origin/main` @ `99b4deba49` @@ -21,7 +21,7 @@ * * The bulk door is right because #11588 taught `resolveErrorResponse`'s * declared-status passthrough to read `sandboxBusinessMessage`, and because - * #14541 excludes a sandbox-origin error from the shared consult entirely. The + * Commit 6d178a408 excludes a sandbox-origin error from the shared consult entirely. The * single door reached the arms and shipped the wrapper — #11588's own defect, * one door over, with the direction reversed rather than closed. * @@ -47,7 +47,7 @@ * crash branch moves", so an ordinary declared refusal is untouched; * §5 the bulk-door control: this change is unreachable from * `resolveErrorResponse`, which declines the consult for a sandbox-origin - * error (#14541), so nothing moves on those routes; + * error (commit 6d178a408), so nothing moves on those routes; * §6 the drift guard: every arm in the shared classification that relays a * PRODUCER sentence asks the shared rule, so the next arm cannot * reintroduce the raw relay silently. @@ -256,7 +256,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out * * - **the flip**, per arm and by NAME over {@link ARMS} — the list the * ruling required be RE-DERIVED from the tree rather than copied from - * #14704, and `§4-derivation` below is the guard that keeps it derived; + * Commit 1c7adc73d, and `§4-derivation` below is the guard that keeps it derived; * - **the positive control STAYS** and is still a control: the same crash * carrying NO declared code reaches the same sanitised 500, so a green * flip leg cannot be read as "the terminal swallowed everything"; @@ -337,7 +337,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out /** * The ruling's own execution constraint: *"the seat re-derives the arm - * list from the tree, not from #14704's list."* Re-deriving once is a + * list from the tree, not from commit 1c7adc73d's list."* Re-deriving once is a * reading that rots; this leg is the same re-derivation asked * mechanically, so the next arm added to the shared classification is * either covered above or excused here BY NAME. @@ -422,7 +422,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out }); it('a sandbox-origin error never reaches the shared consult there (#14541)', () => { - // Proof by the consequence #14541 recorded: the arms' structured + // Proof by the consequence commit 6d178a408 recorded: the arms' structured // fields are absent on this door for a sandbox producer. const wire = bulkDoor(sandboxRefusal({ code: 'DELETE_RESTRICTED', status: 409, object: 'account', dependentObject: 'contact' }), 'account'); expect(wire.body).not.toHaveProperty('dependentObject'); diff --git a/packages/rest/src/error-response-structured-arm-door-parity.test.ts b/packages/rest/src/error-response-structured-arm-door-parity.test.ts index 942276bc8be..abc88da9a68 100644 --- a/packages/rest/src/error-response-structured-arm-door-parity.test.ts +++ b/packages/rest/src/error-response-structured-arm-door-parity.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14541 — the two REST error doors must answer one refusal with one body. + * Commit 6d178a408 — the two REST error doors must answer one refusal with one body. * * ## What was measured, on `origin/main` @ `9b30cc18d9` * @@ -46,7 +46,7 @@ * passthrough's prose-withholding arm (#5437 / #5582 / #5907), a 5xx ARM * never displaces a declared 4xx, a sandboxed producer keeps the unwrap * door's sentence on BOTH doors (#11588 / #7543; the single door's mirror - * defect was closed by #14704, which FLIPPED that case's verdict here from + * defect was closed by commit 1c7adc73d, which FLIPPED that case's verdict here from * ACCEPTED DIVERGENCE to CONVERGED rather than deleting it; #17273 flipped * the sandboxed-CRASH case the same way, and added the 5xx band and the * refusal negative control beside it), and the one @@ -456,7 +456,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { expect(single.status).toBe(400); expect(single.body.code).toBe('ERR_DATASOURCE_UNAVAILABLE'); expect(bulk.body.code).toBe('ERR_DATASOURCE_UNAVAILABLE'); - // [#14725] The bodies used to differ by ONE key here — the residue + // [commit f5cc78b63] The bodies used to differ by ONE key here — the residue // this case pinned so it was visible rather than implied: // `classifyDataError`'s GENERIC declared-status passthrough // appended `object` from the door's argument and @@ -480,19 +480,19 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { }); /** - * FLIPPED by #14704, deliberately and in that card's PR, from + * FLIPPED by commit 1c7adc73d, deliberately and in that card's PR, from * `ACCEPTED DIVERGENCE` to `CONVERGED (sentence)`. ⛔ The case is not * DELETED: it is the only thing that would notice the divergence coming * back, and what changes is its verdict, not its existence. * * The divergence it recorded was the SENTENCE: the bulk door read * `sandboxBusinessMessage` (#11588) while the single door reached the - * arm and shipped `error.message` — the QuickJS debug wrapper. #14704 + * arm and shipped `error.message` — the QuickJS debug wrapper. Commit 1c7adc73d * gave the code-gated arms the same two-read rule (`armSentence`), so * both doors now answer the business sentence for one hook refusal. * * ⚠️ What remains different is the KEY SET, and it is not this card's: - * #14541's `isSandboxOrigin` guard declines the shared consult on the + * Commit 6d178a408's `isSandboxOrigin` guard declines the shared consult on the * bulk door outright, so the arm's structured fields never ride there. * That is stated below rather than left implied — a case labelled * CONVERGED whose bodies are unequal has to say where and why. @@ -512,12 +512,12 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { // the business sentence; ⛔ never the QuickJS debug wrapper. expect(bulk.body.error).toBe('Opportunity is closed.'); expect(String(bulk.body.error)).not.toContain('threw:'); - // [#14704] The single door now reads the same rule through the + // [commit 1c7adc73d] The single door now reads the same rule through the // arm. This assertion IS the flip — it read // `"hook 'guard' threw: Error: Opportunity is closed."` before. expect(single.body.error).toBe('Opportunity is closed.'); expect(String(single.body.error)).not.toContain('threw:'); - // The residue, named: #14541's sandbox guard keeps the arm's + // The residue, named: commit 6d178a408's sandbox guard keeps the arm's // structured fields off the bulk door. Owned there, not here. expect(single.body).toHaveProperty('dependentObject', 'contact'); expect(bulk.body).not.toHaveProperty('dependentObject'); @@ -531,7 +531,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { * crash terminal above `classifyDataError`'s code-gated arms, so the * single door answers a sandboxed CRASH with the sanitised 500 whatever * code it declares. The bulk door never reached those arms for a - * sandbox producer (#14541's `isSandboxOrigin` guard), so nothing the + * sandbox producer (commit 6d178a408's `isSandboxOrigin` guard), so nothing the * ruling names moved there — its answer for a crash comes from * `resolveErrorResponse`'s declared-status passthrough, which * `sandboxBusinessMessage` declines a crash for and which therefore @@ -566,7 +566,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { /** * FLIPPED by #17273, deliberately and in that card's PR, from * `ACCEPTED DIVERGENCE (commit cf6e0a193 widens it)` to `CONVERGED` — the same - * discipline #14704 used on the sentence case above and commit cf6e0a193 used on + * discipline commit 1c7adc73d used on the sentence case above and commit cf6e0a193 used on * `error-response-sandbox-arm-message.test.ts` §4. ⛔ The case is not * DELETED: it is the only thing that would notice the divergence coming * back, and what changes is its verdict, not its existence. diff --git a/packages/rest/src/error-response.ts b/packages/rest/src/error-response.ts index f7445c937a6..3867ee160ef 100644 --- a/packages/rest/src/error-response.ts +++ b/packages/rest/src/error-response.ts @@ -279,7 +279,7 @@ export function sandboxBusinessMessage(error: any): string | undefined { } /** - * [#14704] The sentence a declared-code structured arm relays to the caller: + * [commit 1c7adc73d] The sentence a declared-code structured arm relays to the caller: * {@link sandboxBusinessMessage} first, `error.message` second. * * ## The defect this retires @@ -304,7 +304,7 @@ export function sandboxBusinessMessage(error: any): string | undefined { * ## Why the bulk door does not change * * {@link resolveErrorResponse} declines the shared consult outright for a - * sandbox-origin error (#14541's `isSandboxOrigin` guard), so this read is + * sandbox-origin error (commit 6d178a408's `isSandboxOrigin` guard), so this read is * unreachable from that door and every bulk / metadata / UI route answers * byte-for-byte what it answered before. The repair lands on * {@link mapDataError} alone, which is where the defect was. @@ -780,14 +780,14 @@ export function boundedDeclaredRefusalMessage(error: unknown): string | undefine } /** - * [#11588 / #7543 / #14541] Did this error come out of a sandboxed body? + * [#11588 / #7543 / commit 6d178a408] Did this error come out of a sandboxed body? * * `SandboxError.innerMessage` is the QuickJS side-channel: `message` carries a * ` '' threw: ` DEBUG WRAPPER written for the server log, and * the sentence addressed to the caller is `innerMessage`. Every arm in * {@link structuredCodeAnswer} ships `error.message`, so a sandboxed producer * is a DIFFERENT producer for their purposes and is answered by the unwrap - * door instead — the rule #14389 already wrote into the `DUPLICATE_RECORD` + * door instead — the rule commit 10220a7bf already wrote into the `DUPLICATE_RECORD` * arm's `name` gate, stated once here for the arms that need it by POSITION. * * Deliberately NOT {@link sandboxBusinessMessage}: that one declines a CRASH @@ -845,7 +845,7 @@ function isSandboxCrash(error: any): boolean { } /** - * [#14541, contract-review condition 4] A structured arm answering a **5xx** + * [commit 6d178a408, contract-review condition 4] A structured arm answering a **5xx** * never displaces a status the producer declared in the **4xx** band — asked by * BOTH doors, so the answer cannot depend on which one caught the error. * @@ -873,7 +873,7 @@ function fiveXxArmDisplacesDeclared4xx( } /** - * [#14389 / commit 65846bc46] Is this thrown value the ENGINE's unique-violation + * [commit 10220a7bf / commit 65846bc46] Is this thrown value the ENGINE's unique-violation * envelope — `@objectstack/objectql`'s `DuplicateRecordError`? * * Gated on the envelope, name AND code, not on the code alone: a hook that @@ -901,7 +901,7 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { } /** - * [#14541] The bespoke structured arms, in ONE place, so BOTH REST error doors + * [commit 6d178a408] The bespoke structured arms, in ONE place, so BOTH REST error doors * can ask them FIRST. * * ## The defect this retires @@ -957,7 +957,7 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { * * ## What the `UNIQUE_VIOLATION` answer restores, per driver * - * Corrected under the #14541 contract review (condition 7), which measured the + * Corrected under the commit 6d178a408 contract review (condition 7), which measured the * earlier statement backwards. * * On the **SQL** drivers the bulk doors answered `409 UNIQUE_VIOLATION` with the @@ -977,13 +977,13 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { * * ## One wire spelling on the route — the rows too (commit 65846bc46) * - * The #14541 contract review (condition 2) disclosed a fork this file's "one + * The commit 6d178a408 contract review (condition 2) disclosed a fork this file's "one * condition, one wire code" framing did not cover: the DOORS answered a - * `DuplicateRecordError` as `UNIQUE_VIOLATION` (#14389's ruling, the arm + * `DuplicateRecordError` as `UNIQUE_VIOLATION` (commit 10220a7bf's ruling, the arm * below), while a batch or import ROW did not go through this classification * at all — `metadata-protocol`'s `toRowApiError` put the thrown REGISTERED * code on the row verbatim and `import-runner`'s row report did the same — so - * after #14541 a whole-request failure on `POST /data/:object/batch` or + * after commit 6d178a408 a whole-request failure on `POST /data/:object/batch` or * `POST /data/:object/import` said `UNIQUE_VIOLATION` while a row on the SAME * route said `DUPLICATE_RECORD`. * @@ -994,7 +994,7 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { * the same way ({@link isEngineDuplicateRecordEnvelope}: registered code AND * class name, never message text): `toRowApiError` for the rows of * `POST /data/:object/batch`, and `toFailedResult` for the import runner's - * row reports. The single-record door's code did not move (#14389's refusal + * row reports. The single-record door's code did not move (commit 10220a7bf's refusal * stands), no ledger waiver was added — the duplication is removed, not * declared — and the ENGINE's thrown identity is unchanged: * `DuplicateRecordError.code` is still `DUPLICATE_RECORD` in-process; only @@ -1047,7 +1047,7 @@ function structuredCodeAnswer( }, }; } - // [#14389] The engine's insert-conflict envelope → 409 `UNIQUE_VIOLATION`, + // [commit 10220a7bf] The engine's insert-conflict envelope → 409 `UNIQUE_VIOLATION`, // with the structured `field` restored. // // Since #14095 `engine.insert` answers a driver's unique violation with the @@ -1217,7 +1217,7 @@ function structuredCodeAnswer( // point of #3770 is that this 404 no longer depends on a driver erroring // on a missing table. Must precede the generic 4xx passthrough, which // would otherwise ship the internal SCREAMING_CASE code verbatim. - // [#14541, corrected under contract-review condition 5] Gated on + // [commit 6d178a408, corrected under contract-review condition 5] Gated on // `!isSandboxOrigin` because this arm used to sit BELOW the sandbox unwrap // door and now sits above it. The clause is that POSITION, written down — // and position is its WHOLE justification here. ⛔ Not the sibling arm's @@ -1253,7 +1253,7 @@ function structuredCodeAnswer( // form of the identical mistake), so one condition has one wire shape no // matter which layer noticed it. Must precede the generic 4xx passthrough, // which would ship the message but drop `field`. - // [#14541] `!isSandboxOrigin`: the same clause as the arm above, and here + // [commit 6d178a408] `!isSandboxOrigin`: the same clause as the arm above, and here // it carries the sentence reason TOO — this arm really does ship // `error.message`, which for a sandboxed producer is the QuickJS debug // wrapper #11588 exists to keep off this wire. The same declared-5xx status @@ -1283,7 +1283,7 @@ function classifyDataError(error: any, object?: string): { status: number; body: // ⛔ The terminal is not duplicated — it MOVED here from inside the unwrap // door below, which is why that door now reads a body that REPORTED. if (isSandboxCrash(error)) return UNCLASSIFIED_FAULT(); - // [#14541] The bespoke structured arms first, exactly as they were inline + // [commit 6d178a408] The bespoke structured arms first, exactly as they were inline // here — same arms, same order, same position — now stated once so // {@link resolveErrorResponse} can ask them before ITS passthrough too. // @@ -2124,7 +2124,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // divergence pin flips with it. // // Answered through {@link mapDataError} rather than by returning - // {@link UNCLASSIFIED_FAULT} here, for the reason the #14541 consult below + // {@link UNCLASSIFIED_FAULT} here, for the reason the commit 6d178a408 consult below // gives: same terminal, same {@link withDeclaredUserMessage} wrapper, // nothing for a future edit to desynchronise. Both doors now read ONE // `isSandboxCrash` gate; ⛔ do not grow a second opinion about a crash in @@ -2138,11 +2138,11 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // unconditional prose-drop (#5437 / #5582 / #5907) is not narrowed by this: // the terminal withholds prose too, and what moves for that shape is the // status and the declared `code`, both of which shrink to the sanitised - // pair. #14541's guard 1 is about a producer-declared 5xx that is NOT a + // pair. Commit 6d178a408's guard 1 is about a producer-declared 5xx that is NOT a // crash and is untouched — `error-response-structured-arm-door-parity.test.ts` // §4 pins both shapes, side by side. if (isSandboxCrash(error)) return mapDataError(error, object); - // [#14541] The bespoke structured arms are asked BEFORE this door's + // [commit 6d178a408] The bespoke structured arms are asked BEFORE this door's // declared-status passthrough, because that ordering is the whole defect // this card reports: an engine envelope declaring `status: 409` left // through the passthrough and never reached the arm that owns its wire @@ -2194,7 +2194,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // (`OBJECT_NOT_FOUND`), and short-circuiting here would ship a second wire // code for the same condition depending on which route caught it. // - // [#14541] The consult above now answers that for every DECLARED-code + // [commit 6d178a408] The consult above now answers that for every DECLARED-code // producer, so this clause survives for exactly one residue: a SANDBOXED // body throwing `OBJECT_NOT_FOUND`, which the consult declines. Measured: // without the clause that error takes the 4xx arm below and loses @@ -2391,11 +2391,11 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo : truncateClientMessage(authored); // [#9232] Narrowed, same as the three arms above. // - // [#14725] …and the body names the OBJECT the door was called with, + // [commit f5cc78b63] …and the body names the OBJECT the door was called with, // the limb {@link classifyDataError}'s generic declared-status // passthrough has always ended on. Without it the two copies of one // passthrough differed by exactly one key, which is the residue - // #14541 left behind: after that card the doors agree for every code + // Commit 6d178a408 left behind: after that card the doors agree for every code // a BESPOKE arm classifies, and disagree for every code that reaches // the GENERIC passthrough. Measured on `main` @ `a12b15e394`, one // error object, both doors: @@ -2407,7 +2407,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // 409 {"error":"…","code":"DUPLICATE_RECORD"} // // One refusal, two bodies, decided by which route caught it — the - // #14541 shape one arm over. It also closes that card's second + // Commit 6d178a408 shape one arm over. It also closes that card's second // residue: `recordNotFoundError` (`@objectstack/core`) declares // `code`, `status = 404` AND `object`, so its declared status carries // it past the `RECORD_NOT_FOUND` arm below into THIS passthrough on diff --git a/packages/rest/src/execctx-authz-input-seam-reachability.test.ts b/packages/rest/src/execctx-authz-input-seam-reachability.test.ts index ce8cfe0e558..f29e9b10be5 100644 --- a/packages/rest/src/execctx-authz-input-seam-reachability.test.ts +++ b/packages/rest/src/execctx-authz-input-seam-reachability.test.ts @@ -591,7 +591,7 @@ describe('[#13906] §2 — the Layer 0 ex-member refusal, and what a failed post const captured = await drive(mount(serverWith(viaKernelManager(kernel))), { 'x-api-key': RAW_EXMEMBER_KEY }); expect(captured.status).toBe(503); // ⭐ And it answers as an OUTAGE, not as a permission denial — the - // distinction commit 6a180e42d ruled on and this repair reuses rather than reinvents. + // distinction commit 6a180e42d drew and this repair reuses rather than reinvents. expect(captured.body?.success).not.toBe(true); }); diff --git a/packages/rest/src/execctx-consumer-census.test.ts b/packages/rest/src/execctx-consumer-census.test.ts index 86661827637..f16a67a06d3 100644 --- a/packages/rest/src/execctx-consumer-census.test.ts +++ b/packages/rest/src/execctx-consumer-census.test.ts @@ -182,7 +182,7 @@ const ENTITLED = { isSystem: false, tenantId: 'org_census', systemPermissions: ['manage_metadata', 'studio.access', 'setup.access'], - // [#13214] The internal key `computeExecCtx` stamps on every context it + // [commit cc837dbfe] The internal key `computeExecCtx` stamps on every context it // produces, naming the environment whose auth service actually validated // the caller. `enforceEnvironmentOwnership` — the new guard on the UI-view // site this census now counts — compares it against the environment the @@ -434,7 +434,7 @@ describe('[#13160] §2 the consumer surface, counted from the tree', () => { // doc-comment recording that `resolveExecCtx` is memoised per request // and so this is not a new org-resolution seam. // - // [#13214] 72 → 73 sites / 89 → 92 mentions. `registerUiEndpoints` was + // [commit cc837dbfe] 72 → 73 sites / 89 → 92 mentions. `registerUiEndpoints` was // the ONE metadata-touching route in the table that resolved no // identity at all — the exception this census surfaced — and the // 2026-08-30 ruling closed it. It joins as a BARE site behind the @@ -467,7 +467,7 @@ describe('[#13160] §2 the consumer surface, counted from the tree', () => { // silently loses eight sites. [#20237] 15 → 13 and 23 → 21: the list // route's app and dashboard sites moved into the shared list gate (§2). // - // [#13214] The new site is BARE, and that is a decision the next case + // [commit cc837dbfe] The new site is BARE, and that is a decision the next case // enforces: a locally-caught site sitting behind the shared floor would // be the first of its kind and would break the structural claim below. const sameLine = CAUGHT.filter((s) => SOURCE.split('\n')[s.line - 1].includes('.catch(')); diff --git a/packages/rest/src/external-datasource-envelope.conformance.test.ts b/packages/rest/src/external-datasource-envelope.conformance.test.ts index b20461c8afb..7377733ad81 100644 --- a/packages/rest/src/external-datasource-envelope.conformance.test.ts +++ b/packages/rest/src/external-datasource-envelope.conformance.test.ts @@ -51,9 +51,9 @@ interface Captured { * would read the 401 body instead of the arm it names, and this file would * silently stop measuring what it exists to measure. * - * [#9901/commit 6ce58a735] …and an ENTITLED one: every route now also requires a + * [#9901 / commit 6ce58a735] …and an ENTITLED one: every route now also requires a * capability (`manage_platform_settings` on the reads — `validate` among them - * since the 2026-08-20 commit 6ce58a735 ruling — `manage_metadata` on the writes), so + * since the 2026-08-20 ruling, commit 6ce58a735 — `manage_metadata` on the writes), so * this stub holds both. Same reasoning one step further — a * resolver carrying an identity but no grants would turn every case below into * a reading of the 403 body. Holding both rather than one per case is diff --git a/packages/rest/src/external-datasource-validate-scope.test.ts b/packages/rest/src/external-datasource-validate-scope.test.ts index fe03cb5a5b8..25f11eb3667 100644 --- a/packages/rest/src/external-datasource-validate-scope.test.ts +++ b/packages/rest/src/external-datasource-validate-scope.test.ts @@ -82,7 +82,7 @@ const OBJECTS = [ { name: 'local_thing', datasource: 'default', fields: { id: { type: 'text' } } }, ]; -/** An entitled caller — the capability gate (#9901/commit 6ce58a735) is not this file's subject. */ +/** An entitled caller — the capability gate (#9901 / commit 6ce58a735) is not this file's subject. */ const CREDENTIALED = async () => ({ userId: 'u_validate_scope', systemPermissions: ['manage_platform_settings'], diff --git a/packages/rest/src/http-request-test-builder.ts b/packages/rest/src/http-request-test-builder.ts index 223f10eaa59..eef38a9a62c 100644 --- a/packages/rest/src/http-request-test-builder.ts +++ b/packages/rest/src/http-request-test-builder.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * The one place this package builds an `IHttpRequest` for a test (#13377). + * The one place this package builds an `IHttpRequest` for a test (commit e10cf3444). * * Test layer only — nothing in `src/index.ts` reaches it, so tsup (entry: * `src/index.ts`) never emits it into `dist` and it is not published. Same @@ -32,7 +32,7 @@ * ## Why each default is the default * * **`method` and `path` are NOT defaulted — they are read off the route under - * test.** A constant default here is precisely the hazard #13377 names: a + * test.** A constant default here is precisely the hazard commit e10cf3444 names: a * `path` that does not match the route under test makes a passing test measure * something other than what it names, and `req.path` is live rather than * decorative — `RestServer.enforceAuth` feeds it to `isAuthGateAllowlisted` diff --git a/packages/rest/src/http-response-test-builder.ts b/packages/rest/src/http-response-test-builder.ts index f89c65fe834..ae1fd7554e7 100644 --- a/packages/rest/src/http-response-test-builder.ts +++ b/packages/rest/src/http-response-test-builder.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * The one place this package builds an `IHttpResponse` for a test (#13454). + * The one place this package builds an `IHttpResponse` for a test (commit 7ad57e17a). * * Test layer only — nothing in `src/index.ts` reaches it, so tsup (entry: * `src/index.ts`) never emits it into `dist` and it is not published. Same @@ -26,7 +26,7 @@ * ⚠️ Those two errors were never absent — they were MASKED. `tsc` reports at * most one argument-assignability error per call expression, so while argument * 1 was a non-conforming request literal it hid argument 2 entirely; repairing - * the request half (#13377) is what made them visible, at the very same two + * the request half (commit e10cf3444) is what made them visible, at the very same two * sites and with the per-file ledger count unmoved at 2. That mechanism has not * gone away and is why the repair here is one builder rather than two edits: * the decision about what a mock response IS belongs in a place a reader can diff --git a/packages/rest/src/import-dryrun-parity.test.ts b/packages/rest/src/import-dryrun-parity.test.ts index 11d017a41fc..c9e126bb0ef 100644 --- a/packages/rest/src/import-dryrun-parity.test.ts +++ b/packages/rest/src/import-dryrun-parity.test.ts @@ -12,7 +12,7 @@ * with `VALIDATION_FAILED`. * * Ruling D (maintainer, 2026-08-06) replaced prediction with the verdict - * itself: the dry run asks `DataProtocol.validateData` (commit 18189983d / commit 18189983d), + * itself: the dry run asks `DataProtocol.validateData` (commit 18189983d), * which runs the same `validateRecord` / `evaluateValidationRules` `insert()` * runs. So this file never pins the dry run's output ALONE — every case runs * BOTH halves against one live engine and asserts they agree. A test that diff --git a/packages/rest/src/import-runner-unique-violation-row.test.ts b/packages/rest/src/import-runner-unique-violation-row.test.ts index 29df8508857..adefb715ed2 100644 --- a/packages/rest/src/import-runner-unique-violation-row.test.ts +++ b/packages/rest/src/import-runner-unique-violation-row.test.ts @@ -163,7 +163,7 @@ describe('[#14723] §3 — the row and the whole-request door agree on the spell describe('[#14723] [GUARD] what the mapping must NOT do', () => { it('a producer that merely SPEAKS `DUPLICATE_RECORD` is not the engine\'s envelope and keeps its own code', async () => { - // The same discrimination the whole-request arm makes (#14389 §5): the + // The same discrimination the whole-request arm makes (commit 10220a7bf §5): the // gate is the registered code AND the class name. const hookRefusal = Object.assign(new Error('already there, says the hook'), { code: 'DUPLICATE_RECORD', status: 409 }); const p = protocolWith({ createData: vi.fn(async () => { throw hookRefusal; }) }); diff --git a/packages/rest/src/meta-state-route-engine-outage.test.ts b/packages/rest/src/meta-state-route-engine-outage.test.ts index 7250e48cbe1..77e3921623a 100644 --- a/packages/rest/src/meta-state-route-engine-outage.test.ts +++ b/packages/rest/src/meta-state-route-engine-outage.test.ts @@ -7,7 +7,7 @@ * * ## The defect this file refuses * - * ⚠️ CORRECTED [#18546] — the superseded sentence kept so the change is legible + * ⚠️ CORRECTED [commit 58f60e37e] — the superseded sentence kept so the change is legible * rather than lost. This file opened with *"`objectQLProvider` has two consumers * in `rest-server.ts`"*, and #14251's phase-1 census table counted the same two. * There are **THREE**, and the third was already on the tree both readings were @@ -73,7 +73,7 @@ * | no provider wired at all | 404 NOT_FOUND ⭐ PIN | * | provider RESOLVES `undefined` (absence) | 404 NOT_FOUND ⭐ PIN | * | provider REJECTS (wired, failed to build) | 503 SERVICE_UNAVAILABLE ⭐ | - * | provider THROWS SYNCHRONOUSLY (#13280) | 503 SERVICE_UNAVAILABLE | + * | provider THROWS SYNCHRONOUSLY (commit add6a1b1c) | 503 SERVICE_UNAVAILABLE | * * ⭐ The NEGATIVE CONTROL (§3) is the half that keeps this a restoration rather * than a behaviour change: on a HEALTHY engine, an object that genuinely does @@ -258,7 +258,7 @@ const providerRejecting = async () => { throw new Error('driver handshake failed * The same fault from a host that wired a NON-`async` provider. The seam's * declared type cannot prevent this and `RestServer`'s constructor is the * public wiring point; it throws before any promise exists, so a `.catch` - * attached to the returned promise never sees it (#13280). + * attached to the returned promise never sees it (commit add6a1b1c). */ const providerSyncThrowing = (() => { throw new Error('driver handshake failed'); }) as any; @@ -406,7 +406,7 @@ describe('[#15405] §3 a healthy engine is untouched — the negative control', // transcribed beside it. // --------------------------------------------------------------------------- -// ⚠️ [#18546] Title corrected from "the two consumers of the `objectQLProvider` +// ⚠️ [commit 58f60e37e] Title corrected from "the two consumers of the `objectQLProvider` // slot now agree": what this section measures is THIS consumer agreeing with // the `computeExecCtx` sibling, and there is a third (`POST /batch`) that // agrees with neither. The agreement pinned here is the pair it drives. diff --git a/packages/rest/src/objectql-slot-consumer-census.test.ts b/packages/rest/src/objectql-slot-consumer-census.test.ts index 40271feaa75..632e412626f 100644 --- a/packages/rest/src/objectql-slot-consumer-census.test.ts +++ b/packages/rest/src/objectql-slot-consumer-census.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#18546] The `objectQLProvider` slot's consumer census, made MECHANICAL — + * [commit 58f60e37e] The `objectQLProvider` slot's consumer census, made MECHANICAL — * and its THIRD consumer, `POST /batch`, driven for the first time. * * ## Why this file exists @@ -40,7 +40,7 @@ * | no provider wired at all | 501 NOT_IMPLEMENTED | 501 — unchanged | * | provider RESOLVES `undefined` (absence) | 501 NOT_IMPLEMENTED | 501 — unchanged | * | provider REJECTS (wired, failed to build) | **500 INTERNAL_ERROR** | **503 SERVICE_UNAVAILABLE** | - * | provider THROWS SYNCHRONOUSLY (#13280) | **500 INTERNAL_ERROR** | **503 SERVICE_UNAVAILABLE** | + * | provider THROWS SYNCHRONOUSLY (commit add6a1b1c) | **500 INTERNAL_ERROR** | **503 SERVICE_UNAVAILABLE** | * * ⇒ this consumer never re-collapsed: a rejection and a resolved `undefined` * always reached two different answers, which is the whole of the decidable @@ -327,7 +327,7 @@ const ONE_OP = { operations: [{ object: 'account', action: 'create', data: { nam const providerAbsent = async () => undefined; /** Wired and failed to build — a rejection, the shape #13904 made visible. */ const providerRejecting = async () => { throw new Error('driver handshake failed'); }; -/** The same fault from a host that wired a NON-`async` provider (#13280). */ +/** The same fault from a host that wired a NON-`async` provider (commit add6a1b1c). */ const providerSyncThrowing = (() => { throw new Error('driver handshake failed'); }) as any; /** An engine that can open a transaction — enough to pass this door's probe. */ const engineHealthy = async () => ({ transaction: async (fn: any) => fn({}) }); diff --git a/packages/rest/src/package-door-16019-raw-statement-fault-code.test.ts b/packages/rest/src/package-door-16019-raw-statement-fault-code.test.ts index 0881af34812..c482b1703f5 100644 --- a/packages/rest/src/package-door-16019-raw-statement-fault-code.test.ts +++ b/packages/rest/src/package-door-16019-raw-statement-fault-code.test.ts @@ -48,8 +48,8 @@ * test layer (it is not in `rest`'s unaliased-import ledger). * * ⛔ Not a re-judgement of either catch: `declaresHttpAnswer`'s docblock - * already says a declared 5xx is re-thrown too. The contract review of PR - * Commit 001a83b04 required the consequence to be NAMED and PINNED, nothing else. + * already says a declared 5xx is re-thrown too. The contract review of commit + * 001a83b04 required the consequence to be NAMED and PINNED, nothing else. */ import { describe, it, expect, vi } from 'vitest'; diff --git a/packages/rest/src/package-door-execctx-fault-reachability.test.ts b/packages/rest/src/package-door-execctx-fault-reachability.test.ts index b212eb63032..c26b027f137 100644 --- a/packages/rest/src/package-door-execctx-fault-reachability.test.ts +++ b/packages/rest/src/package-door-execctx-fault-reachability.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#13255] REACHABILITY and CONSEQUENCE of a swallowed execution-context + * [commit 43028a8f8] REACHABILITY and CONSEQUENCE of a swallowed execution-context * resolution, measured at the PACKAGE-MANAGEMENT door. * * ## What this file is, and what its sibling already answered @@ -92,7 +92,7 @@ * * ## What this file does, and no longer does not (commit 6a180e42d) * - * As written for #13255 this file repaired nothing and asserted no verdict — + * As written for commit 43028a8f8 this file repaired nothing and asserted no verdict — * distinguishing "no context" from "resolution failed" was a behaviour change * on a public door and out of that card's scope. Commit 6a180e42d RULED that change for * the permission-store half, so the assertions covering it are now regression @@ -105,7 +105,7 @@ * half of that sentence — it is repaired, and its assertions are regression * pins now rather than measurements of a defect. * - * ## ⭐ [#13280] The SEAM ASYMMETRY is repaired; section 7 pins the repair + * ## ⭐ [commit add6a1b1c] The SEAM ASYMMETRY is repaired; section 7 pins the repair * * Section 7 was filed as a finding of its own: at one and the same provider * seam, a REJECTION was absorbed and a SYNCHRONOUS throw lost the whole @@ -397,7 +397,7 @@ const CLASSES: FaultClass[] = [ faulted: () => ({ ...healthy(), authServiceProvider: async () => ({ api: { getSession: async () => { throw new Error('session store down'); } } }) }), ctx: 'lost', read: DENY, write: DENY, }, - // ⭐ [#13280] `SETTINGS_PROVIDER_SYNC_THROW` USED TO LIVE HERE, and its + // ⭐ [commit add6a1b1c] `SETTINGS_PROVIDER_SYNC_THROW` USED TO LIVE HERE, and its // removal from this table is the repair, not a gap in it. The row read: // // id: 'SETTINGS_PROVIDER_SYNC_THROW', @@ -541,7 +541,7 @@ describe('[#13255] consequence — the door\'s answer for each fault class', () // > see it. // // That class is now in the `loud` cohort above. What remains `quiet` is the - // CONTEXT-LOST family (#13255), still unruled and still measured, never + // CONTEXT-LOST family (commit 43028a8f8), still unruled and still measured, never // asserted away — so this half keeps its original reading and this test // stays a regression pin rather than a rubber stamp. expect(quiet.filter((s) => s >= 500)).toEqual([]); @@ -758,10 +758,10 @@ describe('[#13255] no degraded class is ever served as anonymous ACCESS or as a }); // --------------------------------------------------------------------------- -// 7. ⭐ [#13280] SEAM AGREEMENT — the same provider seam, the same fault, and +// 7. ⭐ [commit add6a1b1c] SEAM AGREEMENT — the same provider seam, the same fault, and // now the SAME answer whichever way the provider fails. // -// ⭐ INVERTED IN PLACE, not re-baselined. As written for #13255 this section +// ⭐ INVERTED IN PLACE, not re-baselined. As written for commit 43028a8f8 this section // RECORDED a divergence and asserted it, under the heading "sync-throw and // rejection do not agree": // @@ -806,7 +806,7 @@ describe('[#13280] at a post-identity provider seam, sync-throw and rejection AG }); it('⭐ objectQL — the SECOND divergent seam the card did not measure: both shapes answer 503', async () => { - // [#13280] Not in the card's table, found while verifying it: this seam + // [commit add6a1b1c] Not in the card's table, found while verifying it: this seam // diverged too, 403 (reject) vs 401 (sync throw). It agrees — and ⭐ // [#13476] MOVED THE AGREED VALUE, 403 → 503. The superseded reading: // @@ -816,7 +816,7 @@ describe('[#13280] at a post-identity provider seam, sync-throw and rejection AG // // "Reaches an EMPTY grant set" was the defect: a WIRED engine that failed // is not an empty grant set, it is an UNDETERMINED one. Both shapes are now - // the outage they are. ⚠️ #13280's property is untouched and is what this + // the outage they are. ⚠️ commit add6a1b1c's property is untouched and is what this // test still exists for — the two shapes AGREE; only the value they agree // on moved, and it moved for both together. const { rejecting, syncThrowing } = await bothShapes('objectQLProvider'); diff --git a/packages/rest/src/plugin-metadata-retired-fields.pin.test.ts b/packages/rest/src/plugin-metadata-retired-fields.pin.test.ts index 0603ef648f0..e3a89894254 100644 --- a/packages/rest/src/plugin-metadata-retired-fields.pin.test.ts +++ b/packages/rest/src/plugin-metadata-retired-fields.pin.test.ts @@ -12,7 +12,7 @@ // // ⚠️ NOT because core cannot compile a pin — this header used to say // `@objectstack/core` "has no `typecheck` script (it is a type-check DEBT -// ledger entry)", and that is false on this tree in BOTH halves. #14613 split +// ledger entry)", and that is false on this tree in BOTH halves. Commit 81208086a split // a `tsconfig.test.json` out of core's build config and core's `typecheck` // NAMES it (via `check:test-typecheck --project`), so a `@ts-expect-error` // over there is compiled rather than the phantom pin diff --git a/packages/rest/src/plugin-type-closed-set.pin.test.ts b/packages/rest/src/plugin-type-closed-set.pin.test.ts index 3cf35c6109f..3ede7b70255 100644 --- a/packages/rest/src/plugin-type-closed-set.pin.test.ts +++ b/packages/rest/src/plugin-type-closed-set.pin.test.ts @@ -24,7 +24,7 @@ // // ⚠️ NOT because core cannot compile a pin — this header used to say // `@objectstack/core` "has no `typecheck` script (it is a type-check DEBT -// ledger entry)", and that is false on this tree. #14613 split a +// ledger entry)", and that is false on this tree. Commit 81208086a split a // `tsconfig.test.json` out of core's build config and core's `typecheck` // NAMES it (via `check:test-typecheck --project`), so a `@ts-expect-error` // over there is compiled rather than the phantom pin diff --git a/packages/rest/src/rest-14078-invalid-date-total-arm.test.ts b/packages/rest/src/rest-14078-invalid-date-total-arm.test.ts index 1e3eab5dc3e..5b2f4ed8dfc 100644 --- a/packages/rest/src/rest-14078-invalid-date-total-arm.test.ts +++ b/packages/rest/src/rest-14078-invalid-date-total-arm.test.ts @@ -16,7 +16,7 @@ * * ## Reachability is measured, not argued * - * Commit 3ecb7dc1a (landed `3ecb7dc1a`) drove both live client libraries: mysql2 + * Commit 3ecb7dc1a drove both live client libraries: mysql2 * 3.23.1 returns a module constant literally named `INVALID_DATE` for a zero * `DATETIME`, and postgres-date 1.0.7 builds `new Date(NaN)` for every year in * 275760..294276 — a range Postgres itself stores. The maintainer ruled option diff --git a/packages/rest/src/rest-api-config-defaults-follow-spec.pin.test.ts b/packages/rest/src/rest-api-config-defaults-follow-spec.pin.test.ts index ee67566b00f..687f45d2b41 100644 --- a/packages/rest/src/rest-api-config-defaults-follow-spec.pin.test.ts +++ b/packages/rest/src/rest-api-config-defaults-follow-spec.pin.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14366] `RestApiConfigSchema` is the SINGLE SOURCE of the `api` sub-object's + * [commit 53cbad9f7] `RestApiConfigSchema` is the SINGLE SOURCE of the `api` sub-object's * defaults — `RestServer.normalizeConfig` follows a change to a * `z.default(...)` in `packages/spec` rather than restating it. * diff --git a/packages/rest/src/rest-approvals-wire-codes.test.ts b/packages/rest/src/rest-approvals-wire-codes.test.ts index b2b8e34f2a0..d5e5c493dc4 100644 --- a/packages/rest/src/rest-approvals-wire-codes.test.ts +++ b/packages/rest/src/rest-approvals-wire-codes.test.ts @@ -34,7 +34,7 @@ * whose emission was — contrary to that card's premise — already observed * elsewhere. See its own comment for where, and why it is pinned here too. * - * [#14849] Six more rows joined that home: VALIDATION_FAILED, DUPLICATE_REQUEST, + * [commit 226e72443] Six more rows joined that home: VALIDATION_FAILED, DUPLICATE_REQUEST, * INVALID_STATE, REQUEST_NOT_FOUND, RESUME_TARGET_LOST and RESUME_FAILED had no * live-emission pin ANYWHERE — established by ablating each row and running the * whole `packages/rest` suite, not by grepping this file. The per-row results and @@ -191,7 +191,7 @@ describe('approvals wire codes are registered vocabulary (#8885)', () => { ).toBe(true); }); - // [#13182] `READ_BACK_FAILED` is a NAMED wire row (the RESUME_FAILED + // [commit 5b3ff63cc] `READ_BACK_FAILED` is a NAMED wire row (the RESUME_FAILED // precedent: a genuine server-side inconsistency, but named): the write is // recorded and NOT rolled back, the read-back is org-filtered, and the // 500 semantics stay. Pinned here so the prefix→code mapping and ledger @@ -216,7 +216,7 @@ describe('approvals wire codes are registered vocabulary (#8885)', () => { ).toBe(true); }); - // ── [#14849] The six rows that had NO live-emission pin ────────────── + // ── [commit 226e72443] The six rows that had NO live-emission pin ────────────── // // Method first, because this card exists BECAUSE a grep got this wrong // once already: every one of the nine rows was confirmed by ABLATION, not @@ -237,7 +237,7 @@ describe('approvals wire codes are registered vocabulary (#8885)', () => { // the three reds the #14573 correction measured, two of them in a file // whose declared subject is a DIFFERENT contract — precisely the pin a // file-scoped grep cannot see. Same instrument, zero reds for the six ⇒ - // they were genuinely uncovered, not covered somewhere unobvious. #14849 + // they were genuinely uncovered, not covered somewhere unobvious. Commit 226e72443 // predicted at least one of the six would turn out already pinned; it did // not, and that prediction is now answered by measurement rather than // carried forward as a caveat. diff --git a/packages/rest/src/rest-config-parse-not-cast.test.ts b/packages/rest/src/rest-config-parse-not-cast.test.ts index 45a1182a0c9..3e13ab51983 100644 --- a/packages/rest/src/rest-config-parse-not-cast.test.ts +++ b/packages/rest/src/rest-config-parse-not-cast.test.ts @@ -275,12 +275,12 @@ describe('[#11637] §C regression guards — the narrowing is exactly the declar }); // --------------------------------------------------------------------------- -// §D — [#14366] the parsed output is CONSUMED +// §D — [commit 53cbad9f7] the parsed output is CONSUMED // --------------------------------------------------------------------------- /** * #11637 ran the parse and threw its result away; the block was rebuilt from a - * `??` chain over the raw cast. #14366 folded the chain onto the parse after + * `??` chain over the raw cast. Commit 53cbad9f7 folded the chain onto the parse after * re-measuring both of #11637's reasons expired and the key diff empty in both * directions (14 read, 14 declared after the `.omit()`). * @@ -335,7 +335,7 @@ describe('[#14366] §D the `api` sub-object consumes the parsed output', () => { }); it('THE BOUNDED DELTA: an authored `documentation` arrives as the parse outputs it', () => { - // The single measured behaviour change of #14366, pinned rather than + // The single measured behaviour change of commit 53cbad9f7, pinned rather than // left to be rediscovered. The deleted `??` chain copied this object // through untouched (`documentation: api.documentation`), so a partial // one stayed partial; the parse fills the inner `.default()`s — of @@ -384,7 +384,7 @@ describe('[#14366] §D the `api` sub-object consumes the parsed output', () => { }); it('an undeclared key under `api` is not carried into the normalized config', () => { - // Unchanged by #14366 and pinned as the bound: the `??` chain copied a + // Unchanged by commit 53cbad9f7 and pinned as the bound: the `??` chain copied a // fixed list of 14 keys, and the non-strict parse strips anything not // declared. Both drop it — so consuming cannot have widened the surface. const api = normalizedApi(construct({ totallyUndeclared: 'x' } as never)); diff --git a/packages/rest/src/rest-duplicate-record-arm.test.ts b/packages/rest/src/rest-duplicate-record-arm.test.ts index 17ce8daf682..0aa96eb799b 100644 --- a/packages/rest/src/rest-duplicate-record-arm.test.ts +++ b/packages/rest/src/rest-duplicate-record-arm.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14389 — `classifyDataError`'s arm for the engine's insert-conflict envelope. + * Commit 10220a7bf — `classifyDataError`'s arm for the engine's insert-conflict envelope. * * ## What was measured * diff --git a/packages/rest/src/rest-exec-ctx-principal-kind.test.ts b/packages/rest/src/rest-exec-ctx-principal-kind.test.ts index c5a2161b719..cf3d0988d1a 100644 --- a/packages/rest/src/rest-exec-ctx-principal-kind.test.ts +++ b/packages/rest/src/rest-exec-ctx-principal-kind.test.ts @@ -295,7 +295,7 @@ describe('#6216 — the REST face assembles through the SHARED assembler, output // it, so it is an assembled field now and absent for the same reason // every other unset field is: this session carries no gate. '__kernel', - // [#13214] The SECOND post-assembly internal key, added by the + // [commit cc837dbfe] The SECOND post-assembly internal key, added by the // 2026-08-30 security ruling and named here rather than left to a // subset check — this pin exists precisely to make a key ARRIVING // as loud as a key going missing, and this one arrived. diff --git a/packages/rest/src/rest-server-meta-read-org-scope.test.ts b/packages/rest/src/rest-server-meta-read-org-scope.test.ts index b931a835a8b..9aeeb44d468 100644 --- a/packages/rest/src/rest-server-meta-read-org-scope.test.ts +++ b/packages/rest/src/rest-server-meta-read-org-scope.test.ts @@ -595,7 +595,7 @@ describe('#13764 the history seams of this harness honour the org partition', () // fold happens, not about whether one happens. `getMetaDiagnostics` reads each // swept type through `getMetaItems({ type: t, organizationId })`. // -// ⚠️ [commit 96326040f, recorded by #15034] `getMetaItems` NOW APPLIES THE REGISTRY GATE +// ⚠️ [commit 96326040f, recorded by commit abf9101f1] `getMetaItems` NOW APPLIES THE REGISTRY GATE // ITSELF, after folding the request type. This header used to say it applied // none and that the scope was therefore the caller's to decide per type; that // sentence is FALSE on today's tree. What that dissolved is the obstacle the @@ -623,7 +623,7 @@ describe('#13764 the history seams of this harness honour the org partition', () // either half: alone, neither can tell a per-type gate from an unconditional // tenant. // -// ── ⛔ WHAT THIS FILE NO LONGER DISCRIMINATES (#15034, MEASURED) ─────────── +// ── ⛔ WHAT THIS FILE NO LONGER DISCRIMINATES (commit abf9101f1, MEASURED) ─────────── // // This header used to end: "Swap `organizationIdForMetaRead` for a raw // `ctx?.tenantId` at the call site and that assertion, and only it, turns red." @@ -634,7 +634,7 @@ describe('#13764 the history seams of this harness honour the org partition', () // // ⇒ What this file DOES still discriminate is the organization being DROPPED: // remove the `organizationId` the `?type=` arm passes and the six repair cases -// above turn red (measured at #15034: 6 failed / 24 passed). Read the two apart before +// above turn red (measured at commit abf9101f1: 6 failed / 24 passed). Read the two apart before // citing this file as a pin on the door-side predicate — it pins that the arm // still FOLDS, never that the fold happens at the door. @@ -708,7 +708,7 @@ describe('#13753 GET /meta/diagnostics states the org partition on the ?type= ar // than written through the door. Rows like it exist in deployments // that ran before that ruling; boot hydration walks past them, so // they are dead, and a read door that named the org for every type - // would serve them again. ⚠️ [#15034] PREDICTED DIRECTION, + // would serve them again. ⚠️ [commit abf9101f1] PREDICTED DIRECTION, // CORRECTED: replacing the predicate with `ctx?.tenantId` at the // call site no longer moves this count — `getMetaItems`' own gate // (commit 96326040f) re-folds it. What still drives it to 2 is a read door diff --git a/packages/rest/src/rest-server.ts b/packages/rest/src/rest-server.ts index ec47cff8991..0c24cba66c5 100644 --- a/packages/rest/src/rest-server.ts +++ b/packages/rest/src/rest-server.ts @@ -1112,7 +1112,7 @@ type NormalizedRestServerConfig = { enableSearch: boolean; enableProjectScoping: boolean; projectResolution: 'required' | 'optional' | 'auto'; - // [#14366] The PARSED shape, not the authored one: this block is + // [commit 53cbad9f7] The PARSED shape, not the authored one: this block is // built from `RestApiConfigSchema`'s output, so a `documentation` the // caller wrote arrives with its OWN declared inner defaults applied // (`.title`). [#20295] `documentation.enabled` and the whole @@ -1169,7 +1169,7 @@ type NormalizedRestServerConfig = { * [commit b3a63d32c] Every key of `RouteGenerationConfigSchema` is a `retiredKey()` * tombstone (ADR-0049 enforce-or-remove — nothing here ever read * `includeObjects` / `excludeObjects` / `nameTransform` / `overrides`; the - * #14369 census). The sub-object is still PARSED, so an authored key is + * Commit a3d5724c8 census). The sub-object is still PARSED, so an authored key is * refused at construction with its prescription rather than stripped, but * nothing is threaded: per-object exposure is the object's own * `enable.apiEnabled` / `enable.apiMethods`, enforced by `enforceApiAccess`. @@ -1210,7 +1210,7 @@ function buildDeclaredSubConfigSchemas() { type DeclaredSubConfigSchemas = ReturnType; type DeclaredSubConfigName = keyof DeclaredSubConfigSchemas; /** - * [#14366] The parsed `api` sub-object, which `normalizeConfig` now BUILDS + * [commit 53cbad9f7] The parsed `api` sub-object, which `normalizeConfig` now BUILDS * FROM. Taken off the table's own entry rather than off `RestApiConfigParsed`, * so it is the post-`.omit()` shape: the retired `requireAuth` tombstone is * absent here exactly as it is absent from the schema this seam runs. @@ -1450,7 +1450,7 @@ async function seamOrUndefined(call: () => T | PromiseLike): Promise`) declaring absence, not failing. Only a THROW or a REJECTION is * the outage — which is why this helper, like {@link seamOrUndefined}, invokes * `call` synchronously so a non-`async` provider that throws before returning a - * promise reaches the same answer as one that rejects (#13280). + * promise reaches the same answer as one that rejects (commit add6a1b1c). * * ⚠️ RESIDUE, deliberately not repaired here and filed separately — do not * read this helper as covering it. The KERNEL branch of the seam resolves @@ -2233,7 +2233,7 @@ export class RestServer { } /** - * [#13214] Refuse a request whose RESOLVED environment is not one the CALLER + * [commit cc837dbfe] Refuse a request whose RESOLVED environment is not one the CALLER * holds — the comparison this server did not have. * * ## The defect this closes, and why the anonymous gate alone did not @@ -2244,7 +2244,7 @@ export class RestServer { * identity resolved at all, so an ANONYMOUS caller received another * environment's UI view — object label plus every field's name / label / * type / required — and the route doubled as an object-existence oracle for - * whatever environment it named. Driven and reported on #13214 (PRs commit 889ec5b42, + * whatever environment it named. Driven and reported on commit cc837dbfe (PRs commit 889ec5b42, * Commit 3d10755f0). * * Adding `resolveExecCtx` + `enforceAuth` was measured NOT to be the repair @@ -2755,7 +2755,7 @@ export class RestServer { // environmentId. let authService: any; let kernel: any; - // [#13214] WHICH environment's auth service actually validated this + // [commit cc837dbfe] WHICH environment's auth service actually validated this // caller — the fact an ownership check needs and the one this method // used to compute and drop. Three branches below can answer, and the // SECOND of them answers for a DIFFERENT environment than the one the @@ -3094,7 +3094,7 @@ export class RestServer { // NOT an `ExecutionContext` field — hence the cast, which now // covers this key and `__authEnvironmentId` below. __kernel: kernel, - // [#13214] Internal: the environment whose auth service actually + // [commit cc837dbfe] Internal: the environment whose auth service actually // validated this caller — the left-hand side of the ownership // comparison at the UI-view seam. ⚠️ Unlike `__kernel` this one IS // an authorization input, at exactly one reader @@ -4062,7 +4062,7 @@ export class RestServer { * walked straight past it and mounted the whole API at `/api//`, and * `'v1/beta'` spliced an extra path segment into every route. * - * [#14366] The parsed output is CONSUMED — `normalizeConfig` builds the + * [commit 53cbad9f7] The parsed output is CONSUMED — `normalizeConfig` builds the * `api` block from what this returns. It was VALIDATE-ONLY from #11637 * until then, for two measured reasons that have both since expired: * @@ -4077,7 +4077,7 @@ export class RestServer { * * - `api.projectResolution` was `.omit()`ed until #12450 withdrew it. * - * ⇒ Re-measured at #14366 on the landed tree, because the discard is + * ⇒ Re-measured at commit 53cbad9f7 on the landed tree, because the discard is * only safe to remove if the key diff is EMPTY: the 14 keys * `normalizeConfig` reads and the 14 `RestApiConfigSchema` declares * after the `.omit()` are the same 14, in both directions. So the @@ -4089,7 +4089,7 @@ export class RestServer { * `documentation` or `responseFormat` object the caller WRITES now * arrives carrying its own declared inner defaults, where the `??` * chain copied the authored object through untouched. Both keys have - * zero read sites outside this block (the #14369 census), so nothing + * zero read sites outside this block (the commit 53cbad9f7 census), so nothing * observes it today — but it is a real change to this structure's * contents and belongs in the record rather than in a reader's surprise. * @@ -4148,7 +4148,7 @@ export class RestServer { * CONSUMED. The asymmetry with `api` is measured, not stylistic: for each * of the four, every key `normalizeConfig` reads is one its schema * declares (the key diff is empty), and none carries a tombstone, so a - * consumed parse cannot strip anything the runtime honours. [#14366] `api` + * consumed parse cannot strip anything the runtime honours. [commit 53cbad9f7] `api` * went through the same door last, separately measured rather than ridden * on the siblings: the asymmetry is gone and all five now build from their * parsed output. @@ -4174,16 +4174,16 @@ export class RestServer { * Normalize configuration with defaults */ private normalizeConfig(config: RestServerConfig): NormalizedRestServerConfig { - // [#11637 / #14366] `api`: parsed AND consumed. #11637 ran the declared + // [#11637 / commit 53cbad9f7] `api`: parsed AND consumed. #11637 ran the declared // contract here but discarded its output, leaving the block below to be // built from a cast over the raw input through a `??` chain that // duplicated `RestApiConfigSchema`'s defaults key for key — ELEVEN // literals in `packages/rest` restating the eleven top-level // `z.default(...)`s in `packages/spec`, with nothing pinning that the - // two stayed equal. (Eleven, measured on both sides at #14366; the + // two stayed equal. (Eleven, measured on both sides at commit 53cbad9f7; the // filing card said twelve, having counted the `config.api ?? {}` that // guards the whole object rather than a per-key default.) - // #14366 folded the chain onto the parse after re-measuring the key + // Commit 53cbad9f7 folded the chain onto the parse after re-measuring the key // diff empty in both directions (see `parseDeclaredApiConfig`), so the // schema is now the single source of these defaults. The cast is gone // with it: the parsed output is already typed. @@ -5471,7 +5471,7 @@ export class RestServer { // arm Studio's per-type directory drill-down uses, and // it is the arm #13753 repaired. // - // ── WHY THE FOLD IS DOUBLED, AND STAYS DOUBLED (#15034) ── + // ── WHY THE FOLD IS DOUBLED, AND STAYS DOUBLED (commit abf9101f1) ── // // The VALUE is redundant, and measured to be. Both sites fold // the identical string through the identical map — here @@ -5509,7 +5509,7 @@ export class RestServer { // a fan-out per overridable type plus a REST-side // re-aggregation of `total`/`stats`/`scannedTypes`. // - // ⚠️ Commit 96326040f DISSOLVED THAT OBSTACLE (#15034 recorded + // ⚠️ Commit 96326040f DISSOLVED THAT OBSTACLE (commit abf9101f1 recorded // it, #15622 acted on it). `getMetaDiagnostics` does // not spend the organization once: it loops `for (const // t of targetTypes)` calling `getMetaItems({ type: t, @@ -8160,7 +8160,7 @@ export class RestServer { // `wiredEngineOrLoud` also invokes the provider // SYNCHRONOUSLY, so a host wiring a non-`async` provider — // which the seam's declared type cannot prevent — reaches the - // same answer as one that rejects (#13280) instead of + // same answer as one that rejects (commit add6a1b1c) instead of // escaping past a `.catch` that never came into existence. const ql = await wiredEngineOrLoud( Boolean(this.objectQLProvider), @@ -8323,7 +8323,7 @@ export class RestServer { // inventing org RESOLUTION here, and this reads // `tenantId` off the execution context `resolveExecCtx` // already resolves, exactly as #8803 did for the audit - // read. [#14907] The CALLEE gates: `getMetaItemLayered` + // read. [commit e1d4f9e3f] The CALLEE gates: `getMetaItemLayered` // resolves `organizationIdForMetaRead` AFTER its canonical // fold, so the tenant goes over RAW. ⛔ Pre-gating HERE, on // the unfolded `:type`, would be the commit 26f3588fb defect. ⛔ And @@ -8516,7 +8516,7 @@ export class RestServer { /** * Register UI endpoints * - * ## [#13214] This registrar's one route is identity- AND ownership-gated + * ## [commit cc837dbfe] This registrar's one route is identity- AND ownership-gated * * It used to be the single route in this server's table that resolved NO * identity: it went straight from `resolveProtocol` to `getUiView`, so it @@ -8553,7 +8553,7 @@ export class RestServer { handler: async (req: any, res: any) => { try { const routeEnvironmentId = isScoped ? req.params?.environmentId : undefined; - // [#13214] THE environment decision for this request, taken + // [commit cc837dbfe] THE environment decision for this request, taken // once through the shared entry point and then reused — so // the identity below, the ownership comparison and the // protocol that answers cannot be about three different @@ -8579,7 +8579,7 @@ export class RestServer { const viewRequest: TransportScopedMetaRequest = { object: req.params.object, type: req.params.type, - // [#13214] `routeEnvironmentId`, NOT the resolved id. + // [commit cc837dbfe] `routeEnvironmentId`, NOT the resolved id. // The gate above changed WHO may reach the producer; // it deliberately did not change WHAT the producer is // told. This key has only ever been present on the @@ -10150,7 +10150,7 @@ export class RestServer { // `RestServer`'s constructor is the public wiring point — // throws while the expression is still being evaluated, so // there is no promise to attach to and the handler is never - // reached (#13280). + // reached (commit add6a1b1c). // // ⚠️ NOT reachable from the SHIPPED wiring: the provider // `rest-api-plugin.ts` hands over is declared `async`. @@ -12549,7 +12549,7 @@ export class RestServer { // row is invisible inside the caller's organization scope, so // the result envelope cannot be built. Same class as // RESUME_FAILED — a genuine server-side inconsistency, named - // (#13182): read the request back with a system or + // (commit 5b3ff63cc): read the request back with a system or // matching-organization context. [/^READ_BACK_FAILED/, 500, 'READ_BACK_FAILED'], ]; @@ -13023,7 +13023,7 @@ export class RestServer { // rather than failing. `wiredEngineOrLoud` also invokes the // provider SYNCHRONOUSLY, so a host wiring a non-`async` // provider — which the seam's declared type cannot prevent — - // reaches the same answer as one that rejects (#13280). + // reaches the same answer as one that rejects (commit add6a1b1c). const ql = await wiredEngineOrLoud( Boolean(this.objectQLProvider), () => this.objectQLProvider!(environmentId), diff --git a/packages/rest/src/rest-sub-config-parse-not-cast.test.ts b/packages/rest/src/rest-sub-config-parse-not-cast.test.ts index cb4d7b9f3d8..a606900a69b 100644 --- a/packages/rest/src/rest-sub-config-parse-not-cast.test.ts +++ b/packages/rest/src/rest-sub-config-parse-not-cast.test.ts @@ -40,12 +40,12 @@ * `normalizeConfig` reads is declared by the sub-object's schema (measured * key by key; the diff is empty for all four), so the PARSED output is what * the normalized config is built from and the schema's own defaults are the - * defaults. `api` held #11637's validate-only posture until [#14366] measured + * defaults. `api` held #11637's validate-only posture until [commit 53cbad9f7] measured * its key diff empty too and folded its `??` chain onto the parse; it keeps * the `.omit()`ed `requireAuth` tombstone, and is not this file's subject. * * [commit b3a63d32c] Ten of the keys these pins originally exercised were RETIRED under - * ADR-0049 enforce-or-remove (the #14369 liveness census found them normalized + * ADR-0049 enforce-or-remove (the commit a3d5724c8 liveness census found them normalized * and never read): `crud.patterns` / `objectParamStyle`, `metadata.cacheTtl` / * `endpoints.schema`, `batch.operations.upsertMany` / `defaultAtomic`, and all * of `routes.*`. Each is now a `retiredKey()` tombstone, so the pins below that diff --git a/packages/rest/src/ui-view-environment-ownership.test.ts b/packages/rest/src/ui-view-environment-ownership.test.ts index 632c060f928..61818d2246e 100644 --- a/packages/rest/src/ui-view-environment-ownership.test.ts +++ b/packages/rest/src/ui-view-environment-ownership.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#13214] The fact the ownership gate reads — pinned against its PRODUCER. + * [commit cc837dbfe] The fact the ownership gate reads — pinned against its PRODUCER. * * ## Why this file has to exist separately * diff --git a/packages/rest/src/ui-view-route-identity.measurement.test.ts b/packages/rest/src/ui-view-route-identity.measurement.test.ts index 7a390af1b91..e50b1cf02c2 100644 --- a/packages/rest/src/ui-view-route-identity.measurement.test.ts +++ b/packages/rest/src/ui-view-route-identity.measurement.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#13214] What `GET /api/v1/ui/view/:object/:type` decides about the caller — + * [commit 889ec5b42] What `GET /api/v1/ui/view/:object/:type` decides about the caller — * at the REST seam AND downstream in `getUiView`. * * ## ⭐ What this file is NOW: the single-tenant half of the regression pin @@ -30,7 +30,7 @@ * 1. §1-§2 — the seam, reproduced INDEPENDENTLY of commit 4801296e7 (its own harness, * its own instrument), plus the exact argument object the seam hands the * producer. - * 2. §3-§4 — ⭐ the half #13214 marks UNMEASURED: does `getUiView` apply + * 2. §3-§4 — ⭐ the half commit 889ec5b42 marks UNMEASURED: does `getUiView` apply * authorization of its own? Driven against the REAL * `ObjectStackProtocolImplementation`, not read off a grep. * 3. §5 — `isAuthGateAllowlisted` does not name a `/ui` path, verified by @@ -85,7 +85,7 @@ type Handler = (req: any, res: any) => any; // --------------------------------------------------------------------------- // Harness — same shape as `execctx-consumer-census.test.ts`, rebuilt here so -// this file's readings do not inherit that file's fixtures (#13214 asks for an +// this file's readings do not inherit that file's fixtures (commit 889ec5b42 asks for an // INDEPENDENT reproduction, not a citation). // --------------------------------------------------------------------------- @@ -371,7 +371,7 @@ describe('[#13214] §2 the argument object — the producer cannot gate on what }); // --------------------------------------------------------------------------- -// 3. ⭐ The question #13214 marks UNMEASURED — does the producer gate? +// 3. ⭐ The question commit 889ec5b42 marks UNMEASURED — does the producer gate? // --------------------------------------------------------------------------- describe('[#13214] §3 downstream — the REAL `getUiView`, driven', () => { @@ -401,7 +401,7 @@ describe('[#13214] §3 downstream — the REAL `getUiView`, driven', () => { }, 120_000); it('the producer applies NO authorization of its own — called directly, an identity in the argument changes nothing', async () => { - // ⚠️ This is #13214's originally-UNMEASURED half and the answer has not + // ⚠️ This is commit 889ec5b42's originally-UNMEASURED half and the answer has not // changed: the repair is at the seam, and the producer still gates // nothing. Measured where it can still be measured — §2 and §4 supply // the other half (the seam tells it nothing, and the instance is not diff --git a/packages/rest/src/ui-view-route-tenancy.measurement.test.ts b/packages/rest/src/ui-view-route-tenancy.measurement.test.ts index d53ed04d2b6..494069bbe6e 100644 --- a/packages/rest/src/ui-view-route-tenancy.measurement.test.ts +++ b/packages/rest/src/ui-view-route-tenancy.measurement.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#13214] Does `GET /api/v1/ui/view/:object/:type` cross ENVIRONMENTS? + * [commit 3d10755f0] Does `GET /api/v1/ui/view/:object/:type` cross ENVIRONMENTS? * * ## ⭐ What this file is NOW: the regression pin for the repair it measured * diff --git a/packages/rest/src/xlsx-test-loader.ts b/packages/rest/src/xlsx-test-loader.ts index f3ce5889bf9..63e3b596385 100644 --- a/packages/rest/src/xlsx-test-loader.ts +++ b/packages/rest/src/xlsx-test-loader.ts @@ -2,7 +2,7 @@ /** * The one place this package asserts around `exceljs`'s broken `load` signature - * (#13378). Test layer only — nothing in `src/index.ts` reaches it, so tsup + * (commit 82faea03f). Test layer only — nothing in `src/index.ts` reaches it, so tsup * (entry: `src/index.ts`) never emits it into `dist` and it is not published. * * ## Why the assertion below is unavoidable, in the dependency's own bytes @@ -35,7 +35,7 @@ * ⭐ There is NO Node `Buffer` value that satisfies that parameter. The defect is * in the published declaration, not at any call site — so this is not laziness, * and no amount of care at a call site can remove it. What a call site CAN do is - * not restate it: before #13378 the package paid this at 6 anonymous `as any`s + * not restate it: before commit 82faea03f the package paid this at 6 anonymous `as any`s * and left a 7th site as a ledgered `TS2345`. Now it is stated once, here. * * ## Why option C (upgrade) is not the answer — measured 2026-08-30 From 8b1475c251f07ea13c28c96e0c81cb9cede0a695 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <50353452+hotlong@users.noreply.github.com> Date: Tue, 29 Sep 2026 18:59:23 +0800 Subject: [PATCH 3/3] wip(rest): review pass over the re-anchored comment lines Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289 Co-authored-by: Claude --- .../src/analytics-fault-user-message.test.ts | 2 +- ...allowlist-fault-window.measurement.test.ts | 2 +- ...-generic-passthrough-object-parity.test.ts | 6 +-- ...error-response-sandbox-arm-message.test.ts | 10 ++--- ...esponse-structured-arm-door-parity.test.ts | 8 ++-- packages/rest/src/error-response.ts | 24 ++++++------ ...ernal-datasource-routes-auth-guard.test.ts | 10 ++--- .../rest/src/external-datasource-routes.ts | 8 ++-- .../rest/src/http-request-test-builder.ts | 2 +- .../rest/src/import-job-integration.test.ts | 4 +- .../import-run-automations-agreement.test.ts | 2 +- ...import-runner-unique-violation-row.test.ts | 2 +- packages/rest/src/import-runner.ts | 2 +- packages/rest/src/meta-501-envelope.test.ts | 2 +- .../meta-compound-save-force-parity.test.ts | 2 +- .../meta-compound-save-mode-parity.test.ts | 2 +- packages/rest/src/meta-object-fls.test.ts | 2 +- packages/rest/src/meta-plural-i18n.test.ts | 4 +- .../src/meta-publish-package-scope.test.ts | 2 +- .../meta-state-route-engine-outage.test.ts | 2 +- .../src/objectql-slot-consumer-census.test.ts | 2 +- ...ge-door-execctx-fault-reachability.test.ts | 10 ++--- .../src/rest-approvals-wire-codes.test.ts | 6 +-- ...st-field-visibility-fault-envelope.test.ts | 4 +- .../rest-hook-refusal-message-parity.test.ts | 6 +-- .../rest-hook-script-fault-envelope.test.ts | 2 +- packages/rest/src/rest-route-ledger.ts | 2 +- ...server-meta-org-scope-url-spelling.test.ts | 6 +-- .../rest-server-meta-read-org-scope.test.ts | 2 +- packages/rest/src/rest-server.ts | 38 +++++++++---------- ...st-share-user-message-bypass-exits.test.ts | 2 +- .../rest-sub-config-parse-not-cast.test.ts | 4 +- ...ui-view-route-identity.measurement.test.ts | 8 ++-- 33 files changed, 95 insertions(+), 95 deletions(-) diff --git a/packages/rest/src/analytics-fault-user-message.test.ts b/packages/rest/src/analytics-fault-user-message.test.ts index fea6527d2ea..2f6028c256d 100644 --- a/packages/rest/src/analytics-fault-user-message.test.ts +++ b/packages/rest/src/analytics-fault-user-message.test.ts @@ -323,7 +323,7 @@ describe('[#12710] §4 both doors carry the same producer mark for the same thro const flat = dataDoor(c.error()); // POSITIVE CONTROL — without this the analytics assertion below could pass // for the wrong reason (two doors agreeing the mark does not belong on - // this terminal). Commit 79c46da90 rules that it does; `/data` is where that ruling + // this terminal). The ruling commit 79c46da90 landed says it does; `/data` is where that ruling // already lives. expect( flat.body.userMessage, diff --git a/packages/rest/src/auth-gate-allowlist-fault-window.measurement.test.ts b/packages/rest/src/auth-gate-allowlist-fault-window.measurement.test.ts index 553c837cebc..bdffc8e42df 100644 --- a/packages/rest/src/auth-gate-allowlist-fault-window.measurement.test.ts +++ b/packages/rest/src/auth-gate-allowlist-fault-window.measurement.test.ts @@ -530,7 +530,7 @@ describe('[#15021] §5 can a mounted route capture a CONCRETE remediation path?' // mounts (`plugin-auth`'s `/api/v1/auth/*`, `plugin-hono-server`'s // `/auth/me/*`) that never enter `computeExecCtx`. // - // ⚠️ If this goes RED, the reachability qualifier on commit cc238db8b is gone and the + // ⚠️ If this goes RED, the reachability qualifier commit cc238db8b pinned is gone and the // card's impact sentence has become true: a mounted route now answers a // remediation path, and §2 says every such answer is 503 for the duration // of a session-backend fault. ⛔ Do not relax this to make a new mount diff --git a/packages/rest/src/error-response-generic-passthrough-object-parity.test.ts b/packages/rest/src/error-response-generic-passthrough-object-parity.test.ts index de92e9fcd55..641ccdeee22 100644 --- a/packages/rest/src/error-response-generic-passthrough-object-parity.test.ts +++ b/packages/rest/src/error-response-generic-passthrough-object-parity.test.ts @@ -121,8 +121,8 @@ const singleDoor = (error: unknown, object?: string): Wire => mapDataError(error * * ⚠️ "Three siblings" is itself easy to over-read, so the measured limit: §3 * keys on `RECORD_LOCKED`, one of §1's OWN codes, so an arm for that code - * migrates §3 along with §1. Only §2 and commit 6d178a408's §4 are independent of the - * codes below. Commit 6d178a408 §5's "every arm in the SHARED classification has a §1 + * migrates §3 along with §1. Only §2 and the door-parity file's §4 are independent of the + * codes below. The door-parity file's §5 "every arm in the SHARED classification has a §1 * parity case" reddens when an arm ARRIVES, but goes green again as soon as its * author adds the parity case it asks for — it does not hold THIS file's §1 to * the passthrough. @@ -140,7 +140,7 @@ describe('#14725 — the generic declared-status passthrough carries `object` on // The card's own measurement. `DUPLICATE_RECORD` HAS a bespoke arm // keyed on `DuplicateRecordError`'s class/`name`; a bare property // write does not carry it, which is exactly the shape the card - // measured on the commit 6d178a408 branch. + // measured on the branch that landed as commit 6d178a408. { code: 'DUPLICATE_RECORD', status: 409, message: 'A record with this value already exists' }, { code: 'RECORD_LOCKED', status: 409, message: 'This record is frozen' }, // A 4xx from the other end of the band, so the pin is not a diff --git a/packages/rest/src/error-response-sandbox-arm-message.test.ts b/packages/rest/src/error-response-sandbox-arm-message.test.ts index 6621e9b8174..8907d84abc3 100644 --- a/packages/rest/src/error-response-sandbox-arm-message.test.ts +++ b/packages/rest/src/error-response-sandbox-arm-message.test.ts @@ -21,7 +21,7 @@ * * The bulk door is right because #11588 taught `resolveErrorResponse`'s * declared-status passthrough to read `sandboxBusinessMessage`, and because - * Commit 6d178a408 excludes a sandbox-origin error from the shared consult entirely. The + * commit 6d178a408 excludes a sandbox-origin error from the shared consult entirely. The * single door reached the arms and shipped the wrapper — #11588's own defect, * one door over, with the direction reversed rather than closed. * @@ -63,7 +63,7 @@ const HERE = dirname(fileURLToPath(import.meta.url)); /** * The classification's own source, read once: §4-derivation and §6 both scan it - * — one re-derives the arm list from the tree (the commit cf6e0a193 ruling's execution + * — one re-derives the arm list from the tree (the ruling commit cf6e0a193 landed: its execution * constraint), the other guards the sentence rule. Same package, so the read * does not escape it (AGENTS.md → cross-package test inputs). */ @@ -233,7 +233,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out }); /** - * FLIPPED by commit cf6e0a193, deliberately and in that card's PR, from + * FLIPPED by commit cf6e0a193, deliberately and in that commit, from * `ACCEPTED DIVERGENCE` to `CONVERGED` — the same discipline commit 1c7adc73d used * on its own §4 one file over. ⛔ The section is not DELETED: it is the only * thing that would notice the divergence coming back, and what changes is @@ -256,7 +256,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out * * - **the flip**, per arm and by NAME over {@link ARMS} — the list the * ruling required be RE-DERIVED from the tree rather than copied from - * Commit 1c7adc73d, and `§4-derivation` below is the guard that keeps it derived; + * the list commit 1c7adc73d enumerated, and `§4-derivation` below is the guard that keeps it derived; * - **the positive control STAYS** and is still a control: the same crash * carrying NO declared code reaches the same sanitised 500, so a green * flip leg cannot be read as "the terminal swallowed everything"; @@ -337,7 +337,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out /** * The ruling's own execution constraint: *"the seat re-derives the arm - * list from the tree, not from commit 1c7adc73d's list."* Re-deriving once is a + * list from the tree, not from [commit 1c7adc73d]'s list."* Re-deriving once is a * reading that rots; this leg is the same re-derivation asked * mechanically, so the next arm added to the shared classification is * either covered above or excused here BY NAME. diff --git a/packages/rest/src/error-response-structured-arm-door-parity.test.ts b/packages/rest/src/error-response-structured-arm-door-parity.test.ts index abc88da9a68..05eda4db2a3 100644 --- a/packages/rest/src/error-response-structured-arm-door-parity.test.ts +++ b/packages/rest/src/error-response-structured-arm-door-parity.test.ts @@ -460,7 +460,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { // this case pinned so it was visible rather than implied: // `classifyDataError`'s GENERIC declared-status passthrough // appended `object` from the door's argument and - // `resolveErrorResponse`'s did not. That card added the limb, so + // `resolveErrorResponse`'s did not. That commit added the limb, so // the verdict this case is labelled with now holds for the BODY // too, and the pin says so rather than describing a closed gap. expect(single.body).toHaveProperty('object', 'account'); @@ -480,7 +480,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { }); /** - * FLIPPED by commit 1c7adc73d, deliberately and in that card's PR, from + * FLIPPED by commit 1c7adc73d, deliberately and in that commit, from * `ACCEPTED DIVERGENCE` to `CONVERGED (sentence)`. ⛔ The case is not * DELETED: it is the only thing that would notice the divergence coming * back, and what changes is its verdict, not its existence. @@ -597,7 +597,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { err.object = 'account'; const bulk = bulkDoor(err, 'account'); const single = singleDoor(err, 'account'); - // The single door: what commit cf6e0a193 ruled — a crash is a fault. + // The single door: what commit cf6e0a193 decided — a crash is a fault. expect(single.status).toBe(500); expect(single.body.code).toBe('INTERNAL_ERROR'); expect(String(single.body.error)).not.toContain('threw:'); @@ -651,7 +651,7 @@ describe('#14541 · structured arms are consulted by BOTH doors', () => { * the flip moved. An implementation that degraded every SANDBOX-origin * error to the fault terminal would turn both cases above green while * deleting the whole sandbox-refusal surface on the bulk door — - * Commit cf6e0a193's ruling fences exactly that: *"Ordinary declared refusals (a + * the ruling commit cf6e0a193 implemented fences exactly that: *"Ordinary declared refusals (a * hook that throws a business error carrying a code, no crash) are * **untouched** — only the crash branch moves."* * diff --git a/packages/rest/src/error-response.ts b/packages/rest/src/error-response.ts index 3867ee160ef..24839b9bc4c 100644 --- a/packages/rest/src/error-response.ts +++ b/packages/rest/src/error-response.ts @@ -957,7 +957,7 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { * * ## What the `UNIQUE_VIOLATION` answer restores, per driver * - * Corrected under the commit 6d178a408 contract review (condition 7), which measured the + * Corrected under the contract review of commit 6d178a408 (condition 7), which measured the * earlier statement backwards. * * On the **SQL** drivers the bulk doors answered `409 UNIQUE_VIOLATION` with the @@ -977,9 +977,9 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { * * ## One wire spelling on the route — the rows too (commit 65846bc46) * - * The commit 6d178a408 contract review (condition 2) disclosed a fork this file's "one + * The contract review of commit 6d178a408 (condition 2) disclosed a fork this file's "one * condition, one wire code" framing did not cover: the DOORS answered a - * `DuplicateRecordError` as `UNIQUE_VIOLATION` (commit 10220a7bf's ruling, the arm + * `DuplicateRecordError` as `UNIQUE_VIOLATION` (the ruling commit 10220a7bf implemented, the arm * below), while a batch or import ROW did not go through this classification * at all — `metadata-protocol`'s `toRowApiError` put the thrown REGISTERED * code on the row verbatim and `import-runner`'s row report did the same — so @@ -994,7 +994,7 @@ export function isEngineDuplicateRecordEnvelope(error: unknown): boolean { * the same way ({@link isEngineDuplicateRecordEnvelope}: registered code AND * class name, never message text): `toRowApiError` for the rows of * `POST /data/:object/batch`, and `toFailedResult` for the import runner's - * row reports. The single-record door's code did not move (commit 10220a7bf's refusal + * row reports. The single-record door's code did not move (the refusal commit 10220a7bf built * stands), no ledger waiver was added — the duplication is removed, not * declared — and the ENGINE's thrown identity is unchanged: * `DuplicateRecordError.code` is still `DUPLICATE_RECORD` in-process; only @@ -1482,8 +1482,8 @@ function classifyDataError(error: any, object?: string): { status: number; body: // // The `code` rides along on {@link declaresServerFault}, the criterion // `@objectstack/types` already owns for "this producer DECLARED a - // server fault" (`status >= 500` *and* a non-empty string `code`; PR - // Commit 64cd01082, pinned by `error-leak.test.ts`, read by the analytics route + // server fault" (`status >= 500` *and* a non-empty string `code`; + // commit 64cd01082, pinned by `error-leak.test.ts`, read by the analytics route // here and by `runtime`'s dispatcher). Inside this branch its status // half is already true, so what it adds is the `code` half — and it // adds it as a TESTED predicate rather than a fourth open-coded @@ -2113,7 +2113,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // answers, decided by which route caught it — and the one this door gave // put the runner's `TypeError: …` text on the wire at a business status. // - // The ruling that decides it is commit cf6e0a193's, quoted on {@link isSandboxCrash} + // The ruling that decides it is the one commit cf6e0a193 implemented, quoted on {@link isSandboxCrash} // and NOT restated here: *"A declared code is the author's statement about // the failure mode they **handled**. A crash … is not that mode, so it is // classified as a fault"*, against *"an internal stack-shaped sentence at a @@ -2124,7 +2124,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // divergence pin flips with it. // // Answered through {@link mapDataError} rather than by returning - // {@link UNCLASSIFIED_FAULT} here, for the reason the commit 6d178a408 consult below + // {@link UNCLASSIFIED_FAULT} here, for the reason the consult commit 6d178a408 added below // gives: same terminal, same {@link withDeclaredUserMessage} wrapper, // nothing for a future edit to desynchronise. Both doors now read ONE // `isSandboxCrash` gate; ⛔ do not grow a second opinion about a crash in @@ -2138,7 +2138,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // unconditional prose-drop (#5437 / #5582 / #5907) is not narrowed by this: // the terminal withholds prose too, and what moves for that shape is the // status and the declared `code`, both of which shrink to the sanitised - // pair. Commit 6d178a408's guard 1 is about a producer-declared 5xx that is NOT a + // pair. Guard 1 of commit 6d178a408's consult is about a producer-declared 5xx that is NOT a // crash and is untouched — `error-response-structured-arm-door-parity.test.ts` // §4 pins both shapes, side by side. if (isSandboxCrash(error)) return mapDataError(error, object); @@ -2277,7 +2277,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // {@link thrownCodeFields}. This arm's old gate was bare truthiness, so // it also admitted a non-string `code`; that limb is gone with the // narrowing, and the flat arms now ask one question (five of them since - // Commit cad8b42f0 brought the sandbox unwrap door into the vocabulary). + // commit cad8b42f0 brought the sandbox unwrap door into the vocabulary). // [commit 79c46da90] Both passthrough arms ride a producer-declared `userMessage` // onto the body, the same rule as the exported `mapDataError` wrapper — // see {@link withDeclaredUserMessage}. On the 5xx arm the PROSE is @@ -2395,7 +2395,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // the limb {@link classifyDataError}'s generic declared-status // passthrough has always ended on. Without it the two copies of one // passthrough differed by exactly one key, which is the residue - // Commit 6d178a408 left behind: after that card the doors agree for every code + // commit 6d178a408 left behind: after that commit the doors agree for every code // a BESPOKE arm classifies, and disagree for every code that reaches // the GENERIC passthrough. Measured on `main` @ `a12b15e394`, one // error object, both doors: @@ -2407,7 +2407,7 @@ function resolveErrorResponse(error: any, object?: string): { status: number; bo // 409 {"error":"…","code":"DUPLICATE_RECORD"} // // One refusal, two bodies, decided by which route caught it — the - // Commit 6d178a408 shape one arm over. It also closes that card's second + // shape commit 6d178a408 fixed, one arm over. It also closes that commit's second // residue: `recordNotFoundError` (`@objectstack/core`) declares // `code`, `status = 404` AND `object`, so its declared status carries // it past the `RECORD_NOT_FOUND` arm below into THIS passthrough on diff --git a/packages/rest/src/external-datasource-routes-auth-guard.test.ts b/packages/rest/src/external-datasource-routes-auth-guard.test.ts index f8c764dc9f0..34a13ad5e3a 100644 --- a/packages/rest/src/external-datasource-routes-auth-guard.test.ts +++ b/packages/rest/src/external-datasource-routes-auth-guard.test.ts @@ -3,7 +3,7 @@ /** * [#9686] The `/api/v1/datasources/:name/external/*` federation family requires * an authenticated caller — on every route, read and write alike — and - * [#9901/commit 6ce58a735] a CAPABILITY above that on every route. + * [#9901 / commit 6ce58a735] a CAPABILITY above that on every route. * * ## What this pins, and why it is driven through the real plugin * @@ -59,7 +59,7 @@ * [commit 6ce58a735] `POST /external/validate` was the one route the #9901 ruling did * not name: no admin twin, no metadata created, so it kept the #9686 * authentication floor — pinned here as an explicit `capability: null` row so - * that gating it later had to change the table. That later card is commit 6ce58a735, + * that gating it later had to change the table. That later edit is commit 6ce58a735, * ruled 2026-08-20 (verbatim: 「同意你的意见。」, accepting option A): validate * takes the READ capability, because validation drives the same live * remote-schema introspection the read twins gate and reports on it. The row @@ -105,7 +105,7 @@ type Handler = (req: any, res: any) => any; * [commit 6ce58a735] There is no `capability: null` row any more: `POST * /external/validate` carried one — spelled as an explicit `null` rather than * omitted, so that a later edit gating it had to change this table — and the - * 2026-08-20 commit 6ce58a735 ruling is that later edit: validate is a read + * 2026-08-20 ruling, landed as commit 6ce58a735, is that later edit: validate is a read * (validation drives the same live remote introspection the read twins * gate), so its row now carries `READ_CAPABILITY` like its two read siblings. * @@ -483,10 +483,10 @@ describe('[#9901] the family requires a capability above authentication', () => it('[#10255] POST /external/validate requires the READ capability — the authentication-floor era is over', async () => { // This case is the previous pin FLIPPED, deliberately. Until the - // 2026-08-20 commit 6ce58a735 ruling it asserted the exact opposite — an + // 2026-08-20 ruling (commit 6ce58a735) it asserted the exact opposite — an // authenticated caller holding nothing was SERVED here while refused the // other four — because #9901's ruling did not name this route. The ruling - // that changed it is recorded on commit 6ce58a735 (option A): validation drives + // that changed it is recorded in commit 6ce58a735's message (option A): validation drives // the same live remote-schema introspection the read twins gate, so // validate is a read and answers to the read capability. const { table, service } = await bootFederation({ diff --git a/packages/rest/src/external-datasource-routes.ts b/packages/rest/src/external-datasource-routes.ts index 5dda26ab0ed..d0b7a5a8049 100644 --- a/packages/rest/src/external-datasource-routes.ts +++ b/packages/rest/src/external-datasource-routes.ts @@ -142,7 +142,7 @@ export interface ExternalDatasourceRoutesOptions { * [commit 6ce58a735] `validate` has no admin twin to converge with, so #9901 left it on * the #9686 authentication floor and filed the question instead of deciding * it. The follow-up ruling (maintainer, 2026-08-20, verbatim: - * 「同意你的意见。」, accepting option A on commit 6ce58a735) converged it here: what + * 「同意你的意见。」, accepting option A, landed as commit 6ce58a735) converged it here: what * validation does is drive the SAME live remote-schema introspection the * two read twins gate (`introspect` per datasource, in * `service-datasource/src/external-datasource-service.ts`), and its report — @@ -225,7 +225,7 @@ export function registerExternalDatasourceRoutes( * `503` which services a deployment has wired, and — for the two routes that * write — so the refusal provably precedes the write rather than following it. * - * ## [#9901/commit 6ce58a735] …and a CAPABILITY above it, on every route + * ## [#9901 / commit 6ce58a735] …and a CAPABILITY above it, on every route * * #9686 left this family gated on authentication alone and pointed the * capability question at #9593, which answered it for the admin half only. @@ -277,7 +277,7 @@ export function registerExternalDatasourceRoutes( * twin on the admin spelling, no metadata created — kept the #9686 * authentication floor under its own explicit kind: an un-ruled route * silently inheriting a neighbour's gate would have read as ruled. The - * question was filed as commit 6ce58a735 and ruled on 2026-08-20: validate takes the + * question was ruled on 2026-08-20 and landed as commit 6ce58a735: validate takes the * READ capability (see {@link FEDERATION_READ_CAPABILITY}'s note for why it * is a read). With every route now ruled, the `'authenticated'` kind would * be a door no route walks through, so it is REMOVED rather than kept — a @@ -362,7 +362,7 @@ export function registerExternalDatasourceRoutes( * * A wired service with no scoped spelling could be served by falling back to * `validateAll()` and post-filtering — which is precisely the behaviour - * Commit e634ecf6a removed. A silent fallback would leave the fan-out reachable, on a + * commit e634ecf6a removed. A silent fallback would leave the fan-out reachable, on a * path no test drives, for exactly the deployments nobody is looking at. So * absence takes the same 503 arm every other route here takes when the * service cannot serve it: loud, and already the declared shape of "this diff --git a/packages/rest/src/http-request-test-builder.ts b/packages/rest/src/http-request-test-builder.ts index eef38a9a62c..800fa2152a3 100644 --- a/packages/rest/src/http-request-test-builder.ts +++ b/packages/rest/src/http-request-test-builder.ts @@ -32,7 +32,7 @@ * ## Why each default is the default * * **`method` and `path` are NOT defaulted — they are read off the route under - * test.** A constant default here is precisely the hazard commit e10cf3444 names: a + * test.** A constant default here is precisely the hazard commit e10cf3444 was written to remove: a * `path` that does not match the route under test makes a passing test measure * something other than what it names, and `req.path` is live rather than * decorative — `RestServer.enforceAuth` feeds it to `isAuthGateAllowlisted` diff --git a/packages/rest/src/import-job-integration.test.ts b/packages/rest/src/import-job-integration.test.ts index 89b4f850a87..51f09867bc7 100644 --- a/packages/rest/src/import-job-integration.test.ts +++ b/packages/rest/src/import-job-integration.test.ts @@ -25,7 +25,7 @@ import { ObjectQL } from '@objectstack/objectql'; import { SqlDriver } from '@objectstack/driver-sql'; import { ObjectStackProtocolImplementation } from '@objectstack/metadata-protocol'; import { SysImportJob } from '@objectstack/platform-objects/audit'; -// Commit a92b1793c: the ONE definition of the async-import row ceiling. The pin below reads it +// [commit a92b1793c] The ONE definition of the async-import row ceiling. The pin below reads it // from here so that moving it is observable at the enforcement point. import { IMPORT_JOB_MAX_ROWS } from '@objectstack/spec/api'; import { RestServer } from './rest-server'; @@ -175,7 +175,7 @@ describe('async import job — real engine + protocol integration', () => { expect(results._json.results.find((r: any) => !r.ok)).toMatchObject({ field: 'score', code: 'invalid_number' }); }); - // Commit a92b1793c: the ceiling has ONE definition — the spec export — and rest is its only + // [commit a92b1793c] The ceiling has ONE definition — the spec export — and rest is its only // enforcer. So this case derives everything it knows about the ceiling from that // export: how big a payload must be to breach it, and the number the 413 copy is // required to name. Re-spelling 50_000 here would just move the duplicated literal diff --git a/packages/rest/src/import-run-automations-agreement.test.ts b/packages/rest/src/import-run-automations-agreement.test.ts index 9a3135046ec..814cb60d2ae 100644 --- a/packages/rest/src/import-run-automations-agreement.test.ts +++ b/packages/rest/src/import-run-automations-agreement.test.ts @@ -86,7 +86,7 @@ describe('runAutomations — declared default agrees with the server (#6704)', ( } it('validating before sending cannot change the outcome', async () => { - // The concrete harm commit c3f491626 names: a client that parses its request through + // The concrete harm commit c3f491626 removed: a client that parses its request through // the published schema and sends the PARSED object used to get the opposite // behaviour from one that sent the same body unvalidated. Drive both paths // through the server and require one answer. diff --git a/packages/rest/src/import-runner-unique-violation-row.test.ts b/packages/rest/src/import-runner-unique-violation-row.test.ts index adefb715ed2..6ca4a331ca6 100644 --- a/packages/rest/src/import-runner-unique-violation-row.test.ts +++ b/packages/rest/src/import-runner-unique-violation-row.test.ts @@ -163,7 +163,7 @@ describe('[#14723] §3 — the row and the whole-request door agree on the spell describe('[#14723] [GUARD] what the mapping must NOT do', () => { it('a producer that merely SPEAKS `DUPLICATE_RECORD` is not the engine\'s envelope and keeps its own code', async () => { - // The same discrimination the whole-request arm makes (commit 10220a7bf §5): the + // The same discrimination the whole-request arm makes (commit 10220a7bf, `rest-duplicate-record-arm.test.ts` §5): the // gate is the registered code AND the class name. const hookRefusal = Object.assign(new Error('already there, says the hook'), { code: 'DUPLICATE_RECORD', status: 409 }); const p = protocolWith({ createData: vi.fn(async () => { throw hookRefusal; }) }); diff --git a/packages/rest/src/import-runner.ts b/packages/rest/src/import-runner.ts index 96383a2b244..4081e9010ac 100644 --- a/packages/rest/src/import-runner.ts +++ b/packages/rest/src/import-runner.ts @@ -332,7 +332,7 @@ export function sanitizeRowError(raw: unknown): string { * `cause`), and this report used to relay that code verbatim — while the * WHOLE-REQUEST failure on the very same `POST /data/:object/import` answered * `UNIQUE_VIOLATION` through `mapDataError`. Maintainer ruling (2026-09-03, - * Commit 65846bc46): one wire spelling on every route. So the engine's envelope is mapped + * commit 65846bc46): one wire spelling on every route. So the engine's envelope is mapped * to `UNIQUE_VIOLATION` here, by the same predicate the whole-request arm uses * ({@link isEngineDuplicateRecordEnvelope}: registered code AND class name), * before the producer's own code is read. A field-level finding still wins diff --git a/packages/rest/src/meta-501-envelope.test.ts b/packages/rest/src/meta-501-envelope.test.ts index b32369a7cca..bb603fe27a5 100644 --- a/packages/rest/src/meta-501-envelope.test.ts +++ b/packages/rest/src/meta-501-envelope.test.ts @@ -20,7 +20,7 @@ * sampled one of the twins, not both. * * ⚠️ [commit 7986d973f] The compound `PUT /meta/:type/:section/:name` in that table is - * RETIRED (commit 7986d973f stage 3). The row is kept because it is the historical + * RETIRED (stage 3, commit 7986d973f). The row is kept because it is the historical * measurement this file exists to explain; the case that drove it is replaced * by a pin that the arity stays unmounted, so a re-mount cannot quietly * reintroduce a fourth envelope dialect. diff --git a/packages/rest/src/meta-compound-save-force-parity.test.ts b/packages/rest/src/meta-compound-save-force-parity.test.ts index 00e119c21ef..e5b4ddaad10 100644 --- a/packages/rest/src/meta-compound-save-force-parity.test.ts +++ b/packages/rest/src/meta-compound-save-force-parity.test.ts @@ -16,7 +16,7 @@ * do, got the identical refusal back, with nothing saying the parameter had * been ignored. #11095 closed it by threading the parameter. * - * Commit 7986d973f's maintainer ruling (2026-08-25) then retired compound metadata item + * The maintainer ruling of 2026-08-25 (completed by commit 7986d973f) then retired compound metadata item * names outright. Stage 1 (commit 311433f6b) declared the item-name grammar and refuses * every slash-bearing name at the publish door — BEFORE the destructive gate * this file was written about — and stage 3 (commit 7986d973f) un-mounts the arity. diff --git a/packages/rest/src/meta-compound-save-mode-parity.test.ts b/packages/rest/src/meta-compound-save-mode-parity.test.ts index bcf3e82b241..0c9b0f7ffa1 100644 --- a/packages/rest/src/meta-compound-save-mode-parity.test.ts +++ b/packages/rest/src/meta-compound-save-mode-parity.test.ts @@ -23,7 +23,7 @@ * The caller asked for a staging buffer and got a publish, with a `200` and no * signal at the call site. * - * Commit 7986d973f's maintainer ruling (2026-08-25) retired compound metadata item names + * The maintainer ruling of 2026-08-25 (completed by commit 7986d973f) retired compound metadata item names * outright. Stage 1 (commit 311433f6b) declared the item-name grammar and refuses every * slash-bearing name at the publish door; stage 3 (commit 7986d973f) un-mounts the arity. * So the divergence is not fixed — the door it needed is GONE. diff --git a/packages/rest/src/meta-object-fls.test.ts b/packages/rest/src/meta-object-fls.test.ts index e2290c2b8e2..dc259863994 100644 --- a/packages/rest/src/meta-object-fls.test.ts +++ b/packages/rest/src/meta-object-fls.test.ts @@ -164,7 +164,7 @@ const EXITS: ObjectSchemaMaskExit[] = [ { name: 'GET /meta/objects/:name?state=draft — uncached branch via the canonical PLURAL spelling', run: (testCase) => { - // #3984/commit 83a3b1f2e: the plural spelling is canonical, and a gate keyed on + // #3984 / commit 83a3b1f2e: the plural spelling is canonical, and a gate keyed on // the raw `:type` param is a gate it walks past. Driving one row of // the table through it keeps that from being re-learned. const { rest } = boot({ testCase, cached: true }); diff --git a/packages/rest/src/meta-plural-i18n.test.ts b/packages/rest/src/meta-plural-i18n.test.ts index 436340d2caa..300ade7fbf8 100644 --- a/packages/rest/src/meta-plural-i18n.test.ts +++ b/packages/rest/src/meta-plural-i18n.test.ts @@ -334,12 +334,12 @@ describe('#6349 §3 — the compound-name arity no longer exists', () => { /** * This section drove `GET /meta/:type/:section/:name` and asserted the * plural type spelling translated identically to the singular there. The - * arity is retired (commit 7986d973f stage 3), so the translation surface it covered + * arity is retired (stage 3, commit 7986d973f), so the translation surface it covered * is served by §2's single-item read — which folds the type through the * same `canonicalMetaUrlType` and runs the same translator. * * What is left to pin is the absence, so a re-mounted compound arity cannot - * quietly reappear WITHOUT the plural fold (the commit 2443bb4c4 defect: one spelling + * quietly reappear WITHOUT the plural fold (the defect commit 2443bb4c4 fixed: one spelling * translated, the other not). */ it('mounts no compound `:section` arity to translate', () => { diff --git a/packages/rest/src/meta-publish-package-scope.test.ts b/packages/rest/src/meta-publish-package-scope.test.ts index 76039a1f054..1ba75e6059f 100644 --- a/packages/rest/src/meta-publish-package-scope.test.ts +++ b/packages/rest/src/meta-publish-package-scope.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// Commit 9e04c3e35 — the draft→active promotion door could not state the package its +// Before commit 9e04c3e35 the draft→active promotion door could not state the package its // write belongs to, so #9612's package-closure narrowing never fired for the // one door that needed it most. // diff --git a/packages/rest/src/meta-state-route-engine-outage.test.ts b/packages/rest/src/meta-state-route-engine-outage.test.ts index 77e3921623a..c3f22d15515 100644 --- a/packages/rest/src/meta-state-route-engine-outage.test.ts +++ b/packages/rest/src/meta-state-route-engine-outage.test.ts @@ -73,7 +73,7 @@ * | no provider wired at all | 404 NOT_FOUND ⭐ PIN | * | provider RESOLVES `undefined` (absence) | 404 NOT_FOUND ⭐ PIN | * | provider REJECTS (wired, failed to build) | 503 SERVICE_UNAVAILABLE ⭐ | - * | provider THROWS SYNCHRONOUSLY (commit add6a1b1c) | 503 SERVICE_UNAVAILABLE | + * | provider THROWS SYNCHRONOUSLY (commit add6a1b1c) | 503 SERVICE_UNAVAILABLE | * * ⭐ The NEGATIVE CONTROL (§3) is the half that keeps this a restoration rather * than a behaviour change: on a HEALTHY engine, an object that genuinely does diff --git a/packages/rest/src/objectql-slot-consumer-census.test.ts b/packages/rest/src/objectql-slot-consumer-census.test.ts index 632e412626f..e351c615d17 100644 --- a/packages/rest/src/objectql-slot-consumer-census.test.ts +++ b/packages/rest/src/objectql-slot-consumer-census.test.ts @@ -40,7 +40,7 @@ * | no provider wired at all | 501 NOT_IMPLEMENTED | 501 — unchanged | * | provider RESOLVES `undefined` (absence) | 501 NOT_IMPLEMENTED | 501 — unchanged | * | provider REJECTS (wired, failed to build) | **500 INTERNAL_ERROR** | **503 SERVICE_UNAVAILABLE** | - * | provider THROWS SYNCHRONOUSLY (commit add6a1b1c) | **500 INTERNAL_ERROR** | **503 SERVICE_UNAVAILABLE** | + * | provider THROWS SYNCHRONOUSLY (commit add6a1b1c) | **500 INTERNAL_ERROR** | **503 SERVICE_UNAVAILABLE** | * * ⇒ this consumer never re-collapsed: a rejection and a resolved `undefined` * always reached two different answers, which is the whole of the decidable diff --git a/packages/rest/src/package-door-execctx-fault-reachability.test.ts b/packages/rest/src/package-door-execctx-fault-reachability.test.ts index c26b027f137..021c1fc7b45 100644 --- a/packages/rest/src/package-door-execctx-fault-reachability.test.ts +++ b/packages/rest/src/package-door-execctx-fault-reachability.test.ts @@ -92,9 +92,9 @@ * * ## What this file does, and no longer does not (commit 6a180e42d) * - * As written for commit 43028a8f8 this file repaired nothing and asserted no verdict — + * As first written (commit 43028a8f8) this file repaired nothing and asserted no verdict — * distinguishing "no context" from "resolution failed" was a behaviour change - * on a public door and out of that card's scope. Commit 6a180e42d RULED that change for + * on a public door and out of that measurement's scope. Commit 6a180e42d landed that ruled change for * the permission-store half, so the assertions covering it are now regression * pins on the repaired behaviour rather than measurements of a defect. * @@ -541,7 +541,7 @@ describe('[#13255] consequence — the door\'s answer for each fault class', () // > see it. // // That class is now in the `loud` cohort above. What remains `quiet` is the - // CONTEXT-LOST family (commit 43028a8f8), still unruled and still measured, never + // CONTEXT-LOST family (first measured by commit 43028a8f8), still unruled and still measured, never // asserted away — so this half keeps its original reading and this test // stays a regression pin rather than a rubber stamp. expect(quiet.filter((s) => s >= 500)).toEqual([]); @@ -761,7 +761,7 @@ describe('[#13255] no degraded class is ever served as anonymous ACCESS or as a // 7. ⭐ [commit add6a1b1c] SEAM AGREEMENT — the same provider seam, the same fault, and // now the SAME answer whichever way the provider fails. // -// ⭐ INVERTED IN PLACE, not re-baselined. As written for commit 43028a8f8 this section +// ⭐ INVERTED IN PLACE, not re-baselined. As first written in commit 43028a8f8 this section // RECORDED a divergence and asserted it, under the heading "sync-throw and // rejection do not agree": // @@ -816,7 +816,7 @@ describe('[#13280] at a post-identity provider seam, sync-throw and rejection AG // // "Reaches an EMPTY grant set" was the defect: a WIRED engine that failed // is not an empty grant set, it is an UNDETERMINED one. Both shapes are now - // the outage they are. ⚠️ commit add6a1b1c's property is untouched and is what this + // the outage they are. ⚠️ The property commit add6a1b1c established is untouched and is what this // test still exists for — the two shapes AGREE; only the value they agree // on moved, and it moved for both together. const { rejecting, syncThrowing } = await bothShapes('objectQLProvider'); diff --git a/packages/rest/src/rest-approvals-wire-codes.test.ts b/packages/rest/src/rest-approvals-wire-codes.test.ts index d5e5c493dc4..b43a6d350a1 100644 --- a/packages/rest/src/rest-approvals-wire-codes.test.ts +++ b/packages/rest/src/rest-approvals-wire-codes.test.ts @@ -4,7 +4,7 @@ * [commit 30b1c636a] The approvals routes' wire codes are REGISTERED vocabulary — pins * for the population the card's sweep found. * - * The commit 30b1c636a sweep measured 9 codes reaching the wire from `packages/rest` that + * The sweep behind commit 30b1c636a measured 9 codes reaching the wire from `packages/rest` that * were in neither `StandardErrorCode` nor `ERROR_CODE_LEDGER`, all in one * family and all with the same cause: the approvals route factories spell the * terminal 500 catch's code as a TEMPLATE @@ -29,7 +29,7 @@ * (single-occurrence `.replace('-', '_')` included), so a route name the * template would mangle into an invalid code also fails here. * [#14573] The file has since become the home for the approvals door's - * live-emission pins generally, not only the commit 30b1c636a population: the + * live-emission pins generally, not only the population commit 30b1c636a registered: the * `FORBIDDEN` → 403 case below pins a row that is registered vocabulary and * whose emission was — contrary to that card's premise — already observed * elsewhere. See its own comment for where, and why it is pinned here too. @@ -237,7 +237,7 @@ describe('approvals wire codes are registered vocabulary (#8885)', () => { // the three reds the #14573 correction measured, two of them in a file // whose declared subject is a DIFFERENT contract — precisely the pin a // file-scoped grep cannot see. Same instrument, zero reds for the six ⇒ - // they were genuinely uncovered, not covered somewhere unobvious. Commit 226e72443 + // they were genuinely uncovered, not covered somewhere unobvious. The card behind commit 226e72443 // predicted at least one of the six would turn out already pinned; it did // not, and that prediction is now answered by measurement rather than // carried forward as a caveat. diff --git a/packages/rest/src/rest-field-visibility-fault-envelope.test.ts b/packages/rest/src/rest-field-visibility-fault-envelope.test.ts index e33a330d6a3..8c6dcd8a811 100644 --- a/packages/rest/src/rest-field-visibility-fault-envelope.test.ts +++ b/packages/rest/src/rest-field-visibility-fault-envelope.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [commit 30b1c636a] ADR-0112 pins for the two wire codes the card measured, on the REST + * [commit 30b1c636a] ADR-0112 pins for the two wire codes the sweep measured, on the REST * emitters themselves. * * ## 1. `sendFieldVisibilityFault` — the ADR-0106 D6 tier-3 refusal @@ -24,7 +24,7 @@ * * ## 2. `mapDataError`'s comment-access branch — `RECORD_NOT_ACCESSIBLE` * - * Commit 30b1c636a's table claimed this code is in NEITHER `StandardErrorCode` nor the + * The sweep table behind commit 30b1c636a claimed this code is in NEITHER `StandardErrorCode` nor the * ledger. That row was a measurement error: `RECORD_NOT_ACCESSIBLE` has been a * `StandardErrorCode` member (Authorization block, "Sharing rule restriction") * since before the card's own measured commit — the #4630 branch comment diff --git a/packages/rest/src/rest-hook-refusal-message-parity.test.ts b/packages/rest/src/rest-hook-refusal-message-parity.test.ts index 0b738841b6b..d6053d91075 100644 --- a/packages/rest/src/rest-hook-refusal-message-parity.test.ts +++ b/packages/rest/src/rest-hook-refusal-message-parity.test.ts @@ -482,7 +482,7 @@ describe('[#11588] #5437/#5582 and #5423 are exactly where they were', () => { // door while `mapDataError` sanitised the same error to a `500`. #11588 stated // why it stopped there — "making the two agree means moving the STATUS the // passthrough decided, which is a contract question and not this card's" — and -// Commit cf6e0a193 widened the population without being able to take that question +// commit cf6e0a193 widened the population without being able to take that question // either, recording it a second time as an ACCEPTED DIVERGENCE one file over // (`error-response-structured-arm-door-parity.test.ts` §4). // @@ -512,7 +512,7 @@ describe('[#11588 → #17273] the crash-with-a-declared-4xx divergence, now CLOS expect(viaRoute.body.error).toBe(INTERNAL_ERROR_MESSAGE); expect(String(viaRoute.body.error)).not.toContain('threw:'); - // The `/data` door, unmoved since #7543/commit cf6e0a193 — the control that says + // The `/data` door, unmoved since #7543 / commit cf6e0a193 — the control that says // the flip above is the route door meeting it, not both doors sliding. const viaData = mapDataError(withCrash()); expect(viaData.status).toBe(500); @@ -523,7 +523,7 @@ describe('[#11588 → #17273] the crash-with-a-declared-4xx divergence, now CLOS it('#17273 negative control: the same declared 4xx WITHOUT a crash keeps the passthrough, both status and sentence', () => { // One `innerMessage` apart from the case above. A refusal is not a - // crash, and commit cf6e0a193's ruling fences it explicitly — if this goes green + // crash, and the ruling commit cf6e0a193 implemented fences it explicitly — if this goes green // by answering 500, the fix above deleted the refusal surface instead // of moving the crash. const refusal = throughRouteDoor(sandboxRefusal('x', { status: 409 })); diff --git a/packages/rest/src/rest-hook-script-fault-envelope.test.ts b/packages/rest/src/rest-hook-script-fault-envelope.test.ts index fc42178d4b3..5777f0fcfc6 100644 --- a/packages/rest/src/rest-hook-script-fault-envelope.test.ts +++ b/packages/rest/src/rest-hook-script-fault-envelope.test.ts @@ -328,7 +328,7 @@ describe('[#7543] a hook that deliberately refuses still speaks in its own words // [commit cad8b42f0] Re-read, not rewritten to fit. This assertion always tested a // producer that declares NO code, so it pins ADR-0112's "nothing is // invented for a half-declaration" and is green on both sides of that - // card. What it never tested — and what the comment here used to claim + // fix. What it never tested — and what the comment here used to claim // — is that the door withholds a code the producer DID declare; that // claim was the defect, and its "older clients prepend the code to the // message" rationale is retired (see `error-response.ts`). diff --git a/packages/rest/src/rest-route-ledger.ts b/packages/rest/src/rest-route-ledger.ts index aaed1b45665..815b8f845bc 100644 --- a/packages/rest/src/rest-route-ledger.ts +++ b/packages/rest/src/rest-route-ledger.ts @@ -280,7 +280,7 @@ export const REST_ROUTE_LEDGER: readonly RestRouteLedgerEntry[] = [ // // [commit 7986d973f] The ordering constraint this note used to carry is DISCHARGED, // not merely unstated: the compound `/:type/:section/:name` arities are - // retired (stage 3 of commit 7986d973f), and they were the three-segment catch-all + // retired (stage 3, commit 7986d973f), and they were the three-segment catch-all // that every literal three-segment sibling had to be registered above. The // four-segment `/state/:field` collision with the compound `/published` // twin is gone with it. `meta-route-registration-order.test.ts` still pins diff --git a/packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts b/packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts index 626e2f612b8..7918d648f35 100644 --- a/packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts +++ b/packages/rest/src/rest-server-meta-org-scope-url-spelling.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// Commit 26f3588fb — the `/meta` doors decided ORGANIZATION SCOPE from the RAW url +// Before commit 26f3588fb the `/meta` doors decided ORGANIZATION SCOPE from the RAW url // spelling while storage folded it through the COMPLETE map. // // ── What was broken ─────────────────────────────────────────────────────── @@ -47,7 +47,7 @@ import { RestServer } from './rest-server.js'; const META = '/api/v1/meta'; const ORG = 'org_alpha'; -// The two measured members of the disagreement set (commit 26f3588fb's table, +// The two measured members of the disagreement set (both named in commit 26f3588fb, // re-derived at head by execution): URL-only spellings of // `allowOrgOverride: true` types, invisible to the manifest map. const MEMBERS = [ @@ -256,7 +256,7 @@ describe('#10340 the /meta doors decide org scope on the FOLDED type, not the ra }); it('⛔ leaves GET /meta/_drafts unfolded — it matches the draft row STORED type, by design', async () => { - // Deliberately NOT a site (commit 26f3588fb records why): stored types are + // Deliberately NOT a site (commit 26f3588fb keeps it unfolded by design): stored types are // canonical because the protocol folds on save, so `?type=` is a // filter against stored rows, not a URL segment. Folding it would // be a behaviour change, not a repair. diff --git a/packages/rest/src/rest-server-meta-read-org-scope.test.ts b/packages/rest/src/rest-server-meta-read-org-scope.test.ts index 9aeeb44d468..99e37c48cb0 100644 --- a/packages/rest/src/rest-server-meta-read-org-scope.test.ts +++ b/packages/rest/src/rest-server-meta-read-org-scope.test.ts @@ -634,7 +634,7 @@ describe('#13764 the history seams of this harness honour the org partition', () // // ⇒ What this file DOES still discriminate is the organization being DROPPED: // remove the `organizationId` the `?type=` arm passes and the six repair cases -// above turn red (measured at commit abf9101f1: 6 failed / 24 passed). Read the two apart before +// above turn red (measured by commit abf9101f1: 6 failed / 24 passed). Read the two apart before // citing this file as a pin on the door-side predicate — it pins that the arm // still FOLDS, never that the fold happens at the door. diff --git a/packages/rest/src/rest-server.ts b/packages/rest/src/rest-server.ts index 0c24cba66c5..d2b761d1b0b 100644 --- a/packages/rest/src/rest-server.ts +++ b/packages/rest/src/rest-server.ts @@ -236,7 +236,7 @@ export type RestProtocol = DataProtocol & MetadataProtocol; * * `environmentId` is the multi-kernel routing key, and it is OUT of the * protocol request shape **by explicit maintainer decision** (ruling recorded - * 2026-08-18 on commit 2a29caa53): `resolveProtocol(environmentId)` selects the target + * 2026-08-18, landed as commit 2a29caa53): `resolveProtocol(environmentId)` selects the target * kernel *before* the protocol call, and the implementation's parameter types * (`@objectstack/metadata-protocol`) never read it off the request — the spec * schemas (`protocol.zod.ts`) record the same exclusion schema-side. The doors @@ -905,7 +905,7 @@ function importJobUndoable(row: any): boolean { * Ruled **B** by the maintainer (2026-09-02): every copy of this spelling * guards on `Number.isNaN(value.getTime())`, all five arms in ONE change, * because a guard on some arms and not others re-opens the drift the single - * spelling closed. Reachability is MEASURED, not assumed (commit 3ecb7dc1a, landed + * spelling closed. Reachability is MEASURED, not assumed (landed as commit * `3ecb7dc1a`): mysql2 3.23.1 returns a module constant literally named * `INVALID_DATE` for a zero `DATETIME`, and postgres-date 1.0.7 builds * `new Date(NaN)` for every year in 275760..294276 — years Postgres itself @@ -1169,7 +1169,7 @@ type NormalizedRestServerConfig = { * [commit b3a63d32c] Every key of `RouteGenerationConfigSchema` is a `retiredKey()` * tombstone (ADR-0049 enforce-or-remove — nothing here ever read * `includeObjects` / `excludeObjects` / `nameTransform` / `overrides`; the - * Commit a3d5724c8 census). The sub-object is still PARSED, so an authored key is + * liveness census recorded in commit a3d5724c8). The sub-object is still PARSED, so an authored key is * refused at construction with its prescription rather than stripped, but * nothing is threaded: per-object exposure is the object's own * `enable.apiEnabled` / `enable.apiMethods`, enforced by `enforceApiAccess`. @@ -1371,7 +1371,7 @@ export interface MountedRoute extends RouteEntry { * post-identity fault SHOULD discard identity; that is a behaviour change on a * public door and is deliberately left unruled here. * - * ⚠️ Absorbing here cannot weaken the commit 6a180e42d loud path, but the reason is + * ⚠️ Absorbing here cannot weaken the loud path commit 6a180e42d built, but the reason is * no longer "one construction site" — [#13476] added a SECOND one, at the * data-engine seam below ({@link wiredEngineOrLoud}). The invariant that * matters is narrower and is what this helper actually needs: no branded @@ -1423,7 +1423,7 @@ async function seamOrUndefined(call: () => T | PromiseLike): Promise `/api/v1`. The runtime version // is answered by `{basePath}/discovery` and `/health`, derived - // from `OS_RUNTIME_VERSION` (#10993/commit 376c70f98/#11292). OpenAPI + // from `OS_RUNTIME_VERSION` (#10993, commit 376c70f98, #11292). OpenAPI // 3.1 defines this field as "the version of the OpenAPI // document (which is distinct from the OpenAPI Specification // version or the API implementation version)" — the document @@ -5292,7 +5292,7 @@ export class RestServer { * under a switch is a decision, not a tidy-up. * * [commit 7986d973f] The compound-name twins spelled `/:type/:section/:name` used to - * close that list. They are RETIRED (stage 3 of commit 7986d973f): every item is + * close that list. They are RETIRED (stage 3, commit 7986d973f): every item is * addressed through the single-segment `/:type/:name`, with the name * percent-encoded by the caller. * @@ -6226,7 +6226,7 @@ export class RestServer { // // #3984 ruled this shape for exactly that reason ("每个 // handler 顶部归一一次,后续所有闸门都用归一后的值"), and - // Commit 83a3b1f2e is why the ruling is written into the code + // commit 83a3b1f2e is why the ruling is written into the code // rather than trusted to memory: eight days after // #3984 landed, the cache-branch condition below still // excluded `doc`/`book` by LITERAL comparison, so @@ -7310,7 +7310,7 @@ export class RestServer { // reset door above, NOT as a plain `HistoryMetaItemRequest` // like the audit door below: this door still spreads the // transport-level `environmentId` (long-standing wire - // shape, deliberately unchanged — the commit 2a29caa53 ruling keeps + // shape, deliberately unchanged — the ruling commit 2a29caa53 landed keeps // it out of the protocol schema, and the implementation // never reads it), so the wrapper is what layers that one // member on. Every OTHER key is compiled against the spec @@ -8231,7 +8231,7 @@ export class RestServer { // after publish, identical for a name that does not exist: a route // that structurally could not 404. // - // ONE arity since commit 7986d973f (stage 3 of commit 7986d973f's maintainer-ruled + // ONE arity since commit 7986d973f (stage 3 of the maintainer-ruled // retirement of compound-name addressing, 2026-08-25). This route used // to be mounted twice — the second registration was // `/:type/:section/:name/published`, folding `section` and `name` back @@ -8326,7 +8326,7 @@ export class RestServer { // read. [commit e1d4f9e3f] The CALLEE gates: `getMetaItemLayered` // resolves `organizationIdForMetaRead` AFTER its canonical // fold, so the tenant goes over RAW. ⛔ Pre-gating HERE, on - // the unfolded `:type`, would be the commit 26f3588fb defect. ⛔ And + // the unfolded `:type`, would be the defect commit 26f3588fb fixed. ⛔ And // the old "fail-open in the safe direction" reading is the // argument the predicate refutes: an org named on a type // the registry does not declare overridable resurrects the @@ -8488,7 +8488,7 @@ export class RestServer { // ── RETIRED: the compound `/:type/:section/:name` arities ────────── // // `GET` and `PUT /meta/:type/:section/:name` were mounted here until - // Commit 7986d973f (stage 3 of commit 7986d973f's maintainer-ruled retirement of + // commit 7986d973f (stage 3 of the maintainer-ruled retirement of // compound-name addressing, 2026-08-25). Both folded `section` and // `name` back into one slash-bearing key (`views/all_leads`) that the // protocol layer then treated as a single opaque string — the section diff --git a/packages/rest/src/rest-share-user-message-bypass-exits.test.ts b/packages/rest/src/rest-share-user-message-bypass-exits.test.ts index af53507efdc..85bda275df4 100644 --- a/packages/rest/src/rest-share-user-message-bypass-exits.test.ts +++ b/packages/rest/src/rest-share-user-message-bypass-exits.test.ts @@ -45,7 +45,7 @@ * * ⭐ The second row is the card's OPEN question, measured rather than assumed: * the prefix exit had no precedent of its own (the fault terminal has one — - * Commit 79c46da90 deliberately rides the mark onto fault terminals). The measurement + * commit 79c46da90 deliberately rides the mark onto fault terminals). The measurement * answers it. `/data` carries the mark for that identical throw, on all five * prefixes (§3), so the two doors disagree and the exit is in. Had `/data` * omitted it there, the two doors would have AGREED and there would have been diff --git a/packages/rest/src/rest-sub-config-parse-not-cast.test.ts b/packages/rest/src/rest-sub-config-parse-not-cast.test.ts index a606900a69b..6f5fbad715b 100644 --- a/packages/rest/src/rest-sub-config-parse-not-cast.test.ts +++ b/packages/rest/src/rest-sub-config-parse-not-cast.test.ts @@ -40,12 +40,12 @@ * `normalizeConfig` reads is declared by the sub-object's schema (measured * key by key; the diff is empty for all four), so the PARSED output is what * the normalized config is built from and the schema's own defaults are the - * defaults. `api` held #11637's validate-only posture until [commit 53cbad9f7] measured + * defaults. `api` held #11637's validate-only posture until commit 53cbad9f7 measured * its key diff empty too and folded its `??` chain onto the parse; it keeps * the `.omit()`ed `requireAuth` tombstone, and is not this file's subject. * * [commit b3a63d32c] Ten of the keys these pins originally exercised were RETIRED under - * ADR-0049 enforce-or-remove (the commit a3d5724c8 liveness census found them normalized + * ADR-0049 enforce-or-remove (the liveness census recorded in commit a3d5724c8 found them normalized * and never read): `crud.patterns` / `objectParamStyle`, `metadata.cacheTtl` / * `endpoints.schema`, `batch.operations.upsertMany` / `defaultAtomic`, and all * of `routes.*`. Each is now a `retiredKey()` tombstone, so the pins below that diff --git a/packages/rest/src/ui-view-route-identity.measurement.test.ts b/packages/rest/src/ui-view-route-identity.measurement.test.ts index e50b1cf02c2..bf2e2335232 100644 --- a/packages/rest/src/ui-view-route-identity.measurement.test.ts +++ b/packages/rest/src/ui-view-route-identity.measurement.test.ts @@ -30,7 +30,7 @@ * 1. §1-§2 — the seam, reproduced INDEPENDENTLY of commit 4801296e7 (its own harness, * its own instrument), plus the exact argument object the seam hands the * producer. - * 2. §3-§4 — ⭐ the half commit 889ec5b42 marks UNMEASURED: does `getUiView` apply + * 2. §3-§4 — ⭐ the half left UNMEASURED until commit 889ec5b42: does `getUiView` apply * authorization of its own? Driven against the REAL * `ObjectStackProtocolImplementation`, not read off a grep. * 3. §5 — `isAuthGateAllowlisted` does not name a `/ui` path, verified by @@ -85,7 +85,7 @@ type Handler = (req: any, res: any) => any; // --------------------------------------------------------------------------- // Harness — same shape as `execctx-consumer-census.test.ts`, rebuilt here so -// this file's readings do not inherit that file's fixtures (commit 889ec5b42 asks for an +// this file's readings do not inherit that file's fixtures (commit 889ec5b42 is an // INDEPENDENT reproduction, not a citation). // --------------------------------------------------------------------------- @@ -371,7 +371,7 @@ describe('[#13214] §2 the argument object — the producer cannot gate on what }); // --------------------------------------------------------------------------- -// 3. ⭐ The question commit 889ec5b42 marks UNMEASURED — does the producer gate? +// 3. ⭐ The question left UNMEASURED until commit 889ec5b42 — does the producer gate? // --------------------------------------------------------------------------- describe('[#13214] §3 downstream — the REAL `getUiView`, driven', () => { @@ -401,7 +401,7 @@ describe('[#13214] §3 downstream — the REAL `getUiView`, driven', () => { }, 120_000); it('the producer applies NO authorization of its own — called directly, an identity in the argument changes nothing', async () => { - // ⚠️ This is commit 889ec5b42's originally-UNMEASURED half and the answer has not + // ⚠️ This is the originally-UNMEASURED half commit 889ec5b42 measured, and the answer has not // changed: the repair is at the seam, and the producer still gates // nothing. Measured where it can still be measured — §2 and §4 supply // the other half (the seam tells it nothing, and the instance is not