From 5a2f8b46e2d4d9b9a1ecb8729839c55a70370794 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <50353452+hotlong@users.noreply.github.com> Date: Tue, 29 Sep 2026 16:33:01 +0800 Subject: [PATCH 1/3] docs(runtime): re-anchor dead tracker citations to their deciding commits (first 24 numbers) Comment and docblock lines under packages/runtime/src that cited a tracker number answering 404 now cite the commit in this repository's history that decided what the line describes, reusing the anchors the landed spec stages gave the same numbers. Comments only; every touched file keeps its line count. Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289 Co-authored-by: Claude --- .changeset/runtime-provenance-anchors.md | 11 ++++++++ .../src/action-declarative-update.test.ts | 2 +- .../action-door-record-load-denied.test.ts | 6 ++--- packages/runtime/src/action-execution.ts | 24 ++++++++--------- .../src/action-record-load-denied.test.ts | 8 +++--- ...river-text-real-driver.integration.test.ts | 2 +- .../src/discovery-schema-conformance.test.ts | 2 +- .../src/dispatcher-error-vocabulary.ts | 8 +++--- ...plugin.declared-5xx-prose-withhold.test.ts | 2 +- ...tcher-plugin.declared-user-message.test.ts | 8 +++--- packages/runtime/src/dispatcher-plugin.ts | 4 +-- packages/runtime/src/domains/actions.ts | 8 +++--- .../src/domains/automation-flow-clone.test.ts | 8 +++--- packages/runtime/src/domains/automation.ts | 4 +-- .../domain-protocol-handle-typing.test.ts | 2 +- .../src/domains/meta-put-falsy-body.test.ts | 2 +- .../domains/meta-save-capability-gate.test.ts | 2 +- .../src/domains/meta-verb-fallthrough.test.ts | 2 +- packages/runtime/src/domains/meta.ts | 8 +++--- .../packages-protocol-handle-typing.test.ts | 2 +- packages/runtime/src/domains/packages.ts | 4 +-- .../share-links-enforcement-context.test.ts | 6 ++--- packages/runtime/src/domains/share-links.ts | 4 +-- .../runtime/src/endpoint-executor.test.ts | 2 +- packages/runtime/src/flow-clone.ts | 6 ++--- packages/runtime/src/flow-dispatch-status.ts | 4 +-- ...her.permission-denied-user-message.test.ts | 4 +-- packages/runtime/src/http-dispatcher.test.ts | 6 ++--- packages/runtime/src/http-dispatcher.ts | 4 +-- .../src/meta-compound-arity-mint-door.test.ts | 10 +++---- .../src/meta-field-overlay-lock.test.ts | 2 +- .../src/meta-overlay-read-your-writes.test.ts | 4 +-- .../runtime/src/meta-write-org-scope.test.ts | 4 +-- ...ion-schema-conformance.integration.test.ts | 10 +++---- .../notification-schema-conformance.test.ts | 2 +- .../notifications.hono.integration.test.ts | 4 +-- ...ckage-door-namespace-conflict-code.test.ts | 4 +-- .../runtime/src/resolve-project-database.ts | 8 +++--- packages/runtime/src/sandbox/body-runner.ts | 4 +-- .../src/sandbox/error-passthrough.test.ts | 2 +- .../runtime/src/sandbox/quickjs-runner.ts | 14 +++++----- ...ial-field-clear-signal.integration.test.ts | 4 +-- packages/runtime/src/sandbox/script-runner.ts | 4 +-- ...eld-write-driver-split.integration.test.ts | 26 +++++++++---------- .../artifact-granted-permissions.test.ts | 2 +- .../security/artifact-granted-permissions.ts | 2 +- .../src/security/resolve-execution-context.ts | 4 +-- packages/runtime/src/standalone-stack.ts | 10 +++---- packages/runtime/src/turso-driver-factory.ts | 2 +- 49 files changed, 144 insertions(+), 133 deletions(-) create mode 100644 .changeset/runtime-provenance-anchors.md diff --git a/.changeset/runtime-provenance-anchors.md b/.changeset/runtime-provenance-anchors.md new file mode 100644 index 00000000000..4786cf0cd53 --- /dev/null +++ b/.changeset/runtime-provenance-anchors.md @@ -0,0 +1,11 @@ +--- +'@objectstack/runtime': patch +--- + +Provenance comments in `@objectstack/runtime` 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/runtime/src/action-declarative-update.test.ts b/packages/runtime/src/action-declarative-update.test.ts index b692d0db680..e082757749f 100644 --- a/packages/runtime/src/action-declarative-update.test.ts +++ b/packages/runtime/src/action-declarative-update.test.ts @@ -336,7 +336,7 @@ describe('#15079 point 3 — the authorization point: a caller who cannot read o expect(res.body.error.code).toBe('RECORD_NOT_FOUND'); expect(res.body.error.message).toContain(RECORD_ID); expect(res.body.error.message).toContain(OBJECT); - // ⛔ The #14143 class: a swallowed load must never become an implicit + // ⛔ The class commit f19475c0a closed: a swallowed load must never become an implicit // grant. The verdict is CONSUMED — no write was even attempted. expect(rig.updates).toHaveLength(0); expect(rig.row.status).toBe('open'); diff --git a/packages/runtime/src/action-door-record-load-denied.test.ts b/packages/runtime/src/action-door-record-load-denied.test.ts index 0022598ddeb..7751c6d37c6 100644 --- a/packages/runtime/src/action-door-record-load-denied.test.ts +++ b/packages/runtime/src/action-door-record-load-denied.test.ts @@ -32,7 +32,7 @@ * * 1. **Both doors × both surfaces.** The flow door and the script/body door, * on the REST `/actions` route and on the MCP `run_action` bridge. A rule - * implemented at one door is the failure class #14143 and #15168 each paid + * implemented at one door is the failure class commit f19475c0a and #15168 each paid * for on this exact seam, so every case below is asserted on all four. * 2. **⛔ No run, no body.** The refusal lands BEFORE `automation.execute` * (no persisted run) and BEFORE `executeAction` (no trusted, RLS-bypassing @@ -46,7 +46,7 @@ * 4. **Record-less and new-record actions are byte-for-byte unchanged.** An * object-less action key never attempts a load, so its verdict is never * `true` and it still receives the `recordId` stamp — the regression that - * #14143 deliberately kept and that this card must not take away. + * commit f19475c0a deliberately kept and that this card must not take away. * 5. **A load that SUCCEEDS still runs.** The owner reaches the flow and the * handler exactly as before; this is the firing control that stops every * zero above from being a rig that dispatches nothing. @@ -450,7 +450,7 @@ describe('[#16370] refuseDeniedSubjectLoad — the rule, isolated from every doo it('returns silently when the verdict is `false` — and the stamp is NOT the predicate', () => { // ⛔ `record.id` is truthy in BOTH cases; re-deriving the verdict from - // it is the #14143 defect verbatim, so this pair is what says the + // it is the defect commit f19475c0a fixed, verbatim, so this pair is what says the // implementation reads the flag and nothing else. expect(() => refuseDeniedSubjectLoad(OBJECT, RECORD_ID, { record: { id: RECORD_ID }, recordLoadDenied: false })).not.toThrow(); diff --git a/packages/runtime/src/action-execution.ts b/packages/runtime/src/action-execution.ts index 64fef292ebb..7c81014a2e6 100644 --- a/packages/runtime/src/action-execution.ts +++ b/packages/runtime/src/action-execution.ts @@ -900,14 +900,14 @@ export function isFlowActionRefusal(e: unknown): e is FlowActionRefusal { * and a downstream reader that had to tell them apart could only infer. * * [#15168] **The wiring takes the subject LOAD, not a bare record.** The flow - * face of #14143's signal (`AutomationContext.recordLoadDenied`, declared by + * face of commit f19475c0a's signal (`AutomationContext.recordLoadDenied`, declared by * #14244) is derived here, once, from {@link loadActionSubjectRecord}'s * outcome — so a caller cannot hand this door a record while dropping the * verdict that says the caller could not read it. Both call sites already held * that outcome and were passing `subject.record` out of it; taking the whole * `subject` removes the second de-facto source rather than adding a key beside * it, and makes the omission a compile error instead of a silent inertness one - * door over (the shape #14143 was filed for). + * door over (the shape commit f19475c0a fixed). */ export async function dispatchFlowAction(deps: ActionExecutionDeps, requestContext: HttpProtocolContext, @@ -1685,10 +1685,10 @@ export function buildActionEngineFacade(_deps: ActionExecutionDeps, ql: any, ec? /** * The subject-record load's outcome, as the two action doors hand it to a - * handler (#14143). + * handler (commit f19475c0a). */ export interface ActionSubjectRecordLoad { - /** What the handler receives as `ctx.record`. Unchanged by #14143. */ + /** What the handler receives as `ctx.record`. Unchanged by commit f19475c0a. */ record: Record; /** * `true` exactly when a caller-scope load was ATTEMPTED and did not deliver @@ -1700,7 +1700,7 @@ export interface ActionSubjectRecordLoad { /** * Load an action's subject record IN THE CALLER'S OWN SCOPE, and report whether - * that load actually delivered the row (#14143). ONE producer for both action + * that load actually delivered the row (commit f19475c0a). ONE producer for both action * doors — the MCP `run_action` bridge below and the REST `/actions` route * (`domains/actions.ts`) — because the signal it emits is documented to app * authors, and a signal only one of two doors sets is an authorization guard @@ -1793,7 +1793,7 @@ export function actionRecordLoadSignal(load: ActionSubjectRecordLoad): { recordL * reading it left open ("whether the automation engine acts on it … is a * separate reading") is this function. A swallowed load must never become an * implicit grant — the rule is #15079's, and a rule implemented at one of three - * doors is the failure class #14143 and #15168 each already paid for here. + * doors is the failure class commit f19475c0a and #15168 each already paid for here. * * ## The predicate is the LOAD's verdict — ⛔ never the action's `locations` * @@ -1906,11 +1906,11 @@ function declarativeUpdateRefusal(message: string, status: number): Error { * 'update'` + `patch` (#14092, maintainer ruling 2026-09-01, quoted on the * card). ONE implementation, called by BOTH action doors. * - * ## Shared on purpose, for the #14143 reason + * ## Shared on purpose, for the reason of commit f19475c0a * * The REST `/actions` door and the MCP `run_action` bridge are two doors onto * one action model, and this repo has now paid twice for a rule implemented at - * one of them: #14143 (a `recordLoadDenied` signal only one door set) and + * one of them: commit f19475c0a (a `recordLoadDenied` signal only one door set) and * #15168 (a flow face with no populator at all). An authorization rule is the * worst possible thing to fork, and contract point 3 is an authorization rule * — so the branch each door owns is three lines, and everything that decides @@ -1944,7 +1944,7 @@ function declarativeUpdateRefusal(message: string, status: number): Error { * the caller's own scope actually delivered it. A caller who cannot read the * row is refused HERE, before any write is attempted, on * `subject.recordLoadDenied`. Re-deriving that from `subject.record` is the - * #14143 defect verbatim: the door stamps `record.id = recordId` on a refused + * defect commit f19475c0a fixed, verbatim: the door stamps `record.id = recordId` on a refused * load, so `record.id` is truthy either way and `if (!record?.id)` is false on * a row the caller cannot see. A swallowed load must never become an implicit * grant. @@ -2202,7 +2202,7 @@ export async function invokeBusinessAction(deps: ActionExecutionDeps, // Load the subject record under RLS when row-context (engages the same // permission path as get_record — an unseen record reads as not-found). - // [#14143] Through the ONE shared producer, so this door and the REST + // [commit f19475c0a] Through the ONE shared producer, so this door and the REST // `/actions` door emit the same `recordLoadDenied` signal to handlers. const subject = await loadActionSubjectRecord(objectName, recordId, () => callData('get', { object: objectName, id: recordId }, driver, envId, ec)); @@ -2213,7 +2213,7 @@ export async function invokeBusinessAction(deps: ActionExecutionDeps, // first, and an action with no handler has no body to elevate for. The // shared executor the REST `/actions` door also calls, so the two doors // cannot disagree about the identity the write carries — the failure class - // #14143 and #15168 each paid for once, on this exact seam. + // commit f19475c0a and #15168 each paid for once, on this exact seam. if (isDeclarativeUpdateAction(action)) { const result = await executeDeclarativeUpdateAction(deps, action, { objectName, actionName: name, subject, recordId, params, ec, driver, envId, callData, @@ -2281,7 +2281,7 @@ export async function invokeBusinessAction(deps: ActionExecutionDeps, ); const actionContext: any = { record, - // [#14143] The caller-scope load's verdict, on the same context the + // [commit f19475c0a] The caller-scope load's verdict, on the same context the // record rides. `ctx.record.id` is present either way (the stamp is // load-bearing for record-less actions), so this is the ONLY thing that // tells a handler its subject row did not resolve for THIS caller — diff --git a/packages/runtime/src/action-record-load-denied.test.ts b/packages/runtime/src/action-record-load-denied.test.ts index 8ccc962af3e..fd5ad894e2e 100644 --- a/packages/runtime/src/action-record-load-denied.test.ts +++ b/packages/runtime/src/action-record-load-denied.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14143] A handler must be able to tell "the caller cannot read this row" + * [commit f19475c0a] A handler must be able to tell "the caller cannot read this row" * from "this action legitimately has no record". * * ## The defect @@ -493,7 +493,7 @@ describe('[#15168] the FLOW door and its verdict — MCP run_action', () => { * `AutomationContext.recordLoadDenied` is a declared spec key * (`contracts/automation-service.ts`, pinned in `packages/spec`), the * dispatcher is its ONE populator, and a populator that quietly stopped - * populating would be exactly the inert-signal shape #14143 was filed for. So + * populating would be exactly the inert-signal shape commit f19475c0a fixed. So * the assertions #15168 wrote at the doors are re-pinned HERE, on the * dispatcher itself, where a denied subject can still be constructed. * @@ -556,8 +556,8 @@ describe('[#15168] dispatchFlowAction derives the verdict from the subject load' /** * [#15168] The convergence itself. A per-door assertion is satisfied by two - * copies of a rule, and two copies drifting apart is the defect #14143 was - * filed for and the reason this card had to move both doors in one stroke — so + * copies of a rule, and two copies drifting apart is the defect commit f19475c0a + * fixed, and the reason this card had to move both doors in one stroke — so * the SAME caller against the SAME row is driven through both doors and the * signal is compared as a set. */ diff --git a/packages/runtime/src/batch-row-driver-text-real-driver.integration.test.ts b/packages/runtime/src/batch-row-driver-text-real-driver.integration.test.ts index 2f7f50a6254..bd73e44dc46 100644 --- a/packages/runtime/src/batch-row-driver-text-real-driver.integration.test.ts +++ b/packages/runtime/src/batch-row-driver-text-real-driver.integration.test.ts @@ -280,7 +280,7 @@ describe('[#8502] a REAL driver fault is withheld from every batch row', () => { // idempotent batch writer branches on — it was `INTERNAL_ERROR` with no // status while the sentence was withheld. // - // ── [#14723] …and the row speaks the WIRE spelling ───────────────── + // ── [commit 65846bc46] …and the row speaks the WIRE spelling ─────── // The engine's envelope is `code: 'DUPLICATE_RECORD'` in-process (the // objectql pins on `insert` / `insertMany` hold that), and this row // used to relay it verbatim while the whole-request failure on the diff --git a/packages/runtime/src/discovery-schema-conformance.test.ts b/packages/runtime/src/discovery-schema-conformance.test.ts index 0d98c901c6a..6a2b7812399 100644 --- a/packages/runtime/src/discovery-schema-conformance.test.ts +++ b/packages/runtime/src/discovery-schema-conformance.test.ts @@ -376,7 +376,7 @@ describe('[#4828] getDiscoveryInfo() conforms to DiscoverySchema', () => { // two different rules and #5673 deliberately moved only the first — #4828's // "never CLAIM production on a guess" is untouched, and this case is the // guard against a later simplification collapsing them back into one. - // [#6287] `preview` dropped out of this list when it gained a declared fold + // [commit 84c86fb45] `preview` dropped out of this list when it gained a declared fold // (`sandbox`) — it is an `EnvironmentTypeSchema` member, so it is no longer // an example of a spelling this repo does not recognise. The rule and its // remaining examples are untouched. diff --git a/packages/runtime/src/dispatcher-error-vocabulary.ts b/packages/runtime/src/dispatcher-error-vocabulary.ts index 927f045cbe3..b3a4409b3b6 100644 --- a/packages/runtime/src/dispatcher-error-vocabulary.ts +++ b/packages/runtime/src/dispatcher-error-vocabulary.ts @@ -187,14 +187,14 @@ export type CodeStampShape = export type CodeDoor = 'dispatcher' | 'rest' | 'plugin-route' | 'none'; /** - * [#16649] `'boot-refusal'` was HERE, and is retired. It named a refusal raised + * [commit 44c917a47] `'boot-refusal'` was HERE, and is retired. It named a refusal raised * before any HTTP boundary exists — the CLI rethrows it and aborts — and until * #16404 the ledger ratified that class as not owed a row * (`MONGODB_MULTI_TENANT_UNSUPPORTED` was UNregistered by #8035 on "host boot * matching is not wire vocabulary"). #16404 deleted the exemption (the ledger * is the published face, door or no door), which left the verdict meaning only * "a registration this tree still owes" — #16449 discharged nine of those, - * #16649's first half the remaining fourteen, and the second half widened + * commit 613bfbd3d the remaining fourteen, and commit 44c917a47 widened * `check-dispatcher-error-vocabulary`'s face refusal from `packages/spec/src/` * to every published package's `src/`, which is what makes the verdict * unwritable: a row carrying it inside that face is now a @@ -308,7 +308,7 @@ export const UNREGISTERED_CODE_SITES: readonly UnregisteredCodeSite[] = [ // `check:dispatcher-error-vocabulary` refuses any verdict there but // `foreign-vocabulary` / `runtime-pinned`. ── // - // ── [#16649] Fourth cycle, the rest of that class: the fourteen + // ── [commit 613bfbd3d] Fourth cycle, the rest of that class: the fourteen // `boot-refusal` rows that remained after #16449 — the nine // `@objectstack/core` refusals (the three ADR-0130 D4 artifact-package // refusals, the four `MigrationJournalRefusal` codes, @@ -321,7 +321,7 @@ export const UNREGISTERED_CODE_SITES: readonly UnregisteredCodeSite[] = [ // (`stale-row`), the reachability each row recorded now carried on its // ledger row. // - // ── [#16649, second half] The class is now closed MECHANICALLY rather than + // ── [commit 44c917a47, second half] The class is now closed MECHANICALLY rather than // by having been emptied once. `check-dispatcher-error-vocabulary`'s face // refusal, which #16449 could only afford over `packages/spec/src/`, covers // every published package's `src/` — the whole of this scan's population on diff --git a/packages/runtime/src/dispatcher-plugin.declared-5xx-prose-withhold.test.ts b/packages/runtime/src/dispatcher-plugin.declared-5xx-prose-withhold.test.ts index 106f8b1dfe1..74d896fc58f 100644 --- a/packages/runtime/src/dispatcher-plugin.declared-5xx-prose-withhold.test.ts +++ b/packages/runtime/src/dispatcher-plugin.declared-5xx-prose-withhold.test.ts @@ -10,7 +10,7 @@ * * > `errorResponseBase` adopts the **structural withhold for every declared 5xx * > message**, aligning to `/data`'s rule; the author-facing text channel is - * > `userMessage` (#9934), never the raw message. + * > `userMessage` [commit 79c46da90], never the raw message. * * ## The two axes it closes * diff --git a/packages/runtime/src/dispatcher-plugin.declared-user-message.test.ts b/packages/runtime/src/dispatcher-plugin.declared-user-message.test.ts index ad544acf961..21890bc5b03 100644 --- a/packages/runtime/src/dispatcher-plugin.declared-user-message.test.ts +++ b/packages/runtime/src/dispatcher-plugin.declared-user-message.test.ts @@ -32,7 +32,7 @@ * The 2026-08-27 ruling on #12509 (option D), propagated to #12281, made this * exit withhold the message of every **declared** 5xx: * - * > the author-facing text channel is `userMessage` (#9934), never the raw + * > the author-facing text channel is `userMessage` [commit 79c46da90], never the raw * > message. * * That sentence only holds if the channel exists here. Before this change a @@ -43,7 +43,7 @@ * * ## ⚠️ Status-agnostic, which is wider than the card's framing * - * #9934 made the mark status-agnostic on purpose ("a 400, 403, 409 or 503 + * Commit 79c46da90 made the mark status-agnostic on purpose ("a 400, 403, 409 or 503 * refusal may all carry it"), so the gap here was never confined to the * declared-5xx band that motivated it: a marked **4xx** refusal reaching this * exit lost the field too, with no withhold anywhere in the picture. `§2` drives @@ -201,7 +201,7 @@ describe('[#13241] the dispatcher throw-transparent exit carries `userMessage`', // …and the author's channel now survives it. expect(res.body.error.userMessage).toBe('Reporting is briefly offline. Try again in a few minutes.'); - // The mark never MOVES the status or the code (#9934's third + // The mark never MOVES the status or the code (commit 79c46da90, the ruling's third // constraint) — a marked fault is still the sanitised fault. expect(res.body.error.code).toBe('SERVICE_UNAVAILABLE'); }); @@ -299,7 +299,7 @@ describe('[#13241] the dispatcher throw-transparent exit carries `userMessage`', expect(res.statusCode).toBe(403); expect(res.body.error.code).toBe('PERMISSION_DENIED'); // The half this card repaired: the author's channel now survives - // the denial door too (#9934 is status-agnostic, and 403 is the + // the denial door too (commit 79c46da90's mark is status-agnostic, and 403 is the // refusal class most likely to carry authored text). expect(res.body.error.userMessage).toBe('Ask an admin for the Reporting role.'); // …verbatim, and never in place of the diagnostic channel. diff --git a/packages/runtime/src/dispatcher-plugin.ts b/packages/runtime/src/dispatcher-plugin.ts index acbf6f9366a..88bfdd2e453 100644 --- a/packages/runtime/src/dispatcher-plugin.ts +++ b/packages/runtime/src/dispatcher-plugin.ts @@ -712,7 +712,7 @@ function errorResponseBase( // goes through the heuristic alone. A naive `httpStatus >= 500` test would // silently delete that, which is the one way this change could do harm. // - // The author-facing text channel is `userMessage` (#9934), never the raw + // The author-facing text channel is `userMessage` (commit 79c46da90), never the raw // message — a producer whose 5xx prose is addressed to a human declares it // there and it survives the withhold on its own channel. // @@ -771,7 +771,7 @@ function errorResponseBase( // stop, which is why the shared resolver's field is read rather than // `err.userMessage` probed inline. // - // ⚠️ Status-agnostic on purpose (#9934's second constraint) — a 400, 403 or + // ⚠️ Status-agnostic on purpose (the ruling's second constraint, commit 79c46da90) — a 400, 403 or // 409 refusal may carry the mark too, so this is NOT gated on the 5xx limb // above. The withhold touches only the diagnostic `message`; the marked // channel is text an author deliberately addressed to the end user, so it diff --git a/packages/runtime/src/domains/actions.ts b/packages/runtime/src/domains/actions.ts index 5aa9ba6dd77..9e26342b0fb 100644 --- a/packages/runtime/src/domains/actions.ts +++ b/packages/runtime/src/domains/actions.ts @@ -638,7 +638,7 @@ export async function handleActionsRequest(deps: DomainHandlerDeps, path: string } // Load the record (best-effort) so handlers can rely on `ctx.record`. - // [#14143] Through the ONE shared producer `loadActionSubjectRecord`, which + // [commit f19475c0a] Through the ONE shared producer `loadActionSubjectRecord`, which // also reports whether the CALLER's own scope actually delivered the row. // This door and the MCP `run_action` door must emit the same signal: a // documented guard (`if (ctx.recordLoadDenied) …`) that only one of two @@ -707,7 +707,7 @@ export async function handleActionsRequest(deps: DomainHandlerDeps, path: string // #15079 wrote into the declarative executor, now read by the flow door // and the script/body door as well. A signal only one of three doors // consumed is an authorization rule silently inert on the other two, - // which is the #14143 / #15168 failure class on this exact seam. + // which is the commit f19475c0a / #15168 failure class on this exact seam. // // Inside the `try`, like the declarative branch above, so the 404 takes // the ONE catch this door already has and is served with its `.status` / @@ -719,7 +719,7 @@ export async function handleActionsRequest(deps: DomainHandlerDeps, path: string const actionContext: any = { record, - // [#14143] The caller-scope load's verdict — see + // [commit f19475c0a] The caller-scope load's verdict — see // `loadActionSubjectRecord`. `ctx.record.id` is stamped either way, so // this is the only channel that distinguishes "the caller cannot read // this row" from "this action legitimately has no record". @@ -756,7 +756,7 @@ export async function handleActionsRequest(deps: DomainHandlerDeps, path: string // the flow context's `record` AND its `recordLoadDenied` // sibling from the same load outcome, so this door and the // MCP one cannot diverge on the signal the way the two - // doors diverged before #14143. + // doors diverged before commit f19475c0a. subject, params: reqParams, recordId, diff --git a/packages/runtime/src/domains/automation-flow-clone.test.ts b/packages/runtime/src/domains/automation-flow-clone.test.ts index e3be8f3b33a..2ef9ba8ac08 100644 --- a/packages/runtime/src/domains/automation-flow-clone.test.ts +++ b/packages/runtime/src/domains/automation-flow-clone.test.ts @@ -7,9 +7,9 @@ * place. Three of the ADR's rules are the reason this file exists, and each has * a measurement behind it rather than a preference: * - * 1. **Whole-definition copy.** The centrepiece here is the #11703 + * 1. **Whole-definition copy.** The centrepiece here is the facet-drop (commit 5cb62d88b) * counter-example expressed as a test: the cloned definition must deep-equal - * its source apart from the three fields a clone mutates. #11703 measured a + * its source apart from the three fields a clone mutates. Commit 5cb62d88b records a * clone assembled from an ENUMERATED facet list dropping three of six facets * in silence — the record was created, the success toast fired, and the * difference was discoverable only by diffing the two rows. A flow has far @@ -68,7 +68,7 @@ const CTX = { request: {}, executionContext: { userId: 'user_1', systemPermissio * `MetadataProtectionFields`, so these are part of the parsed definition, not * decoration around it). * - * Deliberately fat. The #11703 lesson is that a clone test passes trivially + * Deliberately fat. The lesson of commit 5cb62d88b is that a clone test passes trivially * when the fixture has nothing to lose, so {@link EXEMPLAR_FACET_FLOOR} below * pins that this exemplar keeps exercising the assertion. */ @@ -180,7 +180,7 @@ describe('#12156 — whole-definition copy (the #11703 counter-example as a test expect(facetKeys.length).toBeGreaterThanOrEqual(EXEMPLAR_FACET_FLOOR); // THE assertion. Not a spot-check of `nodes`/`edges` — an enumerated - // check is the very shape #11703 measured failing, so the comparison is + // check is the very shape commit 5cb62d88b records failing, so the comparison is // whole-object or it is nothing. expect(omit(clone, FLOW_CLONE_MUTATED_FIELDS)).toEqual( omit(source, [...FLOW_CLONE_MUTATED_FIELDS, ...FLOW_CLONE_DROPPED_KEYS]), diff --git a/packages/runtime/src/domains/automation.ts b/packages/runtime/src/domains/automation.ts index 2c6ec513d9c..b2b5ac35565 100644 --- a/packages/runtime/src/domains/automation.ts +++ b/packages/runtime/src/domains/automation.ts @@ -1517,7 +1517,7 @@ function flowDefinitionRefusal(err: any): unknown { * disabled-flow exit stamps `'FLOW_DISABLED'`, its start-node-less exit * stamps `'FLOW_NO_START_NODE'`, and the arms below read those. #10025 * repeated the same shape for the definition-level input-schema refusal — - * spec seat first (#11504 registered `'FLOW_INPUT_SCHEMA_INVALID'`), then the + * spec seat first (commit f90e82024 registered `'FLOW_INPUT_SCHEMA_INVALID'`), then the * engine's non-retryable short-circuit stamps it — so its 422 is read here * through the same shared table, again never minted at this call site. * @@ -2370,7 +2370,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str // name (ADR-0126 §7.1). The copy itself, the fields it mutates, the // keys it must not carry forward and the notice it returns all live in // `../flow-clone.ts` — see that module's header for the ADR and for - // #11703, the measurement that decides the copy's SHAPE. + // commit 5cb62d88b, the measurement that decides the copy's SHAPE. // // Built out of `getFlow` + `registerFlow`, not a new contract method: // `IAutomationService` lives in `packages/spec`, and this door needs diff --git a/packages/runtime/src/domains/domain-protocol-handle-typing.test.ts b/packages/runtime/src/domains/domain-protocol-handle-typing.test.ts index e4143c798b8..54f3ae5a227 100644 --- a/packages/runtime/src/domains/domain-protocol-handle-typing.test.ts +++ b/packages/runtime/src/domains/domain-protocol-handle-typing.test.ts @@ -11,7 +11,7 @@ * * 1. **Compile-time** (section 1). An undeclared key — or a misspelt verb — in * one of these domains' request literals must be a COMPILE ERROR. That is - * the #11006 series' end state, and it stopped three seams short here. + * the end state of commit cccbe51bf's ruled pattern, and it stopped three seams short here. * 2. **Runtime** (section 2). ⛔ A host may occupy the `protocol` slot with a * PARTIAL object. Tightening the types and then deleting a * `typeof … === 'function'` probe would trade the compile-time improvement diff --git a/packages/runtime/src/domains/meta-put-falsy-body.test.ts b/packages/runtime/src/domains/meta-put-falsy-body.test.ts index c80188d24cf..25b372b5a8f 100644 --- a/packages/runtime/src/domains/meta-put-falsy-body.test.ts +++ b/packages/runtime/src/domains/meta-put-falsy-body.test.ts @@ -180,7 +180,7 @@ describe('#8842 — dispatcher PUT /meta/:type/:name with a falsy body', () => { // This drove `/lead/views/all_leads` — the compound arity, which // folded the trailing segments into `views/all_leads`. That arity - // is retired (#12176 stage 3), so the same name is addressed + // is retired (stage 3, commit 7986d973f), so the same name is addressed // percent-encoded, which keeps the path at two segments and lands // on the same `saveMetaItem`. The #8842 falsy-body hole this file // exists for is a property of that handler, not of the spelling. diff --git a/packages/runtime/src/domains/meta-save-capability-gate.test.ts b/packages/runtime/src/domains/meta-save-capability-gate.test.ts index eab6e2552fd..d39e45c6cd0 100644 --- a/packages/runtime/src/domains/meta-save-capability-gate.test.ts +++ b/packages/runtime/src/domains/meta-save-capability-gate.test.ts @@ -112,7 +112,7 @@ describe('#7019 — dispatcher PUT /meta/:type/:name: the capability gate', () = it('[#12195] refuses the ENCODED spelling too — one name, one gate', async () => { // This drove `/lead/views/all_leads`, the compound arity that folded // the trailing segments into `views/all_leads`. That arity is retired - // (#12176 stage 3); the same name is addressed percent-encoded, which + // (stage 3, commit 7986d973f); the same name is addressed percent-encoded, which // keeps the path at two segments and reaches the same `saveMetaItem`. // // The point of the case is unchanged: ONE gate covers every name shape. diff --git a/packages/runtime/src/domains/meta-verb-fallthrough.test.ts b/packages/runtime/src/domains/meta-verb-fallthrough.test.ts index 3b04d263647..cdcbfadea6b 100644 --- a/packages/runtime/src/domains/meta-verb-fallthrough.test.ts +++ b/packages/runtime/src/domains/meta-verb-fallthrough.test.ts @@ -196,7 +196,7 @@ describe('#8848 — an unsupported verb on /metadata/:type/:name', () => { const stack = boot(); // This drove `/meta/lead/views/all_leads`, the compound arity. It - // is retired (#12176 stage 3), so the same name is addressed + // is retired (stage 3, commit 7986d973f), so the same name is addressed // percent-encoded — two segments, same verb dispatch. const res = await stack.dispatcher.dispatch( 'DELETE', '/meta/lead/views%2Fall_leads', undefined, {}, SESSION(), diff --git a/packages/runtime/src/domains/meta.ts b/packages/runtime/src/domains/meta.ts index b4ddb362cc2..956b06eb843 100644 --- a/packages/runtime/src/domains/meta.ts +++ b/packages/runtime/src/domains/meta.ts @@ -100,7 +100,7 @@ import type { DomainHandlerDeps, DomainRoute } from '../domain-handler-registry. * ("real services with no written contract, so they keep today's `any` rather * than being given a shape here that nothing verifies"). The `any` is honest * about the SLOT. What it also did, silently, was hand every request literal - * downstream of it an unchecked call target: the #11006 series' end state — + * downstream of it an unchecked call target: the end state of commit cccbe51bf's ruled pattern — * "an undeclared key in a request literal is a compile error" — stopped one * seam short here, so a misspelt or undeclared key in these literals compiled, * and so did a misspelt VERB. @@ -828,7 +828,7 @@ async function answerMetaLayered( * (`parts.slice(1).join('/')`) is what let a slash-bearing name be addressed * on this transport at all — unencoded, across segments. Retiring the fold * without decoding would leave a pre-grammar residue row addressable through - * `packages/rest` and NOT through the dispatcher, breaking #12194's landed + * `packages/rest` and NOT through the dispatcher, breaking the landed (commit 311433f6b) * acceptance criterion that "reads and `deleteMetaItem` still answer for * pre-grammar residue rows, so any stored junk name remains listable and * clearable". Decoding makes ONE spelling — percent-encoded, the spelling the @@ -1047,7 +1047,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin // `parts.length >= 3` with `parts.slice(1, -1).join('/')`, which re-joined // every middle segment into one slash-bearing key so // `lead/views/all_leads/published` resolved as name `views/all_leads`. - // Stage 1 (#12194) refuses every slash-bearing name at the publish door, + // Stage 1 (commit 311433f6b) refuses every slash-bearing name at the publish door, // so that fold could only ever address a name that can no longer be // written. if (parts.length === 3 && parts[2] === 'published' && (!method || method === 'GET')) { @@ -1170,7 +1170,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin // segment after the type was re-joined into one slash-bearing lookup key, // so `/metadata/lead/views/all_leads` resolved as name `views/all_leads`. // That fold WAS compound-name addressing on this transport, and stage 1 - // (#12194) made every name it could reach unwritable at the publish door. + // (commit 311433f6b) made every name it could reach unwritable at the publish door. // // ⚠️ The `>=` also swallowed three-segment paths that were never compound // names at all — `/metadata/object/foo/references` folded to name diff --git a/packages/runtime/src/domains/packages-protocol-handle-typing.test.ts b/packages/runtime/src/domains/packages-protocol-handle-typing.test.ts index 0cf071966af..e9896d22360 100644 --- a/packages/runtime/src/domains/packages-protocol-handle-typing.test.ts +++ b/packages/runtime/src/domains/packages-protocol-handle-typing.test.ts @@ -8,7 +8,7 @@ * and either one alone is a regression: * * 1. **Compile-time** (section 1). An undeclared key in one of this domain's - * request literals must be a COMPILE ERROR. That is the #11006 series' end + * request literals must be a COMPILE ERROR. That is commit cccbe51bf's ruled end * state, and it stopped one seam short here. * 2. **Runtime** (section 2). ⛔ A host may occupy the `protocol` slot with a * PARTIAL object. Tightening the type and then deleting a diff --git a/packages/runtime/src/domains/packages.ts b/packages/runtime/src/domains/packages.ts index 86b509c9da2..a0399a0f870 100644 --- a/packages/runtime/src/domains/packages.ts +++ b/packages/runtime/src/domains/packages.ts @@ -135,7 +135,7 @@ import { PackageInstallBodySchema, PackageInstallRequestSchema } from '@objectst * ("real services with no written contract, so they keep today's `any` rather * than being given a shape here that nothing verifies"). The `any` is honest * about the SLOT. What it also did, silently, was hand every request literal - * downstream of it an unchecked call target: the #11006 series' end state — + * downstream of it an unchecked call target: the end state of commit cccbe51bf's ruled pattern — * "an undeclared key in a request literal is a compile error" — stopped one * seam short here, so a misspelt or undeclared key in these literals compiled. * @@ -1546,7 +1546,7 @@ export async function handlePackagesRequest(deps: DomainHandlerDeps, path: strin // `request.type` itself, and the predicate answers // `undefined` for every type the registry declares // non-overridable — `app` among them, rolled back to - // `allowOrgOverride: false` in #6483. The `organizationId` + // `allowOrgOverride: false` in commit ee58392e1. The `organizationId` // this route still hands that call is dropped at the gate. // // ⛔ Dropping it is the REPAIR, not an oversight to undo. diff --git a/packages/runtime/src/domains/share-links-enforcement-context.test.ts b/packages/runtime/src/domains/share-links-enforcement-context.test.ts index cf0e37e4b16..fbbad1ff01e 100644 --- a/packages/runtime/src/domains/share-links-enforcement-context.test.ts +++ b/packages/runtime/src/domains/share-links-enforcement-context.test.ts @@ -1,12 +1,12 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#6551 / #6206 / #6430] Dispatcher-face `/share-links` enforcement context. + * [#6551 / commit 8e13ca876 / #6430] Dispatcher-face `/share-links` enforcement context. * * The dispatcher domain used to rebuild a two-field `{ userId, tenantId }` * out of the request's ALREADY-COMPLETE resolved `ExecutionContext` and hand * that to `svc.createLink` / `svc.listLinks` / `svc.revokeLink` — the same - * consumption-site truncation #6206 fixed on the plugin-sharing face (PR + * consumption-site truncation commit 8e13ca876 fixed on the plugin-sharing face (PR * #6552), one entry point over. Structural subtyping keeps the trimmed object * compiling against the contract's `ExecutionContext` parameter, so only a * behavioural repro + a seam-parity pin can hold this boundary. @@ -498,7 +498,7 @@ describe('[#6551] the dispatcher seam itself', () => { for (const verb of ['createLink', 'listLinks', 'revokeLink'] as const) { expect(svc[verb]).toHaveBeenCalledTimes(1); const got = seen[verb]; - // The #6206 contract: the WHOLE `resolveExecutionContext` envelope, + // The contract commit 8e13ca876 set: the WHOLE `resolveExecutionContext` envelope, // unchanged — a re-trim shows up here as the exact keys it dropped. const dropped = Object.keys(envelope as any).filter( (k) => !(k in got) || got[k] !== (envelope as any)[k], diff --git a/packages/runtime/src/domains/share-links.ts b/packages/runtime/src/domains/share-links.ts index b94e7a28d3a..0a6021c73d3 100644 --- a/packages/runtime/src/domains/share-links.ts +++ b/packages/runtime/src/domains/share-links.ts @@ -90,7 +90,7 @@ export async function handleShareLinksRequest( const SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] } as const; const m = method.toUpperCase(); const parts = subPath.replace(/^\/+/, '').split('/').filter(Boolean); - // [#6551 / #6206 / #6430] The dispatcher's ALREADY-COMPLETE envelope, + // [#6551 / commit 8e13ca876 / #6430] The dispatcher's ALREADY-COMPLETE envelope, // passed through WHOLE to every adjudicating service call below. // // `createLink` / `listLinks` / `revokeLink` are ENFORCEMENT paths — the @@ -105,7 +105,7 @@ export async function handleShareLinksRequest( // two-field `{ userId, tenantId }` — structural subtyping keeps that // compiling, so the narrowing was invisible to tsc and every // `group`-posture caller was refused links on records they read fine - // elsewhere (the #6206 defect, on the dispatcher face). The routes' own + // elsewhere (the defect commit 8e13ca876 fixed, on the dispatcher face). The routes' own // 401 gate below reads only `ec?.userId` — an authentication decision // needs no authorization envelope. const ec = context.executionContext; diff --git a/packages/runtime/src/endpoint-executor.test.ts b/packages/runtime/src/endpoint-executor.test.ts index 3c8cff308d7..349ddb39f2c 100644 --- a/packages/runtime/src/endpoint-executor.test.ts +++ b/packages/runtime/src/endpoint-executor.test.ts @@ -533,7 +533,7 @@ describe('an unsupported declaration gets a structured 501, never invented seman expect(execute).not.toHaveBeenCalled(); }); - // [#10338] `target` is OPTIONAL in the vocabulary now, so a flow endpoint + // [commit d2619fd0c] `target` is OPTIONAL in the vocabulary now, so a flow endpoint // with the key OMITTED is a parseable declaration — the publish gate // refuses it (`apis-publish-gates.test.ts`), and this is the runtime // counterpart that gate mirrors (`planEndpointTarget`), for a declaration diff --git a/packages/runtime/src/flow-clone.ts b/packages/runtime/src/flow-clone.ts index 913d62c7494..e98131c219b 100644 --- a/packages/runtime/src/flow-clone.ts +++ b/packages/runtime/src/flow-clone.ts @@ -18,7 +18,7 @@ * to `FlowSchema` must never require an edit here. * * That is not stylistic. The permission-set clone this is shaped on assembles - * its payload from an enumerated param list, and #11703 measured what an + * its payload from an enumerated param list, and commit 5cb62d88b records what an * enumerated list costs: three of the six facets (`system_permissions`, * `row_level_security`, `tab_permissions`) were simply not listed, so cloning a * set carrying system permissions or RLS produced a clone with NONE of them — @@ -31,7 +31,7 @@ * grows next — so the enumerated shape is not merely riskier here, it is * unmaintainable. ADR-0126 §7.1 rules it out by name. * - * `flow-clone.test.ts` asserts this as the #11703 counter-example: deep + * `flow-clone.test.ts` asserts this as the counter-example of commit 5cb62d88b: deep * equality of the cloned definition against the source, minus the three * mutated fields. A dropped facet fails that test rather than shipping. * @@ -110,7 +110,7 @@ export const FLOW_CLONE_STATUS = 'draft' as const; * * Exported so the test asserts the mutation set from the same constant the * implementation applies, rather than restating it (a second list here is the - * #11703 mechanism in miniature). + * facet-drop mechanism of commit 5cb62d88b in miniature). */ export const FLOW_CLONE_MUTATED_FIELDS = ['name', 'label', 'status'] as const; diff --git a/packages/runtime/src/flow-dispatch-status.ts b/packages/runtime/src/flow-dispatch-status.ts index 2c9eab2fdef..dd53f01f37b 100644 --- a/packages/runtime/src/flow-dispatch-status.ts +++ b/packages/runtime/src/flow-dispatch-status.ts @@ -15,7 +15,7 @@ * | ran and PAUSED | ran, suspended | not a refusal — see below | * * The `FLOW_INPUT_SCHEMA_INVALID` row TRANSCRIBES the #10025 ruling's - * spec-recorded contract (registered by the spec seat via #11504 — see + * spec-recorded contract (registered by the spec seat via commit f90e82024 — see * `ERROR_CODE_LEDGER['@objectstack/runtime']` and `AutomationResult.code`): * the definition-level guard's verdict is a pure function of the flow * definition, so the engine refuses ONCE, never enters its retry loop, and @@ -109,7 +109,7 @@ import type { AutomationResult } from '@objectstack/spec/contracts'; * `@objectstack/runtime` in `ERROR_CODE_LEDGER` — ⛔ nothing here mints one, * and a fifth row would be a spec-seat widening, never a call-site decision * (the #9384 ruling). `FLOW_INPUT_SCHEMA_INVALID` is the worked example: - * registered by the spec seat first (#11504, under the #10025 ruling), and + * registered by the spec seat first (commit f90e82024, under the #10025 ruling), and * only then transcribed here. */ export type FlowRefusalCode = 'FLOW_DISABLED' | 'FLOW_NO_START_NODE' | 'FLOW_INPUT_SCHEMA_INVALID' | 'FLOW_FAILED'; diff --git a/packages/runtime/src/http-dispatcher.permission-denied-user-message.test.ts b/packages/runtime/src/http-dispatcher.permission-denied-user-message.test.ts index b299ecfcdba..1cdfe3ab3f7 100644 --- a/packages/runtime/src/http-dispatcher.permission-denied-user-message.test.ts +++ b/packages/runtime/src/http-dispatcher.permission-denied-user-message.test.ts @@ -21,7 +21,7 @@ * * ## Why THIS door matters more than its size suggests * - * #9934 made the mark **status-agnostic** precisely so a 403 could carry it, + * Commit 79c46da90 made the mark **status-agnostic** precisely so a 403 could carry it, * and a 403 is the refusal class most likely to carry deliberately-authored * text: *"You do not have access to this report; ask an admin for the Reporting * role"* is exactly the sentence a producer marks. The one door that swallowed @@ -41,7 +41,7 @@ * * That same ruling is also why the change is owed: it makes REST's shape the * contract for BOTH transports, and REST's shape has carried the mark on this - * identical denial since #9934 (`mapDataError` = `withDeclaredUserMessage` over + * identical denial since commit 79c46da90 (`mapDataError` = `withDeclaredUserMessage` over * `classifyDataError`, pinned in * `packages/rest/src/rest-user-facing-refusal-marking.test.ts`). The * dispatcher's 403 was the one that differed. `§6` pins the parity. diff --git a/packages/runtime/src/http-dispatcher.test.ts b/packages/runtime/src/http-dispatcher.test.ts index 57b7265820d..2e74eed0d52 100644 --- a/packages/runtime/src/http-dispatcher.test.ts +++ b/packages/runtime/src/http-dispatcher.test.ts @@ -179,8 +179,8 @@ describe('HttpDispatcher', () => { // name='views/all_leads' — the dispatcher's own compound arity, // folding every trailing segment into one slash-bearing key. // - // #12176 retired compound metadata item names (maintainer ruling - // 2026-08-25); #12194 refuses every slash-bearing name at the + // Commit 7986d973f retired compound metadata item names (maintainer ruling + // 2026-08-25); commit 311433f6b refuses every slash-bearing name at the // publish door, so the fold could only address names that can no // longer be created; #12195 removes it. The domain now DECLINES, // and nothing is written. @@ -202,7 +202,7 @@ describe('HttpDispatcher', () => { // nothing decodes for it, so `%2F` keeps the path at two segments // and `decodeMetaNameSegment` restores the stored key — which is // what keeps a pre-grammar residue row addressable here, per - // #12194's "any stored junk name remains listable and clearable". + // commit 311433f6b: any stored junk name stays listable and clearable. const result = await dispatcher.handleMetadata('/lead/views%2Fall_leads', context, 'PUT', body); expect(result.handled).toBe(true); diff --git a/packages/runtime/src/http-dispatcher.ts b/packages/runtime/src/http-dispatcher.ts index d6ad749b8ce..9b8bd98baee 100644 --- a/packages/runtime/src/http-dispatcher.ts +++ b/packages/runtime/src/http-dispatcher.ts @@ -1125,7 +1125,7 @@ export class HttpDispatcher { // and parses the body against `ApiErrorSchema`, which now PASSES for // every body this door emits — the "parse every body it emits" half. const declaredCode = demotedDeclaredCode(thrown); - // [#9934] The producer-side user-facing marking rides as a declared + // [commit 79c46da90] The producer-side user-facing marking rides as a declared // sibling of `code`/`message` (`ApiErrorSchema.userMessage`), exactly // like `declaredCode` — the shared resolver already answered whether // the throw declared one (`declaredUserMessage`'s non-empty-string @@ -2821,7 +2821,7 @@ export class HttpDispatcher { // FOR the caller, platform and driver code never set it, and it // lands as a declared top-level sibling of `code`/`message` // (`ApiErrorSchema.userMessage`), never inside `details`. - // The mark never moves the status or the `code` (#9934). + // The mark never moves the status or the `code` (commit 79c46da90). const userMessage = declaredUserMessage(e); return { handled: true, diff --git a/packages/runtime/src/meta-compound-arity-mint-door.test.ts b/packages/runtime/src/meta-compound-arity-mint-door.test.ts index a249d2af571..90db77261e3 100644 --- a/packages/runtime/src/meta-compound-arity-mint-door.test.ts +++ b/packages/runtime/src/meta-compound-arity-mint-door.test.ts @@ -8,7 +8,7 @@ * ONE operation reaching ONE `saveMetaItem`. Under #8421 that shape was * EXEMPTED from the unrecognised-type refusal (the `:type` segment carries an * OBJECT name no static contract can enumerate), and this file pinned the - * exemption at the wire. #12194 (stage 1 of #12176's maintainer-ruled + * exemption at the wire. Commit 311433f6b (stage 1 of the maintainer-ruled * retirement of compound-name addressing, 2026-08-25) reverses the pinned * direction: the item-name grammar refuses every slash-bearing name BEFORE the * type verdict runs, so the compound WRITE now answers `400 INVALID_REQUEST` @@ -34,7 +34,7 @@ * * ## Reverse verification, direction predicted BEFORE running * - * On the pre-#12194 tree (grammar gate absent, compound exemption present) + * On the tree before commit 311433f6b (grammar gate absent, compound exemption present) * the two compound cases run the OTHER way — `200`, row stored under the * slash key. Measured on `origin/main@22c42c9b` before the door change: this * file's two compound pins were the acceptance direction; after the door @@ -226,7 +226,7 @@ describe('#8421 — the compound `/meta` arity is not a metadata-type claim', () // The domain answers a LOCATED not-found rather than serving the path. // Until #12195 it folded `views/all_leads` out of the trailing segments // and answered — first by minting the row under the slash key - // (pre-#12194), then by refusing it at the grammar gate (#12194). + // (before commit 311433f6b), then by refusing it at the grammar gate (commit 311433f6b). // Neither happens now: there is no three-segment metadata route. // // ADR-0112: code AND status. A bare 404 assertion could not tell this @@ -257,7 +257,7 @@ describe('#8421 — the compound `/meta` arity is not a metadata-type claim', () // A caller who genuinely means the name `views/all_leads` percent-encodes // it, which keeps the path at TWO segments. `decodeMetaNameSegment` - // restores the stored spelling, and #12194's grammar is what answers — + // restores the stored spelling, and the grammar of commit 311433f6b is what answers — // 400 with the dotted prescription, the caller's mistake named as such. // // This is the pin that separates "the route is gone" from "the name is @@ -296,7 +296,7 @@ describe('#8421 — the compound `/meta` arity is not a metadata-type claim', () // [#6245] spec-valid body — `webhook` resolves a schema through // UNREGISTERED_KIND_SCHEMAS, and this control measures the ARITY // door, so a malformed body would 422 and misread it. (`theme` was - // the specimen until #10485 retired that kind.) + // the specimen until commit 35ad101bc retired that kind.) const res = responseOf(await dispatcher.handleMetadata( '/webhook/midnight_hook', ctx(), 'PUT', { name: 'midnight_hook', label: 'Midnight', object: 'task', triggers: ['create'], url: 'https://example.com/hook' }, diff --git a/packages/runtime/src/meta-field-overlay-lock.test.ts b/packages/runtime/src/meta-field-overlay-lock.test.ts index 9bc3c5be745..5b03b07146f 100644 --- a/packages/runtime/src/meta-field-overlay-lock.test.ts +++ b/packages/runtime/src/meta-field-overlay-lock.test.ts @@ -701,7 +701,7 @@ describe('#7743 — PUT /meta/field/. honours the registry overla // [#6245] spec-valid bodies — `webhook` resolves a schema through // UNREGISTERED_KIND_SCHEMAS, and this control measures the #7894 // PERMISSION verdict, so a malformed body would 422 and misread it. - // (`theme` was the specimen until #10485 retired that kind out of the + // (`theme` was the specimen until commit 35ad101bc retired that kind out of the // spelling contract.) const singular = responseOf(await dispatcher.handleMetadata( '/webhook/midnight_hook', ctx(), 'PUT', diff --git a/packages/runtime/src/meta-overlay-read-your-writes.test.ts b/packages/runtime/src/meta-overlay-read-your-writes.test.ts index 13e5f1dd011..1c44013843e 100644 --- a/packages/runtime/src/meta-overlay-read-your-writes.test.ts +++ b/packages/runtime/src/meta-overlay-read-your-writes.test.ts @@ -202,7 +202,7 @@ describe('#4521 — read-your-writes between saveMeta and the dispatch path', () // `restoreArtifactRegistryView` removes on delete. Pinned here because // the write-through is what makes that separation load-bearing. // - // #6483 rolled `action`'s `allowOrgOverride` back to `false` + // Commit ee58392e1 rolled `action`'s `allowOrgOverride` back to `false` // (ADR-0005: page/app/action are ❌ in the amendment table), so // overriding this PACKAGED action needs the one documented door that // remains — the `OS_METADATA_WRITABLE` operator escape hatch. The @@ -362,7 +362,7 @@ describe('#5079 — list / get / dispatch agree immediately after deleteMeta', ( // "reset to artifact default" would delete the artifact instead of // revealing it. // - // #6483 rolled `action`'s `allowOrgOverride` back to `false` + // Commit ee58392e1 rolled `action`'s `allowOrgOverride` back to `false` // (ADR-0005: page/app/action are ❌ in the amendment table), so // overriding this PACKAGED action needs the one documented door that // remains — the `OS_METADATA_WRITABLE` operator escape hatch, exactly diff --git a/packages/runtime/src/meta-write-org-scope.test.ts b/packages/runtime/src/meta-write-org-scope.test.ts index ca373026a43..0d6ade4b778 100644 --- a/packages/runtime/src/meta-write-org-scope.test.ts +++ b/packages/runtime/src/meta-write-org-scope.test.ts @@ -360,7 +360,7 @@ describe('#7018 — the registry decides whether a metadata write carries the se expect(declaresOrgOverride('flows')).toBe(declaresOrgOverride('flow')); // A runtime-registered type with no registry entry has no per-org read // channel either, so it is env-wide too. (`webhook` took this slot - // from `theme` at #10485 — the retired kind left the contract.) + // from `theme` at commit 35ad101bc — the retired kind left the contract.) expect(declaresOrgOverride('webhook')).toBe(false); // No active org in, no org out — for every type. expect(organizationIdForMetaWrite('view', undefined)).toBeUndefined(); @@ -580,7 +580,7 @@ describe('#10503 the dispatcher /metadata transport decides org scope on the FOL plural: 'translations', singular: 'translation', item: { - // [#12194] The addressing name is snake_case — the item-name + // [commit 311433f6b] The addressing name is snake_case — the item-name // grammar refuses `zh-CN` as an ADDRESSING key (uppercase + // dash). The BCP-47 spelling lives in `locale`, which is this // type's required identity; the name was always free to choose. diff --git a/packages/runtime/src/notification-schema-conformance.integration.test.ts b/packages/runtime/src/notification-schema-conformance.integration.test.ts index 299cd3b37ae..e3d9c065a65 100644 --- a/packages/runtime/src/notification-schema-conformance.integration.test.ts +++ b/packages/runtime/src/notification-schema-conformance.integration.test.ts @@ -481,19 +481,19 @@ describe('[#5792] the notification wire bodies conform to the schemas the catalo // parse and the KEY assertion (⊆, not =) cannot see it either. // // Both were pinned here as the measured behaviour of `origin/main`, on the - // note that whichever way #6361 / #6363 were ruled, these assertions are the + // note that whichever way the two cards were ruled (landed as commits 90bbf2510 / 17d095413), these assertions are the // ones that must flip. BOTH have now been ruled (2026-08-07, Option A, and // ruled JOINTLY — one capability's two halves are never half-deleted), and // both assertions have flipped: // - // * #6363 made the declaration true — `unreadCount` really is the total; - // * #6361 removed the declaration instead — `cursor` is gone from the + // * commit 17d095413 made the declaration true — `unreadCount` really is the total; + // * commit 90bbf2510 removed the declaration instead — `cursor` is gone from the // request half, the response half and the SDK producer, because there was // no implementation to make it true ABOUT. Opposite repairs, same rule: // declared must equal enforced. // // The two directions are why the pair is worth keeping side by side. Note the - // #6361 assertion below now pins something subtler than the #6363 one: the + // `cursor` assertion below (commit 90bbf2510) now pins something subtler than the `unreadCount` one (commit 17d095413): the // WIRE did not change (an unknown `?cursor=` was ignored before and is // ignored now), so what it proves is that the CONTRACT stopped promising the // thing the wire never delivered. A test that only checked "page2 === page1" @@ -515,7 +515,7 @@ describe('[#5792] the notification wire bodies conform to the schemas the catalo // The LIST is still windowed — that half never changed. expect(windowed.notifications).toHaveLength(1); // The BADGE is not: declared 'Total number of unread notifications', and - // now delivered as one. Before #6363 this read `1` — the window's size, + // now delivered as one. Before commit 17d095413 this read `1` — the window's size, // which is what a user with more unread than the page size was told // forever. The parse was green either way; only this assertion can tell. expect(windowed.unreadCount).toBe(all.unreadCount); diff --git a/packages/runtime/src/notification-schema-conformance.test.ts b/packages/runtime/src/notification-schema-conformance.test.ts index fdfdcb5044f..a3801b6fe46 100644 --- a/packages/runtime/src/notification-schema-conformance.test.ts +++ b/packages/runtime/src/notification-schema-conformance.test.ts @@ -198,7 +198,7 @@ describe('[#5792] /notifications conforms to the schemas the catalog declares', }); it('[#6361] the declaration no longer states a `limit` default the route never applies', async () => { - // FLIPPED by #6361 (maintainer ruling 2026-08-07, Option A). This pin + // FLIPPED by commit 90bbf2510 (maintainer ruling 2026-08-07, Option A). This pin // used to record the DEFECT: `limit` was `z.number().default(20)` while // the route forwarded `undefined` and the provider applied its own 50, // so the declared default had never once been in effect. diff --git a/packages/runtime/src/notifications.hono.integration.test.ts b/packages/runtime/src/notifications.hono.integration.test.ts index 9f7158bc933..9aff633a611 100644 --- a/packages/runtime/src/notifications.hono.integration.test.ts +++ b/packages/runtime/src/notifications.hono.integration.test.ts @@ -409,7 +409,7 @@ describe('in-app notifications over a real hono server (integration, #3362)', () // POST /api/v1/notifications/read/all → { readCount: 200 } // GET /api/v1/notifications → { unreadCount: 150 } // - // #6363 did not cause that — it removed the cover. While `unreadCount` was + // Commit 17d095413 did not cause that — it removed the cover. While `unreadCount` was // window-scoped the shortfall was self-consistent and invisible; once the // badge became a true total the same request pair states it out loud, which // is why this pin lives at the wire and not only under the service. @@ -433,7 +433,7 @@ describe('in-app notifications over a real hono server (integration, #3362)', () } const before = await (await as(BULK_USER, '/api/v1/notifications')).json(); - expect(before.data.unreadCount).toBe(TOTAL); // the true total (#6363) + expect(before.data.unreadCount).toBe(TOTAL); // the true total (commit 17d095413) expect(before.data.notifications).toHaveLength(50); // the list is still one window const readAll = await (await as(BULK_USER, '/api/v1/notifications/read/all', { method: 'POST' })).json(); diff --git a/packages/runtime/src/package-door-namespace-conflict-code.test.ts b/packages/runtime/src/package-door-namespace-conflict-code.test.ts index 80d25514c2a..55c1fb815fc 100644 --- a/packages/runtime/src/package-door-namespace-conflict-code.test.ts +++ b/packages/runtime/src/package-door-namespace-conflict-code.test.ts @@ -1,14 +1,14 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14748] `POST /api/v1/packages` answers a namespace collision with + * [commit 92b5d7f00] `POST /api/v1/packages` answers a namespace collision with * `error.code: NAMESPACE_CONFLICT` — the wire half of registering the code in * `ERROR_CODE_LEDGER`. * * ## What changed, and why a pin belongs here rather than beside the throw * * `NamespaceConflictError` (`packages/objectql/src/registry.ts`) has carried - * the ADR-0112 envelope (`code` + `status: 422`) since #14474, and + * the ADR-0112 envelope (`code` + `status: 422`) since commit df657d9df, and * `packages/objectql/src/registry-namespace-install-gate.test.ts` asserts both * fields ON THE THROW. That is a different claim from this one. Until the * ledger row landed, `NAMESPACE_CONFLICT` was not an `ErrorCode` member, so the diff --git a/packages/runtime/src/resolve-project-database.ts b/packages/runtime/src/resolve-project-database.ts index 894a8bb7014..d96a7a10f62 100644 --- a/packages/runtime/src/resolve-project-database.ts +++ b/packages/runtime/src/resolve-project-database.ts @@ -110,7 +110,7 @@ export interface ResolveProjectDatabaseUrlOptions { * Explicit driver selection (`--database-driver` / config). Only `memory` * changes URL resolution (no file default is imposed for an explicitly * in-memory boot); other values select engines, not URLs, and their - * vocabulary is #6345's seam — deliberately not judged here. + * vocabulary is the shared table's seam (commit e2798fab7) — deliberately not judged here. */ explicitDriver?: string; /** Environment to read (`process.env` by default; tests inject their own). */ @@ -180,7 +180,7 @@ function resolveDatabaseStateDir(opts: { * through to the unified default, which is what those projects got before * this tier existed. (Driver-id spellings resolve through the spec's ONE * alias table, `resolveDriverId` — including `turso`/`libsql`, which became - * rows in it in #6345 and no longer need a local special-case here.) + * rows in it in commit e2798fab7 and no longer need a local special-case here.) */ function readConfigDeclaredDefault(opts: { artifactPath?: string; @@ -237,7 +237,7 @@ function readConfigDeclaredDefault(opts: { /** Express a declared datasource's connection as a database URL, or `undefined`. */ function datasourceUrlOf(ds: { driver?: unknown; config?: unknown }, projectRoot?: string): string | undefined { const config = (ds.config ?? {}) as { filename?: unknown; url?: unknown }; - // Since #6345 `turso`/`libsql` are rows in the shared table like every other + // Since commit e2798fab7 `turso`/`libsql` are rows in the shared table like every other // builtin, so the local special-case they needed while turso had no config // contract is gone — one lookup answers for all of them. const canonical = resolveDriverId(ds.driver); @@ -289,7 +289,7 @@ export function resolveProjectDatabaseUrl( // An explicitly in-memory boot gets no file default imposed on it. Only // `memory` is judged here; unknown driver values are refused downstream // (`resolveExplicitDriver`) with the full legal-values list. - // Resolved through the shared table (#6345): `OS_DATABASE_DRIVER=mingo` is an + // Resolved through the shared table (commit e2798fab7): `OS_DATABASE_DRIVER=mingo` is an // accepted spelling of `memory` on both hosts, so it must reach this rung // too — a raw string compare would have imposed the unified default FILE on // a boot that explicitly asked for the in-memory engine. diff --git a/packages/runtime/src/sandbox/body-runner.ts b/packages/runtime/src/sandbox/body-runner.ts index b15bbd1ed3c..f80fbb0ec97 100644 --- a/packages/runtime/src/sandbox/body-runner.ts +++ b/packages/runtime/src/sandbox/body-runner.ts @@ -907,7 +907,7 @@ function buildSandboxContext( // dispatches for one write, and its params bag has no caller options. dispatch, inputOptions, - // [#13644] The declared referential-cleanup marker, carried across the + // [commit 34ce8e7db] The declared referential-cleanup marker, carried across the // sandbox boundary BY CONTRACT — copied only in its declared shape // (`true`), the same unrecognised-shape rule as `dispatch` above: anything // else is left ABSENT, so `ctx.referentialFieldClear === true` reads "not @@ -953,7 +953,7 @@ function buildActionSandboxContext( // downstream writes it back. `warnDiscardedRecordWrites` reports the writes // a body makes to it rather than letting them vanish. record: unwrapProxyToPlain(actionCtx?.record), - // [#14143] The caller-scope load's verdict, marshalled EXPLICITLY for the + // [commit f19475c0a] The caller-scope load's verdict, marshalled EXPLICITLY for the // same reason `dispatch` / `referentialFieldClear` are on the hook face: a // body cannot reach the dispatcher's locals, and `ctx.record.id` is stamped // even when the caller cannot read the row, so without this key an action diff --git a/packages/runtime/src/sandbox/error-passthrough.test.ts b/packages/runtime/src/sandbox/error-passthrough.test.ts index d37925095cc..458b6329d48 100644 --- a/packages/runtime/src/sandbox/error-passthrough.test.ts +++ b/packages/runtime/src/sandbox/error-passthrough.test.ts @@ -239,7 +239,7 @@ describe('[#7867] an error that names its own HTTP status keeps it across the bo }); /* ──────────────────────────────────────────────────────────────────────────── - * [#9934] `userMessage` — the fourth allowlisted property: the producer-side + * [commit 79c46da90] `userMessage` — the fourth allowlisted property: the producer-side * user-facing marking (objectui#5210 ruling). A sandboxed BODY is the authoring * surface the marking exists for, so the author's opt-in must survive the VM * flattening the throw to a string — in both directions, like the other three. diff --git a/packages/runtime/src/sandbox/quickjs-runner.ts b/packages/runtime/src/sandbox/quickjs-runner.ts index 3bec6358b00..1bee8ba0bed 100644 --- a/packages/runtime/src/sandbox/quickjs-runner.ts +++ b/packages/runtime/src/sandbox/quickjs-runner.ts @@ -538,7 +538,7 @@ export class QuickJSScriptRunner implements ScriptRunner { if (ctx.result !== undefined) { setObjectJson(vm, ctxObj, 'result', ctx.result); } - // [#13644] The declared referential-cleanup marker — installed only in its + // [commit 34ce8e7db] The declared referential-cleanup marker — installed only in its // declared shape (`true`), absent otherwise, so a body reads // `ctx.referentialFieldClear === true` with the spec's own back-compatible // absence semantics. A plain boolean: no freeze/graft ceremony needed — @@ -547,7 +547,7 @@ export class QuickJSScriptRunner implements ScriptRunner { if (ctx.referentialFieldClear === true) { vm.setProp(ctxObj, 'referentialFieldClear', vm.true); } - // [#14143] The action face's caller-scope load verdict — same true-only + // [commit f19475c0a] The action face's caller-scope load verdict — same true-only // installation, same reason: a body reads `ctx.recordLoadDenied === true` // and an absent key means "nothing was refused". A plain boolean, so no // freeze/graft ceremony is needed (the write-back channel reads only @@ -1243,7 +1243,7 @@ function safeJsonStringify(v: unknown): string { * nothing downstream needed teaching; the number simply never arrived. A * number, like `code`, carries no host state. * - * [#9934] `userMessage` is the fourth member — the producer-side user-facing + * [commit 79c46da90] `userMessage` is the fourth member — the producer-side user-facing * marking (see `declaredUserMessage` in `@objectstack/types`). A hook or * action BODY is the authoring surface the marking exists for: an app author * writes `const e = new Error(msg); e.userMessage = msg; throw e`, and the @@ -1289,7 +1289,7 @@ function hostErrorToVm(vm: QuickJSContext, err: unknown): QuickJSHandle { vm.setProp(errH, 'status', h); h.dispose(); } - // [#9934] Non-empty strings only, same one-read rule as every other + // [commit 79c46da90] Non-empty strings only, same one-read rule as every other // boundary (`declaredUserMessage`): a blank or non-string value is not a // declaration and must not become one by crossing the VM. if (typeof e?.userMessage === 'string' && e.userMessage.trim().length > 0) { @@ -1619,7 +1619,7 @@ export class SandboxError extends Error { */ readonly status?: number; /** - * [#9934] The user-facing refusal text the error that crossed OUT of the VM + * [commit 79c46da90] The user-facing refusal text the error that crossed OUT of the VM * was marked with — the producer-side opt-in of the objectui#5210 ruling. A * body that throws `e.userMessage = '…'` is saying that exact text is * addressed to the END USER; the HTTP boundaries carry it to the wire's @@ -1645,7 +1645,7 @@ export interface SandboxErrorInfo { fields?: unknown[]; /** [#7867] See {@link SandboxError.status}. */ status?: number; - /** [#9934] See {@link SandboxError.userMessage}. */ + /** [commit 79c46da90] See {@link SandboxError.userMessage}. */ userMessage?: string; /** * [#4431] The error that crossed `__error` was the SANDBOX's own fault — a @@ -1686,7 +1686,7 @@ function readErrorInfo(vm: QuickJSContext): SandboxErrorInfo | undefined { // number JSON-round-trips to `null`, and `NaN` would satisfy `typeof` while // making `errorFromThrown` emit a nonsense status line. if (typeof p?.status === 'number' && Number.isFinite(p.status)) info.status = p.status; - // [#9934] Non-empty strings only — the same "what counts as marked" rule as + // [commit 79c46da90] Non-empty strings only — the same "what counts as marked" rule as // `declaredUserMessage` (`@objectstack/types`), applied at this boundary too. if (typeof p?.userMessage === 'string' && p.userMessage.trim().length > 0) info.userMessage = p.userMessage; if (p?.sandboxFault === true) info.sandboxFault = true; diff --git a/packages/runtime/src/sandbox/referential-field-clear-signal.integration.test.ts b/packages/runtime/src/sandbox/referential-field-clear-signal.integration.test.ts index e44768b052d..7df2393cef7 100644 --- a/packages/runtime/src/sandbox/referential-field-clear-signal.integration.test.ts +++ b/packages/runtime/src/sandbox/referential-field-clear-signal.integration.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#13644] The declared referential-cleanup marker, OBSERVED FROM INSIDE A + * [commit 34ce8e7db] The declared referential-cleanup marker, OBSERVED FROM INSIDE A * SHIPPED BODY — the sandbox-reachability mandate of the adoption ruling. * * ## What is pinned, and why a kernel rig could not pin it @@ -124,7 +124,7 @@ describe('#13644 — a shipped body observes ctx.referentialFieldClear across th body: { language: 'js', source: PROBE_SOURCE, capabilities: ['log'] }, } as any], { packageId: 'probe' }); - // The REST-shaped caller envelope — the corrected #13644 measurement's + // The REST-shaped caller envelope — the corrected measurement's (commit 34ce8e7db) // row 1, on which every other context member is identical between the // engine's cascade and the user's hand-clear. const CALLER = { userId: 'u_probe', isSystem: true }; diff --git a/packages/runtime/src/sandbox/script-runner.ts b/packages/runtime/src/sandbox/script-runner.ts index 2a92d9643b8..2b834a43246 100644 --- a/packages/runtime/src/sandbox/script-runner.ts +++ b/packages/runtime/src/sandbox/script-runner.ts @@ -224,7 +224,7 @@ export interface ScriptContext { dispatch?: { mode: 'record' | 'per-row'; index: number }; /** * The engine's referential-cleanup marker, marshalled for the HOOK face - * (#13644) — `true` exactly when this write is the engine's own reference + * (commit 34ce8e7db) — `true` exactly when this write is the engine's own reference * cleanup (the `set_null` cascade UPDATE clearing, or on a `multiple: true` * lookup member-removing, a lookup that references a record being deleted). * Mirrors the declared `HookContextSchema.referentialFieldClear` @@ -305,7 +305,7 @@ export interface ScriptContext { /** * Action only: `true` exactly when the dispatcher ATTEMPTED to load the * subject row in the CALLER's own scope and that load did not deliver it - * (#14143). Absent otherwise — including on every record-less / new-record + * (commit f19475c0a). Absent otherwise — including on every record-less / new-record * action, which never attempts a load — so read it as * `ctx.recordLoadDenied === true`, the same absence semantics as * {@link referentialFieldClear}. diff --git a/packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts b/packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts index ab96141e49a..f6f803b94b6 100644 --- a/packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts +++ b/packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts @@ -21,7 +21,7 @@ * It neither rejects the unknown key nor strips it. * 3. `engine.ts` hands the row to `driver.create` / the driver's update. * - * ...and, until #13657, the driver decided — so the two families disagreed: + * ...and, until commit b003cf2e8, the driver decided — so the two families disagreed: * * • SQL — the stray column reached the statement and the WHOLE write failed. * Nothing was stored, and the error named a column, not a field, far from @@ -29,7 +29,7 @@ * • Schemaless (memory, and MongoDB on the same `...data` spread) — the key * WAS persisted, as an undeclared column nothing downstream reads. * - * [#13657] That divergence is CLOSED. The declared-field door now has a + * [commit b003cf2e8] That divergence is CLOSED. The declared-field door now has a * POST-hook half (`undeclaredWriteFieldErrors`, run again over the payload the * `before*` hooks produced, before any statement is built), so a body-written * undeclared key is refused by the object's FIELD MAP — `INVALID_FIELD` / 400, @@ -83,7 +83,7 @@ * sentences fail until they are rewritten — which is the half a sentence could * never do for itself (#6664, ruling C). * - * Why it has to stay — and the reason survives #13657 intact, one word over. + * Why it has to stay — and the reason survives commit b003cf2e8 intact, one word over. * This file used to pin a PRODUCT DIVERGENCE between two driver families * (rejected as a whole statement by SQL, accepted verbatim by the schemaless * family); it now pins the CONVERGENCE that replaced it. Either way the claim @@ -93,7 +93,7 @@ * behaves the same on the same `...data` spread, but would put a real database * in CI's path). Delete this arm and the guardrail silently becomes a one-sided * assertion about SQL — and "identical on every driver", the whole point of - * #13657, stops being pinned at all. ⚠️ If anything, the schemaless arm matters + * commit b003cf2e8, stops being pinned at all. ⚠️ If anything, the schemaless arm matters * MORE now: it is the family that used to accept the key, so it is the arm that * would witness a regression first. * @@ -220,9 +220,9 @@ const CORRECT_HOOK = { * The subject is unchanged and still measured on both families: a key a BODY * writes is added AFTER the PRE-hook door, so `applyMutationsToInput` → * `validateRecord`'s `if (!def) continue` is still intact and still proved - * here. [#13657] What it reaches is no longer the driver: the POST-hook half of + * here. [commit b003cf2e8] What it reaches is no longer the driver: the POST-hook half of * the door refuses it first, on both families. The caller-payload half has its - * own cases below, pinning the pre-hook door — which #13657 deliberately did + * own cases below, pinning the pre-hook door — which commit b003cf2e8 deliberately did * NOT move, since #8737 put it ahead of the hooks so a refused payload consumes * no autonumber. */ @@ -261,7 +261,7 @@ describe('#4271 / #13657 an undeclared field written by an L2 body — one answe // a memory boot declares an EMPTY expectation, so this still fails loudly if // a boot ever forgets to install a capture at all. // - // [#13657] `required` is narrowed to nothing — the documented remedy for + // [commit b003cf2e8] `required` is narrowed to nothing — the documented remedy for // "a table read on only SOME of a file's paths", which is what // `sys_organization` became here. The single-tenant probe runs on the way // to the STATEMENT, and the post-hook door now refuses the body-written @@ -312,12 +312,12 @@ describe('#4271 / #13657 an undeclared field written by an L2 body — one answe return engine; } - // ─── [#13657] Both families, one answer ─────────────────────────────────── + // ─── [commit b003cf2e8] Both families, one answer ───────────────────────── /** - * [#13657] What this block used to pin, and why it does not any more. + * [commit b003cf2e8] What this block used to pin, and why it does not any more. * - * Until #13657 these were two arms because the runtime gave two answers to + * Until commit b003cf2e8 these were two arms because the runtime gave two answers to * one question. A key an L2 body wrote was added AFTER the declared-field * door (#8682 / #8738, moved ahead of the hooks by #8737), so nothing between * `applyMutationsToInput` and the driver judged it, and the DRIVER decided: @@ -331,7 +331,7 @@ describe('#4271 / #13657 an undeclared field written by an L2 body — one answe * name, one that field-level security can never gate. * * One app, one body, two meanings decided by which driver a deployment - * happened to run — and nothing in the app could tell which. #13657 added the + * happened to run — and nothing in the app could tell which. Commit b003cf2e8 added the * POST-hook half of the door, so the key is now refused by the object's FIELD * MAP before any statement is built. There is no driver left to disagree. * @@ -354,7 +354,7 @@ describe('#4271 / #13657 an undeclared field written by an L2 body — one answe const err: any = await e.insert('deal', { stage: 'open', amount: 10 }).catch((x: unknown) => x); - // The caller path's answer, on both families. Before #13657 this read + // The caller path's answer, on both families. Before commit b003cf2e8 this read // `code: 'SQLITE_ERROR', status: undefined` on SQL and no error at all on // memory. expect(err?.code).toBe('INVALID_FIELD'); @@ -479,7 +479,7 @@ describe('#4271 / #13657 an undeclared field written by an L2 body — one answe * from, and they are about DIFFERENT call shapes: * * • the L2 BODY block mutates `ctx.input`, which the engine folds into the - * CALLER's payload — refused by the POST-hook half of the door (#13657); + * CALLER's payload — refused by the POST-hook half of the door (commit b003cf2e8); * • the CALLER block hands the engine a payload directly — refused by the * PRE-hook half (#8682 / #8738). * diff --git a/packages/runtime/src/security/artifact-granted-permissions.test.ts b/packages/runtime/src/security/artifact-granted-permissions.test.ts index e2346356ad8..5304f9922bf 100644 --- a/packages/runtime/src/security/artifact-granted-permissions.test.ts +++ b/packages/runtime/src/security/artifact-granted-permissions.test.ts @@ -15,7 +15,7 @@ // through the binding record alone — the binding record is what this module // says it did, the enforcer is what actually happened. // -// ⛔ VERB DISCIPLINE (#17147). Every case here reads a permission BAG and +// ⛔ VERB DISCIPLINE (commit aaacf1d5c). Every case here reads a permission BAG and // asserts what it ANSWERS. None of them asserts that anything was refused, and // none of them could: nothing on this tree queries the registry these entries // land in — `SecurePluginContext` has no production construction site, and the diff --git a/packages/runtime/src/security/artifact-granted-permissions.ts b/packages/runtime/src/security/artifact-granted-permissions.ts index bf2cf9801c8..252a36a39e1 100644 --- a/packages/runtime/src/security/artifact-granted-permissions.ts +++ b/packages/runtime/src/security/artifact-granted-permissions.ts @@ -3,7 +3,7 @@ /** * The artifact→enforcer seam: bind the install-time GRANTED permission set an * environment artifact carries to the plugins that artifact materializes - * (ADR-0025 §3.5 step 2 / F4, #11333 option A phase 1). + * (ADR-0025 §3.5 step 2 / F4; option A phase 1, landed in commit ea4d16420). * * ## What this is the consumer half of * diff --git a/packages/runtime/src/security/resolve-execution-context.ts b/packages/runtime/src/security/resolve-execution-context.ts index 21dbf185c68..2715fa7759d 100644 --- a/packages/runtime/src/security/resolve-execution-context.ts +++ b/packages/runtime/src/security/resolve-execution-context.ts @@ -221,7 +221,7 @@ export async function resolveExecutionContext(opts: ResolveOptions): Promise Date: Tue, 29 Sep 2026 16:44:52 +0800 Subject: [PATCH 2/3] docs(runtime): re-anchor the remaining dead tracker citations to their deciding commits Every other comment and docblock line under packages/runtime/src, tests included, that cited a tracker number answering 404 now cites the commit in this repository's history that decided what the line describes, and says in its own words what was decided. Eight sites stay as they were: an open or never-landed card has no deciding commit, and one comment is read literally by a test. Comments only; every touched file keeps its line count. Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289 Co-authored-by: Claude --- ...action-governance-scope-divergence.test.ts | 18 ++++----- .../action-object-less-key-agreement.test.ts | 2 +- .../action-owner-key-single-source.test.ts | 18 ++++----- .../src/action-params-enforcement.test.ts | 2 +- ...nalytics-query-read-scope-withhold.test.ts | 6 +-- packages/runtime/src/api-exposure.test.ts | 6 +-- packages/runtime/src/api-mapping.ts | 2 +- .../src/app-plugin.job-data-reach.test.ts | 2 +- .../app-plugin.job-degraded-outcome.test.ts | 2 +- .../app-plugin.seed-locale-producer.test.ts | 2 +- .../artifact-function-declarations.test.ts | 2 +- ...river-text-real-driver.integration.test.ts | 22 +++++----- ...ttp-status-real-driver.integration.test.ts | 8 ++-- ...bulk-write-real-driver.integration.test.ts | 8 ++-- ...lue-lookup-real-driver.integration.test.ts | 8 ++-- ...oss-field-refusal-operand-withhold.test.ts | 6 +-- .../src/default-datasource-plugin.test.ts | 6 +-- .../runtime/src/degraded-boot-parity.test.ts | 2 +- ...spatcher-5xx-demoted-code-withhold.test.ts | 16 ++++---- .../src/dispatcher-error-vocabulary.ts | 16 ++++---- ...plugin.declared-5xx-prose-withhold.test.ts | 6 +-- ...tcher-plugin.declared-user-message.test.ts | 8 ++-- packages/runtime/src/dispatcher-plugin.ts | 14 +++---- .../action-activation-posture-gate.test.ts | 4 +- .../actions-fault-vs-rejection.test.ts | 8 ++-- packages/runtime/src/domains/actions.ts | 4 +- ...tion-gate-positions-name-authority.test.ts | 4 +- .../runtime/src/domains/activation-gate.ts | 10 ++--- ...automation-activation-posture-gate.test.ts | 6 +-- .../automation-resume-envelope.test.ts | 4 +- .../automation-resume-value-shape.test.ts | 8 ++-- .../automation-run-lifecycle-door.test.ts | 4 +- .../automation-toggle-deny-message.test.ts | 4 +- .../automation-toggle-unknown-flow.test.ts | 2 +- .../automation-write-capability-gate.test.ts | 10 ++--- packages/runtime/src/domains/automation.ts | 40 +++++++++---------- .../src/domains/mcp-merged-skill-read.test.ts | 4 +- packages/runtime/src/domains/mcp.ts | 10 ++--- .../meta-save-destructive-remedy.test.ts | 10 ++--- .../meta-state-plural-tolerance.test.ts | 2 +- .../src/domains/meta-verb-fallthrough.test.ts | 2 +- packages/runtime/src/domains/meta.ts | 32 +++++++-------- .../packages-list-enabled-filter.test.ts | 4 +- .../packages-seed-apply-org-scope.test.ts | 8 ++-- packages/runtime/src/domains/packages.ts | 18 ++++----- .../scoped-service-miss-attribution.test.ts | 2 +- .../tenancy-posture-outage-gates.test.ts | 4 +- packages/runtime/src/domains/ui.ts | 2 +- ...nested-fields-join-key.integration.test.ts | 8 ++-- ...ad-refusal-noise.channel-asymmetry.test.ts | 10 ++--- .../src/expected-read-refusal-noise.ts | 24 +++++------ .../external-validation-checkonboot.test.ts | 6 +-- .../external-validation-drift-scope.test.ts | 2 +- .../src/external-validation-plugin.test.ts | 8 ++-- .../runtime/src/external-validation-plugin.ts | 30 +++++++------- .../src/federated-boot-binding.test.ts | 6 +-- packages/runtime/src/flow-clone.ts | 2 +- ...http-dispatcher.actions-global-key.test.ts | 2 +- ...her.permission-denied-user-message.test.ts | 4 +- packages/runtime/src/http-dispatcher.test.ts | 8 ++-- packages/runtime/src/http-dispatcher.ts | 4 +- packages/runtime/src/index.ts | 2 +- packages/runtime/src/load-artifact-bundle.ts | 2 +- .../src/meta-compound-arity-mint-door.test.ts | 6 +-- .../runtime/src/meta-write-org-scope.test.ts | 10 ++--- ...nt-vs-bare-transaction.integration.test.ts | 18 ++++----- ...ion-schema-conformance.integration.test.ts | 18 ++++----- .../notifications.hono.integration.test.ts | 12 +++--- ...list-commits-org-scope.integration.test.ts | 8 ++-- ...-attribution-org-scope.integration.test.ts | 8 ++-- ...evert-commit-org-scope.integration.test.ts | 8 ++-- .../src/package-service.null-seam.test.ts | 4 +- ...erve-audit-real-driver.integration.test.ts | 8 ++-- .../src/route-ledger.conformance.test.ts | 2 +- packages/runtime/src/route-ledger.ts | 4 +- .../runtime/src/sandbox/body-runner.test.ts | 4 +- packages/runtime/src/sandbox/body-runner.ts | 26 ++++++------ ...nput-writeback-key-set.integration.test.ts | 2 +- ...ck-readonly-provenance.integration.test.ts | 16 ++++---- ...nested-hook-refusal-is-a-rejection.test.ts | 2 +- ...sted-write-real-sqlite.integration.test.ts | 8 ++-- ...perrow-dispatch-signal.integration.test.ts | 2 +- .../runtime/src/sandbox/quickjs-runner.ts | 6 +-- ...ial-field-clear-signal.integration.test.ts | 2 +- packages/runtime/src/sandbox/script-runner.ts | 6 +-- ...eld-write-driver-split.integration.test.ts | 12 +++--- .../resolve-execution-context.test.ts | 4 +- .../src/security/resolve-execution-context.ts | 6 +-- ...river-text-real-driver.integration.test.ts | 8 ++-- ...lue-lookup-real-driver.integration.test.ts | 8 ++-- ...nancy-autonumber-split.integration.test.ts | 4 +- ...lone-stack-seeder-declaration-copy.test.ts | 8 ++-- .../src/standalone-stack.libsql.test.ts | 4 +- .../src/standalone-stack.mysql.test.ts | 4 +- packages/runtime/src/standalone-stack.ts | 22 +++++----- .../turso-driver-factory.convergence.test.ts | 4 +- packages/runtime/src/turso-driver-factory.ts | 22 +++++----- 97 files changed, 396 insertions(+), 396 deletions(-) diff --git a/packages/runtime/src/action-governance-scope-divergence.test.ts b/packages/runtime/src/action-governance-scope-divergence.test.ts index 3d506d622ec..5828a05df90 100644 --- a/packages/runtime/src/action-governance-scope-divergence.test.ts +++ b/packages/runtime/src/action-governance-scope-divergence.test.ts @@ -1,9 +1,9 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14423 (a) — the AGREEMENT, where this file used to pin the divergence. + * Commit a56baa2bd — the AGREEMENT, where this file used to pin the divergence. * - * The two sites the card names: + * The two sites that diverged: * - the AUDIT, `runActionGovernanceInventory` (`packages/objectql/src/ * action-governance.ts`), whose metadata-plane sources are now * `loadStandaloneActionsKeyed = () => meta.loadManyKeyed('action')` and the @@ -13,7 +13,7 @@ * whose third rung is `meta.loadDiagnosed('action', name)` — resolved per * request off `deps.resolveService(requestContext, 'metadata', envId)`. * - * PR #14421 closed the registry rung. This file measured the remaining one and + * Commit bd8795ea1 closed the registry rung. This file measured the remaining one and * reproduced it four ways; the measurement is now the fix's pin, case for * case, with the same harness. **C1 and C5 are unchanged controls** — they * were green before and must stay green, because a "fix" that simply stopped @@ -184,7 +184,7 @@ function auditAccused(warnings: Array<{ message: string; meta?: Record loadManyKeyed.call(meta, 'action') : undefined, - lookupRegistryAction: () => undefined, // rung 2 holds nothing — #14421's rung is not the one under test + lookupRegistryAction: () => undefined, // rung 2 holds nothing — commit bd8795ea1's rung is not the one under test lookupMetadataAction: meta && typeof loadDiagnosed === 'function' ? async (name: string) => (await loadDiagnosed.call(meta, 'action', name))?.data : (meta && typeof load === 'function' ? (name: string) => load.call(meta, 'action', name) : undefined), @@ -323,7 +323,7 @@ describe('#14423 (a) — the audit and the router now answer from one identity a // The keyed enumeration is short for the same reason — keying is not a // cure for an unreachable loader, and does not claim to be. expect(await meta.loadManyKeyed('action')).toEqual([]); - // [#14423 item 1] ...and the sibling enumeration no longer THROWS where + // [commit a56baa2bd] ...and the sibling enumeration no longer THROWS where // its two siblings merely came back short. await expect(meta.listNames('action')).resolves.toEqual([]); @@ -335,7 +335,7 @@ describe('#14423 (a) — the audit and the router now answer from one identity a }); /** - * C4 — a BOUNDARY, not a defect, and pinned as one. NARROWER since #16610. + * C4 — a BOUNDARY, not a defect, and pinned as one. NARROWER since commit 316a20fc5. * * `metadata` is registered `SCOPED`, so `PluginLoader.getService` mints one * instance per `scopeId`. The kernel's RAW SYNCHRONOUS accessor @@ -348,7 +348,7 @@ describe('#14423 (a) — the audit and the router now answer from one identity a * plane. That asymmetry is what every assertion below exercises — the * accessor, directly, never the plugin's wiring around it. * - * ## What the PLUGIN does with that accessor, after #16610 + * ## What the PLUGIN does with that accessor, after commit 316a20fc5 * * `ObjectQLPlugin.resolveGovernanceMetadataService` no longer calls the * synchronous accessor alone, so the throw is no longer swallowed into @@ -363,7 +363,7 @@ describe('#14423 (a) — the audit and the router now answer from one identity a * ⚠ So do NOT read the paragraph above as a live defect in `plugin.ts`. * It describes the rung the plugin now reaches for SECOND, and this case * pins that rung's behaviour — which is why its assertions stay green and - * stay true across #16610. + * stay true across commit 316a20fc5. * * ## Why this stays accused, and why that is CORRECT * diff --git a/packages/runtime/src/action-object-less-key-agreement.test.ts b/packages/runtime/src/action-object-less-key-agreement.test.ts index 865c95c48f1..2f1ff942a19 100644 --- a/packages/runtime/src/action-object-less-key-agreement.test.ts +++ b/packages/runtime/src/action-object-less-key-agreement.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * "Object-less" has ONE answer inside `action-execution.ts` (#14864). + * "Object-less" has ONE answer inside `action-execution.ts` (commit 066dd3bd0). * * `isObjectLessActionKey` (`@objectstack/objectql`) is the canonical predicate: * the routed object is object-less when it is the canonical diff --git a/packages/runtime/src/action-owner-key-single-source.test.ts b/packages/runtime/src/action-owner-key-single-source.test.ts index d88a457faef..ca333fdb473 100644 --- a/packages/runtime/src/action-owner-key-single-source.test.ts +++ b/packages/runtime/src/action-owner-key-single-source.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * The standalone-action owner-key ladder has ONE spelling (#14422). + * The standalone-action owner-key ladder has ONE spelling (commit dc7c226b9). * * `action.objectName` -> `action.object` -> the object-less * `GLOBAL_ACTION_OBJECT_KEY` decides which engine key a standalone `action` @@ -26,16 +26,16 @@ * B reads this package's own source and fails if the ladder grows a second * body here. * - * Half C closes the same hole one level down (#14678). #14422 converged the + * Half C closes the same hole one level down (commit 73ad0bba7). Commit dc7c226b9 converged the * LADDER, and the runtime kept three bare `'global'` spellings elsewhere in * `action-execution.ts` that the ladder check could not see: a live comparison * in `seedFlowActionParams`, a warn-once log key in `enforceActionParams`, and * a docblock. All three were equal in value and invisible to every test in the - * repo, which is the whole shape #14422 was filed to remove — so the same + * repo, which is the whole shape commit dc7c226b9 was written to remove — so the same * convergence needed the same weld, or the next reader re-inlines one and * nothing says so. * - * Half D (#14878) is the odd one out and says so at its own section below: it + * Half D (commit 29db3cd2a) is the odd one out and says so at its own section below: it * is not about this package's source at all. It is the TREE-scoped absence pin * for the plugin member this convergence deleted, carried here as well as in * `@objectstack/objectql` so that losing either copy still leaves a guard. @@ -157,14 +157,14 @@ describe('standalone-action owner key — half C: no bare literal (#14678)', () // file was written to replace. Both controls are positive assertions // against text the converged file must carry. // - // [#14864] The second control used to be the `seedFlowActionParams` + // [commit 066dd3bd0] The second control used to be the `seedFlowActionParams` // comparison `objectName !== GLOBAL_ACTION_OBJECT_KEY`. That guard is // gone — it was one of the two rival answers to "is this route // object-less", and it now delegates to `isObjectLessActionKey` like // its neighbours. Re-anchored rather than deleted, and deliberately // onto a site this file's own subject does not move: the warn-once log // key in `enforceActionParams`, which is the SECOND of the three bare - // literals #14678 converged and is untouched by the predicate work. + // literals commit 73ad0bba7 converged and is untouched by the predicate work. // ⛔ Do not re-anchor a control onto the thing the next change is most // likely to edit — a control that moves with its subject stops being a // control. @@ -184,9 +184,9 @@ describe('standalone-action owner key — half C: no bare literal (#14678)', () }); /** - * ── Half D [#14878]: the absence assertion is TREE-scoped, not FILE-scoped ─── + * ── Half D [commit 29db3cd2a]: the absence assertion is TREE-scoped, not FILE-scoped ─── * - * #14667 deleted a private `actionObjectKey` member from `ObjectQLPlugin` and + * Commit dc7c226b9 deleted a private `actionObjectKey` member from `ObjectQLPlugin` and * DID write a guard for it — `not.toContain(...)` against `plugin.ts`. The kind * of guard was right; its SCOPE was the defect. A pin written by the deleting PR * can only look where its author thought to look, and the whole failure mode is @@ -260,7 +260,7 @@ describe('standalone-action owner key — half C: no bare literal (#14678)', () */ /** - * The member #14667 deleted from `ObjectQLPlugin`. Held as DATA: naming a symbol + * The member commit dc7c226b9 deleted from `ObjectQLPlugin`. Held as DATA: naming a symbol * in a string cannot resurrect it, and this file is excluded from its own scan * precisely so it may carry the name. */ diff --git a/packages/runtime/src/action-params-enforcement.test.ts b/packages/runtime/src/action-params-enforcement.test.ts index 041bacdc95b..612474201d4 100644 --- a/packages/runtime/src/action-params-enforcement.test.ts +++ b/packages/runtime/src/action-params-enforcement.test.ts @@ -2,7 +2,7 @@ /** * `enforceActionParams` — the ADR-0104 D2 gate itself, not its validator - * (#14864). + * (commit 066dd3bd0). * * ## What was measured, and why this file exists * diff --git a/packages/runtime/src/analytics-query-read-scope-withhold.test.ts b/packages/runtime/src/analytics-query-read-scope-withhold.test.ts index b222b089376..5b8617ce0a6 100644 --- a/packages/runtime/src/analytics-query-read-scope-withhold.test.ts +++ b/packages/runtime/src/analytics-query-read-scope-withhold.test.ts @@ -44,7 +44,7 @@ * withhold got broader" and "the withhold swallowed everything" are one edit * apart. * - * ⚠️ [#12281] The DECLARED half of that predicate has since widened, and this + * ⚠️ [commit 0783d7b80] The DECLARED half of that predicate has since widened, and this * file's half-envelope case was reversed with it. `declaresServerFault` required * a non-empty string `code` beside the 5xx and read the `status` spelling only, * so this exit withheld a NARROWER band than `/data`. Ruled 2026-08-27 on #12509 @@ -270,12 +270,12 @@ describe('[#5811] POST /analytics/query — a read-scope failure says nothing ab }); it('[#12281] a 5xx with only HALF an envelope is ALSO withheld — a status alone declares it', async () => { - // ⚠️ REVERSED, deliberately. Until #12281 this case asserted the opposite + // ⚠️ REVERSED, deliberately. Until commit 0783d7b80 this case asserted the opposite // ("a code is required, not just a status"), on the reasoning that a // producer shipping a status without a code "has not declared anything". // // The maintainer ruled otherwise on #12509, 2026-08-27 (option D), - // propagated to #12281: `errorResponseBase` adopts the structural + // landed in commit 0783d7b80: `errorResponseBase` adopts the structural // withhold for EVERY declared 5xx message, aligning to `/data` — whose // `declaredHttpStatus` never looked at `code` at all. Naming a 5xx status // IS the declaration; the code is a second, independent channel (#9106), diff --git a/packages/runtime/src/api-exposure.test.ts b/packages/runtime/src/api-exposure.test.ts index 0b3ebda877f..970eb693e91 100644 --- a/packages/runtime/src/api-exposure.test.ts +++ b/packages/runtime/src/api-exposure.test.ts @@ -111,7 +111,7 @@ describe('checkApiExposure (#1889)', () => { expect(checkApiExposure(createOnly, 'import', { writeMode: 'update' }).allowed).toBe(false); }); - // [#6259] Was spelled `'batch'`, which reached this rule only through the + // [commit 6968885ef] Was spelled `'batch'`, which reached this rule only through the // `batch: 'bulk'` alias row — a spelling no producer sends (`callData` lost // its `batch` arm in #5856; REST gates `/batch` on `'bulk'`). With the row // gone `'batch'` is an unknown operation and falls to the ungated @@ -126,7 +126,7 @@ describe('checkApiExposure (#1889)', () => { expect(checkApiExposure(createOnly, 'bulk', { bulkChild: 'create' }).allowed).toBe(false); }); - // [#6259] The absence pin's runtime half: `batch` is no longer a spelling + // [commit 6968885ef] The absence pin's runtime half: `batch` is no longer a spelling // this gate understands. It is NOT denied — an unmapped action respects // `apiEnabled` only — which is exactly why the row could not be left in // place as "harmless": it silently bought a bulk∧child judgement for a @@ -138,7 +138,7 @@ describe('checkApiExposure (#1889)', () => { expect(checkApiExposure({ apiEnabled: false }, 'batch').status).toBe(404); }); - // [#6259] The prose half of the same finding: this function's `@param` + // [commit 6968885ef] The prose half of the same finding: this function's `@param` // listed `batch` among the runtime data actions its only caller sends. it('the `@param action` TSDoc does not advertise `batch` as a live action', () => { const source = fs.readFileSync( diff --git a/packages/runtime/src/api-mapping.ts b/packages/runtime/src/api-mapping.ts index 2a72e54c794..9af1c67d7b1 100644 --- a/packages/runtime/src/api-mapping.ts +++ b/packages/runtime/src/api-mapping.ts @@ -26,7 +26,7 @@ * * Five short sentences, and everything below is the MINIMAL faithful reading of * them — `transform`'s now says out loud, at the point of authoring, what this - * module and the E7 publish gate have always answered at rejection time (#6065). + * module and the E7 publish gate have always answered at rejection time (commit 026101660). * Where the text is silent this module takes the least expressive option * available and says so here, because the alternative — inventing expression * power (a template language, JSONPath, wildcards, conditionals) — would put a diff --git a/packages/runtime/src/app-plugin.job-data-reach.test.ts b/packages/runtime/src/app-plugin.job-data-reach.test.ts index 5a362081565..c072268c4f7 100644 --- a/packages/runtime/src/app-plugin.job-data-reach.test.ts +++ b/packages/runtime/src/app-plugin.job-data-reach.test.ts @@ -113,7 +113,7 @@ const live: Array<{ }> = []; /** - * [#10629] This fixture provisions `sweep_note` and nothing else, so the + * [commit 13a6cb4ad] This fixture provisions `sweep_note` and nothing else, so the * engine's own single-tenant probe (`ObjectQL.probeInstallOrganizations`) reads * a `sys_organization` that was never created. The probe is fail-soft by * construction, but the driver and the engine each log the fault on the way out. diff --git a/packages/runtime/src/app-plugin.job-degraded-outcome.test.ts b/packages/runtime/src/app-plugin.job-degraded-outcome.test.ts index 318721c2114..8cfe28c8560 100644 --- a/packages/runtime/src/app-plugin.job-degraded-outcome.test.ts +++ b/packages/runtime/src/app-plugin.job-degraded-outcome.test.ts @@ -91,7 +91,7 @@ afterEach(async () => { /** * A real engine over the migrated test backend, carrying the REAL `sys_job*`. * - * ⚠️ [#10629] No expected-read-refusal capture here, deliberately and by + * ⚠️ [commit 13a6cb4ad] No expected-read-refusal capture here, deliberately and by * MEASUREMENT: every read this file performs carries `isSystem`, so the * engine's single-tenant probe over the unprovisioned `sys_organization` never * fires and neither refusal channel emits a frame (checked on the red run: zero diff --git a/packages/runtime/src/app-plugin.seed-locale-producer.test.ts b/packages/runtime/src/app-plugin.seed-locale-producer.test.ts index 3cd696b8cbd..096d40d6c7f 100644 --- a/packages/runtime/src/app-plugin.seed-locale-producer.test.ts +++ b/packages/runtime/src/app-plugin.seed-locale-producer.test.ts @@ -33,7 +33,7 @@ import { assertEngineFindOnePredicate, type EngineFindOneQueryInput } from '@obj * -time paths in other declared file surfaces, and the ledger row records that * split rather than claiming it away. * - * ⛔ Not housed in `seed-loader.test.ts` — the natural home, held by PR #16783. + * ⛔ Not housed in `seed-loader.test.ts` — the natural home, then held by the change that landed as commit 854639b31. */ /** diff --git a/packages/runtime/src/artifact-function-declarations.test.ts b/packages/runtime/src/artifact-function-declarations.test.ts index 5b8c423ed9d..0d9f3c794af 100644 --- a/packages/runtime/src/artifact-function-declarations.test.ts +++ b/packages/runtime/src/artifact-function-declarations.test.ts @@ -64,7 +64,7 @@ describe('mergeRuntimeModule — declared functions', () => { it('re-attaches into the ARRAY form without dropping what it declared (#6238)', async () => { // The array spelling reaches this seam for the first time now that - // #6238 lets it past the parse. Rebuilding it as a map would attach the + // commit c8d6f6e08 lets it past the parse. Rebuilding it as a map would attach the // callable and drop `effect` beside it — the same silent un-declaring // #4396 fixed for the map form, arriving by the other door. const bundle: any = { diff --git a/packages/runtime/src/batch-row-driver-text-real-driver.integration.test.ts b/packages/runtime/src/batch-row-driver-text-real-driver.integration.test.ts index bd73e44dc46..f4d20439637 100644 --- a/packages/runtime/src/batch-row-driver-text-real-driver.integration.test.ts +++ b/packages/runtime/src/batch-row-driver-text-real-driver.integration.test.ts @@ -77,7 +77,7 @@ const NOTE = { }; /** - * [#10629] This fixture provisions its own business objects and nothing else, + * [commit 13a6cb4ad] This fixture provisions its own business objects and nothing else, * so the engine's single-tenant probe (`ObjectQL.probeInstallOrganizations`, * memoised once per engine) reads a `sys_organization` that was never created. * The probe is fail-soft by construction — it catches `isMissingTableError` and @@ -88,7 +88,7 @@ const NOTE = { const ABSENT_TENANCY_TABLE = 'sys_organization'; /** - * [#14403] The first bytes of the batch-row sink's OWN log line + * [commit 93d2d679b] The first bytes of the batch-row sink's OWN log line * (`clientFacingRowFailureText`, `metadata-protocol/src/protocol.ts`). A * literal rather than an import: the sink keeps that function private on * purpose, and what this suite pins is the line an OPERATOR reads, which is @@ -97,21 +97,21 @@ const ABSENT_TENANCY_TABLE = 'sys_organization'; const SINK_WITHHOLD_PREFIX = "[Protocol] Withheld a caught error's text from a batch row"; describe('[#8502] a REAL driver fault is withheld from every batch row', () => { - /** [#10629] The expected-noise capture belonging to the latest rig. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest rig. */ let noise: ExpectedReadRefusalCapture | null = null; let dir: string | null = null; let engine: ObjectQL | null = null; - /** [#14403] Undoes the latest rig's `console.warn` recorder. */ + /** [commit 93d2d679b] Undoes the latest rig's `console.warn` recorder. */ let restoreWarn: (() => void) | null = null; afterEach(async () => { - // [#14403] First, so a throw below can never leave `console.warn` patched. + // [commit 93d2d679b] First, so a throw below can never leave `console.warn` patched. restoreWarn?.(); restoreWarn = null; try { await engine?.destroy(); } catch { /* noop */ } engine = null; if (dir) { rmSync(dir, { recursive: true, force: true }); dir = null; } - // [#10629] The capture is a PIN, not a mute — asserted after teardown so + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so // a failure here can never leave the engine running. Every test in this // file rigs and writes, so the probe fires for each of them: this holds // for a single `-t` run as well as for the whole file. @@ -126,7 +126,7 @@ describe('[#8502] a REAL driver fault is withheld from every batch row', () => { connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true, }); - // [#10629] Installed on the REAL driver (the one that logs) before it + // [commit 13a6cb4ad] Installed on the REAL driver (the one that logs) before it // runs a statement — the `Object.create(real)` wrapper below resolves // `logger` through the prototype chain to this sink. noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); @@ -161,7 +161,7 @@ describe('[#8502] a REAL driver fault is withheld from every batch row', () => { } const protocol: any = new ObjectStackProtocolImplementation(engine as any); - // [#14403] Record the sink's own withhold line so BOTH directions of + // [commit 93d2d679b] Record the sink's own withhold line so BOTH directions of // its decision can be asserted: it must log exactly when it withheld. // ⛔ Recorded, never muted — every call is forwarded to the real // `console.warn`, so what a shard log shows is unchanged by this @@ -213,7 +213,7 @@ describe('[#8502] a REAL driver fault is withheld from every batch row', () => { expect(payload).not.toContain('SQLITE'); expect(payload).not.toContain('bd_child'); - // ── [#14403] The sink's OPERATOR half, direction one: it withheld, + // ── [commit 93d2d679b] The sink's OPERATOR half, direction one: it withheld, // so it LOGGED — and the line carries the driver's own sentence whole. // That is what keeps withholding distinguishable from DELETING the // diagnostic, which is the failure this file's sink was built against. @@ -306,7 +306,7 @@ describe('[#8502] a REAL driver fault is withheld from every batch row', () => { expect(payload).not.toContain('UNIQUE constraint failed'); expect(payload).not.toContain('SQLITE_CONSTRAINT'); - // ── [#14403] The OPERATOR half — re-measured, and now a PIN ──────── + // ── [commit 93d2d679b] The OPERATOR half — re-measured, and now a PIN ──────── // What stood here called this a KNOWN RESIDUAL and deliberately // asserted nothing, on the reading that the driver's own sentence // "reaches neither the response nor the console". Re-measured on this @@ -322,7 +322,7 @@ describe('[#8502] a REAL driver fault is withheld from every batch row', () => { // `ERROR Insert operation failed {"object":"bd_note","error": // {"message":"UNIQUE constraint failed: bd_note.email …"}}`. // That line takes the envelope's `cause` on purpose (#14095 / - // #14390, `e instanceof DuplicateRecordError ? e.cause : e`, + // commit 9d7f7259f, `e instanceof DuplicateRecordError ? e.cause : e`, // because the platform logger serializes only `message` and // `stack`) and is pinned in objectql's // `driver-fault-redaction.test.ts`, which asserts the failing diff --git a/packages/runtime/src/batch-row-http-status-real-driver.integration.test.ts b/packages/runtime/src/batch-row-http-status-real-driver.integration.test.ts index d6c5aca122d..6dd59353d49 100644 --- a/packages/runtime/src/batch-row-http-status-real-driver.integration.test.ts +++ b/packages/runtime/src/batch-row-http-status-real-driver.integration.test.ts @@ -74,7 +74,7 @@ const CHILD = { }; /** - * [#10629] This fixture provisions its three business objects and nothing else, + * [commit 13a6cb4ad] This fixture provisions its three business objects and nothing else, * so the engine's single-tenant probe (`ObjectQL.probeInstallOrganizations`, * memoised once per engine) reads a `sys_organization` that was never created. * The probe is fail-soft by construction — it catches `isMissingTableError` and @@ -88,13 +88,13 @@ const CHILD = { */ const ABSENT_TENANCY_TABLE = 'sys_organization'; -/** [#10629] The capture is a PIN, not a mute — this is the assertion half. */ +/** [commit 13a6cb4ad] The capture is a PIN, not a mute — this is the assertion half. */ const expectExpectedNoiseWithheld = (noise: ExpectedReadRefusalCapture | null): void => { expect(noise?.silentChannels() ?? ['no capture was installed']).toEqual([]); }; describe('[#8570] a batch row carries the status its producer DECLARED — real driver', () => { - /** [#10629] The expected-noise capture belonging to the latest rig. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest rig. */ let noise: ExpectedReadRefusalCapture | null = null; let dir: string | null = null; let engine: ObjectQL | null = null; @@ -112,7 +112,7 @@ describe('[#8570] a batch row carries the status its producer DECLARED — real connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true, }); - // [#10629] Installed on the REAL driver (the one that logs) before it + // [commit 13a6cb4ad] Installed on the REAL driver (the one that logs) before it // runs a statement — the `Object.create(real)` wrapper below resolves // `logger` through the prototype chain to this sink. noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); diff --git a/packages/runtime/src/bulk-write-real-driver.integration.test.ts b/packages/runtime/src/bulk-write-real-driver.integration.test.ts index a8700d0f542..e721e31752b 100644 --- a/packages/runtime/src/bulk-write-real-driver.integration.test.ts +++ b/packages/runtime/src/bulk-write-real-driver.integration.test.ts @@ -98,7 +98,7 @@ function metadataFor(objects: any[]) { } /** - * [#10629] This fixture provisions its own business objects and nothing else, + * [commit 13a6cb4ad] This fixture provisions its own business objects and nothing else, * so the engine's single-tenant probe (`ObjectQL.probeInstallOrganizations`, * memoised once per engine) reads a `sys_organization` that was never created. * The probe is fail-soft by construction — it catches `isMissingTableError` and @@ -111,14 +111,14 @@ const ABSENT_TENANCY_TABLE = 'sys_organization'; describe('bulk-write hardening on a REAL SqlDriver (framework#3147–#3152, #3172, #3173)', () => { let dir: string | null = null; let engine: ObjectQL | null = null; - /** [#10629] The expected-noise capture belonging to the latest boot. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest boot. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(async () => { try { await engine?.destroy(); } catch { /* noop */ } engine = null; if (dir) { rmSync(dir, { recursive: true, force: true }); dir = null; } - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave the engine running. Every test in this file // boots and writes, so the probe fires for each of them: this holds for a // single `-t` run as well as for the whole file. @@ -129,7 +129,7 @@ describe('bulk-write hardening on a REAL SqlDriver (framework#3147–#3152, #317 async function boot(objects: any[], plan: FaultPlan = {}) { dir = mkdtempSync(join(tmpdir(), 'os-bulk-real-')); const real = new SqlDriver({ client: 'better-sqlite3', connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true }); - // [#10629] Installed on the REAL driver (the one that logs) before it runs + // [commit 13a6cb4ad] Installed on the REAL driver (the one that logs) before it runs // a statement, and on the engine before it issues a read — the two sinks the // expected refusal travels out on. `wrapDriver` prototype-delegates, so the // wrapper resolves `logger` through the chain to this sink. diff --git a/packages/runtime/src/cascade-delete-multivalue-lookup-real-driver.integration.test.ts b/packages/runtime/src/cascade-delete-multivalue-lookup-real-driver.integration.test.ts index ef9ebf9a236..28306ca51a0 100644 --- a/packages/runtime/src/cascade-delete-multivalue-lookup-real-driver.integration.test.ts +++ b/packages/runtime/src/cascade-delete-multivalue-lookup-real-driver.integration.test.ts @@ -164,7 +164,7 @@ const SINGLE = { const OWNER_PACKAGE = 'com.objectstack.test.9362'; /** - * [#10629] This fixture provisions its own business objects and nothing else, + * [commit 13a6cb4ad] This fixture provisions its own business objects and nothing else, * so the engine's single-tenant probe (`ObjectQL.probeInstallOrganizations`, * memoised once per engine) reads a `sys_organization` that was never created. * The probe is fail-soft by construction — it catches `isMissingTableError` and @@ -371,14 +371,14 @@ function declareCascadeDeleteCell(cell: DialectCell): void { () => { let dir: string | null = null; let engine: ObjectQL | null = null; - /** [#10629] The expected-noise capture belonging to the latest rig. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest rig. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(async () => { try { await engine?.destroy(); } catch { /* noop */ } engine = null; if (dir) { rmSync(dir, { recursive: true, force: true }); dir = null; } - // [#10629] The capture is a PIN, not a mute — asserted after teardown so + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so // a failure here can never leave the engine running. Every test in this // file rigs and writes, so the probe fires for each of them: this holds // for a single `-t` run as well as for the whole file. @@ -405,7 +405,7 @@ function declareCascadeDeleteCell(cell: DialectCell): void { async function rig(objects: unknown[]) { const real = await newDriver(); - // [#10629] Installed before the driver runs a statement and before the + // [commit 13a6cb4ad] Installed before the driver runs a statement and before the // engine issues a read — the two sinks the expected refusal travels out on. // [#18617] The reason half is this CELL'S dialect: the refusal line the // driver writes says `no such table: sys_organization` on SQLite and diff --git a/packages/runtime/src/cross-field-refusal-operand-withhold.test.ts b/packages/runtime/src/cross-field-refusal-operand-withhold.test.ts index 80a524aecd0..83dfbb628f2 100644 --- a/packages/runtime/src/cross-field-refusal-operand-withhold.test.ts +++ b/packages/runtime/src/cross-field-refusal-operand-withhold.test.ts @@ -337,10 +337,10 @@ describe('[#7929] a cross-field refusal keeps its envelope and stops disclosing */ let crudScope: FilterCondition | null = null; /** - * [#10983] Every read below that the driver refuses reaches this engine's + * [commit 6a4e929f5] Every read below that the driver refuses reaches this engine's * `find()`, so its `catch` logs an `ERROR Find operation failed` frame * BEFORE rethrowing (`engine.ts`) — a green-test noise instance of the - * same defect class #10629/#10630 closed, just without a table to key on + * same defect class commits 13a6cb4ad / dd8172ee2 closed, just without a table to key on * (the refusal never reaches `backendStatementFault`; see * `expected-read-refusal-noise.ts`'s second predicate for why and how). * Withheld and COUNTED here, never muted — `silentChannels()` and @@ -387,7 +387,7 @@ describe('[#7929] a cross-field refusal keeps its envelope and stops disclosing }); afterAll(() => { - // [#10983] The pin, not the mute: every declared object's channel fired + // [commit 6a4e929f5] The pin, not the mute: every declared object's channel fired // at least once, AND the count is exactly what this describe block's // five `it`s produce — six `ql.find()` calls refused (the sixth test // below drives the driver directly, bypassing this engine on purpose, diff --git a/packages/runtime/src/default-datasource-plugin.test.ts b/packages/runtime/src/default-datasource-plugin.test.ts index 415c3cd5535..3501f06ae71 100644 --- a/packages/runtime/src/default-datasource-plugin.test.ts +++ b/packages/runtime/src/default-datasource-plugin.test.ts @@ -26,7 +26,7 @@ const BOOT_TIMEOUT = 60_000; const ENV = 'OS_ALLOW_DRIVER_CONNECT_FAILURE'; /** - * [#10629] Exactly one case in this file writes through the booted engine, and + * [commit 13a6cb4ad] Exactly one case in this file writes through the booted engine, and * that write runs the engine's single-tenant probe * (`ObjectQL.probeInstallOrganizations`) against a `sys_organization` this * composition never creates. The probe is fail-soft by construction — it @@ -170,7 +170,7 @@ describe('DefaultDatasourcePlugin — the default datasource as a declaration (# const { createPrebuiltDriverFactory } = await import('@objectstack/service-datasource'); const { SqliteWasmDriver } = await import('@objectstack/driver-sqlite-wasm'); const hostBuilt = new SqliteWasmDriver({ filename: ':memory:' }); - // [#10629] Installed before the driver runs a statement; the engine half + // [commit 13a6cb4ad] Installed before the driver runs a statement; the engine half // is scoped after bootstrap, because the read it covers is the `insert` // below rather than anything the boot itself does. const noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); @@ -194,7 +194,7 @@ describe('DefaultDatasourcePlugin — the default datasource as a declaration (# await engine.insert('note', { title: 'through-the-adopted-default' }); const rows = await engine.find('note'); expect(rows.map((r: any) => r.title)).toContain('through-the-adopted-default'); - // [#10629] The capture is a PIN, not a mute: the probe's two log lines + // [commit 13a6cb4ad] The capture is a PIN, not a mute: the probe's two log lines // are withheld from the shared shard log and asserted here instead, so // a probe that stopped running goes red rather than merely quiet. expect(noise.silentChannels()).toEqual([]); diff --git a/packages/runtime/src/degraded-boot-parity.test.ts b/packages/runtime/src/degraded-boot-parity.test.ts index 3d94fe8866e..168c5662d89 100644 --- a/packages/runtime/src/degraded-boot-parity.test.ts +++ b/packages/runtime/src/degraded-boot-parity.test.ts @@ -86,7 +86,7 @@ async function bootDatasource(): Promise { }) as any, engine: () => ({ registerDriver: (d: any) => drivers.set(d.name, d), - // [#12010] The double stores a bare `{ name: 'd' }` stand-in, while + // [commit 77b91bdb4] The double stores a bare `{ name: 'd' }` stand-in, while // `ConnectionEngineLike.getDriverByName` is now derived from the engine // contract and answers `IDataDriver | undefined`. Narrowing on the way // out keeps the double as loose as this parity test needs it without diff --git a/packages/runtime/src/dispatcher-5xx-demoted-code-withhold.test.ts b/packages/runtime/src/dispatcher-5xx-demoted-code-withhold.test.ts index a471fad0823..c7ad0a14e5d 100644 --- a/packages/runtime/src/dispatcher-5xx-demoted-code-withhold.test.ts +++ b/packages/runtime/src/dispatcher-5xx-demoted-code-withhold.test.ts @@ -40,9 +40,9 @@ * * The MESSAGE. `errorResponseBase` still withholds on `declaresServerFault` * (which needs a string code) rather than on every declared 5xx; aligning it - * to `/data` is the same ruling's prose axis and it is #12281's card, with its + * to `/data` is the same ruling's prose axis and it is commit 0783d7b80's change, with its * own measurement-first step. Section 4 pins the message behaviour AS IT - * STANDS so that card's change is visible as a change rather than as a silent + * STANDS so that commit's change is visible as a change rather than as a silent * drift, and names what will move. */ @@ -257,12 +257,12 @@ describe('[#12509] the exits read the shared rule, they do not restate it', () = }); // --------------------------------------------------------------------------- -// 4. The prose axis, pinned AS IT STANDS — #12281's card, not this one +// 4. The prose axis, pinned AS IT STANDS — commit 0783d7b80's change, not this one // --------------------------------------------------------------------------- describe('[#12509] the MESSAGE axis — now widened by #12281, and the code axis is unaffected', () => { it('a declared 5xx WITH a code still has its prose withheld at errorResponseBase', async () => { - // Unchanged by #12281: this shape declared a 5xx, so it was withheld + // Unchanged by commit 0783d7b80: this shape declared a 5xx, so it was withheld // under `declaresServerFault` and is withheld under // `serverFaultProvenance`. Kept as the no-regression end of the band. const answer = await postAnalyticsQuery( @@ -276,13 +276,13 @@ describe('[#12509] the MESSAGE axis — now widened by #12281, and the code axis }); it('[#12281] a declared 5xx with NO code ALSO has its prose withheld now', async () => { - // ⚠️ FLIPPED, as this file said it would be. Until #12281 this asserted + // ⚠️ FLIPPED, as this file said it would be. Until commit 0783d7b80 this asserted // `'Data service not available'` on the wire, with the note: "When - // #12281 lands this expectation flips to the generic sentence — + // [commit 0783d7b80] lands this expectation flips to the generic sentence — // deliberately pinned so that lands as a CHANGE rather than as drift // nobody sees." This is that landing. // - // Ruled 2026-08-27 on #12509 (option D), propagated to #12281: + // Ruled 2026-08-27 on #12509 (option D), landed in commit 0783d7b80: // `errorResponseBase` adopts the structural withhold for EVERY declared // 5xx message. `serverFaultProvenance` reads `status ?? statusCode` and // does not consult `code`, so this shape — `action-execution.ts`'s @@ -299,7 +299,7 @@ describe('[#12509] the MESSAGE axis — now widened by #12281, and the code axis it('[#12281] an UNDECLARED 5xx still keeps its prose — the two axes stay independent', async () => { // The control that keeps the flip above honest. This file's own subject // is `demotedDeclaredCode`, which withholds the CODE on an undeclared - // 5xx; #12281 withholds the MESSAGE on a DECLARED one. They read + // 5xx; commit 0783d7b80 withholds the MESSAGE on a DECLARED one. They read // opposite limbs of `serverFaultProvenance`, so an edit that collapsed // them into "5xx ⇒ withhold everything" would go red here. const answer = await postAnalyticsQuery(thrown('no strategy can handle query for cube "pipeline"', {})); diff --git a/packages/runtime/src/dispatcher-error-vocabulary.ts b/packages/runtime/src/dispatcher-error-vocabulary.ts index b3a4409b3b6..9535357d0ff 100644 --- a/packages/runtime/src/dispatcher-error-vocabulary.ts +++ b/packages/runtime/src/dispatcher-error-vocabulary.ts @@ -107,7 +107,7 @@ export type CodeStampShape = */ | 'codehelper' /** - * [#13233] The SAME code-carrying helper, stamping through an OBJECT + * [commit 3800e4293] The SAME code-carrying helper, stamping through an OBJECT * LITERAL instead of an assignment: `return { severity, code, message }` * (shorthand) or `{ code: errCode }` (longhand). * @@ -483,7 +483,7 @@ export const UNREGISTERED_CODE_SITES: readonly UnregisteredCodeSite[] = [ // `invisible`: each refusal IS served to the client, in the vendor's flat // `{ message, code }` shape. That this endpoint's bodies are the vendor's // wire rather than this repo's envelope is not inferred here — it is the - // 2026-08-21 maintainer ruling (#10554), carried in `check-route-envelope` + // 2026-08-21 maintainer ruling (landed in commit 6abc4df03), carried in `check-route-envelope` // as the `vendorWire` entry for this same file. // // ⛔ `pending-registration` would be FALSE for all four. That verdict says @@ -694,9 +694,9 @@ export const UNREGISTERED_CODE_SITES: readonly UnregisteredCodeSite[] = [ 'that a live wire code is outside the vocabulary; it does not prescribe the remedy.', }, - // ── pending registration [#14921]: a metadata-tree refusal that reaches a + // ── pending registration [commit c1d274de7]: a metadata-tree refusal that reaches a // ── dispatcher-door read ─────────────────────────────────────────────── - // Not a widened scan and not a demotion: this producer is NEW. #14921 made + // Not a widened scan and not a demotion: this producer is NEW. Commit c1d274de7 made // `FilesystemLoader.list()` (and the shared `loadMany()` walk behind it) // refuse a metadata name derived from more than one file, where before it // reported the name twice and served the first by extension precedence. @@ -731,7 +731,7 @@ export const UNREGISTERED_CODE_SITES: readonly UnregisteredCodeSite[] = [ + 'that batch\'s input, and the registration is what ratchets it out again.', }, - // ── [#13233] field-level catalogs, reached by the OBJECT-LITERAL helper ── + // ── [commit 3800e4293] field-level catalogs, reached by the OBJECT-LITERAL helper ── // // The 29 rows below are the whole verdict cost of widening `codehelper` to // the object-literal stamp position, and they are one genre from end to @@ -1221,7 +1221,7 @@ export const UNREGISTERED_CODE_SITES: readonly UnregisteredCodeSite[] = [ ]; /** - * [#13233] Why a helper's codes cannot be read from source, and whether that + * [commit 3800e4293] Why a helper's codes cannot be read from source, and whether that * matters. A DIFFERENT question from {@link CodeVerdict}, so a different * vocabulary — a site row answers "does this code reach a wire and is it * registered", and none of its members can answer "we never learn the value". @@ -1257,7 +1257,7 @@ export type UnresolvedHelperVerdict = | 'restamped-elsewhere'; /** - * [#13233] A code-carrying helper this scan can SEE but cannot READ: the stamp + * [commit 3800e4293] A code-carrying helper this scan can SEE but cannot READ: the stamp * resolves to a parameter, and no in-file call site passes a value that reduces * to a literal. * @@ -1276,7 +1276,7 @@ export type UnresolvedHelperVerdict = * So the helper is classified here instead, with a door, a verdict and its * evidence, and the gate reconciles this list in BOTH directions: an entry the * scan no longer reports goes stale and REDS, exactly like a site row. ⭐ That - * is what makes it a widening rather than an exemption — before #13233 none of + * is what makes it a widening rather than an exemption — before commit 3800e4293 none of * these helpers produced a site OR an unresolved, because no shape reached * them; now every one is recorded, evidenced, and ratcheted. * diff --git a/packages/runtime/src/dispatcher-plugin.declared-5xx-prose-withhold.test.ts b/packages/runtime/src/dispatcher-plugin.declared-5xx-prose-withhold.test.ts index 74d896fc58f..658da6bcb99 100644 --- a/packages/runtime/src/dispatcher-plugin.declared-5xx-prose-withhold.test.ts +++ b/packages/runtime/src/dispatcher-plugin.declared-5xx-prose-withhold.test.ts @@ -1,12 +1,12 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#12281] `errorResponseBase` withholds the message of EVERY **declared** 5xx, + * [commit 0783d7b80] `errorResponseBase` withholds the message of EVERY **declared** 5xx, * aligning this exit to `/data` — and still keeps an **undeclared** 5xx legible. * * ## The ruling this pins * - * Maintainer, 2026-08-27, on #12509 (option D), propagated verbatim to #12281: + * Maintainer, 2026-08-27, on #12509 (option D), landed in commit 0783d7b80: * * > `errorResponseBase` adopts the **structural withhold for every declared 5xx * > message**, aligning to `/data`'s rule; the author-facing text channel is @@ -36,7 +36,7 @@ * * ## ⛔ Why every case below DRIVES the shape rather than asserting the predicate * - * The #12281 measurement established that the population reaching this door is + * Commit 0783d7b80's measurement established that the population reaching this door is * **EMPTY** today: `metadata-protocol`'s `deleteMetaItem` reaches only the REST * `/meta` door (the dispatcher plugin mounts neither `/meta` nor `/data`), and * `action-execution.ts`'s seven `statusCode` throws are all caught before this diff --git a/packages/runtime/src/dispatcher-plugin.declared-user-message.test.ts b/packages/runtime/src/dispatcher-plugin.declared-user-message.test.ts index 21890bc5b03..b6235b9c711 100644 --- a/packages/runtime/src/dispatcher-plugin.declared-user-message.test.ts +++ b/packages/runtime/src/dispatcher-plugin.declared-user-message.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#13241] `errorResponseBase` carries the producer's `userMessage` to the wire + * [commit a21d2a9cf] `errorResponseBase` carries the producer's `userMessage` to the wire * — the author-facing text channel the declared-5xx prose withhold names as its * own compensation, and the one ADR-0112 boundary that dropped it. * @@ -29,7 +29,7 @@ * * ## Why this is the compensation channel and not a decoration * - * The 2026-08-27 ruling on #12509 (option D), propagated to #12281, made this + * The 2026-08-27 ruling on #12509 (option D), landed in commit 0783d7b80, made this * exit withhold the message of every **declared** 5xx: * * > the author-facing text channel is `userMessage` [commit 79c46da90], never the raw @@ -194,7 +194,7 @@ describe('[#13241] the dispatcher throw-transparent exit carries `userMessage`', expect(res.statusCode).toBe(503); expect(res.body.success).toBe(false); - // The withhold still holds — this change must not re-open #12281. + // The withhold still holds — this change must not undo commit 0783d7b80. expect(res.body.error.message).toBe(INTERNAL_ERROR_MESSAGE); expect(JSON.stringify(res.body)).not.toContain('acme_prod'); @@ -209,7 +209,7 @@ describe('[#13241] the dispatcher throw-transparent exit carries `userMessage`', it('an UNMARKED declared 5xx is byte-identical to before — the mark is opt-in', async () => { // The regression guard on the paragraph above: if the field were // synthesised from `message` rather than read from the throw, the - // withheld prose would ride out on the new channel and #12281 would + // withheld prose would ride out on the new channel and commit 0783d7b80 would // be undone by its own compensation. const res = await throwFromAnalyticsQuery( declaring({ status: 503, code: 'SERVICE_UNAVAILABLE' }, 'Upstream warehouse pool exhausted for tenant acme_prod.'), diff --git a/packages/runtime/src/dispatcher-plugin.ts b/packages/runtime/src/dispatcher-plugin.ts index 88bfdd2e453..ebf50bc224a 100644 --- a/packages/runtime/src/dispatcher-plugin.ts +++ b/packages/runtime/src/dispatcher-plugin.ts @@ -600,7 +600,7 @@ function sendResultBase( * boundaries. ⛔ It is NOT "withhold every 5xx" — #5667 kept UNDECLARED 5xx * legible on purpose, and a bare `Error` still goes through the heuristic alone. * - * [#12281] A fifth, and the reason that predicate is now {@link + * [commit 0783d7b80] A fifth, and the reason that predicate is now {@link * serverFaultProvenance}: `declaresServerFault` required a non-empty string * `code` beside the 5xx and read the `status` spelling only, so this exit * withheld a NARROWER band than `/data` — a declared 5xx with no code, and a @@ -618,7 +618,7 @@ function sendResultBase( * into `errorReporter` and the log. * * ⚠️ It reaches the client at `error.code` — NOT `error.details.code`, which is - * where this note pointed until #6270 corrected it (#6123 corrected the same + * where this note pointed until #6270 corrected it (commit 59d1933f9 corrected the same * sentence at three sibling sites). The `details` assembly below (#3842) only * STAGES the code in a local object; `buildApiError` then runs * `splitSemanticCode` (`./error-envelope.ts`), which PROMOTES it into the declared @@ -681,14 +681,14 @@ function errorResponseBase( const raw = err?.message; // [#3842] A thrown error's own `.code` finally has somewhere to go — see the // `declaredCode` note below for WHICH spelling travels. Resolved HERE, above - // the message ternary, because [#12281] that ternary now reads the same + // the message ternary, because [commit 0783d7b80] that ternary now reads the same // resolver answer: one read of the throw, one set of facts, so the prose rule // and the code rule can never be looking at different errors. const thrown = resolveThrownHttpError(err, 500); - // [#5811/#12281] Two independent reasons to withhold, both 5xx-only. The + // [#5811 / commit 0783d7b80] Two independent reasons to withhold, both 5xx-only. The // declaration comes first because it needs no guess about the text. // - // [#12281] The declaration limb is `serverFaultProvenance(thrown) === + // [commit 0783d7b80] The declaration limb is `serverFaultProvenance(thrown) === // 'declared'` — the ONE definition of "the producer named this 5xx itself" // (`@objectstack/types`), ruled 2026-08-27 (option D) and already read by // `demotedDeclaredCode` for the code channel. ⛔ Not re-derived here: "one @@ -732,7 +732,7 @@ function errorResponseBase( // name. // // ⛔ Still NOT a widening of the `'declared'` limb. Absent the flag this - // expression is byte-identical, so #12281's structural withhold is intact + // expression is byte-identical, so commit 0783d7b80's structural withhold is intact // for every producer that declares a FAULT — which is the default, and the // only thing a rewrap can carry. The shared read is fail-closed on its own // account too: it requires a declared in-band 5xx, a non-empty string @@ -759,7 +759,7 @@ function errorResponseBase( // statusCode → validation 400 → 500), so the two reads cannot disagree. A // non-string `.code` (a driver errno) stays in `details`, as context. const declaredCode = demotedDeclaredCode(thrown); - // [#13241] The author-facing text channel the withhold above assumes as its + // [commit a21d2a9cf] The author-facing text channel the withhold above assumes as its // compensation. `resolveThrownHttpError` ALREADY answered whether the throw // declared one — `thrown.userMessage` is `declaredUserMessage`'s non-empty // string rule, the ONE read every boundary applies (`@objectstack/types`) — diff --git a/packages/runtime/src/domains/action-activation-posture-gate.test.ts b/packages/runtime/src/domains/action-activation-posture-gate.test.ts index 80ea2ec7758..756a2048322 100644 --- a/packages/runtime/src/domains/action-activation-posture-gate.test.ts +++ b/packages/runtime/src/domains/action-activation-posture-gate.test.ts @@ -27,7 +27,7 @@ // // `status` AND `code` (the ADR-0112 envelope), AND that the engine's // `setActionActive` was never entered — a gate that refused after the ledger -// was written would still be #10243, with persistence. +// was written would still be the leak commit 02b41232d measured, with persistence. import { describe, it, expect, vi } from 'vitest'; @@ -282,7 +282,7 @@ describe('ADR-0126 §5 — the action activation write is operator-gated in wall // Sweeping a run surface into a metadata gate would lock every // ordinary user out of the actions built for them — the one - // thing the #10243 ruling did not do. + // thing the ruling commit 266436a7f landed did not do. expect(statusOf(res)).toBe(200); expect(h.executeAction).toHaveBeenCalled(); }); diff --git a/packages/runtime/src/domains/actions-fault-vs-rejection.test.ts b/packages/runtime/src/domains/actions-fault-vs-rejection.test.ts index 7721ab23c64..35b77965e27 100644 --- a/packages/runtime/src/domains/actions-fault-vs-rejection.test.ts +++ b/packages/runtime/src/domains/actions-fault-vs-rejection.test.ts @@ -217,10 +217,10 @@ describe('an unexpected FAULT is a 500', () => { }); /** - * [#17273] A sandboxed body that CRASHED is a fault — the face of #15071 this + * [#17273] A sandboxed body that CRASHED is a fault — the face of commit cf6e0a193 this * door left open. * - * #15071 ruled on the `/data` door: *"A declared code is the author's statement + * Ruled on the `/data` door (commit cf6e0a193): *"A declared code is the author's statement * about the failure mode they **handled**. A crash (`isScriptFaultMessage`, * #7543) is not that mode, so it is classified as a fault"*. This door read the * question the other way round. The table above states the discriminator as the @@ -289,7 +289,7 @@ describe('[#17273] a sandboxed body that CRASHED is a fault, not a rejection', ( }); it('negative control: a sandboxed DELIBERATE throw keeps its 400 and its own sentence', async () => { - // One `innerMessage` away from the first case. #15071's ruling fences + // One `innerMessage` away from the first case. Commit cf6e0a193's ruling fences // this explicitly — *"Ordinary declared refusals … are **untouched** — // only the crash branch moves"* — and an implementation that degraded // every sandbox-origin error to the fault terminal would turn the two @@ -336,7 +336,7 @@ describe('[#17273] a sandboxed body that CRASHED is a fault, not a rejection', ( * "message":"Cannot read properties of undefined (reading 'id')","httpStatus":500}} * * The same crash through the `/data` door answered `"Internal server error"` - * (#7543 / #15071). ⇒ the status was already right; what leaked was the + * (#7543 / commit cf6e0a193). ⇒ the status was already right; what leaked was the * sentence. * * **The shape worth carrying: a predicate that classifies by HOW a crash diff --git a/packages/runtime/src/domains/actions.ts b/packages/runtime/src/domains/actions.ts index 9e26342b0fb..f4a0f99ab35 100644 --- a/packages/runtime/src/domains/actions.ts +++ b/packages/runtime/src/domains/actions.ts @@ -122,7 +122,7 @@ function isActionActivationWrite(parts: string[], method: string): boolean { * * ## Order of operations, and why each step is where it is * - * 1. **Both authority gates, first.** `manage_metadata` (#10243: switching a + * 1. **Both authority gates, first.** `manage_metadata` (commit 266436a7f: switching a * shipped artifact off is functionally equivalent to deleting it), then the * ADR-0126 §5 posture gate. Ahead of the body checks and ahead of any * lookup, so a refused caller writes nothing and learns nothing — neither @@ -884,7 +884,7 @@ export async function handleActionsRequest(deps: DomainHandlerDeps, path: string // `ReferenceError` / a driver's own class "is a crash (500)") and the // header of this very file (`did it reject or crash? … crash → 500`). // - // The rule is #15071's, ruled on the `/data` door and quoted there + // The rule is commit cf6e0a193's, ruled on the `/data` door and quoted there // rather than restated: *"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"*. This is the same terminal at the diff --git a/packages/runtime/src/domains/activation-gate-positions-name-authority.test.ts b/packages/runtime/src/domains/activation-gate-positions-name-authority.test.ts index ee6e9269993..04cffaa954e 100644 --- a/packages/runtime/src/domains/activation-gate-positions-name-authority.test.ts +++ b/packages/runtime/src/domains/activation-gate-positions-name-authority.test.ts @@ -20,7 +20,7 @@ // // ⭐ WHAT THE ESCALATION BUYS, driven rather than argued: this gate is the ONLY // thing standing between a tenant org admin and the install-wide activation -// row under a walled posture. It is #10243 exactly — a tenant org owner +// row under a walled posture. It is exactly the leak commit 02b41232d measured — a tenant org owner // switching a shipped flow off ENVIRONMENT-WIDE — except that ADR-0126 made // the row DURABLE, so the same leak now survives a cold boot. The arms below // drive the real `POST /automation/:name/toggle` route and assert on whether @@ -206,7 +206,7 @@ for (const posture of ['group', 'isolated'] as const) { expect(codeOf(response)).toBe('PERMISSION_DENIED'); // The load-bearing assertion: refused BEFORE the write. A gate that // wrote the install-wide row and then refused would satisfy the two - // above and still be #10243. + // above and still be the leak commit 02b41232d measured. expect(h.toggleFlow).not.toHaveBeenCalled(); }); diff --git a/packages/runtime/src/domains/activation-gate.ts b/packages/runtime/src/domains/activation-gate.ts index b7e7b2c96dc..b31ba9672a4 100644 --- a/packages/runtime/src/domains/activation-gate.ts +++ b/packages/runtime/src/domains/activation-gate.ts @@ -25,7 +25,7 @@ * is inert. * - **`group` / `isolated`** — a real multi-organization deployment. Here the * write requires the PLATFORM OPERATOR, because a tenant org admin flipping - * an install-wide switch is precisely #10243: that incident measured a + * an install-wide switch is precisely the leak commit 02b41232d measured: a * tenant org owner switching a shipped flow off ENVIRONMENT-WIDE, read back * by an unrelated tenant in a different organization. ADR-0126 §5 makes * that durable in the correct direction — and a durable install-wide row @@ -64,7 +64,7 @@ * * Driven, not argued: with the minted row present, a tenant org admin holding * only the org-scoped `manage_metadata` capability flipped the install-wide - * switch under both walled postures — #10243 again, now with a DURABLE row. + * switch under both walled postures — the same leak commit 02b41232d measured, now with a DURABLE row. * See `activation-gate-positions-name-authority.test.ts`. * * ## Fail-open on an ABSENT posture is deliberate, not a gap @@ -93,7 +93,7 @@ export const ACTIVATION_DENY_CODE = 'PERMISSION_DENIED'; /** * [ADR-0066 D1 / #10145] The authoring capability every door onto the metadata - * plane demands — and, since the #10243 ruling, the activation switch too: + * plane demands — and, since the ruling commit 266436a7f landed, the activation switch too: * *"Disabling a shipped flow is functionally equivalent to deleting it for as * long as it stays off"*, and `DELETE` already required it. Actions inherit the * sentence with one word changed. @@ -149,7 +149,7 @@ export const ACTION_ACTIVATION_SUBJECT: ActivationSubject = { * ⚠️ Callers MUST run this BEFORE the write is attempted and before body * validation, so a refused caller writes nothing and learns nothing about the * contract. "Write first, refuse second" is the worst shape here — it is - * #10243 with an audit trail. + * the leak commit 02b41232d measured, with an audit trail. * * ⚠️ It has THREE exits, not two: a refusal, `undefined` to proceed, and a * THROW. See the posture read below for the class that throws and why a caller @@ -246,7 +246,7 @@ export async function refuseUngrantedActivationWrite( } /** - * [#10145 / #10243] The capability tier that sits IN FRONT of the §5 gate: the + * [#10145 / commit 266436a7f] The capability tier that sits IN FRONT of the §5 gate: the * caller must hold `manage_metadata` before the posture question is even asked. * * The `/automation` domain enforces this through its own diff --git a/packages/runtime/src/domains/automation-activation-posture-gate.test.ts b/packages/runtime/src/domains/automation-activation-posture-gate.test.ts index 9f45dd42f2d..5191a67e7a3 100644 --- a/packages/runtime/src/domains/automation-activation-posture-gate.test.ts +++ b/packages/runtime/src/domains/automation-activation-posture-gate.test.ts @@ -18,7 +18,7 @@ // // ## What this is made durable against // -// #10243, measured over HTTP: on a real `isolated` posture a tenant org owner +// The leak commit 02b41232d measured over HTTP: on a real `isolated` posture a tenant org owner // switched a shipped flow off through this very route and an unrelated tenant // in a DIFFERENT organization read it off — environment-wide reach from a // tenant caller. That leak went through a PROCESS-LOCAL map, so a cold boot @@ -191,7 +191,7 @@ describe('ADR-0126 §5 — the activation write is operator-gated in walled post expect(codeOf(response)).toBe('PERMISSION_DENIED'); // The load-bearing assertion: refused BEFORE the write. A gate // that wrote the row and then refused would satisfy the two - // above and still be #10243. + // above and still be the leak commit 02b41232d measured. expect(h.toggleFlow).not.toHaveBeenCalled(); }); @@ -275,7 +275,7 @@ describe('ADR-0126 §5 — the activation write is operator-gated in walled post // `POST /automation/trigger/toggle` RUNS a flow literally named // `toggle`; gating it would over-block an execution door, which - // is the one thing the #10243 ruling did not do. + // is the one thing the ruling commit 266436a7f landed did not do. expect(h.toggleFlow).not.toHaveBeenCalled(); }); }); diff --git a/packages/runtime/src/domains/automation-resume-envelope.test.ts b/packages/runtime/src/domains/automation-resume-envelope.test.ts index 01bdfec5545..f3d1e95cd85 100644 --- a/packages/runtime/src/domains/automation-resume-envelope.test.ts +++ b/packages/runtime/src/domains/automation-resume-envelope.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #8796 — the resume body's OUTER envelope is a closed set. + * Commit a4331227b — the resume body's OUTER envelope is a closed set. * * `POST /automation/:name/runs/:runId/resume` assembles its engine signal * field-by-field from the body — deliberately (#3801: never spread the body, or @@ -10,7 +10,7 @@ * ones read. Measured on GA: `{"nodeId":"ask","values":{…}}` — no key of which * the route reads — answered HTTP 200 `success:true` with the screen submission * treated as EMPTY; the run completed and the submitted value never reached the - * flow. Maintainer ruling 2026-08-15 (Option A, on #8796): an unknown top-level + * flow. Maintainer ruling 2026-08-15 (Option A, landed in commit a4331227b): an unknown top-level * key is refused, located, naming the offending key(s) and the accepted set — * exactly `inputs` / `variables` / `output` / `branchLabel`. * diff --git a/packages/runtime/src/domains/automation-resume-value-shape.test.ts b/packages/runtime/src/domains/automation-resume-value-shape.test.ts index d66ac477a6e..c6a8ad46f85 100644 --- a/packages/runtime/src/domains/automation-resume-value-shape.test.ts +++ b/packages/runtime/src/domains/automation-resume-value-shape.test.ts @@ -4,7 +4,7 @@ * #9416 — the resume body refuses a MIS-SHAPED VALUE on an accepted key, and a * body that is not a JSON object at all. * - * #8796 closed the resume envelope's KEY set; this is the same silent-drop + * Commit a4331227b closed the resume envelope's KEY set; this is the same silent-drop * family one axis over, on the VALUE. The assembly type-guarded each accepted * key and skipped whatever failed the guard, so `{"inputs":"a string"}` passed * the closed key set (the key IS accepted), lost its value, and answered HTTP @@ -16,7 +16,7 @@ * * Maintainer ruling on the card — **Option A**: refuse, 400, located, naming * the key and the expected type; non-object and array bodies refuse the same - * way. It inherits #8796's ruling together with its reason, plus #3899's + * way. It inherits the ruling commit a4331227b landed together with its reason, plus #3899's * toggle-arm precedent (a truthy non-boolean `enabled` is refused there, never * coerced or dropped). ⛔ Option B — forward the raw value and let the engine * judge — was rejected: `ResumeSignal` types `variables`/`output` as @@ -184,7 +184,7 @@ describe('#9416 — a type-mismatched value on an accepted key is refused, not d it('refuses the mis-shaped value even when a sibling key is perfectly valid', async () => { // The half-wrong body must not be silently half-dropped — the same - // reasoning #8796 used to decline "refuse only when nothing is + // reasoning commit a4331227b used to decline "refuse only when nothing is // recognized". const r = await refusalFor({ inputs: { real: 'value' }, branchLabel: 7 }); expect(r.details?.fields).toMatchObject([{ field: 'branchLabel', code: 'invalid_type' }]); @@ -194,7 +194,7 @@ describe('#9416 — a type-mismatched value on an accepted key is refused, not d it('reports an unknown KEY ahead of a mis-shaped value — #8796 message unchanged', async () => { // Ordering pin: a body that is both misspelled and mis-shaped still // reports the misspelling, which is the correction the caller needs - // first and the one #8796 pinned. + // first and the one commit a4331227b pinned. const r = await refusalFor({ inputs: 'a string', values: { x: 1 } }); expect(r.details?.fields).toMatchObject([{ field: 'values', code: 'unknown_field' }]); expect(r.message).toMatch(/`values`/); diff --git a/packages/runtime/src/domains/automation-run-lifecycle-door.test.ts b/packages/runtime/src/domains/automation-run-lifecycle-door.test.ts index a1a4ac81486..c40d2bdda04 100644 --- a/packages/runtime/src/domains/automation-run-lifecycle-door.test.ts +++ b/packages/runtime/src/domains/automation-run-lifecycle-door.test.ts @@ -243,9 +243,9 @@ describe('#13953 — the run-lifecycle doors require the platform operator', () it('leaves the legacy execution door alone — `POST /automation/trigger/:name` for a flow named `runs`', async () => { // The gate excludes `parts[0] === 'trigger'`, exactly as the toggle - // (#10243) and clone (#12156) arms do, and BOTH route arms repeat + // (commit 266436a7f) and clone (#12156) arms do, and BOTH route arms repeat // the exclusion so gate and route cannot drift. Over-blocking an - // execution door is the one thing the #10243 ruling did not do. + // execution door is the one thing the ruling commit 266436a7f landed did not do. const h = makeDispatcher(); const { response } = await h.dispatcher.handleAutomation( 'trigger/runs/run_7/cancel', 'POST', undefined, USER_CTX(), undefined, diff --git a/packages/runtime/src/domains/automation-toggle-deny-message.test.ts b/packages/runtime/src/domains/automation-toggle-deny-message.test.ts index 6e6b750707c..1d326cd6694 100644 --- a/packages/runtime/src/domains/automation-toggle-deny-message.test.ts +++ b/packages/runtime/src/domains/automation-toggle-deny-message.test.ts @@ -5,7 +5,7 @@ * * ## The defect, exactly * - * #10243's ruling put the enablement door into the `manage_metadata` authoring + * Commit 266436a7f's ruling put the enablement door into the `manage_metadata` authoring * write set, and #11660 landed it by adding one arm to `isFlowAuthoringWrite`. * The refusal that arm reached was the shared one: * @@ -174,7 +174,7 @@ describe('#11666 — the enablement door refuses in its own words', () => { }); it('says the same thing in both directions — enabling and disabling', async () => { - // #10243's measurement was symmetric, and a caller switching a flow + // Commit 02b41232d's measurement was symmetric, and a caller switching a flow // ON is no more "authoring" than one switching it off. const h = boot(); diff --git a/packages/runtime/src/domains/automation-toggle-unknown-flow.test.ts b/packages/runtime/src/domains/automation-toggle-unknown-flow.test.ts index c52761defc7..d3a3ad9b599 100644 --- a/packages/runtime/src/domains/automation-toggle-unknown-flow.test.ts +++ b/packages/runtime/src/domains/automation-toggle-unknown-flow.test.ts @@ -54,7 +54,7 @@ function makeDispatcher(flowNames: string[] = ['welcome_flow']) { } /** - * [#10243] The caller now holds `manage_metadata`. + * [commit 266436a7f] The caller now holds `manage_metadata`. * * This file is about ERROR MAPPING on `POST /:name/toggle` — that an unknown * flow is a 404 rather than a 500, and that a malformed body is a 400. Its diff --git a/packages/runtime/src/domains/automation-write-capability-gate.test.ts b/packages/runtime/src/domains/automation-write-capability-gate.test.ts index c19b7198bc6..6b8f4140481 100644 --- a/packages/runtime/src/domains/automation-write-capability-gate.test.ts +++ b/packages/runtime/src/domains/automation-write-capability-gate.test.ts @@ -33,12 +33,12 @@ * `stays ungated` block below is the audit that makes any future change to * those verdicts come through this file. * - * ## [#10243] `POST /:name/toggle` CROSSED that line — deliberately, by ruling + * ## [commit 266436a7f] `POST /:name/toggle` CROSSED that line — deliberately, by ruling * * ⭐ This is the flip, recorded here rather than left to be discovered. #10145 * pinned toggle as ungated **in the open**, saying the verdict was a product * call and not a code call, so that a change to it would land in this file and - * be visible. It was filed as #10243, measured over HTTP, and ruled on + * be visible. It was filed, measured over HTTP (commit 02b41232d), and ruled on * 2026-08-23: toggle joins the `manage_metadata` write set. One arm on the * existing `isFlowAuthoringWrite`; ⛔ no new capability name (option C was * declined). @@ -175,7 +175,7 @@ const codeOf = (response: unknown): unknown => { /** * The gated writes, each with the service method it must never reach. * - * [#10243] Four, not three: `POST /:name/toggle` joined by ruling. It is listed + * [commit 266436a7f] Four, not three: `POST /:name/toggle` joined by ruling. It is listed * HERE rather than given a parallel block of its own so it inherits every * direction the other three are held to — the 403 + `PERMISSION_DENIED` * envelope, the "the service method was never entered" spy assertion, and the @@ -202,7 +202,7 @@ const AUTHORING_WRITES = [ spy: (h: Harness) => h.unregisterFlow, }, { - // [#10243] The enablement door. `enabled: false` deliberately — the + // [commit 266436a7f] The enablement door. `enabled: false` deliberately — the // caller trying to switch a shipped flow OFF is the one the measurement // caught reaching every organization on the deployment. name: 'POST /automation/:name/toggle (toggleFlow)', @@ -391,7 +391,7 @@ describe('#10145 — /automation authoring writes require `manage_metadata`', () it('[#10243 FLIPPED] POST /:name/toggle is NO LONGER in this block — it is gated now', async () => { // ⭐ This assertion used to read `.not.toBe(403)` and // `toHaveBeenCalledWith(FLOW, false)`. It is inverted deliberately, - // by the 2026-08-23 ruling on #10243, and the inversion is kept in + // by the 2026-08-23 ruling (commit 266436a7f), and the inversion is kept in // this block — rather than only added to the refusal loop above — // so that the audit reads as a CHANGED verdict instead of a pin // that quietly vanished. The full battery for this route (envelope, diff --git a/packages/runtime/src/domains/automation.ts b/packages/runtime/src/domains/automation.ts index b2b5ac35565..86c5c6f0b7f 100644 --- a/packages/runtime/src/domains/automation.ts +++ b/packages/runtime/src/domains/automation.ts @@ -15,7 +15,7 @@ import { } from '@objectstack/core'; // [ADR-0126 §5] The shared activation write-authority gate — one // implementation, one refusal envelope, per-door wording. See its header for -// the posture rule and the #10243 measurement behind it. +// the posture rule and the measurement behind it (commit 02b41232d). import { refuseUngrantedActivationWrite, FLOW_ACTIVATION_SUBJECT } from './activation-gate.js'; // [#19874] What the run-lifecycle refusal names as the remedy is read off the // SAME inputs the platform-admin derivation reads — the requested posture, the @@ -364,7 +364,7 @@ const FLOW_WRITE_DENY_MESSAGE = * same `code` and the same `status` as {@link FLOW_WRITE_DENY_MESSAGE}, and a * different sentence, because a different operation was attempted. * - * ⛔ Copy, not policy. [#10243]'s ruling put `POST /:name/toggle` into the + * ⛔ Copy, not policy. The ruling commit 266436a7f landed put `POST /:name/toggle` into the * authoring write set and that classification is untouched here: the same * callers are refused, with the same `PERMISSION_DENIED` and the same 403. * What moves is only what a refused caller is TOLD. Switching a shipped flow @@ -393,7 +393,7 @@ const FLOW_ENABLEMENT_DENY_MESSAGE = * sentence the refusal carries — and this file's own rule is that a question * spelled at two call sites is two questions that happen to agree today. * - * ⛔ The truth table is [#10243]'s, moved nowhere: the exclusion of + * ⛔ The truth table is commit 266436a7f's, moved nowhere: the exclusion of * `parts[0] === 'trigger'` and the absence of any depth bound are that arm's, * for that arm's reasons, restated below where they are read. */ @@ -406,15 +406,15 @@ function isFlowEnablementWrite(parts: string[], method: string): boolean { * * One predicate, for the reason {@link isRunStateRead} is one predicate: this * domain gets one policy per data class, and a policy spelled at three call - * sites is three policies that happen to agree today. [#10243] That is why the + * sites is three policies that happen to agree today. [commit 266436a7f] That is why the * toggle ruling below was one arm here rather than a fourth copy of the policy. * * `POST /` → registerFlow (create) * `PUT /:name` → registerFlow (update) * `DELETE /:name` → unregisterFlow (deregister) - * `POST /:name/toggle` → toggleFlow (enablement — #10243, see below) + * `POST /:name/toggle` → toggleFlow (enablement — commit 266436a7f, see below) * - * ## [#10243] Why `toggle` joins them — ruled, not inferred + * ## [commit 266436a7f] Why `toggle` joins them — ruled, not inferred * * #10145 left it out and said so in the open, because whether disabling a flow * is authoring or operating is a product call rather than a code call. It was @@ -459,7 +459,7 @@ function isFlowAuthoringWrite(parts: string[], method: string): boolean { // domain root, so `POST /trigger/:name` (parts `['trigger', name]`) and // `POST /:name/trigger` cannot reach this arm. if (method === 'POST' && parts.length === 0) return true; - // [#10243] `POST /automation/:name/toggle` — the enablement door. + // [commit 266436a7f] `POST /automation/:name/toggle` — the enablement door. // // Matched exactly as the ROUTER matches it, not approximately, because a // gate narrower than its route is a bypass and a gate wider than its route @@ -581,7 +581,7 @@ function isFlowActivationWrite(parts: string[], method: string): boolean { * clause ({@link FLOW_ACTIVATION_SUBJECT}), which is the only part that ever * differed. The shared module's header carries the full rationale: why the * operator test is a POSITION, why an absent posture fails open, and what - * #10243 measured. + * commit 02b41232d measured. */ const refuseUngrantedFlowActivationWrite = ( deps: DomainHandlerDeps, @@ -629,13 +629,13 @@ const RUN_RESTORE_SEGMENT = 'restore-suspension'; * gate narrower than its route is a bypass; a gate wider than its route is an * over-block. * - * ⛔ `parts[0] === 'trigger'` is excluded, exactly as the toggle (#10243) and + * ⛔ `parts[0] === 'trigger'` is excluded, exactly as the toggle (commit 266436a7f) and * clone (#12156) arms exclude it, and the ROUTE ARMS carry the same exclusion * so the two spellings stay byte-identical. `POST /automation/trigger/:name` * is the LEGACY EXECUTION door, answered ABOVE the flow-scoped block, so for a * flow literally named `runs` the path `/automation/trigger/runs/x/cancel` * RUNS that flow. Gating it would over-block an execution door — the one thing - * the #10243 ruling did not do — and dispatching a cancel from it would be the + * the ruling commit 266436a7f landed did not do — and dispatching a cancel from it would be the * mirror bypass. * * No upper bound on depth, for the reason the toggle arm documents: the arms @@ -837,7 +837,7 @@ function refuseUngrantedRunLifecycleWrite( * [#13953] The CLOSED body envelope both lifecycle doors accept — exactly one * optional key, `reason`. * - * Shaped on the resume door's own envelope discipline (#8796 / #9416), for the + * Shaped on the resume door's own envelope discipline (commit a4331227b / #9416), for the * same reason and with the same three refusals: the body itself must be a JSON * object (a string / number / boolean / array body used to normalise to `{}` * there and reach the engine as an empty signal, answered 200), an unknown @@ -1905,7 +1905,7 @@ export async function classifyResumeResult( * a run that PAUSED → 200 with `runId` / `screen`, * on whichever attempt it paused — #9510) * POST /:name/toggle → toggleFlow (unknown name → 404, #7535) - * ⚑ authoring write — `manage_metadata` (#10243): + * ⚑ authoring write — `manage_metadata` (commit 266436a7f): * enablement is environment-wide, so an * unentitled toggle reached every organization * ⚑ refused with its OWN sentence (#11666) — @@ -2024,7 +2024,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str // whether automation is mounted here. Ahead of every body check too — a // refused caller writes nothing and learns nothing about the definition // contract. Which routes: `isFlowAuthoringWrite` above, one predicate, with - // the execution surfaces deliberately outside it — [#10243] `POST + // the execution surfaces deliberately outside it — [commit 266436a7f] `POST // /:name/toggle` moved INSIDE it by ruling, and moved by editing that one // predicate rather than by adding a check here. if (isFlowAuthoringWrite(parts, m)) { @@ -2400,7 +2400,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str unknownKeys.map((k) => ({ field: k, code: 'unknown_field', message: 'not a clone field — the clone body is { name, label }' })), ); } - // The NEW MACHINE NAME IS MANDATORY (ADR-0126 §7.1, the #11513 + // The NEW MACHINE NAME IS MANDATORY (ADR-0126 §7.1, commit e170b0ae5's // shape exactly). Refused here rather than defaulted, because // every default a clone could pick is either the source's own // name — the same-name clone the ADR bans outright — or a name @@ -2488,7 +2488,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str // values, applied as bare flow variables; `output`/`branchLabel` also // forwarded for approval-style resumes. The outer envelope is a CLOSED // set — exactly the four keys below — and an unknown top-level key is - // refused (#8796); since #9416 so is an accepted key carrying a value + // refused (commit a4331227b); since #9416 so is an accepted key carrying a value // of the wrong TYPE, and a body that is not a JSON object at all. // Returns the next paused `{ screen }` (multi-screen) or the completed // result. @@ -2546,7 +2546,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str // below, because its indices read as unknown keys) — so those // reached the engine as an empty signal and answered 200 // `success:true` with the submission treated as EMPTY: the - // #8796 failure shape, reached without misspelling anything. + // failure shape commit a4331227b closed, reached without misspelling anything. // `undefined` / `null` stay the legal bodyless resume (an // empty submission is legal — a screen whose declared fields // are all optional), which is why the normalisation survives @@ -2569,7 +2569,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str ); } const b = rawBody as Record; - // [#8796] The outer envelope is a CLOSED SET (maintainer ruling + // [commit a4331227b] The outer envelope is a CLOSED SET (maintainer ruling // 2026-08-15, Option A): an unknown top-level key is refused, // located, naming the offending key(s) AND the accepted set — // the closed-parameter-set policy (Route & surface ownership @@ -2614,7 +2614,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str })), ); } - // [#9416] VALUE SHAPES — the same silent-drop family as #8796, + // [#9416] VALUE SHAPES — the same silent-drop family commit a4331227b closed, // one axis over: a key that IS accepted, carrying a value the // engine contract excludes. The assembly below used to // type-guard each key and skip what failed the guard, so @@ -2624,7 +2624,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str // submission — the caller told its screen input landed when // nothing did. Ruled Option A (maintainer, on this card): 400, // located, naming the key and the expected type, inheriting - // #8796's ruling together with its reason plus #3899's toggle + // the ruling commit a4331227b landed together with its reason plus #3899's toggle // arm (a truthy non-boolean `enabled` is refused there, never // coerced or dropped). // @@ -2644,7 +2644,7 @@ export async function handleAutomationRequest(deps: DomainHandlerDeps, path: str // // Ordering: after the unknown-key refusal, so a body that is // both misspelled and mis-shaped still reports the misspelling - // #8796 pinned; before `resume()`, so nothing reaches the + // commit a4331227b pinned; before `resume()`, so nothing reaches the // engine until the body is legal and the suspension stays // intact for a corrected retry. const valueFailures: Array<{ field: string; code: 'invalid_type'; message: string }> = []; diff --git a/packages/runtime/src/domains/mcp-merged-skill-read.test.ts b/packages/runtime/src/domains/mcp-merged-skill-read.test.ts index 0fdf1aeca49..83a52a0e8cc 100644 --- a/packages/runtime/src/domains/mcp-merged-skill-read.test.ts +++ b/packages/runtime/src/domains/mcp-merged-skill-read.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { HttpDispatcher } from '../http-dispatcher.js'; /** - * [#8726 — the HTTP half of #8328] `buildMcpBridge.listSkills` must read the + * [commit e783e163d — the HTTP half of #8328] `buildMcpBridge.listSkills` must read the * protocol layer's MERGED listing, not `IMetadataService.list('skill')`. * * ── The defect ──────────────────────────────────────────────────────────── @@ -18,7 +18,7 @@ import { HttpDispatcher } from '../http-dispatcher.js'; * flip never reached MCP prompts and step 3 of #8328's reproduction answered * `{"prompts":[]}`. * - * #8328's stdio half (PR #8724, `packages/mcp`) fixed the long-lived server. + * #8328's stdio half (commit ff4ba6a06, `packages/mcp`) fixed the long-lived server. * This is the per-request HTTP surface the reproduction actually runs through. * * ── Why the fakes are shaped the way they are ───────────────────────────── diff --git a/packages/runtime/src/domains/mcp.ts b/packages/runtime/src/domains/mcp.ts index 539b71b8a8d..dae5ade89b6 100644 --- a/packages/runtime/src/domains/mcp.ts +++ b/packages/runtime/src/domains/mcp.ts @@ -318,7 +318,7 @@ function toMcpWebRequest(_deps: DomainHandlerDeps, raw: any, parsedBody: any): R } /** - * [#8726] The protocol layer's overlay-aware merged read, as this package can + * [commit e783e163d] The protocol layer's overlay-aware merged read, as this package can * name it. * * ⚠️ **Deliberately `Pick`ed from the DECLARED contract rather than restated.** @@ -344,7 +344,7 @@ function toMcpWebRequest(_deps: DomainHandlerDeps, raw: any, parsedBody: any): R export type McpMergedMetadataRead = Pick; /** - * [#8726] Read this environment's `skill` rows through the merged listing. + * [commit e783e163d] Read this environment's `skill` rows through the merged listing. * * ── The defect this closes ──────────────────────────────────────────────── * @@ -361,7 +361,7 @@ export type McpMergedMetadataRead = Pick; * * ── Absent vs. degraded vs. failed — three outcomes, deliberately ───────── * - * 1. **No merged read on this host** → the pre-#8726 registry listing, + * 1. **No merged read on this host** → the registry listing before commit e783e163d, * unchanged, including its `?? []` for a host with no metadata service at * all. Structural absence is not degradation: a host that assembles this * runtime without the metadata protocol has no merged read to offer, so @@ -412,7 +412,7 @@ async function readMergedSkillRows( } /** - * [#8726] Report #6504's completeness verdict for the skill prompt surface. + * [commit e783e163d] Report #6504's completeness verdict for the skill prompt surface. * * This read never had a diagnosed wrapper at all — unlike the stdio bridge, * where #6504 had already landed one — so a known-partial skill surface @@ -644,7 +644,7 @@ export function buildMcpBridge(deps: DomainHandlerDeps, context: HttpProtocolCon // ExecutionContext filtering, exactly like `describeObject` (the MCP // route itself is authenticated). // - // [#8726] Through the protocol layer's MERGED listing — the second half + // [commit e783e163d] Through the protocol layer's MERGED listing — the second half // of #8328, whose own reproduction runs through THIS endpoint. See // {@link readMergedSkillRows}. listSkills: async () => { diff --git a/packages/runtime/src/domains/meta-save-destructive-remedy.test.ts b/packages/runtime/src/domains/meta-save-destructive-remedy.test.ts index fcd85cdf7f9..c2e77efe5a3 100644 --- a/packages/runtime/src/domains/meta-save-destructive-remedy.test.ts +++ b/packages/runtime/src/domains/meta-save-destructive-remedy.test.ts @@ -16,7 +16,7 @@ * * ## Why this half was NOT repaired by threading the parameter * - * The maintainer ruled a SPLIT (2026-08-23) over the two doors #11015 left + * The maintainer ruled a SPLIT (2026-08-23) over the two doors commit 82cb6e849 left * open, and the split is the decision rather than an inconsistency to be tidied * away later: * @@ -29,7 +29,7 @@ * the transport does not have. Threading one would be a NEW public surface, * which no ruling has opened. * - * So the repair is #11015's landed mechanism, applied mechanically: a face value + * So the repair is the mechanism commit 82cb6e849 landed, applied mechanically: a face value * (`'meta-dispatch'`), stated at this call site, that renders a clause naming * what a caller can actually do HERE. * @@ -43,7 +43,7 @@ * `'meta-envelope'` in the first place. Splitting the face for the 409's sake * therefore had to leave the 422 exactly where it was, and the 422's polarity * is "declare to trim" — silence renders the FULL prose — so a face that fell - * through would re-introduce #10888's duplication on this door alone, silently, + * through would re-introduce the duplication commit d806081dd removed on this door alone, silently, * with every 409 assertion green. Section 3 is that pin. * * ## Harness @@ -268,8 +268,8 @@ describe('[#11095] dispatcher PUT /meta — the destructive refusal', () => { const res: any = await put(stack, objectBody(NAME, SHRUNK_FIELDS)); - // Only the remedy clause is face-aware. #10886's sole-carrier verdict is - // untouched by this card exactly as it was untouched by #11015. + // Only the remedy clause is face-aware. Commit 809e61221's sole-carrier verdict is + // untouched by this card exactly as it was untouched by commit 82cb6e849. expect(res.response?.body?.error?.message).toContain("Field 'b' removed"); // Row 3 of the face inventory says this door is NOT a sole carrier, and // the claim is about THIS body. diff --git a/packages/runtime/src/domains/meta-state-plural-tolerance.test.ts b/packages/runtime/src/domains/meta-state-plural-tolerance.test.ts index 16dac90f66a..6945f156d5c 100644 --- a/packages/runtime/src/domains/meta-state-plural-tolerance.test.ts +++ b/packages/runtime/src/domains/meta-state-plural-tolerance.test.ts @@ -168,7 +168,7 @@ describe('dispatcher /meta FSM state read — the deliberate plural tolerance (# 'GET', `/meta/${segment}/task/state/status`, undefined, { from: 'todo' }, CTX(), ); - // [#12195] `ROUTE_NOT_FOUND`, not `RESOURCE_NOT_FOUND`, and the + // [commit 7986d973f] `ROUTE_NOT_FOUND`, not `RESOURCE_NOT_FOUND`, and the // change is the retirement showing through. `/meta/objectss/task/ // state/status` is four segments; the FSM branch requires the two // literals, so it used to fall into the compound fold, which diff --git a/packages/runtime/src/domains/meta-verb-fallthrough.test.ts b/packages/runtime/src/domains/meta-verb-fallthrough.test.ts index cdcbfadea6b..228f24d3089 100644 --- a/packages/runtime/src/domains/meta-verb-fallthrough.test.ts +++ b/packages/runtime/src/domains/meta-verb-fallthrough.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#8848] `DELETE` / `PATCH` / `POST` on `/metadata/:type/:name` must be + * [commit 4fc4a3c0b] `DELETE` / `PATCH` / `POST` on `/metadata/:type/:name` must be * REFUSED with a `405` naming what is allowed — never answered as a READ. * * ## The defect this pins diff --git a/packages/runtime/src/domains/meta.ts b/packages/runtime/src/domains/meta.ts index 956b06eb843..6fcd6a7ef76 100644 --- a/packages/runtime/src/domains/meta.ts +++ b/packages/runtime/src/domains/meta.ts @@ -11,7 +11,7 @@ import { shouldDenyAnonymous, ANONYMOUS_DENY_STATUS, ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_MESSAGE, } from '@objectstack/core'; -// [#10503] `canonicalMetaUrlType` is the FOLD this transport was missing. +// [commit 67ceb9aef] `canonicalMetaUrlType` is the FOLD this transport was missing. // See the two call sites below for what each one was deciding raw. import { canonicalMetaUrlType, pluralToSingular } from '@objectstack/spec/shared'; import { CoreServiceName } from '@objectstack/spec/system'; @@ -113,7 +113,7 @@ import type { DomainHandlerDeps, DomainRoute } from '../domain-handler-registry. * probes below exist to deny — and it would have to answer for the three verbs * in the second group, which no contract declares at all. So the narrowing * happens at the consumer, once, exactly as `domains/packages.ts` (#13598) and - * `domains/mcp.ts` (#8726) narrow the same slot for their own seams. + * `domains/mcp.ts` (commit e783e163d) narrow the same slot for their own seams. * * ## ⛔ Every member is OPTIONAL, and the runtime probes STAY * @@ -197,7 +197,7 @@ function mayReadPendingDrafts(caller: unknown): boolean { } /** - * [#8848] The methods `/metadata/:type/:name` actually serves — the single + * [commit 4fc4a3c0b] The methods `/metadata/:type/:name` actually serves — the single * source for both the `Allow` header and the refusal message, so the two * cannot drift apart. * @@ -816,7 +816,7 @@ async function answerMetaLayered( } /** - * Percent-decode the `:name` path segment. [#12195] + * Percent-decode the `:name` path segment. [commit 7986d973f] * * This dispatcher splits the RAW path (`path.split('/')`) and, unlike the * `packages/rest` Hono routes, nothing decodes its parameters for it — @@ -824,7 +824,7 @@ async function answerMetaLayered( * hands to `dispatch()`, returns `/meta/lead/views%2Fall_leads` verbatim while * `c.req.param('name')` on the same request yields `views/all_leads`. * - * That difference is load-bearing here. Until #12195 the compound fold + * That difference is load-bearing here. Until commit 7986d973f the compound fold * (`parts.slice(1).join('/')`) is what let a slash-bearing name be addressed * on this transport at all — unencoded, across segments. Retiring the fold * without decoding would leave a pre-grammar residue row addressable through @@ -1043,7 +1043,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin // GET /metadata/:type/:name/published → get published version // - // [#12195] EXACTLY three segments, and no fold. This used to be + // [commit 7986d973f] EXACTLY three segments, and no fold. This used to be // `parts.length >= 3` with `parts.slice(1, -1).join('/')`, which re-joined // every middle segment into one slash-bearing key so // `lead/views/all_leads/published` resolved as name `views/all_leads`. @@ -1140,7 +1140,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin const metadataService = await deps.getService(_context, CoreServiceName.enum.metadata); if (metadataService && typeof (metadataService as any).getPublished === 'function') { - // [#10503] FOLDED — the smaller second site of the same class, + // [commit 67ceb9aef] FOLDED — the smaller second site of the same class, // dispatcher edition (the REST twin folds at the same point). The // layered consult above folds internally at the protocol boundary; // this fallback reads the code/package registry, which stores @@ -1156,7 +1156,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin if (metaSvc && typeof (metaSvc as any).getPublished === 'function') { let fallbackData: unknown; try { - // [#10503] Same fold — this slot reads the same canonical store. + // [commit 67ceb9aef] Same fold — this slot reads the same canonical store. fallbackData = await (metaSvc as any).getPublished(canonicalMetaUrlType(type), name); } catch { /* fall through */ } if (fallbackData !== undefined) return servePublished(fallbackData); @@ -1164,7 +1164,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin return { handled: true, response: deps.error('Not found', 404) }; } - // /metadata/:type/:name — EXACTLY two segments. [#12195] + // /metadata/:type/:name — EXACTLY two segments. [commit 7986d973f] // // This used to be `parts.length >= 2` with `parts.slice(1).join('/')`: every // segment after the type was re-joined into one slash-bearing lookup key, @@ -1244,10 +1244,10 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin // partition, never env-wide and never another org's. The active // organization is resolved HERE, once, and reused by the write // threading below — authorization and scope read one value (the - // single-resolution shape the REST doors carry, #8919). Resolving + // single-resolution shape the REST doors carry, commit b5378550e). Resolving // it is a session read, not a protocol probe: the 403-vs-501 // discipline above is untouched. - // [#10503] Folded at the boundary, once — the verdict and the + // [commit 67ceb9aef] Folded at the boundary, once — the verdict and the // scope decision below must read the same spelling. const canonicalType = canonicalMetaUrlType(type); // [#20408] The caller's VETTED organization — the `tenantId` @@ -1305,8 +1305,8 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin // capability gate above already made — scope and // authorization read the same value by construction. // - // [#10503] The segment is FOLDED before the scope decision - // — the correction #10340 landed for the REST `/meta` + // [commit 67ceb9aef] The segment is FOLDED before the scope decision + // — the correction commit 26f3588fb landed for the REST `/meta` // doors, arriving on the second transport. This branch read // the RAW `parts[0]`, while `protocol.saveMetaItem` below // folds the same string through `canonicalizeMetaRequestType` @@ -1334,7 +1334,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin const organizationId = organizationIdForMetaWrite( canonicalType, activeOrganizationId, ); - // [#10888] Server-stated face: this branch answers through + // [commit d806081dd] Server-stated face: this branch answers through // `deps.errorFromThrown`, which carries the refusal's // `issues[]` in `details` (see the `details.issues` pin in // `http-dispatcher.test.ts`), so `saveMetaItem`'s 422 renders @@ -1395,7 +1395,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin return { handled: true, response: deps.error('Save not supported', 501) }; } - // [#8848] The read `try` below is this block's default answer, and it + // [commit 4fc4a3c0b] The read `try` below is this block's default answer, and it // used to carry NO method guard at all: every verb that is not `PUT` // fell into it and was served the ordinary metadata READ. // @@ -1957,7 +1957,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin return { handled: true, response: deps.success({ types: ['object', 'app', 'plugin'] }) }; } - // [#12195] A LOCATED refusal, not a bare `{ handled: false }`. + // [commit 7986d973f] A LOCATED refusal, not a bare `{ handled: false }`. // // This tail was unreachable until this card: the branches above covered // zero segments, one segment, and — through the compound fold — every path diff --git a/packages/runtime/src/domains/packages-list-enabled-filter.test.ts b/packages/runtime/src/domains/packages-list-enabled-filter.test.ts index c8a2a647ae5..e4de12442a0 100644 --- a/packages/runtime/src/domains/packages-list-enabled-filter.test.ts +++ b/packages/runtime/src/domains/packages-list-enabled-filter.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#19394] `GET /api/v1/packages` honours the declared `enabled` filter — + * [commit 0862063ba] `GET /api/v1/packages` honours the declared `enabled` filter — * ruling item 2 of #17667. * * ## The defect this file pins shut @@ -39,7 +39,7 @@ * anything about them in either direction: pinning them as `201` would freeze * known residuals as intended behaviour, and pinning them as refused would be * this file quietly widening a graded scope. - * - **`hasMore` / `nextCursor`.** #19364 retired the request half + * - **`hasMore` / `nextCursor`.** Commit ada701220 retired the request half * (`limit` / `cursor`) and left `hasMore` a constant `false` that is now true * by construction. §5 asserts it is UNMOVED by this card — that is a * preservation pin, not a re-adjudication. diff --git a/packages/runtime/src/domains/packages-seed-apply-org-scope.test.ts b/packages/runtime/src/domains/packages-seed-apply-org-scope.test.ts index f2cbf9404d4..eff1411a6ae 100644 --- a/packages/runtime/src/domains/packages-seed-apply-org-scope.test.ts +++ b/packages/runtime/src/domains/packages-seed-apply-org-scope.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #15068 — the publish-then-read path under `applyPublishedSeeds`, and the + * Commit 8744de9e9 — the publish-then-read path under `applyPublishedSeeds`, and the * proof that its org-then-env ladder cannot choose between its two rungs. * * ## What the ladder was, and why deleting it needed a measurement @@ -24,7 +24,7 @@ * ## The mechanism, in one line * * `getMetaItem` opens with `organizationIdForMetaRead(request.type, - * request.organizationId)` (#14908, the singular twin of #14683's plural + * request.organizationId)` (commit d5cbb44f3, the singular twin of commit 96326040f's plural * gate) and spends that binding — never `request.organizationId` — on every * read below it. `seed` declares `allowOrgOverride: false` * (`metadata-plugin.zod.ts`), so the predicate answers `undefined` whatever @@ -34,7 +34,7 @@ * ⛔ The repair is NOT to restore org-awareness to this read. An org-scoped * `seed` row is the unhydratable phantom `reportUnhydratableOrgScopedRows` * exists to warn about — the same argument the `app` flip one function up - * carries since #15063. + * carries since commit ad35745e8. * * ## How this file is composed, and which half is doubled * @@ -487,7 +487,7 @@ describe('#15068 · 2 · the publish path stops spending an organization the gat const { readBackArgs } = await publishThenRead({ activeOrganizationId: ORG }); // Not cosmetic: an `organizationId` on a non-overridable read is the - // shape #14908 and #15063 exist to stop anyone reading as meaningful. + // shape commits d5cbb44f3 and ad35745e8 exist to stop anyone reading as meaningful. expect(readBackArgs).toEqual([{ type: 'seed', name: SEED }]); }); diff --git a/packages/runtime/src/domains/packages.ts b/packages/runtime/src/domains/packages.ts index a0399a0f870..6884f2c35da 100644 --- a/packages/runtime/src/domains/packages.ts +++ b/packages/runtime/src/domains/packages.ts @@ -101,7 +101,7 @@ import { ManifestSchema, SEMVER_2_0_0_VERSION_PATTERN, manifestIdRefusal } from // `res`, and every error body on this surface is `deps.error`'s. See the // `@objectstack/rest` barrel entry that publishes the pair. import { repeatedQueryParamMessage } from '@objectstack/rest'; -// [#19394] The repo's ONE coercion for a query parameter its schema declares +// [commit 0862063ba] The repo's ONE coercion for a query parameter its schema declares // `z.boolean()`, from the module whose header is the authority on the rule // (`packages/runtime/src/query-param.ts`). Imported, never restated: the list // door's `enabled` is declared `z.boolean().optional()` — character for @@ -678,7 +678,7 @@ function withWritableVerdict ({ const flip = (d: HttpDispatcher, ctx: HttpProtocolContext) => d.handleActions(`/_activation/${OBJECT}/${ACTION}`, 'POST', { enabled: false }, ctx); -/** Door 3 — `POST /automation/:name/toggle` (`./automation.ts`, read-only here: PR #16755 holds that file). */ +/** Door 3 — `POST /automation/:name/toggle` (`./automation.ts`, read-only here: the change that landed as commit 44c849c7d held that file). */ const FLOW = 'vendor_lead_router'; const FLOW_DEFINITION = { name: FLOW, label: 'Vendor Lead Router', type: 'autolaunched', nodes: [], edges: [] }; diff --git a/packages/runtime/src/domains/tenancy-posture-outage-gates.test.ts b/packages/runtime/src/domains/tenancy-posture-outage-gates.test.ts index 3552eade5d7..0a1c2e3b847 100644 --- a/packages/runtime/src/domains/tenancy-posture-outage-gates.test.ts +++ b/packages/runtime/src/domains/tenancy-posture-outage-gates.test.ts @@ -419,7 +419,7 @@ describe('[#15900] the install-wide activation write — a tenancy service that expect(isAuthzStoreUnavailableError(err)).toBe(true); expect((err as { status?: unknown }).status).toBe(OUTAGE_STATUS); expect((err as { code?: unknown }).code).toBe(OUTAGE_CODE); - // Refused BEFORE the write — a gate that refuses afterwards is #10243 + // Refused BEFORE the write — a gate that refuses afterwards is the leak commit 02b41232d measured, // with an audit trail. expect(setActionActive).not.toHaveBeenCalled(); }); @@ -530,7 +530,7 @@ describe('[#15900] the automation toggle — the same install-wide gate, reached expect((err as { status?: unknown }).status).toBe(OUTAGE_STATUS); expect((err as { code?: unknown }).code).toBe(OUTAGE_CODE); // Refused BEFORE the durable row — ADR-0126 made this switch survive a - // cold boot, so a refusal after the write is the #10243 leak with an + // cold boot, so a refusal after the write is the leak commit 02b41232d measured, with an // audit trail. expect(toggleFlow).not.toHaveBeenCalled(); }); diff --git a/packages/runtime/src/domains/ui.ts b/packages/runtime/src/domains/ui.ts index c5baca7c22a..7ae39da7eea 100644 --- a/packages/runtime/src/domains/ui.ts +++ b/packages/runtime/src/domains/ui.ts @@ -13,7 +13,7 @@ // signature here would silently drift from the one the spec declares and // `ObjectStackProtocolImplementation` states it `implements` — which is the // whole reason `UiDomainProtocol` below is `Pick`ed rather than written out. -// Same move `domains/packages.ts` (#13598) and `domains/mcp.ts` (#8726) make. +// Same move `domains/packages.ts` (#13598) and `domains/mcp.ts` (commit e783e163d) make. import type { MetadataProtocol } from '@objectstack/spec/api'; import type { HttpProtocolContext, HttpDispatcherResult } from '../http-dispatcher.js'; import type { DomainHandlerDeps, DomainRoute } from '../domain-handler-registry.js'; diff --git a/packages/runtime/src/expand-nested-fields-join-key.integration.test.ts b/packages/runtime/src/expand-nested-fields-join-key.integration.test.ts index a3f430e015a..2c8e8b81b3d 100644 --- a/packages/runtime/src/expand-nested-fields-join-key.integration.test.ts +++ b/packages/runtime/src/expand-nested-fields-join-key.integration.test.ts @@ -78,7 +78,7 @@ const TASK = { }; /** - * [#10629] This fixture provisions the four business objects it queries and nothing else, so the engine's + * [commit 13a6cb4ad] This fixture provisions the four business objects it queries and nothing else, so the engine's * own single-tenant probe (`ObjectQL.probeInstallOrganizations`, memoised once * per engine) reads a `sys_organization` that was never created. The probe is * fail-soft by construction — it catches `isMissingTableError` and only that — @@ -90,14 +90,14 @@ const ABSENT_TENANCY_TABLE = 'sys_organization'; describe('#7537 expand with a nested `fields` that omits the join key (REAL SqlDriver)', () => { let engine: ObjectQL | null = null; let dir: string | null = null; - /** [#10629] The expected-noise capture belonging to the latest boot. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest boot. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(async () => { try { await engine?.destroy(); } catch { /* noop */ } engine = null; if (dir) { rmSync(dir, { recursive: true, force: true }); dir = null; } - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave the engine running. Every test in this file // boots and writes, so the probe fires for each of them: this holds for a // single `-t` run as well as for the whole file. @@ -112,7 +112,7 @@ describe('#7537 expand with a nested `fields` that omits the join key (REAL SqlD connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true, }); - // [#10629] Installed before the driver runs a statement and before the + // [commit 13a6cb4ad] Installed before the driver runs a statement and before the // engine issues a read — the two sinks the expected refusal travels out on. noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); noise.captureDriver(driver); diff --git a/packages/runtime/src/expected-read-refusal-noise.channel-asymmetry.test.ts b/packages/runtime/src/expected-read-refusal-noise.channel-asymmetry.test.ts index bb076f80937..bb2743f53e2 100644 --- a/packages/runtime/src/expected-read-refusal-noise.channel-asymmetry.test.ts +++ b/packages/runtime/src/expected-read-refusal-noise.channel-asymmetry.test.ts @@ -19,7 +19,7 @@ // `ObjectLogger.write` returns early unless // `LEVEL_ORDER[frame] >= LEVEL_ORDER[config.level]`. // -// ⚠️ [#13273] The frame this probe provokes is a MISSING TABLE, and `engine.ts` +// ⚠️ [commit 3a86a65e7] The frame this probe provokes is a MISSING TABLE, and `engine.ts` // now classifies that class onto `debug` rather than `error` (its own // `reportFindFailure`). Two mechanical consequences for this instrument, both // measured rather than reasoned: @@ -96,7 +96,7 @@ interface Readout { readonly driverPassThrough: number; /** * Process-stream lines carrying the engine's `Find operation failed`, from - * `stderr` and `stdout` together — [#13273] the frame's level decides which + * `stderr` and `stdout` together — [commit 3a86a65e7] the frame's level decides which * of the two it lands on, and this file measures whether a reader saw it at * all, not which pipe carried it. */ @@ -211,9 +211,9 @@ describe('#11569 expected-read-refusal-noise: the two channels are not equally l it( 'engine pass-through: the SAME unrecognised read is loud at `debug` — the instrument produces a positive', async () => { - // [#13273] `debug` is the level that admits THIS frame: the probe reads a + // [commit 3a86a65e7] `debug` is the level that admits THIS frame: the probe reads a // table that does not exist, and `engine.ts` classifies that class onto - // `debug`. Before #13273 the same control was run at `error`. The claim + // `debug`. Before commit 3a86a65e7 the same control was run at `error`. The claim // under test is unchanged — "the engine channel is only as loud as the // kernel's own level" — only the rank it is compared against moved. const seen = await probeRead('debug', UNDECLARED_TABLE, [DECLARED_TABLE]); @@ -232,7 +232,7 @@ describe('#11569 expected-read-refusal-noise: the two channels are not equally l it( 'engine pass-through: the condition is the LEVEL THRESHOLD, not the word `silent` — `fatal` drops it too', async () => { - // `ObjectLogger.isEnabled` compares rank: this frame ([#13273] `debug`, + // `ObjectLogger.isEnabled` compares rank: this frame ([commit 3a86a65e7] `debug`, // rank 0) is admitted only while the configured level is `debug`. // `fatal` (4) and `silent` (5) both refuse it — as do `info` and `warn` // — so a fixture that floats its kernel to `fatal` is just as blind as diff --git a/packages/runtime/src/expected-read-refusal-noise.ts b/packages/runtime/src/expected-read-refusal-noise.ts index 406007af3a3..51c4014d122 100644 --- a/packages/runtime/src/expected-read-refusal-noise.ts +++ b/packages/runtime/src/expected-read-refusal-noise.ts @@ -2,8 +2,8 @@ /** * ═══════════════════════════════════════════════════════════════════════════ - * [#10629] Expected `refused a read on` noise: WITHHELD from the shared log, - * and ASSERTED instead — the shape PR #10630 landed, factored out + * [commit 13a6cb4ad] Expected `refused a read on` noise: WITHHELD from the shared log, + * and ASSERTED instead — the shape commit dd8172ee2 landed, factored out * ═══════════════════════════════════════════════════════════════════════════ * * ## The defect this closes @@ -34,8 +34,8 @@ * … no such table: `, from `SqlDriver.backendStatementFault` * through the driver's own `logger.warn`; * 2. `Find operation failed {"object":"
",…}` one frame up - * (`objectql/src/engine.ts`), carrying the same fault. ⚠️ [#13273] It used - * to be `ERROR`, with a stack, for EVERY cause; since #13273 the engine + * (`objectql/src/engine.ts`), carrying the same fault. ⚠️ [commit 3a86a65e7] It used + * to be `ERROR`, with a stack, for EVERY cause; since commit 3a86a65e7 the engine * asks `isMissingTableError` and puts the "table not provisioned" class * — i.e. exactly the class this module is declared over — on `debug` * instead, with no stack and a `reason: 'table-not-provisioned'` meta. @@ -49,7 +49,7 @@ * Turbo interleaves package logs without attribution, so in the shared shard * log those are indistinguishable from a real failure. Not a hypothetical: * lines of exactly this shape were lifted VERBATIM into a p1 flake signature - * (#10293) and sent a whole dispatch cycle at the wrong mechanism. + * (a vitest teardown race, fixed by commit 92a69d813) and sent a whole dispatch cycle at the wrong mechanism. * Expected-failure noise from a green test is a diagnosis tax on every future * red shard. * @@ -91,7 +91,7 @@ * rule for all of them, and do not read a quiet engine channel in one fixture * as evidence about another. * - * ⚠️ [#13273] The threshold moved for the "table not provisioned" class, and + * ⚠️ [commit 3a86a65e7] The threshold moved for the "table not provisioned" class, and * moved DOWN: that frame is now `debug` (rank 0), so a fixture has to be at * `debug` to see an unrecognised one, where `info` used to be enough. The * asymmetry above is unchanged in shape — the engine channel is still only as @@ -124,11 +124,11 @@ * * ## Why a shared module rather than a copy per fixture * - * PR #10630 established this shape on two files and wrote it inline in each. + * Commit dd8172ee2 established this shape on two files and wrote it inline in each. * The enumerated remainder is sixteen more, across four distinct probe sites, * and sixteen copies of one predicate is sixteen places for it to drift — * including drifting *looser*, which is the direction that turns a pin back - * into a mute without anything going red. The mechanism below is #10630's + * into a mute without anything going red. The mechanism below is commit dd8172ee2's * verbatim: the same two sinks, the same "named table AND named reason" * predicate, the same pending-refusal gate on the engine frame, the same * count-and-assert discipline. Only the duplication is gone. @@ -167,7 +167,7 @@ export interface ExpectedReadRefusalCapture { * The expected channels that never fired, one sentence each — the assertion * surface. `expect(capture.silentChannels()).toEqual([])` is one call that * still makes a silent channel NAME ITSELF in the diff, which is what - * #10630's "one assertion per channel" bought at sixteen times the bulk. + * commit dd8172ee2's "one assertion per channel" bought at sixteen times the bulk. * * ⛔ Repairing a failure here means re-deriving the declared table list or * finding out why the probe stopped — NEVER relaxing this: a runtime read @@ -194,7 +194,7 @@ export interface ExpectedReadRefusalCapture { * setter, which is the same access `engine-readonly-when-parent.test.ts` * established. * - * ⚠️ [#13273] Both channels, because the engine now picks between them by + * ⚠️ [commit 3a86a65e7] Both channels, because the engine now picks between them by * cause: a read whose table was never provisioned goes to `debug`, every * other read failure to `warn` ([#17212]; it was `error`). Wrapping only one * would leave this capture blind on whichever half the engine chose. @@ -409,7 +409,7 @@ export function captureExpectedReadRefusals( target.warn(msg, meta, ...rest); }; } - // [#13273] The SAME frame, on the channel the engine now chooses for + // [commit 3a86a65e7] The SAME frame, on the channel the engine now chooses for // a read whose table was never provisioned — which is every read this // capture is declared over. `debug(msg, meta)` has no `error` // argument, so the driver's envelope arrives as `meta.error` instead; @@ -434,7 +434,7 @@ export function captureExpectedReadRefusals( /** * ═══════════════════════════════════════════════════════════════════════════ - * [#10983] A SECOND, independent predicate: cross-field `{ $field }` refusal + * [commit 6a4e929f5] A SECOND, independent predicate: cross-field `{ $field }` refusal * engine noise (#7929) — the sibling {@link captureExpectedReadRefusals} * cannot recognise, because it has no table to key on * ═══════════════════════════════════════════════════════════════════════════ diff --git a/packages/runtime/src/external-validation-checkonboot.test.ts b/packages/runtime/src/external-validation-checkonboot.test.ts index e8e2b3939cc..0bdcec5c4d5 100644 --- a/packages/runtime/src/external-validation-checkonboot.test.ts +++ b/packages/runtime/src/external-validation-checkonboot.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#13037] `datasource.external.validation.checkOnBoot` — declared with + * [commit e7dfb1d69] `datasource.external.validation.checkOnBoot` — declared with * `.default(true)` since the block was written, and read by NOTHING until this * card. An author who wrote `checkOnBoot: false` and left `onMismatch` at its * default still got the boot sweep, and a measured mismatch still threw @@ -54,7 +54,7 @@ const mismatch: SchemaDiffEntry[] = [ { kind: 'type_mismatch', remoteName: 'fact_orders', column: 'amount', expected: 'number', actual: 'text', severity: 'error' }, ]; -/** [#11166] The indeterminate row: the remote could not be read at all. */ +/** [commit 735f5c709] The indeterminate row: the remote could not be read at all. */ const unreachable: SchemaDiffEntry[] = [ { kind: 'unreachable', remoteName: 'fact_orders', actual: 'connect ECONNREFUSED 10.0.0.5:5432', severity: 'error' }, ]; @@ -136,7 +136,7 @@ describe('checkOnBoot: false — the datasource is skipped by the kernel:ready s }); /** - * [#11166]'s loud unreachable warning is part of the boot gate, so it is part + * Commit 735f5c709's loud unreachable warning is part of the boot gate, so it is part * of what `checkOnBoot: false` opts out of. Skipped means skipped — an author * who took the boot check off their datasource should not be told at every * startup that the boot check could not read it. diff --git a/packages/runtime/src/external-validation-drift-scope.test.ts b/packages/runtime/src/external-validation-drift-scope.test.ts index 49c1e87ea2e..f280538c942 100644 --- a/packages/runtime/src/external-validation-drift-scope.test.ts +++ b/packages/runtime/src/external-validation-drift-scope.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#10961] The BACKGROUND drift check does the work it was ARMED for. + * [commit 222d06fc1] The BACKGROUND drift check does the work it was ARMED for. * * ## The defect this file measures * diff --git a/packages/runtime/src/external-validation-plugin.test.ts b/packages/runtime/src/external-validation-plugin.test.ts index 9305c697cb1..fb33531858d 100644 --- a/packages/runtime/src/external-validation-plugin.test.ts +++ b/packages/runtime/src/external-validation-plugin.test.ts @@ -28,7 +28,7 @@ const sampleDiffs: SchemaDiffEntry[] = [ { kind: 'type_mismatch', remoteName: 'fact_orders', column: 'amount', expected: 'number', actual: 'text', severity: 'error' }, ]; -/** [#11166] The row `validateEach` produces when the remote could not be read. */ +/** [commit 735f5c709] The row `validateEach` produces when the remote could not be read. */ const unreachableDiffs: SchemaDiffEntry[] = [ { kind: 'unreachable', remoteName: 'fact_orders', actual: 'connect ECONNREFUSED 10.0.0.5:5432', severity: 'error' }, ]; @@ -87,7 +87,7 @@ describe('ExternalValidationPlugin (ADR-0015 Gate 2)', () => { }); /** - * [#11166] An `unreachable` row is not a schema mismatch: validation was + * [commit 735f5c709] An `unreachable` row is not a schema mismatch: validation was * indeterminate (the remote could not be read), so the default * `onMismatch: 'fail'` must NOT abort boot for it — a transient outage * during startup used to be a refusal to start. Loud logging instead, @@ -151,7 +151,7 @@ describe('ExternalValidationPlugin — background drift detection (ADR-0015 §5. afterEach(() => vi.useRealTimers()); /** - * [#10961] The fake answers the SCOPED spelling, because that is what the + * [commit 222d06fc1] The fake answers the SCOPED spelling, because that is what the * checker now calls: a timer armed for one datasource asks the service about * that datasource, instead of sweeping the farm and filtering the report. * The rows below live behind that scoping so the fixture cannot hand back a @@ -188,7 +188,7 @@ describe('ExternalValidationPlugin — background drift detection (ADR-0015 §5. }); /** - * [#11166] A briefly-unreachable remote used to raise `external.schema.drift` + * [commit 735f5c709] A briefly-unreachable remote used to raise `external.schema.drift` * events whose diffs claimed `missing_table` on every tick it stayed down. * The event is still emitted (audit/notification consumers see the outage) * but under the distinct `unreachable` kind — and the operator-facing diff --git a/packages/runtime/src/external-validation-plugin.ts b/packages/runtime/src/external-validation-plugin.ts index eb3200efad1..e7d834f77bd 100644 --- a/packages/runtime/src/external-validation-plugin.ts +++ b/packages/runtime/src/external-validation-plugin.ts @@ -28,12 +28,12 @@ interface ExternalDatasourceServiceLike { */ validateAll(): Promise; /** - * [#10961] The scoped twin: validate the federated objects bound to ONE + * [commit 222d06fc1] The scoped twin: validate the federated objects bound to ONE * datasource, driving live introspection against THAT datasource only. * * OPTIONAL, and probed rather than assumed, because it is deliberately not on - * `IExternalDatasourceService` — #10537's triage authorized the service-side - * composition, not a contract-surface expansion, and #10961's triage carried + * `IExternalDatasourceService` — commit e634ecf6a, as triaged, took the service-side + * composition, not a contract-surface expansion, and commit 222d06fc1 carried * that ruling forward unchanged. What is asserted here rather than * contract-checked is the method's NAME; nothing about the shape it returns, * which is the report type both spellings already share. @@ -155,7 +155,7 @@ interface DatasourceDef { validation?: { onMismatch?: 'fail' | 'warn' | 'ignore'; /** - * [#13037] The BOOT gate's per-datasource opt-out — read by + * [commit e7dfb1d69] The BOOT gate's per-datasource opt-out — read by * {@link bootCheckEnabled}, and by nothing else on purpose. The scope * boundary the maintainer pinned when ruling this key ENFORCED (rather * than retired) is stated at that function. @@ -187,7 +187,7 @@ export interface ExternalSchemaDriftEvent { * - `warn` → logs the diff and continues, * - `ignore` → does nothing. * - * [#13037] A datasource that sets `external.validation.checkOnBoot: false` is + * [commit e7dfb1d69] A datasource that sets `external.validation.checkOnBoot: false` is * skipped by this sweep entirely — no policy is applied to its rows, so no * mismatch on it can abort boot. Its BACKGROUND drift checking is a separate * policy and is unaffected; see {@link bootCheckEnabled} for the scope the @@ -197,7 +197,7 @@ export interface ExternalSchemaDriftEvent { * `kind: 'unreachable'` (the remote could not be read, so validation was * indeterminate — see the kind's docblock in `@objectstack/spec/shared`) never * feeds that policy: it is logged loudly and boot continues, under every - * `onMismatch` value (maintainer ruling 2026-08-23, #11166). + * `onMismatch` value (maintainer ruling 2026-08-23, landed in commit 735f5c709). * * No-op when the `external-datasource` service is not registered (federation * unused). @@ -276,7 +276,7 @@ export class ExternalValidationPlugin implements Plugin { } const metadata = safeGet(ctx, 'metadata'); - // [#13037] One definition read per datasource per sweep, shared by the + // [commit e7dfb1d69] One definition read per datasource per sweep, shared by the // `checkOnBoot` gate below and the `onMismatch` resolution after it. const loadDef = createDatasourceDefLoader(metadata); let report: Awaited>; @@ -287,7 +287,7 @@ export class ExternalValidationPlugin implements Plugin { return; } - // [#13037] Honour each datasource's `external.validation.checkOnBoot` + // [commit e7dfb1d69] Honour each datasource's `external.validation.checkOnBoot` // BEFORE any verdict is drawn from its rows. The sweep is whole-farm and // the key is per-datasource, so the opt-out can only be applied here, row // by row — a datasource that set `false` is dropped, and every other @@ -323,7 +323,7 @@ export class ExternalValidationPlugin implements Plugin { } for (const r of failures) { - // [#11166] An `unreachable` row is NOT a schema mismatch — the remote + // [commit 735f5c709] An `unreachable` row is NOT a schema mismatch — the remote // (or the object's own definition) could not be read, so validation was // indeterminate and there is no measured fact to gate on. Maintainer // ruling 2026-08-23: no `onMismatch: 'fail'` abort for unreachable — @@ -379,7 +379,7 @@ export class ExternalValidationPlugin implements Plugin { * (e.g. a second `kernel:ready`) first clears existing timers so intervals * don't accumulate. * - * ⭐ [#13037] **`external.validation.checkOnBoot` does not reach here, by + * ⭐ [commit e7dfb1d69] **`external.validation.checkOnBoot` does not reach here, by * ruling.** The maintainer pinned that gate's scope to the BOOT STEP ONLY * (2026-08-29): a datasource that set `checkOnBoot: false` still gets the * background drift checker it asked for via `checkIntervalMs`, because the @@ -426,7 +426,7 @@ export class ExternalValidationPlugin implements Plugin { * `external.schema.drift` event per mismatch. Exposed for testing; invoked * from the interval armed by {@link scheduleDriftChecks}. Never throws. * - * ## [#10961] The work is scoped by the CALL, not by a filter over a sweep + * ## [commit 222d06fc1] The work is scoped by the CALL, not by a filter over a sweep * * This body used to ask for `validateAll()` — every federated object on every * federated datasource, each validation driving a live remote-schema @@ -438,7 +438,7 @@ export class ExternalValidationPlugin implements Plugin { * two armed timers introspected six remotes per cycle where two were asked * for, and each additional tick repeated it. * - * That makes this the periodic twin of the request-gate defect #10537 named, + * That makes this the periodic twin of the request-gate defect commit e634ecf6a fixed, * and worse in the one way that matters: a request gate has a caller waiting * on the answer and paying attention to the latency, while this is * **unattended** — the fan-out repeats on every interval, forever, with @@ -536,7 +536,7 @@ export class ExternalValidationPlugin implements Plugin { } } if (drifted.length > 0) { - // [#11166] Same distinction as the boot gate, one layer down: an + // [commit 735f5c709] Same distinction as the boot gate, one layer down: an // `unreachable` row is "could not watch", not "schema changed". The // event above is still emitted for it — audit/notification consumers // discriminate on the entry's `kind` — but the operator-facing summary @@ -571,7 +571,7 @@ export function createExternalValidationPlugin(): ExternalValidationPlugin { * Reads one datasource definition per NAME per sweep, answering `undefined` for * anything it could not read. * - * [#13037] Introduced because the boot gate now asks the definition two + * [commit e7dfb1d69] Introduced because the boot gate now asks the definition two * questions — "does this datasource opt out of the boot check?" and, only for * the rows that stayed, "what is its `onMismatch` policy?" — and asking twice * would double the metadata reads for every mismatching row. Memoized per @@ -604,7 +604,7 @@ function createDatasourceDefLoader( } /** - * [#13037] Does the BOOT sweep apply to this datasource? + * [commit e7dfb1d69] Does the BOOT sweep apply to this datasource? * * ## ⭐ Scope, pinned by the maintainer at the ruling (2026-08-29) * diff --git a/packages/runtime/src/federated-boot-binding.test.ts b/packages/runtime/src/federated-boot-binding.test.ts index c3afb037d75..41301e844dc 100644 --- a/packages/runtime/src/federated-boot-binding.test.ts +++ b/packages/runtime/src/federated-boot-binding.test.ts @@ -126,7 +126,7 @@ function orphanArtifact() { } /** - * [#10629] The `OS_SKIP_SCHEMA_SYNC` case's expected read failures: WITHHELD, + * [commit 13a6cb4ad] The `OS_SKIP_SCHEMA_SYNC` case's expected read failures: WITHHELD, * and ASSERTED. * * With boot schema sync skipped, nothing creates `sys_metadata` — that IS what @@ -170,7 +170,7 @@ async function boot(bundle: Record, capture?: ExpectedReadRefus const runtime = new Runtime({ cluster: false }); const kernel = runtime.getKernel(); - // [#10629] Scoped before the driver runs a statement when the caller asked + // [commit 13a6cb4ad] Scoped before the driver runs a statement when the caller asked // for a capture; the default boot passes none and stays fully loud. const driver = await makeDefaultDriver(); capture?.captureDriver(driver); @@ -243,7 +243,7 @@ describe('#7737 federated boot binding — declared external objects are bound w await driver.execute("INSERT INTO remote_invoices (id, amount) VALUES ('i1', 100)"); expect((await engine.find('fed_customer')).map((r) => r.name)).toEqual(['Ada']); expect((await engine.find('fed_invoice')).map((r) => r.id)).toEqual(['i1']); - // [#10629] The capture is a PIN, not a mute: if boot stops reading + // [commit 13a6cb4ad] The capture is a PIN, not a mute: if boot stops reading // `sys_metadata`, or the table starts existing under this flag, the log // goes quiet AND this goes red. expect(noise.silentChannels()).toEqual([]); diff --git a/packages/runtime/src/flow-clone.ts b/packages/runtime/src/flow-clone.ts index e98131c219b..5008277ee69 100644 --- a/packages/runtime/src/flow-clone.ts +++ b/packages/runtime/src/flow-clone.ts @@ -4,7 +4,7 @@ * # Flow clone — whole-definition copy under a new machine name (ADR-0126 §7.1) * * The copy half of ADR-0126's packaged-metadata customization model, shaped on - * the landed permission-set clone (`sys-permission-set.object.ts`, #11513): an + * the landed permission-set clone (`sys-permission-set.object.ts`, commit e170b0ae5): an * admin who cannot edit a packaged flow in place gets an ordinary, * org-authored sibling to edit instead. * diff --git a/packages/runtime/src/http-dispatcher.actions-global-key.test.ts b/packages/runtime/src/http-dispatcher.actions-global-key.test.ts index 455b06cd694..04db04d7375 100644 --- a/packages/runtime/src/http-dispatcher.actions-global-key.test.ts +++ b/packages/runtime/src/http-dispatcher.actions-global-key.test.ts @@ -9,7 +9,7 @@ * 1. **Registration key vs lookup key.** Both writers register an * objectName-less action under the literal `'global'` — `AppPlugin` * (`action.object || 'global'`) and the ObjectQL plugin (whose copy of the - * ladder was converged into `standaloneActionOwnerKey` by #14422). The + * ladder was converged into `standaloneActionOwnerKey` by commit dc7c226b9). The * REST fallback probed `'*'`, and `engine.executeAction` is an * exact-string `Map` lookup with no wildcard semantics, so the probe could * only ever miss: `Action 'log_call' on object '*' not found`. diff --git a/packages/runtime/src/http-dispatcher.permission-denied-user-message.test.ts b/packages/runtime/src/http-dispatcher.permission-denied-user-message.test.ts index 1cdfe3ab3f7..b998c724acb 100644 --- a/packages/runtime/src/http-dispatcher.permission-denied-user-message.test.ts +++ b/packages/runtime/src/http-dispatcher.permission-denied-user-message.test.ts @@ -4,14 +4,14 @@ * [#13623] The DENIAL door carries the producer's `userMessage` — the second * door that dropped it, and the one whose refusals users most need to read. * - * ## Why this is a second door and not the one #13241 repaired + * ## Why this is a second door and not the one commit a21d2a9cf repaired * * `HttpDispatcher.dispatch`'s foot catch is **not a pure rethrow**. It * recognises `isPermissionDeniedError` — `name === 'PermissionDeniedError'` * **or** `code === 'PERMISSION_DENIED'` **or** a message starting * `[Security] Access denied` — and answers it itself, from * `packages/runtime/src/http-dispatcher.ts`. Such a throw therefore never - * reaches `dispatcher-plugin`'s `errorResponseBase`, which is the exit #13241 + * reaches `dispatcher-plugin`'s `errorResponseBase`, which is the exit commit a21d2a9cf * taught to carry the mark. Same field, same contract, different door. * * `ApiErrorSchema.userMessage` has declared the slot all along, and diff --git a/packages/runtime/src/http-dispatcher.test.ts b/packages/runtime/src/http-dispatcher.test.ts index 2e74eed0d52..c24826ec7fc 100644 --- a/packages/runtime/src/http-dispatcher.test.ts +++ b/packages/runtime/src/http-dispatcher.test.ts @@ -79,7 +79,7 @@ const PKG_ADMIN = () => ({ request: {}, executionContext: { userId: 'u_pkg_admin * destroys. Only the caller changes; the gate itself is pinned in * `domains/automation-write-capability-gate.test.ts`. * - * [#10243] `POST /:name/toggle` uses this caller too, since the 2026-08-23 + * [commit 266436a7f] `POST /:name/toggle` uses this caller too, since the 2026-08-23 * ruling put enablement in the same write set. The EXECUTION routes on the * domain (trigger / resume) keep `AUTHED_CALLER`, deliberately — that half of * the line did not move. @@ -141,7 +141,7 @@ describe('HttpDispatcher', () => { type: 'objects', name: 'my_obj', item: body, - // [#10888] Server-stated, and asserted here rather than relaxed + // [commit d806081dd] Server-stated, and asserted here rather than relaxed // to `objectContaining`: this door's whole claim to the face is // that it answers through `errorFromThrown`, which carries a // refusal's `issues[]` in `details` (pinned below). If the face @@ -182,7 +182,7 @@ describe('HttpDispatcher', () => { // Commit 7986d973f retired compound metadata item names (maintainer ruling // 2026-08-25); commit 311433f6b refuses every slash-bearing name at the // publish door, so the fold could only address names that can no - // longer be created; #12195 removes it. The domain now DECLINES, + // longer be created; commit 7986d973f removes it. The domain now DECLINES, // and nothing is written. const path = '/lead/views/all_leads'; @@ -424,7 +424,7 @@ describe('HttpDispatcher', () => { }); it('should toggle a flow via POST /:name/toggle', async () => { - // [#10243] `FLOW_AUTHOR`, not `AUTHED_CALLER`: toggle joined the + // [commit 266436a7f] `FLOW_AUTHOR`, not `AUTHED_CALLER`: toggle joined the // `manage_metadata` write set by ruling. This case is about ROUTING // — which service method the path reaches, with which arguments — // so only the caller changes. diff --git a/packages/runtime/src/http-dispatcher.ts b/packages/runtime/src/http-dispatcher.ts index 9b8bd98baee..ed66811dfdc 100644 --- a/packages/runtime/src/http-dispatcher.ts +++ b/packages/runtime/src/http-dispatcher.ts @@ -663,7 +663,7 @@ export class HttpDispatcher { acceptOAuthAccessToken: /^(?:\/environments\/[^/]+)?\/mcp(?:[/?]|$)/.test(cleanPath), }); } catch (err) { - // [#13906 decision 1 A / #13279] The ONE fault that must stay loud: + // [#13906 decision 1 A / commit 6a180e42d] The ONE fault that must stay loud: // an authorization input that exists and could not be read (a // failed permission-store read, a `tenancy` service that is // registered and failed to build). Swallowing it here answered an @@ -2794,7 +2794,7 @@ export class HttpDispatcher { console.warn(`[HttpDispatcher] PERMISSION_DENIED on ${method} ${cleanPath} — ${withheld}`); } // [#13623] The producer's marked user-facing text rides out — - // the SECOND door that dropped it. #13241 repaired the + // the SECOND door that dropped it. Commit a21d2a9cf repaired the // THROW-TRANSPARENT exit (`dispatcher-plugin.errorResponseBase`); // a marked denial never reaches that exit, because this catch is // not a pure rethrow: it recognises the denial and answers it diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index 0a21232ca24..7b32f459bab 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -11,7 +11,7 @@ export type { RuntimeConfig } from './runtime.js'; export { createStandaloneStack, resolveObjectStackHome, resolveStandaloneDatabase } from './standalone-stack.js'; export type { StandaloneStackConfig, StandaloneStackResult, ResolvedStandaloneDatabase } from './standalone-stack.js'; -// The ONE libSQL/Turso loader (#6268). Public because `@objectstack/cli` is a +// The ONE libSQL/Turso loader (commit 68f5eccb1). Public because `@objectstack/cli` is a // consumer, not a second implementation: `utils/storage-driver.ts` delegates to // `loadTursoDriverFactory` and RE-EXPORTS `MissingDriverPackageError`, so // `serve.ts`'s `e instanceof MissingDriverPackageError` fatal branch tests one diff --git a/packages/runtime/src/load-artifact-bundle.ts b/packages/runtime/src/load-artifact-bundle.ts index d5f0c6e8e7f..c78b131e624 100644 --- a/packages/runtime/src/load-artifact-bundle.ts +++ b/packages/runtime/src/load-artifact-bundle.ts @@ -180,7 +180,7 @@ export async function mergeRuntimeModule(bundle: any, artifactAbsPath: string, t // `effect: 'writes'` included — which is #4396's silent un-declaring in // the other spelling: the function still registers, still runs, and its // writes are still counted as none, so #4354's broken-sweep alert stays - // quiet on the one run that needed it. Unreachable until #6238 let the + // quiet on the one run that needed it. Unreachable until commit c8d6f6e08 let the // array form past the parse; reachable now, so it is handled here. if (Array.isArray(declaredFunctions)) { const moduleFns = fns as Record; diff --git a/packages/runtime/src/meta-compound-arity-mint-door.test.ts b/packages/runtime/src/meta-compound-arity-mint-door.test.ts index 90db77261e3..eab5ea7e96c 100644 --- a/packages/runtime/src/meta-compound-arity-mint-door.test.ts +++ b/packages/runtime/src/meta-compound-arity-mint-door.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #8421/#12194 — the COMPOUND `/meta` arity write is refused at the item-name + * #8421 / commit 311433f6b — the COMPOUND `/meta` arity write is refused at the item-name * grammar gate, pinned at the LIVE ROUTE. * * `/metadata/lead/views/all_leads` is `type='lead'`, `name='views/all_leads'`: @@ -224,7 +224,7 @@ describe('#8421 — the compound `/meta` arity is not a metadata-type claim', () ); // The domain answers a LOCATED not-found rather than serving the path. - // Until #12195 it folded `views/all_leads` out of the trailing segments + // Until commit 7986d973f it folded `views/all_leads` out of the trailing segments // and answered — first by minting the row under the slash key // (before commit 311433f6b), then by refusing it at the grammar gate (commit 311433f6b). // Neither happens now: there is no three-segment metadata route. @@ -308,7 +308,7 @@ describe('#8421 — the compound `/meta` arity is not a metadata-type claim', () it('CONTROL — the capability gate still fires first at the SIMPLE arity', async () => { // #7019's gate is what masked this site, and it must keep masking an - // UNAUTHORIZED caller. [#12195] Driven at the simple arity now: the + // UNAUTHORIZED caller. [commit 7986d973f] Driven at the simple arity now: the // compound form this used to use is no longer handled at all, so it // would answer ROUTE_NOT_FOUND before any gate — which would make this // a control over nothing. diff --git a/packages/runtime/src/meta-write-org-scope.test.ts b/packages/runtime/src/meta-write-org-scope.test.ts index 0d6ade4b778..af0fedd48c1 100644 --- a/packages/runtime/src/meta-write-org-scope.test.ts +++ b/packages/runtime/src/meta-write-org-scope.test.ts @@ -72,7 +72,7 @@ import { } from '@objectstack/metadata-core'; import { ObjectStackProtocolImplementation } from '@objectstack/metadata-protocol'; import { DEFAULT_METADATA_TYPE_REGISTRY } from '@objectstack/spec/kernel'; -// [#10503] The URL spelling contract itself — the map storage folds through, +// [commit 67ceb9aef] The URL spelling contract itself — the map storage folds through, // and the fold the transport was missing. Imported so the sweep below is // quantified over the CONTRACT rather than over a hand-copied specimen list // (Prime Directive #8): a future spelling limb arrives inside the quantifier. @@ -213,7 +213,7 @@ function makeDispatcher( protocol: unknown, engine: any, activeOrganizationId: string | undefined, - // [#10503] The `metadata` CORE-SERVICE slot, absent by default. The + // [commit 67ceb9aef] The `metadata` CORE-SERVICE slot, absent by default. The // `/published` route consults the protocol's layered overlay first and // only then falls back to THIS slot — the code/package store. Registering // it unconditionally would change which branch every #7018 case above @@ -505,8 +505,8 @@ describe('#7018 — the registry decides whether a metadata write carries the se }); /** - * #10503 — the dispatcher `/metadata` transport decided ORGANIZATION SCOPE - * from the RAW path segment. The #10340 defect, one transport over. + * Until commit 67ceb9aef the dispatcher `/metadata` transport decided ORGANIZATION SCOPE + * from the RAW path segment. The defect commit 26f3588fb fixed, one transport over. * * ── What was broken ─────────────────────────────────────────────────────── * @@ -532,7 +532,7 @@ describe('#7018 — the registry decides whether a metadata write carries the se * store, which is keyed by CANONICAL type. Handed the raw segment it answered * 404 under a recognised plural and 200 under the singular twin. * - * The correction is the one #10340 landed for REST and the one + * The correction is the one commit 26f3588fb landed for REST and the one * `packages/spec/src/meta-spelling/metadata-url-spelling.ts` mandates: fold * the segment through `canonicalMetaUrlType` AT THE BOUNDARY, before the scope * decision. ⛔ NOT by widening `declaresOrgOverride` — a predicate below the diff --git a/packages/runtime/src/metadata-list-ambient-vs-bare-transaction.integration.test.ts b/packages/runtime/src/metadata-list-ambient-vs-bare-transaction.integration.test.ts index 0fd696764e4..b21379cd781 100644 --- a/packages/runtime/src/metadata-list-ambient-vs-bare-transaction.integration.test.ts +++ b/packages/runtime/src/metadata-list-ambient-vs-bare-transaction.integration.test.ts @@ -75,7 +75,7 @@ const SEEDED_NAME = 'thing'; const STALLED_OBJECT = 'sys_metadata'; // ═══════════════════════════════════════════════════════════════════════════ -// [#10380] The BARE case's expected error output: WITHHELD from the shared +// [commit dd8172ee2] The BARE case's expected error output: WITHHELD from the shared // log, and ASSERTED instead // ═══════════════════════════════════════════════════════════════════════════ // @@ -92,7 +92,7 @@ const STALLED_OBJECT = 'sys_metadata'; // // Turbo interleaves package logs without attribution, so in that shard log // these are indistinguishable from a real failure. Not a hypothetical: they -// were lifted VERBATIM into a p1 flake signature (#10293) and sent a whole +// were lifted VERBATIM into a p1 flake signature (a vitest teardown race, fixed by commit 92a69d813) and sent a whole // dispatch cycle at the wrong mechanism. Expected-failure noise from a green // test is a diagnosis tax on every future red shard. // @@ -203,7 +203,7 @@ interface Fixture { loader: DatabaseLoader; /** Every `driver.find` the fixture has observed, and whether it carried a transaction. */ reads: () => Array<{ object: string; hasTx: boolean }>; - /** [#10380] What this fixture withheld from the shared log, per channel. */ + /** [commit dd8172ee2] What this fixture withheld from the shared log, per channel. */ withheld: WithheldNoise; } @@ -220,7 +220,7 @@ afterEach(async () => { }); async function boot(): Promise { - // [#10380] Installed BEFORE the driver exists, because knex's logger is + // [commit dd8172ee2] Installed BEFORE the driver exists, because knex's logger is // baked into the client at construction. const noise = newNoiseCapture(); @@ -230,10 +230,10 @@ async function boot(): Promise { useNullAsDefault: true, // See the header: shortens the wait, not the shape. acquireConnectionTimeout: ACQUIRE_MS, - // [#10380] Channel 1 of 3 — knex's own `Acquire connection error`. + // [commit dd8172ee2] Channel 1 of 3 — knex's own `Acquire connection error`. log: { warn: noise.knexWarn }, }); - // [#10380] Channel 2 of 3 — the driver's read-exit envelope. Assignment + // [commit dd8172ee2] Channel 2 of 3 — the driver's read-exit envelope. Assignment // rather than a constructor option because `logger` is a protected field // with a `console` default; this is the idiom the field's own doc comment // names ("Tests inject a spy") and that ~20 sibling driver suites use. @@ -252,7 +252,7 @@ async function boot(): Promise { }); const engine = new ObjectQL(); - // [#10380] Channel 3 of 3 — the engine frame above the driver's exit. A + // [commit dd8172ee2] Channel 3 of 3 — the engine frame above the driver's exit. A // Proxy on ONE method, the idiom `engine-readonly-when-parent.test.ts` // established: every other logger method resolves to the engine's own. // [#17212] That method is `warn` — the level the engine reports this frame at. @@ -362,7 +362,7 @@ describe('#7842 metadata list under an open transaction: ambient vs bare (real O // the acquire bound the bare case exhausts. expect(elapsed).toBeLessThan(STALL_CEILING_MS); - // ── [#10380] The capture's own anti-vacuity guard, on the side that is + // ── [commit dd8172ee2] The capture's own anti-vacuity guard, on the side that is // expected to be SILENT. The ambient path must produce none of the three // features — so if it ever started stalling, the sinks installed for the // bare case would swallow the evidence and this case would still pass on @@ -422,7 +422,7 @@ describe('#7842 metadata list under an open transaction: ambient vs bare (real O expect(bare.length).toBeGreaterThan(0); expect(bare.every((r) => !r.hasTx)).toBe(true); - // ── [#10380] The capture is a PIN, not a mute. These three lines used + // ── [commit dd8172ee2] The capture is a PIN, not a mute. These three lines used // to reach the shared `Test Core` log out of a PASSING test and were // read there as a real failure; they are withheld now, and asserted // here instead. If the stall stops happening, the log goes quiet AND diff --git a/packages/runtime/src/notification-schema-conformance.integration.test.ts b/packages/runtime/src/notification-schema-conformance.integration.test.ts index e3d9c065a65..4e8bcb57ceb 100644 --- a/packages/runtime/src/notification-schema-conformance.integration.test.ts +++ b/packages/runtime/src/notification-schema-conformance.integration.test.ts @@ -65,7 +65,7 @@ const declaredMarkReadKeys = () => new Set(Object.keys((MarkNotificationsReadRes const declaredMarkAllReadKeys = () => new Set(Object.keys((MarkAllNotificationsReadResponseSchema as any).shape)); // ═══════════════════════════════════════════════════════════════════════════ -// [#10380 → #10629 → #13325] The authz resolver's expected read failures: +// [commits dd8172ee2 → 13a6cb4ad → 2e0b7b18f] The authz resolver's expected read failures: // WITHHELD from the shared log, and ASSERTED instead // ═══════════════════════════════════════════════════════════════════════════ // @@ -75,7 +75,7 @@ const declaredMarkAllReadKeys = () => new Set(Object.keys((MarkAllNotificationsR // one by design — the resolver is fail-closed and must always resolve — but on // the way out the driver and the engine each log it. // -// ⚠️ [#13273] WHICH ENGINE CHANNEL — and why this file stopped rolling its own +// ⚠️ [commit 3a86a65e7] WHICH ENGINE CHANNEL — and why this file stopped rolling its own // capture. `ObjectQL.reportFindFailure` now picks the level from the CAUSE: a // read whose table was never provisioned — i.e. every read this block is // declared over — is logged at `debug`, carrying a @@ -88,11 +88,11 @@ const declaredMarkAllReadKeys = () => new Set(Object.keys((MarkAllNotificationsR // which satisfied that arm's own predicate. Dead suppression that read as live // protection, and the file stayed green throughout because everything it // asserted was fed by the DRIVER channel. It now uses the shared -// `captureExpectedReadRefusals` (#10629), which wraps BOTH channels, so which +// `captureExpectedReadRefusals` (commit 13a6cb4ad), which wraps BOTH channels, so which // channel a frame arrives on is the ENGINE's classification and never this // fixture's problem. // -// Counts RE-MEASURED on this tree (#13325), not transcribed: +// Counts RE-MEASURED on this tree (commit 2e0b7b18f), not transcribed: // // pnpm --filter @objectstack/runtime exec vitest run \ // src/notification-schema-conformance.integration.test.ts @@ -108,7 +108,7 @@ const declaredMarkAllReadKeys = () => new Set(Object.keys((MarkAllNotificationsR // // Turbo interleaves package logs without attribution, so in the `Test Core` // shard log those are indistinguishable from a real failure — they were lifted -// verbatim into a p1 flake signature (#10293) and cost a full dispatch cycle +// verbatim into a p1 flake signature (a vitest teardown race, fixed by commit 92a69d813) and cost a full dispatch cycle // aimed at the wrong mechanism. // // ⛔ Not a mute. A capture that only silences would make this file blind: if @@ -278,7 +278,7 @@ describe('[#5792] the notification wire bodies conform to the schemas the catalo let baseUrl: string; let messaging: MessagingService; /** - * [#10629] The expected-noise capture, asserted in `afterAll`. The SHARED + * [commit 13a6cb4ad] The expected-noise capture, asserted in `afterAll`. The SHARED * one — see the block above for what the per-fixture copy this replaced * could no longer do. */ @@ -286,7 +286,7 @@ describe('[#5792] the notification wire bodies conform to the schemas the catalo beforeAll(async () => { kernel = new ObjectKernel({ logger: { level: 'silent' } }); - // [#10380] The driver is named rather than inlined so its logger can be + // [commit dd8172ee2] The driver is named rather than inlined so its logger can be // scoped before it ever runs a statement. const driver = new SqliteWasmDriver({ filename: ':memory:' }); noise.captureDriver(driver); @@ -299,7 +299,7 @@ describe('[#5792] the notification wire bodies conform to the schemas the catalo await kernel.use(createDispatcherPlugin({ prefix: '/api/v1', securityHeaders: false, requireAuth: false })); await kernel.bootstrap(); - // [#10380] The engine only exists once the kernel has bootstrapped; the + // [commit dd8172ee2] The engine only exists once the kernel has bootstrapped; the // reads this scopes all happen later, per request. noise.captureEngine(kernel.getService('objectql')); @@ -326,7 +326,7 @@ describe('[#5792] the notification wire bodies conform to the schemas the catalo }, 60_000); afterAll(async () => { - // ── [#18070] The #10380 / #13325 pin, turned around. It used to assert + // ── [#18070] The commits dd8172ee2 / 2e0b7b18f pin, turned around. It used to assert // that the five resolver reads were still being REFUSED here — the symptom // pinned, not the defect closed. They are provisioned now, so the // assertion is that they SUCCEED, and `[]` means an empty table rather diff --git a/packages/runtime/src/notifications.hono.integration.test.ts b/packages/runtime/src/notifications.hono.integration.test.ts index 9aff633a611..574e1a1629a 100644 --- a/packages/runtime/src/notifications.hono.integration.test.ts +++ b/packages/runtime/src/notifications.hono.integration.test.ts @@ -200,7 +200,7 @@ describe('in-app notifications over a real hono server (integration, #3362)', () let kernel: ObjectKernel; let baseUrl: string; let messaging: MessagingService; - /** [#10629] The expected-noise capture, asserted by every authed test below. */ + /** [commit 13a6cb4ad] The expected-noise capture, asserted by every authed test below. */ const noise = captureExpectedReadRefusals([...ABSENT_AUTHZ_TABLES]); beforeAll(async () => { @@ -210,7 +210,7 @@ describe('in-app notifications over a real hono server (integration, #3362)', () // MessagingServicePlugin registers the `notification` service the dispatcher // resolves and owns the inbox tables. Inline delivery (reliableDelivery:false) // writes the inbox row synchronously so `emit()` is observable immediately. - // [#10629] The driver is named rather than inlined so its logger can be + // [commit 13a6cb4ad] The driver is named rather than inlined so its logger can be // scoped before it ever runs a statement. const driver = new SqliteWasmDriver({ filename: ':memory:' }); noise.captureDriver(driver); @@ -230,7 +230,7 @@ describe('in-app notifications over a real hono server (integration, #3362)', () await kernel.bootstrap(); - // [#10629] The engine only exists once the kernel has bootstrapped; the + // [commit 13a6cb4ad] The engine only exists once the kernel has bootstrapped; the // reads this scopes all happen later, per request. noise.captureEngine(kernel.getService('objectql')); @@ -339,7 +339,7 @@ describe('in-app notifications over a real hono server (integration, #3362)', () expect(served.status).toBe(200); expect((await served.json() as { success: boolean }).success).toBe(true); - // ── [#18070] The #10629 pin, turned around: this used to assert that the + // ── [#18070] The commit 13a6cb4ad pin, turned around: this used to assert that the // five resolver reads were still being REFUSED here. They are provisioned // now, so the assertion is that they SUCCEED. Kept per authed test rather // than moved to `afterAll` for the reason the old one was — two tests in @@ -392,7 +392,7 @@ describe('in-app notifications over a real hono server (integration, #3362)', () expect(receipts.length).toBe(2); expect(receipts.every((r: any) => r.state === 'read')).toBe(true); - // ── [#18070] The #10629 pin, turned around: this used to assert that the + // ── [#18070] The commit 13a6cb4ad pin, turned around: this used to assert that the // five resolver reads were still being REFUSED here. They are provisioned // now, so the assertion is that they SUCCEED. Kept per authed test rather // than moved to `afterAll` for the reason the old one was — two tests in @@ -450,7 +450,7 @@ describe('in-app notifications over a real hono server (integration, #3362)', () expect(receipts.length).toBe(TOTAL); expect(receipts.every((r: any) => r.state === 'read')).toBe(true); - // ── [#18070] The #10629 pin, turned around: this used to assert that the + // ── [#18070] The commit 13a6cb4ad pin, turned around: this used to assert that the // five resolver reads were still being REFUSED here. They are provisioned // now, so the assertion is that they SUCCEED. Kept per authed test rather // than moved to `afterAll` for the reason the old one was — two tests in diff --git a/packages/runtime/src/package-list-commits-org-scope.integration.test.ts b/packages/runtime/src/package-list-commits-org-scope.integration.test.ts index becfc655c07..0bd185005b9 100644 --- a/packages/runtime/src/package-list-commits-org-scope.integration.test.ts +++ b/packages/runtime/src/package-list-commits-org-scope.integration.test.ts @@ -97,7 +97,7 @@ const ACTIVE_ORG = 'org_active'; const OTHER_ORG = 'org_other'; /** - * [#10629] Every publish this fixture makes runs the metadata-protocol build + * [commit 13a6cb4ad] Every publish this fixture makes runs the metadata-protocol build * probes (`metadata-protocol/src/build-probes.ts`), and the views it publishes * are bound to the placeholder object `anything` — the #7741 inline arm * requires an object binding pair, and nothing here creates that table. The @@ -110,12 +110,12 @@ const UNBOUND_PROBE_OBJECT = 'anything'; let cleanup: Array<() => void> = []; -/** [#10629] The expected-noise capture belonging to the latest `boot()`. */ +/** [commit 13a6cb4ad] The expected-noise capture belonging to the latest `boot()`. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(() => { for (const c of cleanup) c(); cleanup = []; - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave an engine running. Every test in this file publishes at // least once, so the probe fires for each of them: this holds for a single // `-t` run as well as for the whole file. @@ -141,7 +141,7 @@ async function boot() { SysMetadataAuditObject, SysMetadataCommitObject, ] as any[]; - // [#10629] Installed before the driver runs a statement and before the + // [commit 13a6cb4ad] Installed before the driver runs a statement and before the // engine issues a read — the two sinks the expected refusal travels out on. noise = captureExpectedReadRefusals([UNBOUND_PROBE_OBJECT]); noise.captureDriver(driver); diff --git a/packages/runtime/src/package-revert-commit-attribution-org-scope.integration.test.ts b/packages/runtime/src/package-revert-commit-attribution-org-scope.integration.test.ts index 54073e8b359..629e26de5fe 100644 --- a/packages/runtime/src/package-revert-commit-attribution-org-scope.integration.test.ts +++ b/packages/runtime/src/package-revert-commit-attribution-org-scope.integration.test.ts @@ -88,7 +88,7 @@ const ACTIVE_ORG = 'org_active'; const OTHER_ORG = 'org_other'; /** - * [#10629] Every publish this fixture makes runs the metadata-protocol build + * [commit 13a6cb4ad] Every publish this fixture makes runs the metadata-protocol build * probes (`metadata-protocol/src/build-probes.ts`), and the views it publishes * are bound to the placeholder object `anything` — the #7741 inline arm * requires an object binding pair, and nothing here creates that table. The @@ -101,12 +101,12 @@ const UNBOUND_PROBE_OBJECT = 'anything'; let cleanup: Array<() => void> = []; -/** [#10629] The expected-noise capture belonging to the latest `boot()`. */ +/** [commit 13a6cb4ad] The expected-noise capture belonging to the latest `boot()`. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(() => { for (const c of cleanup) c(); cleanup = []; - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave an engine running. Every test in this file publishes at // least once, so the probe fires for each of them: this holds for a single // `-t` run as well as for the whole file. @@ -130,7 +130,7 @@ async function boot() { SysMetadataAuditObject, SysMetadataCommitObject, ] as any[]; - // [#10629] Installed before the driver runs a statement and before the + // [commit 13a6cb4ad] Installed before the driver runs a statement and before the // engine issues a read — the two sinks the expected refusal travels out on. noise = captureExpectedReadRefusals([UNBOUND_PROBE_OBJECT]); noise.captureDriver(driver); diff --git a/packages/runtime/src/package-revert-commit-org-scope.integration.test.ts b/packages/runtime/src/package-revert-commit-org-scope.integration.test.ts index c0d98723294..963874e8f6c 100644 --- a/packages/runtime/src/package-revert-commit-org-scope.integration.test.ts +++ b/packages/runtime/src/package-revert-commit-org-scope.integration.test.ts @@ -115,7 +115,7 @@ const ACTIVE_ORG = 'org_active'; const OTHER_ORG = 'org_other'; /** - * [#10629] Every publish this fixture makes runs the metadata-protocol build + * [commit 13a6cb4ad] Every publish this fixture makes runs the metadata-protocol build * probes (`metadata-protocol/src/build-probes.ts`), and the views it publishes * are bound to the placeholder object `anything` — the #7741 inline arm * requires an object binding pair, and nothing here creates that table. The @@ -128,12 +128,12 @@ const UNBOUND_PROBE_OBJECT = 'anything'; let cleanup: Array<() => void> = []; -/** [#10629] The expected-noise capture belonging to the latest `boot()`. */ +/** [commit 13a6cb4ad] The expected-noise capture belonging to the latest `boot()`. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(() => { for (const c of cleanup) c(); cleanup = []; - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave an engine running. Every test in this file publishes at // least once, so the probe fires for each of them: this holds for a single // `-t` run as well as for the whole file. @@ -160,7 +160,7 @@ async function boot() { SysMetadataAuditObject, SysMetadataCommitObject, ] as any[]; - // [#10629] Installed before the driver runs a statement and before the + // [commit 13a6cb4ad] Installed before the driver runs a statement and before the // engine issues a read — the two sinks the expected refusal travels out on. noise = captureExpectedReadRefusals([UNBOUND_PROBE_OBJECT]); noise.captureDriver(driver); diff --git a/packages/runtime/src/package-service.null-seam.test.ts b/packages/runtime/src/package-service.null-seam.test.ts index 5bac666f0bf..01e8b6f956b 100644 --- a/packages/runtime/src/package-service.null-seam.test.ts +++ b/packages/runtime/src/package-service.null-seam.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #10965 — the `service-package` seam guard, on a REAL booted driver. + * Commit ab47f6974 — the `service-package` seam guard, on a REAL booted driver. * * The card established the conflation by reading and named the boot path as * unverified: *"Whether the DevPlugin zero-install stack (a real @@ -37,7 +37,7 @@ * ⚠️ **What the double does NOT model.** It is not evidence about * `@objectstack/driver-memory`'s behaviour. That the real driver logs * `Raw execution not supported in InMemory driver` and returns `null` was - * measured on a real boot while triaging #10965, and it stays pinned on a real + * measured on a real boot in the triage behind commit ab47f6974, and it stays pinned on a real * booted driver by `packages/cli/src/commands/migrate/duplicates.null-seam.test.ts` * (#10677), which reaches it through the datasource factory rather than by * importing it. Nothing about that fact is re-asserted here, and this file would diff --git a/packages/runtime/src/preserve-audit-real-driver.integration.test.ts b/packages/runtime/src/preserve-audit-real-driver.integration.test.ts index 90097cb92c4..8cb010df0a2 100644 --- a/packages/runtime/src/preserve-audit-real-driver.integration.test.ts +++ b/packages/runtime/src/preserve-audit-real-driver.integration.test.ts @@ -47,7 +47,7 @@ const TICKET = { }; /** - * [#10629] This fixture provisions `ticket` and nothing else, so the engine's + * [commit 13a6cb4ad] This fixture provisions `ticket` and nothing else, so the engine's * own single-tenant probe (`ObjectQL.probeInstallOrganizations`, memoised once * per engine) reads a `sys_organization` that was never created. The probe is * fail-soft by construction — it catches `isMissingTableError` and only that — @@ -59,14 +59,14 @@ const ABSENT_TENANCY_TABLE = 'sys_organization'; describe('preserveAudit end-to-end on a REAL SqlDriver (#3493 / #3549)', () => { let engine: ObjectQL | null = null; let dir: string | null = null; - /** [#10629] The expected-noise capture belonging to the latest boot. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest boot. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(async () => { try { await engine?.destroy(); } catch { /* noop */ } engine = null; if (dir) { rmSync(dir, { recursive: true, force: true }); dir = null; } - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave the engine running. Every test in this file // boots and writes, so the probe fires for each of them: this holds for a // single `-t` run as well as for the whole file. @@ -77,7 +77,7 @@ describe('preserveAudit end-to-end on a REAL SqlDriver (#3493 / #3549)', () => { async function boot() { dir = mkdtempSync(join(tmpdir(), 'os-preserveaudit-')); const driver = new SqlDriver({ client: 'better-sqlite3', connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true }); - // [#10629] Installed before the driver runs a statement and before the + // [commit 13a6cb4ad] Installed before the driver runs a statement and before the // engine issues a read — the two sinks the expected refusal travels out on. noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); noise.captureDriver(driver); diff --git a/packages/runtime/src/route-ledger.conformance.test.ts b/packages/runtime/src/route-ledger.conformance.test.ts index 6a9e3c6ecfb..6acbc610deb 100644 --- a/packages/runtime/src/route-ledger.conformance.test.ts +++ b/packages/runtime/src/route-ledger.conformance.test.ts @@ -38,7 +38,7 @@ * tracked in #17041; this paragraph states today's coverage, not a plan for * tomorrow's. Deliberately no row/domain counts here: a hand-typed number in * this prose is exactly the unguarded-count defect this lane spent the same - * day eliminating elsewhere (#16919, #17039), and nothing in this file would + * day eliminating elsewhere (commits 2cd4c548e, edf59e359), and nothing in this file would * ever notice it going stale. */ diff --git a/packages/runtime/src/route-ledger.ts b/packages/runtime/src/route-ledger.ts index e1674d9f6fa..0229afa9be0 100644 --- a/packages/runtime/src/route-ledger.ts +++ b/packages/runtime/src/route-ledger.ts @@ -285,7 +285,7 @@ export const NON_DISPATCH_MOUNT_PREFIXES = [ * digits and nothing else. It exists because this list is CENSUS-SHAPED: its * value is its completeness, and a WRONG row fails a gate that reads rows while * a MISSING row fails only a gate that knows how many rows there should be. - * #16758 filed the second kind, after an index-slice edit meant to add two rows + * Commit 6e9bee640 gated the second kind, after an index-slice edit meant to add two rows * removed 105 lines — route rows plus the whole `/actions` section — and exited * 0, caught only because an unrelated gate happened to redden. * @@ -448,7 +448,7 @@ export const ROUTE_LEDGER: readonly RouteLedgerEntry[] = [ // route, no CLI command, and until the contract half landed (PR #16563, card #16495) // not on `IAutomationService` either. #15981 is the correction this gate is built on // at birth: the platform-operator test is the ADR-0095 rung, never the `positions[]` - // name. #13909 is the parent card the repair verb belongs to; #10243 / #12156 are the + // name. #13909 is the parent card the repair verb belongs to; commit 266436a7f / #12156 are the // toggle and clone arms whose `trigger` exclusion this predicate copies; #5519 is the // anonymous floor that answers first. { route: 'POST /automation/:name/runs/:runId/cancel', domain: '/automation', disposition: 'server-only', diff --git a/packages/runtime/src/sandbox/body-runner.test.ts b/packages/runtime/src/sandbox/body-runner.test.ts index c68900f89fb..ec041d7c58e 100644 --- a/packages/runtime/src/sandbox/body-runner.test.ts +++ b/packages/runtime/src/sandbox/body-runner.test.ts @@ -212,7 +212,7 @@ describe('hookBodyRunnerFactory', () => { }); }); - // [#6316] `ctx.user` is seeded from `engineCtx.user` and from nothing else. + // [commit 448ac9565] `ctx.user` is seeded from `engineCtx.user` and from nothing else. // `buildSandboxContext` used to spell `engineCtx?.user ?? engineCtx?.session?.user`; // the second limb was unreachable, because `HookContext['session']` declares // no `user` key and its sole producer — `buildSession()` in objectql, called @@ -524,7 +524,7 @@ describe('actionBodyRunnerFactory', () => { }); }); - // [#6316] The action face of the same removal. `ActionSession` declares + // [commit 448ac9565] The action face of the same removal. `ActionSession` declares // `userId` / `organizationId` / `positions` / `roles` and no `user`, and its // sole producer `buildActionSession()` writes exactly those four — for both // action ctx assembly sites (MCP `run_action` in `action-execution.ts`, REST diff --git a/packages/runtime/src/sandbox/body-runner.ts b/packages/runtime/src/sandbox/body-runner.ts index f80fbb0ec97..49cfdfb8465 100644 --- a/packages/runtime/src/sandbox/body-runner.ts +++ b/packages/runtime/src/sandbox/body-runner.ts @@ -84,7 +84,7 @@ interface FactoryOptions { * body's own `ctx.log.info('task completed: …')` absent. * * That is the third limb of this shape removed from this file, not the first: - * `doc` / `previousDoc` (#5906) and `session.user` (#6316) were also keys no + * `doc` / `previousDoc` (#5906) and `session.user` (commit 448ac9565) were also keys no * producer ever wrote, deleted rather than left as a second de-facto contract * (Prime Directive #12). The remedy is the same — read the source that exists. * `opts.logger` is the engine's own `Logger`, handed to the factory by all four @@ -505,7 +505,7 @@ function vmVisibleEntryKeys(entryInput: unknown): string[] { } /** - * [#14760] The entry value as the VM could actually have seen it, or `ok: + * [commit ee32e1cb8] The entry value as the VM could actually have seen it, or `ok: * false` for a host value the round-trip cannot evaluate at all. * * Leg 2 of {@link carriedInputKeys} compares an entry snapshot against the VM's @@ -527,7 +527,7 @@ function vmVisibleEntryKeys(entryInput: unknown): string[] { * readonly. Normalising the comparison closes both, because an untouched key is * no longer carried at all and the host simply keeps its own value. * - * ⛔ The fail-open is NOT reversed. #14758 chose "anything we cannot prove + * ⛔ The fail-open is NOT reversed. Commit 84199cb87 chose "anything we cannot prove * equal is reported as changed and therefore CARRIED" deliberately, and a value * that throws here — a cycle, a bigint, a `toJSON` returning `undefined` — still * takes exactly that path. What changes is that the fail-open stops firing on @@ -538,14 +538,14 @@ function jsonSeenByVm(value: unknown): { ok: true; value: unknown } | { ok: fals try { return { ok: true, value: JSON.parse(JSON.stringify(value)) as unknown }; } catch { - /* unrepresentable (cycle, bigint) — #14758's fail-open, for this key only */ + /* unrepresentable (cycle, bigint) — commit 84199cb87's fail-open, for this key only */ return { ok: false }; } } /** - * [#14758] Which keys of the exit dump the write-back should re-assert, or - * `undefined` to assert all of them (the pre-#14758 behaviour). + * [commit 84199cb87] Which keys of the exit dump the write-back should re-assert, or + * `undefined` to assert all of them (the behaviour before commit 84199cb87). * * Two sources, unioned, and neither is sufficient alone: * @@ -565,7 +565,7 @@ function jsonSeenByVm(value: unknown): { ok: true; value: unknown } | { ok: fals * whose ENTRY value is an object because a primitive cannot be mutated in * place — every change to one is an assignment (1) already saw — and * confining it there is what keeps this leg from re-widening into the value - * diff #14099's ruling refused. [#14760] Normalising the entry side is what + * diff #14099's ruling refused. [commit ee32e1cb8] Normalising the entry side is what * makes the comparison answer "did the body write through this?" instead of * "is this host value already JSON?"; without it every `Date`-valued key * answered the second question, in the wrong direction, forever. @@ -603,7 +603,7 @@ function carriedInputKeys( * preserves insertion order for string keys but reorders integer-like ones, and * a reorder is not a write. * - * [#14760] BOTH sides are JSON values by the time they reach here: `b` is the + * [commit ee32e1cb8] BOTH sides are JSON values by the time they reach here: `b` is the * VM's exit dump, and `a` is the entry snapshot already put through * {@link jsonSeenByVm}. So this compares like for like, and it no longer stands * in for the round-trip itself. It used to: an unequal verdict meant either @@ -668,7 +668,7 @@ function sameJsonValue(a: unknown, b: unknown): boolean { * returns it (`delete ctx.input.x; return { x: 1 };`) keeps the explicit patch * — the return value is the later, more deliberate statement of the two. * - * ## [#14758] Why the merge is a KEY SET and no longer the whole dump + * ## [commit 84199cb87] Why the merge is a KEY SET and no longer the whole dump * * `mutatedInput` is the whole post-run `ctx.input`, so `Object.assign(target, * mutated)` re-asserted every key a body could see, touched or not. `target` is @@ -709,7 +709,7 @@ function sameJsonValue(a: unknown, b: unknown): boolean { * itself ever fires, so the recorder cannot list `meta`. The dump is the only * witness for those, and {@link carriedInputKeys} reads it the narrowest way * available: an OBJECT-valued entry key whose dumped value no longer matches - * the entry snapshot — [#14760] as {@link jsonSeenByVm} shows it to the VM — + * the entry snapshot — [commit ee32e1cb8] as {@link jsonSeenByVm} shows it to the VM — * was written through, and is carried. Primitives need no such leg: a * primitive cannot be mutated in place, so every change to one is an * assignment the recorder saw. @@ -732,7 +732,7 @@ function applyMutationsToInput( } const carried = carriedInputKeys(mutated, result.mutatedInputKeys, entryInput); if (carried === undefined) { - // The recorder could not speak — pre-#14758 behaviour, verbatim. + // The recorder could not speak — the behaviour before commit 84199cb87, verbatim. Object.assign(target, mutated); } else { for (const key of carried) { @@ -877,7 +877,7 @@ function buildSandboxContext( // reliably distinguish create (`!ctx.previous`) from update/delete. previous: unwrapProxyToPlain(previousRaw), // `engineCtx.user` is the ONLY source, and the `?? engineCtx?.session?.user` - // limb that used to follow it was removed in #6316 (same family as #5906 + // limb that used to follow it was removed in commit 448ac9565 (same family as #5906 // above, and as #4984): `HookContext['session']` declares no `user` key // (`packages/spec/src/data/hook.zod.ts`) and its sole producer — // ObjectQL's `buildSession()` (`packages/objectql/src/engine.ts`), which @@ -935,7 +935,7 @@ function buildActionSandboxContext( return { input: unwrapProxyToPlain(actionCtx?.params ?? {}), previous: undefined, - // Same removal as the hook face above (#6316), measured on this face's own + // Same removal as the hook face above (commit 448ac9565), measured on this face's own // shapes: `ActionSession` (`packages/spec/src/ui/action-params.zod.ts`) // declares `userId` / `organizationId` / `positions` / `roles` and no // `user`, and its sole producer `buildActionSession()` diff --git a/packages/runtime/src/sandbox/hook-input-writeback-key-set.integration.test.ts b/packages/runtime/src/sandbox/hook-input-writeback-key-set.integration.test.ts index fc8bbdea5c4..8c9caf56bd9 100644 --- a/packages/runtime/src/sandbox/hook-input-writeback-key-set.integration.test.ts +++ b/packages/runtime/src/sandbox/hook-input-writeback-key-set.integration.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14758] The sandbox write-back carries back the keys the BODY wrote — so + * [commit 84199cb87] The sandbox write-back carries back the keys the BODY wrote — so * #14099's per-row divergence refusal is true for shipped hook bodies too, in * either row order. * diff --git a/packages/runtime/src/sandbox/hook-input-writeback-readonly-provenance.integration.test.ts b/packages/runtime/src/sandbox/hook-input-writeback-readonly-provenance.integration.test.ts index f4ba6adf895..6a86924b164 100644 --- a/packages/runtime/src/sandbox/hook-input-writeback-readonly-provenance.integration.test.ts +++ b/packages/runtime/src/sandbox/hook-input-writeback-readonly-provenance.integration.test.ts @@ -1,12 +1,12 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14760] A caller-supplied `readonly` field that no hook body ever names must + * [commit ee32e1cb8] A caller-supplied `readonly` field that no hook body ever names must * NOT survive `stripReadonlyFields` just because a sandboxed body ran. * * ## What was measured broken * - * #14758 narrowed the sandbox write-back to the keys the body wrote. Its leg 2 + * Commit 84199cb87 narrowed the sandbox write-back to the keys the body wrote. Its leg 2 * — "did the body write THROUGH this object-valued key?" — compared the HOST * entry snapshot against the VM's exit dump. The dump is JSON; the snapshot was * not. So a host `Date` was compared against its own ISO projection, could not @@ -376,8 +376,8 @@ describe('#14760 — an untouched readonly key is not laundered by the sandbox w // // ⚠️ That fault is a REFUSAL, not a silent no-op: a `body` hook's default // `onError` is `abort`, so the caller's whole write is rejected and the row - // is untouched. Loud beats silent — and #17219 supplied the second half the - // refusal was missing. Measured here before that card, through this very + // is untouched. Loud beats silent — and commit 706ad0fcc supplied the second half the + // refusal was missing. Measured here before that commit, through this very // harness, at both doors: // // direct SandboxError: hook 'guard_task_body' threw: @@ -391,7 +391,7 @@ describe('#14760 — an untouched readonly key is not laundered by the sandbox w // that can tell "the platform took this away" from "nobody sent it". // // ⛔ Still no `ctx.submitted` on the sandbox face: that face is assembled - // key by key and the shape was measured and refused in PR #17195. The + // key by key and the shape was measured and refused in commit d2c1d1980. The // supported source for a derived column is `ctx.previous`, which is what // the message now says. const { engine, driver } = await boot(WRITES_THROUGH_SOURCE); @@ -445,7 +445,7 @@ describe('#14760 — an untouched readonly key is not laundered by the sandbox w * - the SECOND harm — a carried key is re-asserted FROM THE DUMP, so an * untouched host `Date` used to be replaced by its ISO string and an object * used to lose its `undefined` member even where nothing was readonly; - * - the FAIL-OPEN, which #14758 chose deliberately and this card does not + * - the FAIL-OPEN, which commit 84199cb87 chose deliberately and this card does not * reverse. `safeJsonStringify` lets a cyclic or bigint-bearing value cross * into the VM in degraded form, so such a key IS in the exit dump and DOES * reach the comparison — where a plain round-trip of the host value throws. @@ -490,7 +490,7 @@ describe('#14760 — write-back fidelity and the preserved fail-open', () => { const fn = bind("ctx.input.touched_by = 'hook';"); // `safeJsonStringify` drops the back-edge on the way in, so the VM sees // `{ tag: 'cyclic' }` and dumps it — but a plain round-trip of the HOST - // value throws, which is exactly the case #14758's fail-open exists for. + // value throws, which is exactly the case commit 84199cb87's fail-open exists for. const cyclic: Record = { tag: 'cyclic' }; cyclic.self = cyclic; const engineCtx = { input: { status: 'done', meta: cyclic } } as any; @@ -499,7 +499,7 @@ describe('#14760 — write-back fidelity and the preserved fail-open', () => { expect(engineCtx.input.touched_by).toBe('hook'); // Carried: the host key now holds the dump's degraded copy, byte for byte - // the pre-#14760 behaviour for a value JSON cannot represent. + // the behaviour before commit ee32e1cb8 for a value JSON cannot represent. expect(Object.is(engineCtx.input.meta, cyclic)).toBe(false); expect(engineCtx.input.meta).toEqual({ tag: 'cyclic' }); }); diff --git a/packages/runtime/src/sandbox/nested-hook-refusal-is-a-rejection.test.ts b/packages/runtime/src/sandbox/nested-hook-refusal-is-a-rejection.test.ts index 976fac860e0..207f5f8cef2 100644 --- a/packages/runtime/src/sandbox/nested-hook-refusal-is-a-rejection.test.ts +++ b/packages/runtime/src/sandbox/nested-hook-refusal-is-a-rejection.test.ts @@ -172,7 +172,7 @@ describe('[#17265] a nested sandboxed hook refusal keeps its business message', // The fault branch dropped the whole `__errorInfo` payload, not just // `innerMessage`, so a hook declaring `{ status: 409, code: // 'RECORD_LOCKED' }` lost both and was flattened to 500. `/data` - // answers `declared ?? 400` for this producer (#9967); the action door + // answers `declared ?? 400` for this producer (commit 8f266f1cd); the action door // honours a declared status at its own first arm (#7867), so once the // classification is right the two agree without a second rule. const locked = () => { diff --git a/packages/runtime/src/sandbox/nested-write-real-sqlite.integration.test.ts b/packages/runtime/src/sandbox/nested-write-real-sqlite.integration.test.ts index 52f10dbe1ed..eb53d7f6b11 100644 --- a/packages/runtime/src/sandbox/nested-write-real-sqlite.integration.test.ts +++ b/packages/runtime/src/sandbox/nested-write-real-sqlite.integration.test.ts @@ -73,7 +73,7 @@ const ROLLUP_HOOK = { }; /** - * [#10629] This fixture provisions `expense_report` / `expense_line` and + * [commit 13a6cb4ad] This fixture provisions `expense_report` / `expense_line` and * nothing else, so the engine's own single-tenant probe * (`ObjectQL.probeInstallOrganizations`, memoised once per engine) reads a * `sys_organization` that was never created. That read is fail-soft by @@ -86,7 +86,7 @@ const ABSENT_TENANCY_TABLE = 'sys_organization'; describe('#1867 nested cross-object write — REAL SqlDriver (better-sqlite3, on-disk)', () => { let engine: ObjectQL | null = null; let dir: string | null = null; - /** [#10629] The expected-noise capture belonging to the latest {@link boot}. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest {@link boot}. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(async () => { @@ -98,7 +98,7 @@ describe('#1867 nested cross-object write — REAL SqlDriver (better-sqlite3, on async function boot() { dir = mkdtempSync(join(tmpdir(), 'os-nested-1867-')); const driver = new SqlDriver({ client: 'better-sqlite3', connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true }); - // [#10629] Installed before the driver runs a statement and before the + // [commit 13a6cb4ad] Installed before the driver runs a statement and before the // engine issues a read — the two sinks the expected refusal travels out on. noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); noise.captureDriver(driver); @@ -131,7 +131,7 @@ describe('#1867 nested cross-object write — REAL SqlDriver (better-sqlite3, on parent = (await e.find('expense_report', { where: { id: report.id } }))[0]; expect(parent.total_amount).toBe(175); - // ── [#10629] The capture is a PIN, not a mute. These two lines used to + // ── [commit 13a6cb4ad] The capture is a PIN, not a mute. These two lines used to // reach the shared `Test Core` log out of a PASSING test and were read // there as a real failure; they are withheld now and asserted here. If the // probe stops running, or `sys_organization` starts resolving, the log goes diff --git a/packages/runtime/src/sandbox/perrow-dispatch-signal.integration.test.ts b/packages/runtime/src/sandbox/perrow-dispatch-signal.integration.test.ts index 02a8bba425c..140ecf1f6c3 100644 --- a/packages/runtime/src/sandbox/perrow-dispatch-signal.integration.test.ts +++ b/packages/runtime/src/sandbox/perrow-dispatch-signal.integration.test.ts @@ -213,7 +213,7 @@ describe('#11552 — a shipped body observes the per-row dispatch signal and the // predicate write from inside a body. expect(single[0].optionsMulti).not.toBe(true); - // [#10629] Withheld-noise pin, same as the sibling real-SQLite harness. + // [commit 13a6cb4ad] Withheld-noise pin, same as the sibling real-SQLite harness. expect(noise?.silentChannels() ?? ['no capture was installed']).toEqual([]); }, 30000); }); diff --git a/packages/runtime/src/sandbox/quickjs-runner.ts b/packages/runtime/src/sandbox/quickjs-runner.ts index 1bee8ba0bed..aaefa344b37 100644 --- a/packages/runtime/src/sandbox/quickjs-runner.ts +++ b/packages/runtime/src/sandbox/quickjs-runner.ts @@ -420,7 +420,7 @@ export class QuickJSScriptRunner implements ScriptRunner { // Capture mutated ctx.input so the host can write through. const mutatedInput = readCtxInputJson(vm); // …and, on the hook path, WHICH of those keys the body actually - // wrote (#14758), so the write-back carries the body's own key set + // wrote (commit 84199cb87), so the write-back carries the body's own key set // rather than re-asserting the whole dump onto the engine's payload. const mutatedInputKeys = args.origin.kind === 'hook' ? readInputWritesJson(vm) : undefined; @@ -878,7 +878,7 @@ export class QuickJSScriptRunner implements ScriptRunner { } sugar.value.dispose(); - // [#14758] The hook path's INPUT write-recorder — the instrument that lets + // [commit 84199cb87] The hook path's INPUT write-recorder — the instrument that lets // `applyMutationsToInput` carry back the keys the body wrote instead of // every key it could see. // @@ -1532,7 +1532,7 @@ function readRecordWritesJson(vm: QuickJSContext): string[] | undefined { } /** - * [#14758] After the script has settled, dump the keys the write-recorder proxy + * [commit 84199cb87] After the script has settled, dump the keys the write-recorder proxy * saw on `ctx.input` — the keys the BODY assigned, defined or deleted, as * opposed to every key `readCtxInputJson` can see. * diff --git a/packages/runtime/src/sandbox/referential-field-clear-signal.integration.test.ts b/packages/runtime/src/sandbox/referential-field-clear-signal.integration.test.ts index 7df2393cef7..9f74662ad77 100644 --- a/packages/runtime/src/sandbox/referential-field-clear-signal.integration.test.ts +++ b/packages/runtime/src/sandbox/referential-field-clear-signal.integration.test.ts @@ -169,7 +169,7 @@ describe('#13644 — a shipped body observes ctx.referentialFieldClear across th const cleared = (await engine.findOne('probe_rfc_note', { where: { id: n.id } })) as any; expect(cleared.account).toBeNull(); - // [#10629] Withheld-noise pin, same as the sibling harnesses. + // [commit 13a6cb4ad] Withheld-noise pin, same as the sibling harnesses. expect(noise?.silentChannels() ?? ['no capture was installed']).toEqual([]); }, 30000); }); diff --git a/packages/runtime/src/sandbox/script-runner.ts b/packages/runtime/src/sandbox/script-runner.ts index 2b834a43246..66e258cc7c2 100644 --- a/packages/runtime/src/sandbox/script-runner.ts +++ b/packages/runtime/src/sandbox/script-runner.ts @@ -96,7 +96,7 @@ export type ScriptSession = ActionSession | HookContext['session']; * `ActionSession`) and neither producer writes one (`buildSession()` in * objectql, `buildActionSession()` in `../action-execution.ts`) — and left it * alone, because typing a seam does not get to re-decide a runtime expression. - * #6316 re-ran that sweep across every producer on both faces, confirmed it, + * Commit 448ac9565 re-ran that sweep across every producer on both faces, confirmed it, * and deleted both limbs (the #4984 dead-limb family). So the union's arms are * the two REAL producer shapes and nothing else; if a session ever should * carry a user, DECLARE it on the session contract rather than restoring a @@ -418,7 +418,7 @@ export interface ScriptResult { */ mutatedInput?: Record; /** - * [#14758] Hook path only: the keys of {@link mutatedInput} the BODY actually + * [commit 84199cb87] Hook path only: the keys of {@link mutatedInput} the BODY actually * assigned, defined or deleted — as opposed to every key the dump can see. * * `mutatedInput` alone cannot answer that question: it is the whole @@ -437,7 +437,7 @@ export interface ScriptResult { * nothing. * - `undefined` — this runner cannot say (no recorder installed, the runner * predates this field, the read failed). Carry back the whole dump, which - * is the pre-#14758 behaviour: narrowing on a key set that cannot speak + * is the behaviour before commit 84199cb87: narrowing on a key set that cannot speak * would silently drop a write the body really made. * * Keys reachable only THROUGH a value on `ctx.input` — `ctx.input.meta.x = 1` diff --git a/packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts b/packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts index f6f803b94b6..6af053153b5 100644 --- a/packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts +++ b/packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts @@ -234,7 +234,7 @@ const UPDATE_TYPO_HOOK = { }; /** - * [#10629] The SQL half of this fixture provisions `deal` and nothing else, so + * [commit 13a6cb4ad] The SQL half of this fixture provisions `deal` and nothing else, so * the engine's single-tenant probe (`ObjectQL.probeInstallOrganizations`, * memoised once per engine) reads a `sys_organization` that was never created. * The probe is fail-soft by construction — it catches `isMissingTableError` and @@ -249,14 +249,14 @@ const ABSENT_TENANCY_TABLE = 'sys_organization'; describe('#4271 / #13657 an undeclared field written by an L2 body — one answer on both families', () => { let engine: ObjectQL | null = null; let dir: string | null = null; - /** [#10629] The expected-noise capture belonging to the latest boot. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest boot. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(async () => { try { await engine?.destroy(); } catch { /* noop */ } engine = null; if (dir) { rmSync(dir, { recursive: true, force: true }); dir = null; } - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave the engine running. Unconditional on purpose: // a memory boot declares an EMPTY expectation, so this still fails loudly if // a boot ever forgets to install a capture at all. @@ -282,7 +282,7 @@ describe('#4271 / #13657 an undeclared field written by an L2 body — one answe connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true, }); - // [#10629] Installed before the driver runs a statement — the sink the + // [commit 13a6cb4ad] Installed before the driver runs a statement — the sink the // expected refusal's first half travels out on. noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); noise.captureDriver(driver); @@ -291,7 +291,7 @@ describe('#4271 / #13657 an undeclared field written by an L2 body — one answe } async function bootMemory(hook?: unknown) { - // [#10629] A schemaless driver never refuses a read on a missing table, so + // [commit 13a6cb4ad] A schemaless driver never refuses a read on a missing table, so // this family expects no noise at all — an EMPTY declaration rather than a // skipped one, which keeps the shared `afterEach` assertion honest. noise = captureExpectedReadRefusals([]); @@ -300,7 +300,7 @@ describe('#4271 / #13657 an undeclared field written by an L2 body — one answe async function boot(driver: unknown, hook?: unknown) { engine = new ObjectQL(); - // [#10629] The engine frame that sits directly above the driver's refusal. + // [commit 13a6cb4ad] The engine frame that sits directly above the driver's refusal. noise?.captureEngine(engine); engine.registerDriver(driver as any, true); await engine.init(); diff --git a/packages/runtime/src/security/resolve-execution-context.test.ts b/packages/runtime/src/security/resolve-execution-context.test.ts index d5895607b9b..c029f7f524f 100644 --- a/packages/runtime/src/security/resolve-execution-context.test.ts +++ b/packages/runtime/src/security/resolve-execution-context.test.ts @@ -13,7 +13,7 @@ import { hashApiKey } from './api-key.js'; * tests isolate the API-key verify path. */ /** - * [#10978] Enforce the caller's `limit`, the way a real driver does. + * [commit 4c9780c7a] Enforce the caller's `limit`, the way a real driver does. * * A double that matches `where` and returns every matched row cannot tell a read * bounded at 200 from the same read bounded at 1000, or from an unbounded one — @@ -741,7 +741,7 @@ describe('[#13906 decision 1 A, runtime door] the tenancy posture seam tells "ne }); // ------------------------------------------------------------------------- - // [#17114] The classification above is now `classifyAdmissionTenancyPosture` + // [commit 4af758d47] The classification above is now `classifyAdmissionTenancyPosture` // (`@objectstack/core`) rather than a hand-written copy of it — one of the // two seams #16013 left behind. The RESOLUTION stayed here: this facade's // `opts.getService` is handed in as the thunk. diff --git a/packages/runtime/src/security/resolve-execution-context.ts b/packages/runtime/src/security/resolve-execution-context.ts index 2715fa7759d..38358ad5349 100644 --- a/packages/runtime/src/security/resolve-execution-context.ts +++ b/packages/runtime/src/security/resolve-execution-context.ts @@ -19,7 +19,7 @@ * guest envelope (`{ isSystem: false, positions: [], permissions: [] }`) — * and throws `AuthzStoreUnavailableError` (503) for the one class of fault * that leaves the answer undetermined: an authorization INPUT that exists and - * could not be read (a permission-store read that failed, #13279; a `tenancy` + * could not be read (a permission-store read that failed, commit 6a180e42d; a `tenancy` * service that is registered and failed to build, #13906 decision 1 A). The * dispatcher's net (`HttpDispatcher.resolveRequestScope`) re-raises exactly * that class and degrades everything else to anonymous, as before. @@ -194,7 +194,7 @@ export async function resolveExecutionContext(opts: ResolveOptions): Promise { let dir: string | null = null; let engine: ObjectQL | null = null; - /** [#10629] The expected-noise capture belonging to the latest boot. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest boot. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(async () => { try { await engine?.destroy(); } catch { /* noop */ } engine = null; if (dir) { rmSync(dir, { recursive: true, force: true }); dir = null; } - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave the engine running. The single test in this // file boots and writes, so the probe fires for it. expect(noise?.silentChannels() ?? ['no capture was installed']).toEqual([]); @@ -120,7 +120,7 @@ describe('[#8442] a REAL driver constraint violation is withheld from the seed r connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true, }); - // [#10629] Installed on the REAL driver (the one that logs) before it runs + // [commit 13a6cb4ad] Installed on the REAL driver (the one that logs) before it runs // a statement — the `Object.create(real)` wrapper below resolves `logger` // through the prototype chain to this sink. noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); diff --git a/packages/runtime/src/seed-multi-value-lookup-real-driver.integration.test.ts b/packages/runtime/src/seed-multi-value-lookup-real-driver.integration.test.ts index 303c63e089e..4d5e23c5b89 100644 --- a/packages/runtime/src/seed-multi-value-lookup-real-driver.integration.test.ts +++ b/packages/runtime/src/seed-multi-value-lookup-real-driver.integration.test.ts @@ -64,7 +64,7 @@ const SEEDS = [ ]; /** - * [#10629] This fixture provisions the seeded business objects and nothing else, so the engine's + * [commit 13a6cb4ad] This fixture provisions the seeded business objects and nothing else, so the engine's * own single-tenant probe (`ObjectQL.probeInstallOrganizations`, memoised once * per engine) reads a `sys_organization` that was never created. The probe is * fail-soft by construction — it catches `isMissingTableError` and only that — @@ -76,14 +76,14 @@ const ABSENT_TENANCY_TABLE = 'sys_organization'; describe('multi-value lookup seeds on a REAL SqlDriver (framework#3911)', () => { let dir: string | null = null; let engine: ObjectQL | null = null; - /** [#10629] The expected-noise capture belonging to the latest boot. */ + /** [commit 13a6cb4ad] The expected-noise capture belonging to the latest boot. */ let noise: ExpectedReadRefusalCapture | null = null; afterEach(async () => { try { await engine?.destroy(); } catch { /* noop */ } engine = null; if (dir) { rmSync(dir, { recursive: true, force: true }); dir = null; } - // [#10629] The capture is a PIN, not a mute — asserted after teardown so a + // [commit 13a6cb4ad] The capture is a PIN, not a mute — asserted after teardown so a // failure here can never leave the engine running. Every test in this file // boots and writes, so the probe fires for each of them: this holds for a // single `-t` run as well as for the whole file. @@ -98,7 +98,7 @@ describe('multi-value lookup seeds on a REAL SqlDriver (framework#3911)', () => connection: { filename: join(dir, 'data.sqlite') }, useNullAsDefault: true, }); - // [#10629] Installed before the driver runs a statement and before the + // [commit 13a6cb4ad] Installed before the driver runs a statement and before the // engine issues a read — the two sinks the expected refusal travels out on. noise = captureExpectedReadRefusals([ABSENT_TENANCY_TABLE]); noise.captureDriver(driver); diff --git a/packages/runtime/src/seed-tenancy-autonumber-split.integration.test.ts b/packages/runtime/src/seed-tenancy-autonumber-split.integration.test.ts index 364727e8971..95ff7cb1d17 100644 --- a/packages/runtime/src/seed-tenancy-autonumber-split.integration.test.ts +++ b/packages/runtime/src/seed-tenancy-autonumber-split.integration.test.ts @@ -529,7 +529,7 @@ describe('#8686 seed/API tenancy split — autonumber scope', () => { expect(await readSequences(driver)).toEqual([{ tenant: GLOBAL_TENANT, lastValue: 3 }]); }); /** - * #10789 — PRESERVED-BEHAVIOUR control for the `absent`/`no-split` separation. + * Commit 38bc74ed1 — PRESERVED-BEHAVIOUR control for the `absent`/`no-split` separation. * * `backfillSeedTenancy` used to answer `no-split` over a seam it never * queried: a no-op `execute` returns `null`, `normalizeRows(null)` is `[]`, @@ -573,7 +573,7 @@ describe('#8686 seed/API tenancy split — autonumber scope', () => { expect(result.status).toBe('no-split'); expect(result.detail).toBeUndefined(); - // Nothing moved: the SQL path is untouched by #10789. + // Nothing moved: the SQL path is untouched by commit 38bc74ed1. expect(await readSequences(driver)).toEqual([{ tenant: ORG_ID, lastValue: 2 }]); expect(await countUntenanted(driver)).toBe(0); }); diff --git a/packages/runtime/src/standalone-stack-seeder-declaration-copy.test.ts b/packages/runtime/src/standalone-stack-seeder-declaration-copy.test.ts index bb5455b2844..a0aebe7c0a7 100644 --- a/packages/runtime/src/standalone-stack-seeder-declaration-copy.test.ts +++ b/packages/runtime/src/standalone-stack-seeder-declaration-copy.test.ts @@ -26,7 +26,7 @@ // 4. which copy wins in the persisted `sys_*` row. // // ⛔ This file changes NO production behaviour and asserts no repair. It is a -// divergence pin in the style of PR #14398's +// divergence pin in the style of commit 317132495's // `standalone-stack-security-registrar.test.ts`: one real boot, both copies // read at the same moment, key by key, beside the row that survived. // @@ -85,8 +85,8 @@ import '@objectstack/service-datasource'; /** * The probe artifact. `engines.protocol` sits one minor below the runtime spec - * so the door's ADR-0087 forward-conversion window is open — the same lever PR - * #14398's probe uses, and the reason the two copies can differ at all. + * so the door's ADR-0087 forward-conversion window is open — the same lever + * commit 317132495's probe uses, and the reason the two copies can differ at all. * * Each declaration isolates one axis of triage's question: * @@ -97,7 +97,7 @@ import '@objectstack/service-datasource'; * - `capabilities[0]` — no `scope`, so the door's schema default is observable * (triage question 3). * - `sharingRules[0]` `share_legacy_deals` — BOTH legacy spellings at once - * (`sharedWith.type: 'role'`, `accessLevel: 'full'`), the PR #14398 probe + * (`sharedWith.type: 'role'`, `accessLevel: 'full'`), the commit 317132495 probe * bytes. * - `sharingRules[1]` `share_legacy_level` — the legacy `accessLevel` ALONE, * over a recipient type the seeder accepts, so the `accessLevel` axis is not diff --git a/packages/runtime/src/standalone-stack.libsql.test.ts b/packages/runtime/src/standalone-stack.libsql.test.ts index 7f75ee884a5..da057411eb4 100644 --- a/packages/runtime/src/standalone-stack.libsql.test.ts +++ b/packages/runtime/src/standalone-stack.libsql.test.ts @@ -21,7 +21,7 @@ // // No test here touches a real Turso endpoint. Every loader-level case // substitutes the package through `importDriverPackage`; the whole-boot case in -// ③ has no such seam and stages absence with `vi.doMock` instead (#12943). +// ③ has no such seam and stages absence with `vi.doMock` instead (commit 090f2302e). // Both make the "package missing" arm testable in a workspace where the package // IS installed — which, since `@objectstack/driver-turso` became a declared // optional peer of this package, is now every workspace. @@ -294,7 +294,7 @@ describe('loadTursoDriverFactory — the OPTIONAL driver package, both ways (#58 // // ⭐ This case's old comment predicted its own future and was right: "Should the // package ever become a dependency of this one, this case turns red and names -// exactly why in this comment." #12943 declared `@objectstack/driver-turso` an +// exactly why in this comment." Commit 090f2302e declared `@objectstack/driver-turso` an // OPTIONAL PEER of `@objectstack/runtime` — install-time honesty for a // relationship the source already had, installing nothing for a consumer — and // pnpm LINKS an optional workspace peer. Measured on that change: the boot diff --git a/packages/runtime/src/standalone-stack.mysql.test.ts b/packages/runtime/src/standalone-stack.mysql.test.ts index 268e8146749..d3b87d2a9a4 100644 --- a/packages/runtime/src/standalone-stack.mysql.test.ts +++ b/packages/runtime/src/standalone-stack.mysql.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// #6265 — two halves of one defect family in `standalone-stack.ts`, pinned +// Commit cfb549db8 — two halves of one defect family in `standalone-stack.ts`, pinned // together because they close the same hole from opposite sides: a driver // selection this stack could not dispatch. // @@ -254,7 +254,7 @@ describe('the existing schemes are untouched (positive controls, #6265)', () => expect(resolveStandaloneDatabase({ databaseUrl: url }).driver).toBe(kind); }); - // #6220's e2e pins this exit path from the CLI end — the new mysql arm must + // Commit 83df2fd73's e2e pins this exit path from the CLI end — the new mysql arm must // not have turned the trailing throw into a catch-all. it('an unknown scheme still throws, and the message now lists mysql://', () => { expect(() => resolveStandaloneDatabase({ databaseUrl: 'wat://nope' })) diff --git a/packages/runtime/src/standalone-stack.ts b/packages/runtime/src/standalone-stack.ts index 052e540f95e..97e7597b66c 100644 --- a/packages/runtime/src/standalone-stack.ts +++ b/packages/runtime/src/standalone-stack.ts @@ -24,7 +24,7 @@ * Unknown URL schemes throw — we never silently fall back to sqlite, since * that historically created bogus directories on disk (e.g. `mongodb:/`) * when an unsupported URL was treated as a file path. The SAME refusal now - * covers an unknown `OS_DATABASE_DRIVER` value (#6265): that env var used to be + * covers an unknown `OS_DATABASE_DRIVER` value (commit cfb549db8): that env var used to be * a bare `as` cast, so a typo — or `mysql` before this stack could dispatch it * — fell through the driver chain's trailing `else` into SQLite without a word. * @@ -42,7 +42,7 @@ * comes through here — refused it as an unsupported scheme. * * NOTE: `mysql://` is the same family with none of the optional-package weight - * (#6265). The CLI has classified it as `mysql` since forever + * (commit cfb549db8). The CLI has classified it as `mysql` since forever * (`inferDriverTypeFromUrl`), the SHARED factory has always been able to build * it (`kind === 'mysql'` → SqlDriver on `mysql2`), and only this file was * missing the arm — so one `OS_DATABASE_URL=mysql://…` booted under `os start` @@ -96,16 +96,16 @@ export function resolveObjectStackHome(): string { /** * The driver kinds a standalone boot can dispatch — the ONE list, and the only - * one (#6265), now shared with the CLI rather than merely singular here (commit e2798fab7). + * one (commit cfb549db8), now shared with the CLI rather than merely singular here (commit e2798fab7). * * Three consumers read it and every one of them used to carry its own answer: * the `databaseDriver` config key (a zod enum that rejected loudly), the * `OS_DATABASE_DRIVER` env var (a bare `as` cast that validated nothing, so an * unknown value fell through the dispatch chain's trailing `else` into SQLite), - * and the `ResolvedDriverKind` union (a hand-written third copy). #6265 made + * and the `ResolvedDriverKind` union (a hand-written third copy). Commit cfb549db8 made * them one declaration. * - * What #6265 could not fix from inside this file is that the CLI had a FOURTH + * What commit cfb549db8 could not fix from inside this file is that the CLI had a FOURTH * answer. This enum listed canonical spellings only, while * `packages/cli/src/utils/storage-driver.ts` accepted `pg`, `mysql2`, `mongo`, * `libsql`, `wasm`, `sql`, `mingo`, … — measured on `main`, **10 of 21 spellings @@ -318,7 +318,7 @@ type ResolvedDriverKind = z.infer; function detectDriverFromUrl(dbUrl: string): ResolvedDriverKind { if (/^memory:\/\//i.test(dbUrl)) return 'memory'; if (/^(postgres(ql)?|pg):\/\//i.test(dbUrl)) return 'postgres'; - // MySQL / MariaDB (#6265). Character-for-character the regex the CLI uses + // MySQL / MariaDB (commit cfb549db8). Character-for-character the regex the CLI uses // (`utils/storage-driver.ts` `inferDriverTypeFromUrl`), for the same reason // the turso arm below copies its spellings: the two functions answer the // same question about the same `OS_DATABASE_URL`, so any divergence IS the @@ -354,7 +354,7 @@ function detectDriverFromUrl(dbUrl: string): ResolvedDriverKind { /** * The explicit driver selection for this boot, or `undefined` when none was made. * - * Two sources, ONE vocabulary (#6265). `cfg.databaseDriver` has always been + * Two sources, ONE vocabulary (commit cfb549db8). `cfg.databaseDriver` has always been * parsed by {@link StandaloneDatabaseDriverSchema}; `OS_DATABASE_DRIVER` was * `process.env.OS_DATABASE_DRIVER?.trim() as ResolvedDriverKind` — an assertion, * which checks nothing at runtime. An unknown value therefore reached the @@ -381,7 +381,7 @@ function resolveExplicitDriver( const raw = process.env.OS_DATABASE_DRIVER?.trim(); if (!raw) return undefined; // Commit e2798fab7: the ACCEPTED SPELLINGS are the spec table's selection aliases, not - // this file's canonical list. Lower-casing stays for the reason #6265 gave — + // this file's canonical list. Lower-casing stays for the reason commit cfb549db8 gave — // the CLI's reader of this same variable lower-cases — and is now redundant // with `resolveDatabaseDriverId`'s own normalization rather than the only // normalization there is. @@ -502,7 +502,7 @@ function resolveArtifactPathInput(cfg: z.output { - // ⭐ STAGED absence since #12943. `@objectstack/driver-turso` is now an + // ⭐ STAGED absence since commit 090f2302e. `@objectstack/driver-turso` is now an // OPTIONAL PEER of `@objectstack/service-datasource` and of this package — // the honest install-time declaration of a relationship the source already // had. It installs nothing for a consumer, but pnpm LINKS an optional diff --git a/packages/runtime/src/turso-driver-factory.ts b/packages/runtime/src/turso-driver-factory.ts index b00e0058c61..4649eeebb5a 100644 --- a/packages/runtime/src/turso-driver-factory.ts +++ b/packages/runtime/src/turso-driver-factory.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * libSQL/Turso driver loading — the SINGLE owner for both hosts (#6268). + * libSQL/Turso driver loading — the SINGLE owner for both hosts (commit 68f5eccb1). * * `@objectstack/driver-turso` drags `@libsql/client` (native bindings included), * so it is an OPTIONAL install rather than a dependency. Neither host can @@ -25,9 +25,9 @@ * engine), and it is the ruling both halves landed under (#5602 / PR #5819 for * the CLI, #5820 for the standalone stack). * - * ## #6268 — why this module owns it, and what the hosts still own + * ## Commit 68f5eccb1 — why this module owns it, and what the hosts still own * - * Until #6268 this shape existed TWICE: here, and in + * Until commit 68f5eccb1 this shape existed TWICE: here, and in * `packages/cli/src/utils/storage-driver.ts`. They were kept equal by hand * because the dependency direction forbids the reverse import (cli → runtime, * never runtime → cli) and each of the two rulings that created them had a @@ -42,7 +42,7 @@ * * - **{@link LoadTursoDriverFactoryOptions.importDriverPackage} — the module * resolution root.** `@objectstack/driver-turso` is an OPTIONAL PEER of - * `@objectstack/cli` and, since #12943, of `@objectstack/runtime` too. An + * `@objectstack/cli` and, since commit 090f2302e, of `@objectstack/runtime` too. An * optional peer NAMES the relationship and installs nothing, so the package * still sits in whichever tree the operator installed it into — and a bare * `import('@objectstack/driver-turso')` resolves from the node_modules tree @@ -55,7 +55,7 @@ * own root, for the standalone stack. * ⚠️ Inside THIS workspace pnpm links an optional peer, so the default thunk * resolves here. Every test covering the missing-package arm therefore stages - * the absence rather than relying on the layout to supply it (#12943). + * the absence rather than relying on the layout to supply it (commit 090f2302e). * - **{@link LoadTursoDriverFactoryOptions.missingUrlError} — the error TYPE * for a config with no url.** The CLI raises its own `UnsupportedDriverError` * (a CLI-only semantic: `serve.ts` re-throws it as a fatal boot error), which @@ -70,7 +70,7 @@ * * ## #7314 — and the THIRD loader, one layer down * - * #6268 converged the two HOST-injected loaders. It could not reach the + * Commit 68f5eccb1 converged the two HOST-injected loaders. It could not reach the * open-core one: `createDefaultDatasourceDriverFactory`'s `turso` arm in * `@objectstack/service-datasource`, which serves every door that is not a * host's `default` — a datasource created in Setup, `testConnection`, a declared @@ -136,7 +136,7 @@ export { TURSO_DRIVER_PACKAGE, TURSO_DRIVER_INSTALL_COMMAND, MissingDriverPackag * Resolved through `@objectstack/spec`'s shared driver table rather than a local * `Set`, so "which spellings mean libSQL" has ONE answer across the CLI, the * standalone stack, the open-core factory and the metadata gate. The private - * `Set(['turso', 'libsql'])` this replaced (#6268) happened to agree with the + * `Set(['turso', 'libsql'])` this replaced (commit 68f5eccb1) happened to agree with the * table on the day it was written — the table's `turso` row lists exactly those * two aliases — and would have silently stopped agreeing the moment a third * spelling was added on one side only. @@ -155,7 +155,7 @@ export interface LoadTursoDriverFactoryOptions { * * NOT merely a test seam: the specifier resolves from the node_modules tree of * whichever module evaluates the `import()`, and the package is an optional - * peer of BOTH `@objectstack/cli` and `@objectstack/runtime` (#12943) — a + * peer of BOTH `@objectstack/cli` and `@objectstack/runtime` (commit 090f2302e) — a * declaration that installs nothing, so which tree actually holds the package * is still decided by where the operator installed it. The CLI passes its own * thunk so its operators keep resolving the package they installed next to the @@ -173,7 +173,7 @@ export interface LoadTursoDriverFactoryOptions { * * Host-chosen because the TYPE is host semantics: the CLI raises its own * `UnsupportedDriverError`, which `serve.ts` re-throws as a fatal boot error - * and which by the #6268 ruling stays in the CLI. The MESSAGE is passed in + * and which by the ruling commit 68f5eccb1 landed stays in the CLI. The MESSAGE is passed in * from here, so the wording is still single-sourced. * * Defaults to the standalone stack's plain `Error` with its `[StandaloneStack]` @@ -203,7 +203,7 @@ export async function loadTursoDriverFactory( ): Promise { // `as any` on the specifier: the package is an OPTIONAL PEER of // `@objectstack/runtime`, never a dependency (that is what "optional" means - // here — #12943 declared the relationship, and an optional peer installs + // here — commit 090f2302e declared the relationship, and an optional peer installs // nothing), so the literal must not be type-resolved: a consumer who did not // install it must still compile. Same shape the shared factory uses for the // other optional drivers (`default-datasource-driver-factory.ts`). @@ -219,7 +219,7 @@ export async function loadTursoDriverFactory( driverType: 'turso', packageName: TURSO_DRIVER_PACKAGE, installCommand: TURSO_DRIVER_INSTALL_COMMAND, - // One wording for both hosts (#6268). It names BOTH consequences rather + // One wording for both hosts (commit 68f5eccb1). It names BOTH consequences rather // than picking one, because one message now answers a failed `os serve` // boot and a failed `os migrate` / embedded `createStandaloneStack` alike, // and an operator who is told only about the other host's symptom would From a5cdfd8a46bb2f37c952f73e7a5a51c2c778df27 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <50353452+hotlong@users.noreply.github.com> Date: Tue, 29 Sep 2026 17:08:03 +0800 Subject: [PATCH 3/3] docs(runtime): leave domains/meta.ts at its base blob while another open PR edits it An open pull request opened after this stage's claim edits packages/runtime/src/domains/meta.ts, so this stage returns that file to the bytes it has on main and lists its twenty sites, with their verified anchors, for a follow-up once that pull request lands. Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289 Co-authored-by: Claude --- packages/runtime/src/domains/meta.ts | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/runtime/src/domains/meta.ts b/packages/runtime/src/domains/meta.ts index 6fcd6a7ef76..b4ddb362cc2 100644 --- a/packages/runtime/src/domains/meta.ts +++ b/packages/runtime/src/domains/meta.ts @@ -11,7 +11,7 @@ import { shouldDenyAnonymous, ANONYMOUS_DENY_STATUS, ANONYMOUS_DENY_CODE, ANONYMOUS_DENY_MESSAGE, } from '@objectstack/core'; -// [commit 67ceb9aef] `canonicalMetaUrlType` is the FOLD this transport was missing. +// [#10503] `canonicalMetaUrlType` is the FOLD this transport was missing. // See the two call sites below for what each one was deciding raw. import { canonicalMetaUrlType, pluralToSingular } from '@objectstack/spec/shared'; import { CoreServiceName } from '@objectstack/spec/system'; @@ -100,7 +100,7 @@ import type { DomainHandlerDeps, DomainRoute } from '../domain-handler-registry. * ("real services with no written contract, so they keep today's `any` rather * than being given a shape here that nothing verifies"). The `any` is honest * about the SLOT. What it also did, silently, was hand every request literal - * downstream of it an unchecked call target: the end state of commit cccbe51bf's ruled pattern — + * downstream of it an unchecked call target: the #11006 series' end state — * "an undeclared key in a request literal is a compile error" — stopped one * seam short here, so a misspelt or undeclared key in these literals compiled, * and so did a misspelt VERB. @@ -113,7 +113,7 @@ import type { DomainHandlerDeps, DomainRoute } from '../domain-handler-registry. * probes below exist to deny — and it would have to answer for the three verbs * in the second group, which no contract declares at all. So the narrowing * happens at the consumer, once, exactly as `domains/packages.ts` (#13598) and - * `domains/mcp.ts` (commit e783e163d) narrow the same slot for their own seams. + * `domains/mcp.ts` (#8726) narrow the same slot for their own seams. * * ## ⛔ Every member is OPTIONAL, and the runtime probes STAY * @@ -197,7 +197,7 @@ function mayReadPendingDrafts(caller: unknown): boolean { } /** - * [commit 4fc4a3c0b] The methods `/metadata/:type/:name` actually serves — the single + * [#8848] The methods `/metadata/:type/:name` actually serves — the single * source for both the `Allow` header and the refusal message, so the two * cannot drift apart. * @@ -816,7 +816,7 @@ async function answerMetaLayered( } /** - * Percent-decode the `:name` path segment. [commit 7986d973f] + * Percent-decode the `:name` path segment. [#12195] * * This dispatcher splits the RAW path (`path.split('/')`) and, unlike the * `packages/rest` Hono routes, nothing decodes its parameters for it — @@ -824,11 +824,11 @@ async function answerMetaLayered( * hands to `dispatch()`, returns `/meta/lead/views%2Fall_leads` verbatim while * `c.req.param('name')` on the same request yields `views/all_leads`. * - * That difference is load-bearing here. Until commit 7986d973f the compound fold + * That difference is load-bearing here. Until #12195 the compound fold * (`parts.slice(1).join('/')`) is what let a slash-bearing name be addressed * on this transport at all — unencoded, across segments. Retiring the fold * without decoding would leave a pre-grammar residue row addressable through - * `packages/rest` and NOT through the dispatcher, breaking the landed (commit 311433f6b) + * `packages/rest` and NOT through the dispatcher, breaking #12194's landed * acceptance criterion that "reads and `deleteMetaItem` still answer for * pre-grammar residue rows, so any stored junk name remains listable and * clearable". Decoding makes ONE spelling — percent-encoded, the spelling the @@ -1043,11 +1043,11 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin // GET /metadata/:type/:name/published → get published version // - // [commit 7986d973f] EXACTLY three segments, and no fold. This used to be + // [#12195] EXACTLY three segments, and no fold. This used to be // `parts.length >= 3` with `parts.slice(1, -1).join('/')`, which re-joined // every middle segment into one slash-bearing key so // `lead/views/all_leads/published` resolved as name `views/all_leads`. - // Stage 1 (commit 311433f6b) refuses every slash-bearing name at the publish door, + // Stage 1 (#12194) refuses every slash-bearing name at the publish door, // so that fold could only ever address a name that can no longer be // written. if (parts.length === 3 && parts[2] === 'published' && (!method || method === 'GET')) { @@ -1140,7 +1140,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin const metadataService = await deps.getService(_context, CoreServiceName.enum.metadata); if (metadataService && typeof (metadataService as any).getPublished === 'function') { - // [commit 67ceb9aef] FOLDED — the smaller second site of the same class, + // [#10503] FOLDED — the smaller second site of the same class, // dispatcher edition (the REST twin folds at the same point). The // layered consult above folds internally at the protocol boundary; // this fallback reads the code/package registry, which stores @@ -1156,7 +1156,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin if (metaSvc && typeof (metaSvc as any).getPublished === 'function') { let fallbackData: unknown; try { - // [commit 67ceb9aef] Same fold — this slot reads the same canonical store. + // [#10503] Same fold — this slot reads the same canonical store. fallbackData = await (metaSvc as any).getPublished(canonicalMetaUrlType(type), name); } catch { /* fall through */ } if (fallbackData !== undefined) return servePublished(fallbackData); @@ -1164,13 +1164,13 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin return { handled: true, response: deps.error('Not found', 404) }; } - // /metadata/:type/:name — EXACTLY two segments. [commit 7986d973f] + // /metadata/:type/:name — EXACTLY two segments. [#12195] // // This used to be `parts.length >= 2` with `parts.slice(1).join('/')`: every // segment after the type was re-joined into one slash-bearing lookup key, // so `/metadata/lead/views/all_leads` resolved as name `views/all_leads`. // That fold WAS compound-name addressing on this transport, and stage 1 - // (commit 311433f6b) made every name it could reach unwritable at the publish door. + // (#12194) made every name it could reach unwritable at the publish door. // // ⚠️ The `>=` also swallowed three-segment paths that were never compound // names at all — `/metadata/object/foo/references` folded to name @@ -1244,10 +1244,10 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin // partition, never env-wide and never another org's. The active // organization is resolved HERE, once, and reused by the write // threading below — authorization and scope read one value (the - // single-resolution shape the REST doors carry, commit b5378550e). Resolving + // single-resolution shape the REST doors carry, #8919). Resolving // it is a session read, not a protocol probe: the 403-vs-501 // discipline above is untouched. - // [commit 67ceb9aef] Folded at the boundary, once — the verdict and the + // [#10503] Folded at the boundary, once — the verdict and the // scope decision below must read the same spelling. const canonicalType = canonicalMetaUrlType(type); // [#20408] The caller's VETTED organization — the `tenantId` @@ -1305,8 +1305,8 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin // capability gate above already made — scope and // authorization read the same value by construction. // - // [commit 67ceb9aef] The segment is FOLDED before the scope decision - // — the correction commit 26f3588fb landed for the REST `/meta` + // [#10503] The segment is FOLDED before the scope decision + // — the correction #10340 landed for the REST `/meta` // doors, arriving on the second transport. This branch read // the RAW `parts[0]`, while `protocol.saveMetaItem` below // folds the same string through `canonicalizeMetaRequestType` @@ -1334,7 +1334,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin const organizationId = organizationIdForMetaWrite( canonicalType, activeOrganizationId, ); - // [commit d806081dd] Server-stated face: this branch answers through + // [#10888] Server-stated face: this branch answers through // `deps.errorFromThrown`, which carries the refusal's // `issues[]` in `details` (see the `details.issues` pin in // `http-dispatcher.test.ts`), so `saveMetaItem`'s 422 renders @@ -1395,7 +1395,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin return { handled: true, response: deps.error('Save not supported', 501) }; } - // [commit 4fc4a3c0b] The read `try` below is this block's default answer, and it + // [#8848] The read `try` below is this block's default answer, and it // used to carry NO method guard at all: every verb that is not `PUT` // fell into it and was served the ordinary metadata READ. // @@ -1957,7 +1957,7 @@ export async function handleMetadataRequest(deps: DomainHandlerDeps, path: strin return { handled: true, response: deps.success({ types: ['object', 'app', 'plugin'] }) }; } - // [commit 7986d973f] A LOCATED refusal, not a bare `{ handled: false }`. + // [#12195] A LOCATED refusal, not a bare `{ handled: false }`. // // This tail was unreachable until this card: the branches above covered // zero segments, one segment, and — through the compound fold — every path