diff --git a/.changeset/20595-metadata-protocol-provenance-anchors.md b/.changeset/20595-metadata-protocol-provenance-anchors.md new file mode 100644 index 00000000000..8ba87a08a56 --- /dev/null +++ b/.changeset/20595-metadata-protocol-provenance-anchors.md @@ -0,0 +1,15 @@ +--- +'@objectstack/metadata-protocol': patch +--- + +Provenance comments in `@objectstack/metadata-protocol` cite the commits that decided them, not tracker numbers that no longer resolve + +Clause-②: no + +Docblocks and comments across the package cited issue-tracker numbers that now answer 404 on GitHub. +Each one now cites the commit in this repository's history that made the decision it describes +(and ADR-0005's design-principle-3 correction where that record exists). Some of these docblocks sit +on exported members, so the reworded text appears in the published `index.d.ts` / `index.d.cts`, and +a few comments that esbuild keeps appear in the JavaScript output. + +Comment only: no export, type, error code, status, message text or runtime behaviour changes. diff --git a/packages/metadata-protocol/src/discovery-version.test.ts b/packages/metadata-protocol/src/discovery-version.test.ts index c7d197cd51a..ccd5aeba419 100644 --- a/packages/metadata-protocol/src/discovery-version.test.ts +++ b/packages/metadata-protocol/src/discovery-version.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #11235 — the `version` field `getDiscovery()` serves must be DERIVED: an + * Commit 376c70f98 — the `version` field `getDiscovery()` serves must be DERIVED: an * injected `OS_RUNTIME_VERSION` stamp, falling back to the resolved * `@objectstack/metadata-protocol` package version — never the `'1.0'` literal * this producer hardcoded before the fix, and never any other constant. diff --git a/packages/metadata-protocol/src/discovery-version.ts b/packages/metadata-protocol/src/discovery-version.ts index 03a3c22ec7b..849b3affa9c 100644 --- a/packages/metadata-protocol/src/discovery-version.ts +++ b/packages/metadata-protocol/src/discovery-version.ts @@ -4,7 +4,7 @@ * Resolves the value `ObjectStackProtocolImplementation.getDiscovery()` serves * as the `DiscoverySchema` "System Identity" `version` field (`./protocol.ts`). * - * ## #11235 — why the literal it replaces was provably not a contract value + * ## Commit 376c70f98 — why the literal it replaces was provably not a contract value * * This producer hardcoded `version: '1.0'`. It is the SECOND * `DiscoverySchema`-conforming producer; the first @@ -23,7 +23,7 @@ * `@objectstack/metadata-protocol`, not the reverse, so importing it would * invert the dependency direction. Hoisting a shared helper into * `@objectstack/types` or `@objectstack/core` (both already dependencies of - * this package) was considered and declined at #11235 triage: a hoist widens + * this package) was considered and declined when the derivation landed (commit 376c70f98): a hoist widens * two packages' published surface for ~10 lines serving two call sites. * Consolidation rides a later card if a third caller ever appears. * @@ -103,7 +103,7 @@ function resolvePackageVersion(): string | undefined { * 3. `'unknown'` — only if BOTH of the above are unavailable (the package's own * `package.json` is unreadable). Honest about not knowing, rather than a * plausible-looking literal a caller could mistake for real identity — the - * exact failure mode #10993 and #11235 exist to close. + * exact failure mode #10993 and commit 376c70f98 close. */ export function resolveDiscoveryVersion(): string { return getEnv('OS_RUNTIME_VERSION') || resolvePackageVersion() || 'unknown'; diff --git a/packages/metadata-protocol/src/get-meta-item-layered-org-read-gate.test.ts b/packages/metadata-protocol/src/get-meta-item-layered-org-read-gate.test.ts index b09fba31366..f95253c6f4d 100644 --- a/packages/metadata-protocol/src/get-meta-item-layered-org-read-gate.test.ts +++ b/packages/metadata-protocol/src/get-meta-item-layered-org-read-gate.test.ts @@ -1,13 +1,13 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14907] `getMetaItemLayered` — the THIRD `/meta` read verb — applies the + * [commit e1d4f9e3f] `getMetaItemLayered` — the THIRD `/meta` read verb — applies the * registry read gate ITSELF, so a caller cannot spend a raw active * organization on a type that has no per-org read channel. * * ── The defect, and why this verb was graded on its own harm ────────────── * - * The series is #9454 → #14683 (plural `getMetaItems`) → #14770 (singular + * The series is #9454 → commit 96326040f (plural `getMetaItems`) → commit d5cbb44f3 (singular * `getMetaItem`) → this one. On the plural verb an ungated organization can * only ADD a row; on the singular verb it SUBSTITUTES the served document. * Here the affected value is the `overlay` LAYER of a three-layer diagnostic @@ -28,19 +28,19 @@ * and it is correct there because the binding already sat AFTER * `canonicalizeMetaRequestType`. Here the binding sat BEFORE the fold, so the * one-liner does NOT port: dropping the same expression in place would gate on - * the RAW type. #10340 measured what that costs — `declaresOrgOverride` + * the RAW type. Commit 26f3588fb measured what that costs — `declaresOrgOverride` * tolerates the MANIFEST plurals but not the URL-only ones (`translations` / * `email_templates` have no manifest key), so a raw segment splits one item * across two partitions. The fix is therefore a REORDER, and §3 is what fails * if a later author moves the binding back above the fold: it asserts that a * URL-only spelling of an OVERRIDABLE type still reaches its org partition. * - * ── §4–§5 are the idempotence proof the #14683 ruling made this conditional + * ── §4–§5 are the idempotence proof the ruling behind commit 96326040f made this conditional * on, discharged over THIS door's caller population ────────────────────── * * That ruling makes a callee-side gate conditional on proving no already-gating * caller is double-scoped or wrongly denied, discharged PER DOOR over that - * door's own callers. #14770's proof covers none of this verb's population, so + * door's own callers. Commit d5cbb44f3's proof covers none of this verb's population, so * it is re-discharged here: §4 covers `f(t, undefined) === undefined` (the four * `plugin-security` invocations that name no organization) and §5 covers * `f(t, f(t, o)) === f(t, o)` over the COMPLETE accepted-spelling population @@ -359,13 +359,13 @@ describe('§3 the gate resolves AFTER canonicalizeMetaRequestType', () => { expect(res.overlayScope, spelling).toBe('org'); // ONLY the org partition: the org row wins, so the `overlay === // null` env fallback never runs. Gated on the raw segment this - // list is `[null]` instead — the partition split #10340 measured. + // list is `[null]` instead — the partition split commit 26f3588fb measured. expect(partitions(findOnes), spelling).toEqual([ORG]); } }); it('answers the URL spelling and the canonical spelling identically', async () => { - // The #10340 statement restated as an equality: one item, ONE + // The statement of commit 26f3588fb restated as an equality: one item, ONE // partition, whichever accepted spelling addresses it. for (const spelling of URL_ONLY_OVERRIDABLE) { const canonical = canonicalMetaUrlType(spelling); diff --git a/packages/metadata-protocol/src/get-meta-item-org-read-gate.test.ts b/packages/metadata-protocol/src/get-meta-item-org-read-gate.test.ts index 63d5278db2e..8856acd3660 100644 --- a/packages/metadata-protocol/src/get-meta-item-org-read-gate.test.ts +++ b/packages/metadata-protocol/src/get-meta-item-org-read-gate.test.ts @@ -1,13 +1,13 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14770] `getMetaItem` — the SINGULAR verb — applies the registry read gate + * [commit d5cbb44f3] `getMetaItem` — the SINGULAR verb — applies the registry read gate * ITSELF, so a caller cannot spend a raw active organization on a type that has * no per-org read channel. * * ── The defect, and why the singular verb is the sharper half ───────────── * - * #14683 (PR #14767) moved {@link organizationIdForMetaRead} INSIDE the PLURAL + * Commit 96326040f (PR #14767) moved {@link organizationIdForMetaRead} INSIDE the PLURAL * verb, `getMetaItems`, and deliberately did not carry to this one. There, the * two `queryByOrg` reads are UNIONed, so an ungated organization can only ADD * rows — the resurrection that card is about. Here the two `findOverlay` reads @@ -37,7 +37,7 @@ * The inner precedence rests on two other things: ADR-0005 design principle 3 * stores the ENTIRE item document per overlay row (so a layering has nothing * to layer), and the field-level patch model that would have given "layering" - * any meaning was retired and deleted whole under ADR-0049 (#13185, PR #13186, + * any meaning was retired and deleted whole under ADR-0049 (ADR-0005 principle 3's correction, commit 9e0ba21a1, * maintainer ruling 2026-08-29), with ADR-0126 §6 ruling out the phase it was * held for; and `organizationIdForMetaRead`'s own docblock quotes this very * expression as the intended shape while defining #9454. ADR-0029 D9 reaches @@ -374,7 +374,7 @@ describe('§4 an already-gating caller receives the same scope it did before', ( // // ⛔ This is why the gate sits AFTER the fold. `declaresOrgOverride` // tolerates the MANIFEST plurals and not the URL-only ones - // (`translations` / `email_templates` have no manifest key) — #10340 + // (`translations` / `email_templates` have no manifest key) — commit 26f3588fb // measured what that costs when a raw segment reaches the predicate. for (const spelling of ALL_SPELLINGS) { const doorGate = organizationIdForMetaRead(canonicalMetaUrlType(spelling), ORG); diff --git a/packages/metadata-protocol/src/get-meta-items-org-read-gate.test.ts b/packages/metadata-protocol/src/get-meta-items-org-read-gate.test.ts index 6dad6434660..5304f2d713a 100644 --- a/packages/metadata-protocol/src/get-meta-items-org-read-gate.test.ts +++ b/packages/metadata-protocol/src/get-meta-items-org-read-gate.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14683] `getMetaItems` applies the registry read gate ITSELF, so a sweep + * [commit 96326040f] `getMetaItems` applies the registry read gate ITSELF, so a sweep * that reads MORE THAN ONE type per request is scoped per type instead of per * request. * diff --git a/packages/metadata-protocol/src/meta-overlay-cache.test.ts b/packages/metadata-protocol/src/meta-overlay-cache.test.ts index ecedde3abb5..dd55086807d 100644 --- a/packages/metadata-protocol/src/meta-overlay-cache.test.ts +++ b/packages/metadata-protocol/src/meta-overlay-cache.test.ts @@ -578,7 +578,7 @@ describe('[#11967] §7 distinct reads never share an entry', () => { expect((scoped.items as any[]).map((i) => i.name)).toEqual(['beta']); }); - // ⚠️ [#14683] `view`, NOT `object`, and the type is LOAD-BEARING here in a + // ⚠️ [commit 96326040f] `view`, NOT `object`, and the type is LOAD-BEARING here in a // way it is not in this section's three siblings. `getMetaItems` now // resolves its own read scope through `organizationIdForMetaRead`, so a // type the registry declares NON-overridable has exactly one partition to diff --git a/packages/metadata-protocol/src/migrations/live-mysql-database.isolation.test.ts b/packages/metadata-protocol/src/migrations/live-mysql-database.isolation.test.ts index 77b4bd333e8..47978939593 100644 --- a/packages/metadata-protocol/src/migrations/live-mysql-database.isolation.test.ts +++ b/packages/metadata-protocol/src/migrations/live-mysql-database.isolation.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #10382 — this package's live-MySQL suites must not be able to share one + * Commit ee09d2119 — this package's live-MySQL suites must not be able to share one * database. * * ## Why this suite is structural, and what it is a control FOR diff --git a/packages/metadata-protocol/src/migrations/live-mysql-database.testkit.ts b/packages/metadata-protocol/src/migrations/live-mysql-database.testkit.ts index 177767e9635..859446d42fa 100644 --- a/packages/metadata-protocol/src/migrations/live-mysql-database.testkit.ts +++ b/packages/metadata-protocol/src/migrations/live-mysql-database.testkit.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #10382 — the per-file live MySQL database for this package's live suites. + * Commit ee09d2119 — the per-file live MySQL database for this package's live suites. * * ## What was actually wrong, which is not what the card said * diff --git a/packages/metadata-protocol/src/migrations/partial-index-probe.ts b/packages/metadata-protocol/src/migrations/partial-index-probe.ts index 61b87179719..3f917454647 100644 --- a/packages/metadata-protocol/src/migrations/partial-index-probe.ts +++ b/packages/metadata-protocol/src/migrations/partial-index-probe.ts @@ -41,7 +41,7 @@ * message that discloses neither the statement nor the diagnostic — and carries * the dialect error whole under a non-enumerable `cause`. Read bare, `detail` * became *"the database refused to run a raw statement"* for every caller that - * stores it. `operatorFacingErrorText` (`@objectstack/types`, #16657) reads the + * stores it. `operatorFacingErrorText` (`@objectstack/types`, commit 5a95b0e93) reads the * dialect's own words back out of that chain, so a stored record still names * `no such column: foo`. The envelope itself is left exactly as the driver * declared it: this is a READ of the cause, never a widening of the disclosure. @@ -392,7 +392,7 @@ export async function probeThenReplaceIndex( } catch (err: unknown) { // `detail` is the OPERATOR-facing text: the dialect's own prose, read // out of the `cause` the raw seam attaches when it declares its fault - // (#16019/#16657 — see the module header). Callers STORE it, and a + // (#16019/commit 5a95b0e93 — see the module header). Callers STORE it, and a // stored record is the only copy its reader ever gets. // The VERDICT is taken from the error object itself, so a conflict // reported on `code` / `errno` / `cause` with unhelpful prose is still diff --git a/packages/metadata-protocol/src/migrations/raw-exec-operator-detail-16657.test.ts b/packages/metadata-protocol/src/migrations/raw-exec-operator-detail-16657.test.ts index 84375f40071..c421df2b0cb 100644 --- a/packages/metadata-protocol/src/migrations/raw-exec-operator-detail-16657.test.ts +++ b/packages/metadata-protocol/src/migrations/raw-exec-operator-detail-16657.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#16657] The operator records this package stores name the DIALECT, not the + * [commit 5a95b0e93] The operator records this package stores name the DIALECT, not the * driver's composed refusal. * * ## The regression @@ -31,7 +31,7 @@ * * ⚠️ That formula is now the WHOLE record at every site this change touched — * all nine in this package, fourteen across the repository. It was eight of - * those nine until #17167: `seed-tenancy-backfill`'s ORGANIZATION probe spelled + * those nine until commit dc709b2cf: `seed-tenancy-backfill`'s ORGANIZATION probe spelled * `operatorFacingErrorText(e) || 'unknown error'` — the file's last fallback — * so where the channel was EMPTY that record read `'unknown error'` and never * `''`. Measured at that probe before the removal: a thrown `''`, a thrown @@ -44,7 +44,7 @@ * "the probe did not fail", so deleting the placeholder and putting NOTHING in * its place routes a thrown `''` down the benign `no-organization-yet` path * instead of the ambiguous one (measured by ablation, both before and after - * #17167) — the "unknown read as zero" confusion #9261 exists to prevent. The + * commit dc709b2cf) — the "unknown read as zero" confusion #9261 exists to prevent. The * fact now travels in the TYPE (`string | undefined`), so the status arm is * pinned beside the record arm in the empty-channel case below: a re-added * placeholder and a lost discrimination each redden one of them. @@ -233,7 +233,7 @@ describe('[#16657] seed-tenancy-backfill — the stored operator record', () => * injectable refusal so a single run can be pointed at one seam at a time. * * `thrown` defaults to the declared raw-statement fault every case below - * asserts against; the empty-channel cases (#17167) pass their own value, + * asserts against; the empty-channel cases (commit dc709b2cf) pass their own value, * which is why it is a parameter rather than a second fixture. */ function seamExec(refuse: (sql: string) => boolean, thrown: unknown = rawStatementFault()) { @@ -383,7 +383,7 @@ describe('[#16657] seed-tenancy-backfill — the stored operator record', () => it('an UNDECLARED refusal reads its own message channel at every site', async () => { // No site here carries a fallback any more — the ORGANIZATION probe's - // `|| 'unknown error'` was the last one and #17167 removed it, which + // `|| 'unknown error'` was the last one and commit dc709b2cf removed it, which // the empty-channel case below pins. This pin drives the duplicates // warning with a NON-EMPTY message, the shape for which the channel is // the whole answer at every site. diff --git a/packages/metadata-protocol/src/migrations/read-probe.ts b/packages/metadata-protocol/src/migrations/read-probe.ts index fd66ad50a43..f14dbff5eff 100644 --- a/packages/metadata-protocol/src/migrations/read-probe.ts +++ b/packages/metadata-protocol/src/migrations/read-probe.ts @@ -45,7 +45,7 @@ * than an oversight. Quietening a refusal requires CLASSIFYING it, this repo has * exactly one predicate for that (`isMissingTableError`, `@objectstack/types`), * and it needs `readObject` — the name of the thing the caller was reading — - * both to avoid the #13324 fail-open and because + * both to avoid the fail-open commit 4cda78c9b closed and because * `driver-error-classification.callers.test.ts` fails any in-repo call that * omits it. The raw path has no such name: `execute()` takes a string, and * `rawStatementFaultError` declares no targeted table (pinned by @@ -111,7 +111,7 @@ export type ReadProbeExec = (sql: string) => Promise; * array (better-sqlite3 through knex), `{ rows }` (pg), and the `[rows, fields]` * tuple (mysql2). An empty result set in any of those spellings is still a * result set, and still `true` — that is what keeps a healthy install's - * `no-split` intact, and it is the half of #10789 that stopped it being a + * `no-split` intact, and it is the half of commit 38bc74ed1 that stopped it being a * rename. * * This cannot lose a split that {@link normalizeRows} would have found: every @@ -255,7 +255,7 @@ export type TablePresenceVerdict = | 'absent' /** * The seam accepted the statement and returned no result set at all — a - * memory engine's no-op `execute` (#10789). Not a failure and not an answer; + * memory engine's no-op `execute` (commit 38bc74ed1). Not a failure and not an answer; * each caller maps it the way its own history already ruled. */ | 'no-answer' @@ -274,7 +274,7 @@ export interface TablePresenceProbe { /** * The table whose presence is asked. Also the `readObject` the fallback arm's * classification compares the dialect's phrase against, so a refusal naming - * some OTHER relation is ⛔ not read as this table's absence (#13324). + * some OTHER relation is ⛔ not read as this table's absence (commit 4cda78c9b). */ table: string; /** The knex client name, when the caller resolved one. */ diff --git a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.live-mysql.test.ts b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.live-mysql.test.ts index 5d9a7aeface..e3b335cbfec 100644 --- a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.live-mysql.test.ts +++ b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.live-mysql.test.ts @@ -36,7 +36,7 @@ * (`_objectstack_sequences`, `sys_organization`) that other live suites also * use. * - * That database is DERIVED FROM THIS FILE's path (#10382) rather than named by + * That database is DERIVED FROM THIS FILE's path (commit ee09d2119) rather than named by * a constant. It used to be the literal `os_metadata_protocol_9381`, which was * distinct from the sibling suite's only because two authors happened to type * two different strings — and `afterAll` below issues `drop database`, so a diff --git a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.live-postgres.test.ts b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.live-postgres.test.ts index bc46cbbd8e3..35469d66d8a 100644 --- a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.live-postgres.test.ts +++ b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.live-postgres.test.ts @@ -61,7 +61,7 @@ * fixed platform names (`_objectstack_sequences`, `sys_organization`) that other * live suites on the same CI server also use. `drop schema … cascade` in * `afterAll` is what makes a SHARED name destructive rather than merely - * contended (#10382), and `scripts/check-live-db-isolation.mjs` refuses any live + * contended (commit ee09d2119), and `scripts/check-live-db-isolation.mjs` refuses any live * suite in the tree whose name reaches that DDL as a literal. * * ⚠️ The name comes from `currentLiveMysqlDatabase()` — the MySQL-named resolver diff --git a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.null-seam.test.ts b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.null-seam.test.ts index 1e0136f6e99..ca42d1ea819 100644 --- a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.null-seam.test.ts +++ b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.null-seam.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #10789 — `backfillSeedTenancy` reported `no-split` over a driver it never + * Commit 38bc74ed1 — `backfillSeedTenancy` reported `no-split` over a driver it never * queried, and its own `absent` branch was unreachable on a no-op seam. * * ## The defect @@ -26,7 +26,7 @@ * three dialect result-set shapes `normalizeRows` flattens — it means "I did not * run your query", and it was mapped onto "your query returned no rows". * - * Same class, same consumer-side shape, as #10677 / PR #10788 landed for + * Same class, same consumer-side shape, as #10677 / commit 3a7ec2d3b landed for * `os migrate duplicates`: judge the seam by whether it returns a RESULT SET, * not by whether `execute` exists. No driver is named by the implementation. * diff --git a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.test.ts b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.test.ts index 843f283b8a4..a77349aece7 100644 --- a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.test.ts +++ b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.test.ts @@ -881,7 +881,7 @@ describe('#12395 zero organizations is a third state, not the ambiguous one', () * * `organizationProbeThrown` names the value the organization probe throws; * omitted, it is a normal driver `Error`. It exists so the EMPTY-channel - * shapes (#17167) can be driven through the same seam — and it is compared + * shapes (commit dc709b2cf) can be driven through the same seam — and it is compared * against `undefined` rather than reached through `??`, because `''` is not * nullish and is exactly the value under test. */ diff --git a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts index 95b2c142371..1d7e8b009aa 100644 --- a/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts +++ b/packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts @@ -190,7 +190,7 @@ export type SeedTenancyBackfillStatus = * No raw-SQL-capable driver at all — the engine exposes neither `execute` nor * `raw`, so no seam was resolved. A test double with no driver is the case. * - * ⚠️ NOT a memory engine, however plausible that reads (#10789). A memory + * ⚠️ NOT a memory engine, however plausible that reads (commit 38bc74ed1). A memory * engine's `execute` is a no-op that RETURNS rather than being absent, so it * resolves a seam and reports {@link 'absent'} — this branch never sees it. */ @@ -198,7 +198,7 @@ export type SeedTenancyBackfillStatus = /** * The counter table could not be read: either there is no * `_objectstack_sequences` (nothing has ever allocated a number), or the seam - * answered nothing at all — a memory engine's no-op `execute` (#10789), and + * answered nothing at all — a memory engine's no-op `execute` (commit 38bc74ed1), and * the case this branch's comment always claimed. `detail` names which. */ | 'absent' @@ -414,7 +414,7 @@ export function resolveSeedTenancyExec(engine: unknown): SeedTenancyExec | undef } /** - * ── The seam that ACCEPTS a query but never ANSWERS one (#10789) ─────────── + * ── The seam that ACCEPTS a query but never ANSWERS one (commit 38bc74ed1) ─────────── * * {@link normalizeRows} flattens the three shapes a raw SELECT comes back as. * A seam can hand back a FOURTH thing, and it means something else entirely: @@ -435,7 +435,7 @@ export function resolveSeedTenancyExec(engine: unknown): SeedTenancyExec | undef * the only thing that distinguishes them: a driver that answers returns a RESULT * SET. Nothing here names a driver, so any host with the same no-op shape is * covered without an allowlist to maintain — the consumer-side shape #10677 / - * PR #10788 landed for `os migrate duplicates`, applied to this module's own + * commit 3a7ec2d3b landed for `os migrate duplicates`, applied to this module's own * probes. */ @@ -961,7 +961,7 @@ function toNumber(value: unknown): number { // ruled destination, is not: it resolves there with no engine bound, so // `set()` answers "resolved" while nothing reaches the database — a receipt // that reports success and persists nothing is the very defect this card -// exists to remove. Measured; recorded separately as #10159.) +// exists to remove. Measured; recorded separately, and refused since commit 1ec36b730.) // - its API surface is read-only (`apiMethods: ['get', 'list']`), so the // receipt cannot be edited back through the shipped routes; // - its row contract lives in `@objectstack/spec/system`, which this package @@ -1228,7 +1228,7 @@ export async function backfillSeedTenancy( // statement above is kept and is still what runs on a dialect // `read-probe.ts` has no catalog arm for. // - // FOUR verdicts, and the third and fourth are the two #10789 named. A seam + // FOUR verdicts, and the third and fourth are the two commit 38bc74ed1 named. A seam // that accepts the statement and never runs it (a memory engine's no-op // `execute`) answers nothing — still `absent`, still separated by // `detail`, exactly as ruled. ⛔ But `'unreadable'` is NOT folded in with @@ -1317,7 +1317,7 @@ export async function backfillSeedTenancy( // `resolveSystemWriteOrganization`'s probe (#9261). Unknown is not zero. // // "Separately" is `undefined` versus a string, and the distinction is - // load-bearing (#17167): the failure FACT must not ride on the failure + // load-bearing (commit dc709b2cf): the failure FACT must not ride on the failure // TEXT, because the operator channel is allowed to be empty — a thrown // `''`, a thrown `[]`, an `Error` whose `name` and `message` are both // empty. A site that reads "the text is empty" as "there was no failure" @@ -1336,7 +1336,7 @@ export async function backfillSeedTenancy( .map((r) => (r.id == null ? '' : String(r.id))) .filter((id) => id.length > 0); } catch (e) { - // [#16657, #17167] The record is the helper's return AS IS, `''` included — + // [commit 5a95b0e93, commit dc709b2cf] The record is the helper's return AS IS, `''` included — // the rule the other four `operatorFacingErrorText` sites in this file // follow. ⛔ No placeholder on top of it: a record reading `'unknown error'` // where the backend said nothing is this migration writing operator-facing @@ -1393,7 +1393,7 @@ export async function backfillSeedTenancy( (organizationProbeError === undefined ? '' : // The parenthetical is dropped, never filled in, when the backend's - // operator channel was empty (#17167): the FAILURE is the load- + // operator channel was empty (commit dc709b2cf): the FAILURE is the load- // bearing half of this note and it is stated either way, while the // text is the backend's own or is not there at all. `NOTE: the ${ORGANIZATION_TABLE} probe FAILED` + @@ -1404,7 +1404,7 @@ export async function backfillSeedTenancy( // `organizationProbeError` is `undefined` — and so serializes AWAY — when // the probe answered; a probe that failed carries its text, `''` and all. // Absent-versus-empty is what tells the two apart in the stored record - // now that no placeholder does it (#17167). + // now that no placeholder does it (commit dc709b2cf). { splits, organizationCount: organizationIds.length, organizationProbeError }, ); return { status: 'skipped-ambiguous-organization', splits, collisions: [], objectsStamped: 0 }; diff --git a/packages/metadata-protocol/src/migrations/sys-setting-identity-index.live-mysql.test.ts b/packages/metadata-protocol/src/migrations/sys-setting-identity-index.live-mysql.test.ts index 72ee0dea58e..fc224770286 100644 --- a/packages/metadata-protocol/src/migrations/sys-setting-identity-index.live-mysql.test.ts +++ b/packages/metadata-protocol/src/migrations/sys-setting-identity-index.live-mysql.test.ts @@ -64,7 +64,7 @@ * Everything runs in its OWN database, created on the spot, because * `sys_setting` is a fixed platform table name that other live suites also use. * - * That database is DERIVED FROM THIS FILE's path (#10382) rather than named by + * That database is DERIVED FROM THIS FILE's path (commit ee09d2119) rather than named by * a constant. It used to be the literal `os_metadata_protocol_9434`, which was * distinct from the sibling suite's only because two authors happened to type * two different strings — and `afterAll` below issues `drop database`, so a diff --git a/packages/metadata-protocol/src/protocol-14078-audit-invalid-date-total-arm.test.ts b/packages/metadata-protocol/src/protocol-14078-audit-invalid-date-total-arm.test.ts index f6c3bda8655..203b2f787b6 100644 --- a/packages/metadata-protocol/src/protocol-14078-audit-invalid-date-total-arm.test.ts +++ b/packages/metadata-protocol/src/protocol-14078-audit-invalid-date-total-arm.test.ts @@ -16,7 +16,7 @@ * * ## Reachability is measured, not argued * - * PR #14409 (landed `3ecb7dc1a`): mysql2 3.23.1 returns a module constant + * Commit `3ecb7dc1a`: mysql2 3.23.1 returns a module constant * literally named `INVALID_DATE` for a zero `DATETIME`; postgres-date 1.0.7 * builds `new Date(NaN)` for every year in 275760..294276, a range Postgres * itself stores. The maintainer ruled option B on 2026-09-02, on all five arms diff --git a/packages/metadata-protocol/src/protocol-publish-drafts-package-scope.test.ts b/packages/metadata-protocol/src/protocol-publish-drafts-package-scope.test.ts index 368a5a4f76d..df942081fa0 100644 --- a/packages/metadata-protocol/src/protocol-publish-drafts-package-scope.test.ts +++ b/packages/metadata-protocol/src/protocol-publish-drafts-package-scope.test.ts @@ -306,9 +306,9 @@ describe('publishPackageDrafts — two packages holding drafts for one (type, na }); /** - * [#10350] The PER-ITEM door's half of the same key. + * [commit 490879ad0] The PER-ITEM door's half of the same key. * - * `POST /meta/:type/:name/publish?package=PKG_ID` (#10063) made + * `POST /meta/:type/:name/publish?package=PKG_ID` (commit 9e04c3e35) made * `publishMetaItem` a package-naming caller too, so the narrowing the cases * above pin for `publishPackageDrafts` now has a SECOND entry point. The * runtime path already carried the value — `publishMetaItem` forwards its @@ -396,8 +396,8 @@ describe('publishMetaItem — the per-item door names a package too (#10350)', ( }); /** - * [#11003] The ORG-SCOPE probes' half of the same ADR-0048 key — maintainer - * ruling 2026-08-22, option A (recorded on the issue): the scope probes ask + * [commit c74aefe63] The ORG-SCOPE probes' half of the same ADR-0048 key — maintainer + * ruling 2026-08-22, option A (recorded in that commit's message): the scope probes ask * the promote's question, i.e. `resolveDraftOrgScopeForPublish` threads the * stated `packageId` into BOTH of its `sys_metadata` probes. * @@ -407,7 +407,7 @@ describe('publishMetaItem — the per-item door names a package too (#10350)', ( * scopes, a package-stating publish resolved the wrong scope: probe 1 was * package-agnostic, matched the OTHER package's row in the caller's org, * named that org as the scope — and the promote (whose `whereFor` IS - * package-exact since #8907/#10350) then found nothing there and answered + * package-exact since #8907/commit 490879ad0) then found nothing there and answered * `404 [no_draft]` over a draft sitting env-wide, publishable, and named by * the caller. * @@ -596,7 +596,7 @@ describe('publishMetaItem — the scope probes ask the promote\'s question (#110 // No `packageId` key at all: the probes stay package-agnostic, the // promote matches any package, and the ADR-0005 precedence picks the // caller's own org row — app.other's, whatever package it belongs to. - // This is the same absent-key contract the #10350 case above pins + // This is the same absent-key contract the case above (commit 490879ad0) pins // env-wide, exercised HERE because these probes only run for an // org-scoped caller (`requestOrgId === null` returns early). const res = await protocol.publishMetaItem({ diff --git a/packages/metadata-protocol/src/protocol.adr0005-org-override-rollback.test.ts b/packages/metadata-protocol/src/protocol.adr0005-org-override-rollback.test.ts index 683060f7947..db9d0cdefce 100644 --- a/packages/metadata-protocol/src/protocol.adr0005-org-override-rollback.test.ts +++ b/packages/metadata-protocol/src/protocol.adr0005-org-override-rollback.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #6483 — the nine ADR-0005 whitelist divergences, rolled back. The WRITE + * Commit ee58392e1 — the nine ADR-0005 whitelist divergences, rolled back. The WRITE * PATH now says what the ADR's amendment table has said since 2026-05-22. * * `DEFAULT_METADATA_TYPE_REGISTRY` carried `allowOrgOverride: true` on nine @@ -24,7 +24,7 @@ * (`getMetadataTypeSchema`), so (b) — the written rationale — is the * discriminating clause, and none of the three carries one. * - * The 2026-08-08 maintainer ruling on #6483 settled all nine: `permission` / + * The 2026-08-08 maintainer ruling recorded in commit ee58392e1 settled all nine: `permission` / * `tool` / `skill` roll back unconditionally; the other six roll back unless * live org-scoped overlay rows AND a complete admission pair exist. Measured * in-repo: zero committed `sys_metadata` overlay rows for any of the nine diff --git a/packages/metadata-protocol/src/protocol.batch-row-http-status.test.ts b/packages/metadata-protocol/src/protocol.batch-row-http-status.test.ts index b5d8284899f..9229e670004 100644 --- a/packages/metadata-protocol/src/protocol.batch-row-http-status.test.ts +++ b/packages/metadata-protocol/src/protocol.batch-row-http-status.test.ts @@ -454,7 +454,7 @@ describe('[#8570] section 6 — anti-vacuity: the doubles are the shapes they cl }); }); -// ─── [#14723] The row speaks the WIRE spelling of a unique-constraint refusal ─ +// ─── [commit 65846bc46] The row speaks the WIRE spelling of a unique-constraint refusal ─ /** * MEASURED — `@objectstack/objectql`'s `DuplicateRecordError` as it reaches diff --git a/packages/metadata-protocol/src/protocol.bulk-record-not-found.test.ts b/packages/metadata-protocol/src/protocol.bulk-record-not-found.test.ts index 99e546951f1..0bcc2a6be62 100644 --- a/packages/metadata-protocol/src/protocol.bulk-record-not-found.test.ts +++ b/packages/metadata-protocol/src/protocol.bulk-record-not-found.test.ts @@ -427,7 +427,7 @@ describe('[#5088] batchData delete — the driver`s return decides, as in delete describe('[#19433] batchData delete — a row that MATCHED and was deliberately NOT removed', () => { /** * The THIRD by-id delete door, and the last one still pushing the literal. - * The single-record face (#19306) and `deleteManyData` (#19412) both learned + * The single-record face (commit f9e16d856) and `deleteManyData` (#19412) both learned * to read the engine's answer; this branch — "the OTHER by-id bulk delete, * ten lines from it", as its own comment calls it — kept `success: true` for * every result that was not the driver contract's `false`. diff --git a/packages/metadata-protocol/src/protocol.code-only-types.test.ts b/packages/metadata-protocol/src/protocol.code-only-types.test.ts index 94d72803c8f..0863c4f0c15 100644 --- a/packages/metadata-protocol/src/protocol.code-only-types.test.ts +++ b/packages/metadata-protocol/src/protocol.code-only-types.test.ts @@ -412,7 +412,7 @@ describe('code-only metadata types are refused on every kernel (#5086)', () => { // so the probe body must be spec-valid — the door under test // (authorization) is unchanged, but a malformed body would 422 // before proving anything about it. (`theme` was the specimen until - // #10485 retired that kind out of the spelling contract.) + // commit 35ad101bc retired that kind out of the spelling contract.) const result = await protocol.saveMetaItem({ type: 'webhook', name: 'rc3_probe_webhook', @@ -511,7 +511,7 @@ describe('code-only metadata types are refused on every kernel (#5086)', () => { { type: 'webhook', // no static registry entry (plugin-registered) // [#6245] spec-valid body — webhook resolves a schema. - // (`theme` was the specimen until #10485 retired that kind.) + // (`theme` was the specimen until commit 35ad101bc retired that kind.) item: { name: 'rc3_receipt_view', label: 'Receipt', object: 'task', triggers: ['create'], url: 'https://example.com/hook' }, }, ]; diff --git a/packages/metadata-protocol/src/protocol.delete-receipt-wording.test.ts b/packages/metadata-protocol/src/protocol.delete-receipt-wording.test.ts index 4c922f0aed5..83143a1766f 100644 --- a/packages/metadata-protocol/src/protocol.delete-receipt-wording.test.ts +++ b/packages/metadata-protocol/src/protocol.delete-receipt-wording.test.ts @@ -165,9 +165,9 @@ describe('#5927 — a delete receipt names what actually happened', () => { expect(entry('object')).toMatchObject({ allowRuntimeCreate: true, allowOrgOverride: false }); expect(entry('view')).toMatchObject({ allowRuntimeCreate: true, allowOrgOverride: true }); expect(entry('job')).toMatchObject({ allowRuntimeCreate: false, allowOrgOverride: false }); - // #6283 → #6483 — the overlay-less-yet-overridable specimen the last + // #6283 → commit ee58392e1 — the overlay-less-yet-overridable specimen the last // case in this file needs. It was `flow` until #6283 rolled that - // flag back to `false` (ADR-0005:57), then `action` until #6483 + // flag back to `false` (ADR-0005:57), then `action` until commit ee58392e1 // rolled back the remaining nine unratified `true` flags. The // population is now EMPTY by ruling and pinned empty; the last case // reaches the pairing through `OS_METADATA_WRITABLE` — the one @@ -235,7 +235,7 @@ describe('#5927 — a delete receipt names what actually happened', () => { // // The specimen was `flow` until #6283 rolled that type's // `allowOrgOverride` back to `false` (ADR-0005:57), then bare - // `action` until #6483 rolled back the remaining nine unratified + // `action` until commit ee58392e1 rolled back the remaining nine unratified // flags — the premise pin above now holds the population EMPTY. The // pairing stays reachable through `OS_METADATA_WRITABLE` (ADR-0005's // documented operator escape hatch, consulted by both write gates), diff --git a/packages/metadata-protocol/src/protocol.destructive-409-face-inventory.test.ts b/packages/metadata-protocol/src/protocol.destructive-409-face-inventory.test.ts index 0eae0342dd1..a86564b0a82 100644 --- a/packages/metadata-protocol/src/protocol.destructive-409-face-inventory.test.ts +++ b/packages/metadata-protocol/src/protocol.destructive-409-face-inventory.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #10886 — the face inventory for `saveMetaItem`'s Phase 3a-destructive + * Commit 809e61221 — the face inventory for `saveMetaItem`'s Phase 3a-destructive * `409 DESTRUCTIVE_CHANGE`, and the pins that hold its conclusion. * * ## The duplication that raised the card @@ -33,7 +33,7 @@ * `object`, an item already exists under the target name, and the diff is * non-empty. That predicate is what eliminates four of the seven. * - * ⚠️ [#11014] That type list read `object` or `field` while this inventory was + * ⚠️ [commit 2d8b92ff1] That type list read `object` or `field` while this inventory was * being built, and the `field` half could not produce a finding — so the * enumeration above had to chase a `field` face population that does not * exist. The limb is now trimmed; the reachable type set is `object` alone and @@ -77,7 +77,7 @@ * - `PublishPackageDraftsResponseSchema`'s `failed[]` * (`packages/spec/src/api/protocol.zod.ts`) DOES declare * `issues: z.array(RuntimeAuthoringIssueSchema).optional()`. That DECLARED - * channel is what #10524 / #10895 trimmed the message against. + * channel is what #10524 / commit a79bd3561 trimmed the message against. * * ⇒ The verdict is unchanged and the axis is sharper: #10524's order — * declare a structured channel, and only then trim — is still unsatisfied @@ -114,17 +114,17 @@ * the ablation therefore needs no rebuild, and its RED result is what rules * out the stale-artifact false green. * - * ## [#11015] The same inventory, read one column further left + * ## [commit 82cb6e849] The same inventory, read one column further left * * The `force` column above is not decoration: it says which faces can lift - * this refusal. When #11015 was written only ROW 1 could. Rows 2, 3 and 6 all + * this refusal. When commit 82cb6e849 was written only ROW 1 could. Rows 2, 3 and 6 all * reached the gate with no way to set `force` — rows 2 and 3 because their * routes never threaded the parameter, row 6 because `duplicatePackage` has no * `force` field at all — yet every one of them was handed the sentence * `re-submit with ?force=true to proceed.` A caller who did what it said got * the identical refusal back. * - * #11015 repaired the clause on ROW 6, where a genuinely different remedy + * Commit 82cb6e849 repaired the clause on ROW 6, where a genuinely different remedy * exists to prescribe (a free target namespace, or reconciling the collision). * Rows 2 and 3 were left as measured and filed as #11095: the honest repair for * a `PUT` that cannot acknowledge a risk may be to thread `force` on those @@ -288,13 +288,13 @@ async function destructiveRefusal(writeFace?: string): Promise { } /** - * The remedy sentence that must survive ANY future trim (#10886 non-effect), + * The remedy sentence that must survive ANY future trim (the non-effect commit 809e61221 measured), * as the ordinary REST `PUT` door renders it. `?force=true` is a real query * parameter THERE — the route reads it and threads it into the request. */ const PUT_REMEDY = 're-submit with ?force=true to proceed.'; /** - * [#11015] …and as the DUPLICATE door renders it, which is a different + * [commit 82cb6e849] …and as the DUPLICATE door renders it, which is a different * sentence because `?force=true` is not a thing a caller can set on that face. * See section 4 — the remedy stays, the mechanism it names becomes one that * exists. @@ -344,7 +344,7 @@ describe('[#10886] the 409 renders its findings into the message AND attaches th // whole point, it is not one of the `issues`, and nothing else on any // face carries it. // No `writeFace` on this request — the ordinary REST/Studio save, the - // one door where `?force=true` is real. [#11015] made this clause + // one door where `?force=true` is real. [commit 82cb6e849] made this clause // face-aware; this default is byte-identical to what it always said. expect(err.message).toContain(PUT_REMEDY); const wire = JSON.stringify(err.issues); @@ -352,7 +352,7 @@ describe('[#10886] the 409 renders its findings into the message AND attaches th }); /** - * [#10888] The two switches that read `writeFace` answer DIFFERENT + * [commit d806081dd] The two switches that read `writeFace` answer DIFFERENT * questions, and this pin holds them independent. * * That card made the sibling `422 INVALID_METADATA` findings clause @@ -375,7 +375,7 @@ describe('[#10886] the 409 renders its findings into the message AND attaches th expect(err.message).toContain(PUT_REMEDY); expect(err.message).not.toContain(DUPLICATE_REMEDY_HEAD); // …and the findings prose is still restated here, because this gate's - // sole-carrier verdict (#10886) is untouched by #10888: the 422's face + // sole-carrier verdict (commit 809e61221) is untouched by commit d806081dd: the 422's face // split applies to the 422's clause only. expect(err.message).toContain(FINDING_PROSE); }); @@ -456,12 +456,12 @@ describe('[#10886] [GUARD] `duplicatePackage`’s `failed[].error` is the SOLE c sourcePackageId: PKG, targetPackageId: TARGET_PKG, }); - // ⚠️ [#11015] This assertion USED to read `toContain(REMEDY)` with + // ⚠️ [commit 82cb6e849] This assertion USED to read `toContain(REMEDY)` with // REMEDY = the `?force=true` sentence, and it passed — because the // producer rendered that sentence on every face. It was pinning the // defect: this door accepts no `force`, so the prescription it quoted // was unactionable. Replaced rather than re-spelled, because what it - // asserted stopped being true of a correct producer. What #10886 put + // asserted stopped being true of a correct producer. What commit 809e61221 put // it here to protect is unchanged and still asserted: SOME remedy // reaches the caller through this string and through nothing else. expect(r.failed[0].error).toContain(DUPLICATE_REMEDY_HEAD); @@ -474,7 +474,7 @@ describe('[#10886] [GUARD] `duplicatePackage`’s `failed[].error` is the SOLE c }); // ═══════════════════════════════════════════════════════════════════════════ -// 4. [#11015] [GUARD] The remedy names a mechanism THIS face actually has +// 4. [commit 82cb6e849] [GUARD] The remedy names a mechanism THIS face actually has // ═══════════════════════════════════════════════════════════════════════════ describe('[#11015] [GUARD] the destructive remedy clause is face-aware', () => { @@ -521,7 +521,7 @@ describe('[#11015] [GUARD] the destructive remedy clause is face-aware', () => { it('[#10886 non-effect] the per-field findings prose is still there, untrimmed', async () => { const r = await duplicateFailure(); - // ⛔ This card repaired the remedy clause ONLY. #10886's verdict — the + // ⛔ This card repaired the remedy clause ONLY. Commit 809e61221's verdict — the // findings prose stays, because `failed[].error` is its sole carrier on // this face — is untouched, and this is the assertion that says so. expect(r.failed[0].error).toContain(FINDING_PROSE); @@ -612,8 +612,8 @@ describe('[#11095] [GUARD] the `meta-dispatch` face prescribes a remedy that doo it('[#10886 non-effect] the per-field findings prose is still there, untrimmed', async () => { const err = await destructiveRefusal('meta-dispatch'); - // ⛔ #10886's sole-carrier verdict is untouched by this card, exactly as - // it was untouched by #11015: only the remedy clause is face-aware, and + // ⛔ Commit 809e61221's sole-carrier verdict is untouched by this card, exactly as + // it was untouched by commit 82cb6e849: only the remedy clause is face-aware, and // the findings the refusal renders stay whole on every face. expect(err.message).toContain(FINDING_PROSE); expect(err.message).toContain('would drop or transform existing data'); @@ -651,7 +651,7 @@ describe('[#11095] [GUARD] the `meta-dispatch` face prescribes a remedy that doo * * The 422's polarity makes that failure SILENT in the dangerous direction: * silence renders the full prose, so a `'meta-dispatch'` that fell to the - * default would re-introduce #10888's duplication on one door only, with + * default would re-introduce the duplication commit d806081dd removed on one door only, with * every 409 assertion above still green. This case is what says otherwise. */ it('⛔ [COUPLING] the new face changes the 409 clause and NOTHING about the 422', async () => { diff --git a/packages/metadata-protocol/src/protocol.destructive-gate-reachable-types.test.ts b/packages/metadata-protocol/src/protocol.destructive-gate-reachable-types.test.ts index 9564f14dc37..fbe263a4782 100644 --- a/packages/metadata-protocol/src/protocol.destructive-gate-reachable-types.test.ts +++ b/packages/metadata-protocol/src/protocol.destructive-gate-reachable-types.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #11014 — the Phase 3a-destructive gate's REACHABLE TYPE SET is `object` + * Commit 2d8b92ff1 — the Phase 3a-destructive gate's REACHABLE TYPE SET is `object` * alone, and this file is the measurement that says so. * * ## Why a type set needs a pin at all @@ -10,7 +10,7 @@ * open on `(singularType === 'object' || singularType === 'field')`. The * `field` limb could not produce a finding, so the condition made the gate's * coverage READ wider than it is — and that is not a cosmetic problem: - * #10886's face inventory had to establish, per face, exactly which types can + * Commit 809e61221's face inventory had to establish, per face, exactly which types can * reach this gate, and the `field` spelling is the one thing that made the * answer look bigger. An inventory that trusted the condition chased a face * population that does not exist. @@ -87,7 +87,7 @@ import { ObjectStackProtocolImplementation } from './protocol.js'; import { resetEnvWritableMetadataTypes } from './sys-metadata-repository.js'; // --------------------------------------------------------------------------- -// Harness — a `sys_metadata`-backed kernel, the shape the #10886 face +// Harness — a `sys_metadata`-backed kernel, the shape commit 809e61221's face // inventory uses. `update` is present because §2's hatch-open cases really do // PERSIST (that is what "the write got past reason 2" means), and it routes // through the producer's predicate for the reason above. `delete` is diff --git a/packages/metadata-protocol/src/protocol.diff-credential-redaction.test.ts b/packages/metadata-protocol/src/protocol.diff-credential-redaction.test.ts index 2fe850c28b5..02e88925900 100644 --- a/packages/metadata-protocol/src/protocol.diff-credential-redaction.test.ts +++ b/packages/metadata-protocol/src/protocol.diff-credential-redaction.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #8671 — `GET /api/v1/meta/:type/:name/diff` must not serve stored credential + * Commit 75e66fc8e — `GET /api/v1/meta/:type/:name/diff` must not serve stored credential * VALUES, while still reporting that the credential CHANGED. * * The endpoint is routed and live (`rest-server.ts` answers `res.json(result)` diff --git a/packages/metadata-protocol/src/protocol.diff-dead-history-read.test.ts b/packages/metadata-protocol/src/protocol.diff-dead-history-read.test.ts index 44c70ca3b56..c1efb8ae3a1 100644 --- a/packages/metadata-protocol/src/protocol.diff-dead-history-read.test.ts +++ b/packages/metadata-protocol/src/protocol.diff-dead-history-read.test.ts @@ -625,7 +625,7 @@ describe('#20451 — the default from side is the nearest earlier row whose body }); it('the walk compares RAW bodies: a credential-only rotation stops it, and the served values stay redacted', async () => { - // The #8671 ruling (diff raw, redact what is emitted) applies to the + // The ruling commit 75e66fc8e implements (diff raw, redact what is emitted) applies to the // walk's comparison too. Compared redacted, the two bodies below are // equal and the walk would pass the rotation by. const { engine, tables } = makeStubEngine(); diff --git a/packages/metadata-protocol/src/protocol.invalid-metadata-422-face-inventory.test.ts b/packages/metadata-protocol/src/protocol.invalid-metadata-422-face-inventory.test.ts index 3bac7b55996..0a98541bcbb 100644 --- a/packages/metadata-protocol/src/protocol.invalid-metadata-422-face-inventory.test.ts +++ b/packages/metadata-protocol/src/protocol.invalid-metadata-422-face-inventory.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #10888 — the face inventory for `saveMetaItem`'s spec-validation + * Commit d806081dd — the face inventory for `saveMetaItem`'s spec-validation * `422 INVALID_METADATA`, and the pins that hold its conclusion. * * ## The duplication that raised the card @@ -17,10 +17,10 @@ * A blanket trim was tried during #10524 and reverted: some faces put this * sentence on a **200 response body** or in a **log**, where no structured * channel exists and the sentence is the SOLE carrier of the author's - * prescription. #10886 reached the same verdict for the sibling 409. + * prescription. Commit 809e61221 reached the same verdict for the sibling 409. * * The maintainer ruling on #11017 (2026-08-22, option D) resolved it by - * reusing #11015/#11099's per-face rendering rather than by declaring a + * reusing commit 82cb6e849/#11099's per-face rendering rather than by declaring a * response contract for `duplicatePackage`: faces that already carry a * structured `issues[]` drop the prose restatement; the duplicate face keeps * it in full. @@ -290,7 +290,7 @@ describe('[#10888 · GUARD] a face that carries no `issues[]` keeps the whole se const duplicate = await refusal(protocol, 'package-duplicate'); const plain = await refusal(protocol); - // #10886's verdict, unchanged: `failed[].error` is the sole carrier. + // Commit 809e61221's verdict, unchanged: `failed[].error` is the sole carrier. // (The end-to-end pin through `duplicatePackage` itself is P10 in // `protocol.batch-verb-driver-text.test.ts`, still green, untouched.) expect(duplicate.message).toBe(plain.message); diff --git a/packages/metadata-protocol/src/protocol.item-name-grammar.test.ts b/packages/metadata-protocol/src/protocol.item-name-grammar.test.ts index accddc94802..4a473fb71bf 100644 --- a/packages/metadata-protocol/src/protocol.item-name-grammar.test.ts +++ b/packages/metadata-protocol/src/protocol.item-name-grammar.test.ts @@ -1,15 +1,15 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #12194 — the metadata item-name grammar is enforced at the publish door. + * Commit 311433f6b — the metadata item-name grammar is enforced at the publish door. * - * Stage 1 of #12176's maintainer-ruled retirement of compound-name addressing + * Stage 1 of the maintainer-ruled retirement of compound-name addressing * (2026-08-25): item names are lowercase snake_case segments, optionally * dot-qualified (`METADATA_ITEM_NAME_PATTERN`, `@objectstack/spec/shared` — * the same segment source as `ViewItemNameSchema`'s dot-required arity), and * `saveMetaItem` / `publishMetaItem` refuse an off-grammar name loudly. * - * What the #12176 census measured BEFORE this landed — every refusal case in + * What the census measured BEFORE this landed — every refusal case in * this suite was an acceptance then: `''`, `'a//b'`, `'Views/All Leads'` and * `'views/all_leads'` were all accepted and stored as item names, and a slash * in the name BYPASSED the #8421 unrecognised-type refusal entirely @@ -178,7 +178,7 @@ describe('#12194 — the names that must keep working', () => { }); describe('#12194 — the junk shapes the census measured ACCEPTED are now refused', () => { - // Each entry was accepted and stored on the pre-#12194 tree (census P2–P8). + // Each entry was accepted and stored on the tree before commit 311433f6b (census P2–P8). // The refusal asserts the ADR-0112 envelope — `code` AND `status` — never a // bare `.toThrow()`, which an unrelated 422 one layer down would satisfy. const JUNK: Array<[label: string, name: string]> = [ @@ -219,7 +219,7 @@ describe('#12194 — the junk shapes the census measured ACCEPTED are now refuse describe('#12194 — the slash bypass of the unrecognised-type refusal is CLOSED', () => { it('refuses unrecognised type + slash name (the census P10 acceptance)', async () => { - // Pre-#12194: `refuseUnmintableMetaType` opened with + // Before commit 311433f6b: `refuseUnmintableMetaType` opened with // `if (request.name.includes('/')) return;` — so this exact request was // ACCEPTED and stored `type='fieldz' name='a/b'` (census P10, and the // residue #8421's own docblock stated rather than hid). The grammar diff --git a/packages/metadata-protocol/src/protocol.legacy-overlay-delete.test.ts b/packages/metadata-protocol/src/protocol.legacy-overlay-delete.test.ts index 77953af831b..940d62b57bb 100644 --- a/packages/metadata-protocol/src/protocol.legacy-overlay-delete.test.ts +++ b/packages/metadata-protocol/src/protocol.legacy-overlay-delete.test.ts @@ -6,7 +6,7 @@ * * ## The defect * - * #6483 / PR #6608 flipped six types to `allowOrgOverride: false`. That closed + * Commit ee58392e1 flipped six types to `allowOrgOverride: false`. That closed * the WRITE door and deliberately left the READ path alone: `supportsOverlay` * stayed `true`, so an overlay row authored BEFORE the rollback still merges * overlay-wins and still shapes the effective body. Removing it was refused at @@ -266,7 +266,7 @@ describe('#6960 — the registry is the tier boundary, and it is DATA', () => { expect([...ROLLED_BACK_OVERLAYABLE_TYPES]).toEqual([ 'app', 'book', 'dataset', 'page', 'permission', 'position', 'skill', 'tool', ]); - // The six #6483 / PR #6608 named, all present. + // The six commit ee58392e1 named, all present. for (const t of ['permission', 'position', 'page', 'app', 'dataset', 'book']) { expect(ROLLED_BACK_OVERLAYABLE_TYPES).toContain(t); } diff --git a/packages/metadata-protocol/src/protocol.marked-refusal-classification.test.ts b/packages/metadata-protocol/src/protocol.marked-refusal-classification.test.ts index 71bf9aa9570..062fa7ef03c 100644 --- a/packages/metadata-protocol/src/protocol.marked-refusal-classification.test.ts +++ b/packages/metadata-protocol/src/protocol.marked-refusal-classification.test.ts @@ -7,7 +7,7 @@ // The defect, measured on `origin/main` (aef1b7e64) before the fix // --------------------------------------------------------------------------- // A metadata app's sandboxed hook on `sys_metadata` may refuse a read and mark -// its refusal with `userMessage` — the #9934 producer-side opt-in where the +// its refusal with `userMessage` — the producer-side opt-in of commit 79c46da90, where the // field's PRESENCE is the marking (maintainer ruling 2026-08-19, // objectui#5210 option 1). `metadataStoreUnavailableError` built a fresh error // carrying only `code` / `status` / `cause`, and `declaredUserMessage` reads @@ -127,7 +127,7 @@ const STORE_UNAVAILABLE_MESSAGE = // --------------------------------------------------------------------------- /** - * What a sandboxed hook that MARKS its refusal produces. The canonical #9934 + * What a sandboxed hook that MARKS its refusal produces. The canonical (commit 79c46da90) * authoring shape is `const e = new Error(msg); e.userMessage = msg`, and the * QuickJS side-channel carries `code` / `status` / `userMessage` out of the VM * onto `SandboxError`. The `message` here is deliberately the sandbox's own @@ -301,7 +301,7 @@ describe('[#12536 §1] a producer-marked refusal is classified as a refusal, not const caught = await captureThrow(() => p.getMetaItems({ type: 'object' } as any)); // 400 is not chosen here — it is `error-response.ts`'s `declared ?? 400` - // for a sandbox hook refusal that named no status (#9967), reused so the + // for a sandbox hook refusal that named no status (commit 8f266f1cd), reused so the // two doors classify one undeclared refusal identically. expect(caught.status).toBe(400); // ADR-0112 D4: whatever code ships must be in the closed vocabulary. diff --git a/packages/metadata-protocol/src/protocol.meta-types-mint-door-agreement.test.ts b/packages/metadata-protocol/src/protocol.meta-types-mint-door-agreement.test.ts index 2b47d203ae6..b29cacf3b1a 100644 --- a/packages/metadata-protocol/src/protocol.meta-types-mint-door-agreement.test.ts +++ b/packages/metadata-protocol/src/protocol.meta-types-mint-door-agreement.test.ts @@ -42,7 +42,7 @@ * registry entry, IN the static spelling contract, still advertised and * still mintable. This is the discriminating control: without it the change * cannot show its narrowing is narrow; - * 3. **withdrawn** (`policy`, `data`, `package`, `kind` — and, since #10485, + * 3. **withdrawn** (`policy`, `data`, `package`, `kind` — and, since commit 35ad101bc, * `theme`, whose carrier retired out of the spelling contract while legacy * stored rows can still hold the key live) — live `SchemaRegistry` keys, * in NEITHER half of the static contract, advertised `false` and refused. @@ -161,11 +161,11 @@ const SAMPLE: Array<{ // UNREGISTERED_KIND_SCHEMAS, and the "behaves as advertised" case // drives this body through a real write, so a malformed one would // 422 and misread the ADVERTISEMENT door this suite measures. - // (`theme` held this slot until #10485 retired the themes surface.) + // (`theme` held this slot until commit 35ad101bc retired the themes surface.) item: { name: 'probe_webhook', label: 'Probe', object: 'task', triggers: ['create'], url: 'https://example.com/hook' }, }, { - // [#10485] `theme` moved from class 2 to class 3: the carrier retired + // [commit 35ad101bc] `theme` moved from class 2 to class 3: the carrier retired // out of the spelling contract, while a legacy environment's stored // rows can still hold the key in the live set — so it must be // advertised `false` and refused at the mint door, like the four. @@ -250,7 +250,7 @@ describe('#8421 — the read door and the mint door agree, across all three clas // no hand-written spec-valid body here, so they are pinned on the door // that this change actually moved — the advertisement. Breaking any of // them is the one outcome that would make this change worse than the - // defect it closes. (`theme` left the set at #10485.) + // defect it closes. (`theme` left the set at commit 35ad101bc.) const { protocol } = makeProtocol(); const listing = await protocol.getMetaTypes(); for (const kind of [ diff --git a/packages/metadata-protocol/src/protocol.metadata-store-outage.test.ts b/packages/metadata-protocol/src/protocol.metadata-store-outage.test.ts index af3287f206e..eb82983fb4f 100644 --- a/packages/metadata-protocol/src/protocol.metadata-store-outage.test.ts +++ b/packages/metadata-protocol/src/protocol.metadata-store-outage.test.ts @@ -88,7 +88,7 @@ function engineThatCannotBeRead( error: (object: string) => unknown, registryItems: Record = {}, ) { - // [#13324] The object reaches the factory, so a missing-table fault can be + // [commit 4cda78c9b] The object reaches the factory, so a missing-table fault can be // phrased for the table that was actually read. A driver never names one // table while failing a read of another, and `isMissingTableError` now // tells those two apart — a fixed phrase would make this fixture assert @@ -361,7 +361,7 @@ describe('[#5707] the layered read stops painting an outage as "nothing was cust // perfectly readable was reported as "no overlay" because the org read // failed ahead of it. // - // ⚠️ [#14907] `view`, not `object` — and the type is now load-bearing + // ⚠️ [commit e1d4f9e3f] `view`, not `object` — and the type is now load-bearing // rather than incidental. This verb gates its organization through // `organizationIdForMetaRead`, so an `allowOrgOverride: false` type // (`object`, which the rest of this file uses as its generic subject) diff --git a/packages/metadata-protocol/src/protocol.org-scoped-cold-boot-audit.test.ts b/packages/metadata-protocol/src/protocol.org-scoped-cold-boot-audit.test.ts index 8855a901ff6..141c72675a1 100644 --- a/packages/metadata-protocol/src/protocol.org-scoped-cold-boot-audit.test.ts +++ b/packages/metadata-protocol/src/protocol.org-scoped-cold-boot-audit.test.ts @@ -6,7 +6,7 @@ * --------------------------------------------------------------------------- * What survived the upstream ruling, measured against `origin/main` * --------------------------------------------------------------------------- - * #6155 Q1=B → #6283 → PR #6478 rolled `flow`'s `allowOrgOverride` back to + * #6155 Q1=B → #6283 → commit 474f131cf rolled `flow`'s `allowOrgOverride` back to * `false` and proved declared=enforced on the write side: overlaying a * PACKAGED flow per org is now a 403 `NOT_OVERRIDABLE` before persistence. * @@ -177,7 +177,7 @@ describe('#6190 — cold boot names the org-scoped rows it cannot hydrate', () = // ── the premise, read from the registry rather than restated ────────── it('flow is the specimen: not per-org overridable, still runtime-creatable', () => { - // Both halves matter. `allowOrgOverride: false` (#6283 / PR #6478) is + // Both halves matter. `allowOrgOverride: false` (#6283 / commit 474f131cf) is // why an org-scoped flow row can never be read back as an overlay; // `allowRuntimeCreate: true` is why one can still be WRITTEN. If a // later ruling closes the second flag, this case goes red and the diff --git a/packages/metadata-protocol/src/protocol.org-scoped-write-refused.test.ts b/packages/metadata-protocol/src/protocol.org-scoped-write-refused.test.ts index 015c05c00dd..4764a001df9 100644 --- a/packages/metadata-protocol/src/protocol.org-scoped-write-refused.test.ts +++ b/packages/metadata-protocol/src/protocol.org-scoped-write-refused.test.ts @@ -7,7 +7,7 @@ * ## The defect this closes * * `allowOrgOverride` and `allowRuntimeCreate` are orthogonal tiers. #6283 / - * PR #6478 closed the OVERLAY tier for `flow`; the runtime-create tier stayed + * commit 474f131cf closed the OVERLAY tier for `flow`; the runtime-create tier stayed * open by design and never consulted the ORG dimension at all — * `SysMetadataRepository.put` stamps `organization_id: this.organizationId` * whatever the type is. So a Studio-authored item of an @@ -317,7 +317,7 @@ describe('#6190 — org-scoped writes of non-org-overridable types are refused', it('R4 — flow: the original #6190 specimen, brand-new and org-scoped, is refused', async () => { // No artifact is shadowed here, so this is the `allowRuntimeCreate` - // tier — the tier PR #6478 deliberately left open and the tier the + // tier — the tier commit 474f131cf deliberately left open and the tier the // tenant scenario in the issue actually uses (authoring a NEW flow in // Studio, not overlaying a packaged one). const { protocol, rows } = makeProtocol([], 'env_prod'); diff --git a/packages/metadata-protocol/src/protocol.runtime-authoring-gate.test.ts b/packages/metadata-protocol/src/protocol.runtime-authoring-gate.test.ts index f3e5c8e77b3..3603b0982c6 100644 --- a/packages/metadata-protocol/src/protocol.runtime-authoring-gate.test.ts +++ b/packages/metadata-protocol/src/protocol.runtime-authoring-gate.test.ts @@ -560,7 +560,7 @@ describe('#6710 — gate activation is keyed on the declared authoring channel', // [#8310] That build-time reason is the carve-out's ONLY footing. It does // not also rest on the runtime door lacking the rule, and must not be // re-founded on one: `validateSecurityPosture` declares both authoring - // surfaces (PR #8390) and PR #8600 put `object` in its `runtimeTypes`, so + // surfaces (PR #8390) and commit 018d22cc3 put `object` in its `runtimeTypes`, so // it answers at the runtime publish door as well as on every CLI command. // What skips a `package-author` write is the CHANNEL — // `assertRuntimeAuthoringRules` returns early on it at every call site, diff --git a/packages/metadata-protocol/src/protocol.save-meta-missing-item.test.ts b/packages/metadata-protocol/src/protocol.save-meta-missing-item.test.ts index fb0c4bf5433..1c885307460 100644 --- a/packages/metadata-protocol/src/protocol.save-meta-missing-item.test.ts +++ b/packages/metadata-protocol/src/protocol.save-meta-missing-item.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #8818 — `saveMetaItem`'s opening guard was the ONE refusal in the method + * Commit fd6bdf89f — `saveMetaItem`'s opening guard was the ONE refusal in the method * that declared no ADR-0112 envelope, so consumers applying the rule withheld * its sentence and the REST boundary served it as a server fault. * diff --git a/packages/metadata-protocol/src/protocol.save-receipt-wording.test.ts b/packages/metadata-protocol/src/protocol.save-receipt-wording.test.ts index 752b7fce95e..9edbbba88e3 100644 --- a/packages/metadata-protocol/src/protocol.save-receipt-wording.test.ts +++ b/packages/metadata-protocol/src/protocol.save-receipt-wording.test.ts @@ -171,10 +171,10 @@ describe('#5265 — a save receipt names what was actually written', () => { for (const type of Object.keys(OVERLAYLESS_PROBES)) { expect(OVERLAYLESS_RUNTIME_WRITABLE, `${type} left the overlay-less set`).toContain(type); } - // #6283 → #6483 — the override-artifact case at the bottom of this + // #6283 → commit ee58392e1 — the override-artifact case at the bottom of this // file needs a type that is BOTH overlay-less and per-org overridable. // `flow` played that part until #6283 rolled its `allowOrgOverride` - // back to `false` (ADR-0005:57); `action` inherited it until #6483 + // back to `false` (ADR-0005:57); `action` inherited it until commit ee58392e1 // rolled back the remaining nine unratified `true` flags — `action`'s // overlay-less-yet-overridable pairing was the #6190 phantom shape // exactly, the very thing being closed. The population is now EMPTY @@ -312,7 +312,7 @@ describe('#5265 — a save receipt names what was actually written', () => { // not assumed — this case was written against `object` first.) // // The specimen was `flow` until #6283 rolled its `allowOrgOverride` - // back to `false` (ADR-0005:57), then bare `action` until #6483 + // back to `false` (ADR-0005:57), then bare `action` until commit ee58392e1 // rolled back the remaining nine unratified flags — no statically // registered type pairs overlay-less with overridable anymore (the // premise pin above holds the population empty). The pairing is diff --git a/packages/metadata-protocol/src/protocol.ts b/packages/metadata-protocol/src/protocol.ts index e030e4ca03c..5be50ab5907 100644 --- a/packages/metadata-protocol/src/protocol.ts +++ b/packages/metadata-protocol/src/protocol.ts @@ -10,7 +10,7 @@ import { declaredUserMessage, readEnvWithDeprecation, resolveTenancyPosture, res // this question with it is a bug (cloud#1020, #5233) — so the posture, and only // the posture, is what the runtime authoring gate is told. import { postureEnforcesWall } from '@objectstack/spec/security'; -// [#11235] The derived `version` this file's `getDiscovery()` serves as the +// [commit 376c70f98] The derived `version` this file's `getDiscovery()` serves as the // `DiscoverySchema` "System Identity" field — never a literal again. import { resolveDiscoveryVersion } from './discovery-version.js'; import type { MetadataHostEngine } from './host-engine.js'; @@ -123,11 +123,11 @@ import { PLURAL_TO_SINGULAR, SINGULAR_TO_PLURAL, canonicalMetaUrlType, metaUrlSp import type { IObjectQLEngine, IPubSub } from '@objectstack/spec/contracts'; import { applyConversionsToStoredItem, type ConversionNotice, type ConversionTodoNotice } from '@objectstack/spec'; import { type FormView, type I18nLabel, isAggregatedViewContainer, expandViewContainer, resolveI18nLabel } from '@objectstack/spec/ui'; -// [#11350] Emitted-specifier pin. This module's inferred public declarations +// [commit ece4dad31] Emitted-specifier pin. This module's inferred public declarations // structurally mention `FormFieldInput` (FormView `sections[].fields`), and // this file imports BOTH `@objectstack/spec` (root, for // `applyConversionsToStoredItem` above) and `@objectstack/spec/ui`. Once -// #11350 made `FormFieldInput` nameable from the root entry, tsc's +// commit ece4dad31 made `FormFieldInput` nameable from the root entry, tsc's // declaration emitter switched its synthesized reference from the `/ui` slice // to the root — both are portable, but the root specifier drags spec's ENTIRE // root module graph into every downstream tsc program that reads this @@ -2416,7 +2416,7 @@ type BatchDataRowResult = BatchOperationResult; * httpStatus: 409 }` for a `statusCode`-spelled refusal whose own code the * ledger does not know. * - * ## One wire spelling for a unique-constraint refusal (#14723) + * ## One wire spelling for a unique-constraint refusal (commit 65846bc46) * * The engine answers a driver's unique-constraint refusal with its * `DuplicateRecordError` envelope — `code: 'DUPLICATE_RECORD'`, `status: 409`, @@ -2424,12 +2424,12 @@ type BatchDataRowResult = BatchOperationResult; * member, so the verbatim limb above used to put it on the row as-is, while * every WHOLE-REQUEST door in `@objectstack/rest` answers the same class as * `UNIQUE_VIOLATION` — the standard-catalog member the published protocol - * docs give for the 409 constraint-violation body. After #14541 the two + * docs give for the 409 constraint-violation body. After commit 6d178a408 the two * spellings sat side by side in one route's responses: a whole-request * failure on `POST /data/:object/batch` said `UNIQUE_VIOLATION`, a row on the * same route said `DUPLICATE_RECORD`. * - * Maintainer ruling (2026-09-03, #14723): one wire spelling on every route, + * Maintainer ruling (2026-09-03, recorded in commit 65846bc46): one wire spelling on every route, * `UNIQUE_VIOLATION`; the row reports it too. So this limb maps the engine's * envelope to the wire spelling BEFORE the verbatim registered-code rule — * keyed exactly as the whole-request arm keys it (`error-response.ts`'s @@ -2460,7 +2460,7 @@ function toRowApiError(err: any, fallback: string): ApiError { } /** - * [#14723] Is this thrown value the ENGINE's unique-violation envelope? + * [commit 65846bc46] Is this thrown value the ENGINE's unique-violation envelope? * * The same two-part gate `@objectstack/rest`'s whole-request arm applies — * the registered code AND the class name — so a batch row and a whole-request @@ -2736,7 +2736,7 @@ export function clientFacingFailureText(err: unknown, fallback: string): string * counters reconcile), which is the AGENTS.md judgment question the durability * levels turn on. * - * ## [#14403] …and the DISCLOSED row deliberately logs NOTHING + * ## [commit 93d2d679b] …and the DISCLOSED row deliberately logs NOTHING * * Since #14095 a driver unique violation arrives here already wrapped in the * engine's `DUPLICATE_RECORD` envelope, which declares `status: 409` — so the @@ -2749,7 +2749,7 @@ export function clientFacingFailureText(err: unknown, fallback: string): string * over better-sqlite3 through this very sink, in `@objectstack/runtime`'s * `batch-row-driver-text-real-driver.integration.test.ts` — the sentence is * NOT lost: the engine's own insert door logs the envelope's `cause` - * (#14095 / #14390, `e instanceof DuplicateRecordError ? e.cause : e`, + * (#14095 / commit 9d7f7259f, `e instanceof DuplicateRecordError ? e.cause : e`, * because the platform logger serializes only `message` and `stack`), so * `UNIQUE constraint failed: bd_note.email` is in the server log with the * failing column intact. The diagnostic moved one hop; it was not deleted. @@ -2927,7 +2927,7 @@ function metadataIssueHeadline(issues: MetadataIssueEntry[]): string { } /** - * [#10888] The `422 INVALID_METADATA` findings clause, rendered PER FACE. + * [commit d806081dd] The `422 INVALID_METADATA` findings clause, rendered PER FACE. * * The refusal is raised in one place ({@link * ObjectStackProtocolImplementation.saveMetaItem}'s overlay spec check) and @@ -2990,14 +2990,14 @@ function specValidationFindings( // there — nothing about the 422 moved, and this door's structured // channel (`details.issues`) is the very one the comment above // names. Letting `'meta-dispatch'` fall to the default instead would - // have re-introduced the #10888 duplication on one door only, with + // have re-introduced the duplication commit d806081dd removed on one door only, with // every 409 test green: the polarity below is "declare to trim", so // a face that stops declaring loses the trim SILENTLY. Pinned in // `protocol.destructive-409-face-inventory.test.ts`'s [#11095] // section, which asserts the 422 clause did not move under it. return metadataIssueHeadline(issues); default: - // Byte-identical to the pre-#10888 clause: the first three findings + // Byte-identical to the clause before commit d806081dd: the first three findings // as `: `, then a `(+N more)` tail. Read by // `duplicatePackage`'s `failed[].error`, `migrateStoredMetadata`'s // `rows[].reason`, and the two out-of-package log faces — none of @@ -3071,7 +3071,7 @@ function metadataStoreUnavailableError(cause: unknown): Error { * ## The defect it closes * * A metadata app's sandboxed hook on `sys_metadata` may REFUSE a read and mark - * its refusal with `userMessage` — the #9934 producer-side opt-in, where the + * its refusal with `userMessage` — the producer-side opt-in commit 79c46da90 added, where the * field's PRESENCE is the marking (maintainer ruling, 2026-08-19, objectui#5210 * option 1). Every such refusal used to be handed straight to {@link * metadataStoreUnavailableError}, which builds a FRESH error carrying only @@ -3116,7 +3116,7 @@ function metadataReadFailureError(cause: unknown): Error { * ## What is quoted, and what is not * * `message` is the marked text itself. That is the one string the producer - * declared is addressed to the end user (#9934), so quoting it discloses + * declared is addressed to the end user (commit 79c46da90), so quoting it discloses * nothing that was not authored for a caller — and it is the ONLY thing taken * from the cause. The cause's own `message` is a diagnostic and is NOT read: * it rides on `cause`, which `handleRouteError` / `logWithheldServerFault` @@ -3136,7 +3136,7 @@ function metadataReadFailureError(cause: unknown): Error { * * The fallback status is 400, and it is NOT invented here: it is what the REST * sandbox door already answers for a hook refusal that named no status of its - * own (`error-response.ts`, #9967 — `declared ?? 400`, pinned by + * own (`error-response.ts`, commit 8f266f1cd — `declared ?? 400`, pinned by * `hook-error-format.dogfood.test.ts`). A hook that DID name one keeps it * (#7867: "an error that NAMES its own HTTP status is asking to be served with * it"), which is also why this is status-agnostic in the way the `userMessage` @@ -3159,7 +3159,7 @@ function markedApplicationRefusalError(cause: unknown, userMessage: string): Err /** * [#12536] The status a marked refusal takes when its producer named none — - * the REST sandbox door's own `declared ?? 400` (#9967), reused rather than + * the REST sandbox door's own `declared ?? 400` (commit 8f266f1cd), reused rather than * chosen again, so the metadata read door and the hook door classify one * undeclared hook refusal identically. */ @@ -3170,7 +3170,7 @@ const MARKED_REFUSAL_UNDECLARED_STATUS = 400; * re-wrapping — the exact sibling of {@link carryCatalogedErrorCode}, one * field over. * - * A re-wrap that drops the mark destroys the #9934 channel just as completely + * A re-wrap that drops the mark destroys the channel commit 79c46da90 added just as completely * as building a fresh error does, and for the same reason: `declaredUserMessage` * reads the TOP level, never `cause`. Copying only the marked field quotes * nothing else — the cause's diagnostic `message` stays governed by whichever @@ -3411,7 +3411,7 @@ const ARRAY_VALUED_LIST_QUERY_PARAMS: ReadonlySet = (() => { * worse: `Number(['1','2'])` is `NaN`, so the window reached the driver as * `limit: NaN` — driver-dependent behaviour under a 200, never an error. That * is the same class #6928 / PR #7299 refused one layer over on - * `GET /api/v1/notifications`, and the same rule #6307 / #6877 landed in + * `GET /api/v1/notifications`, and the same rule commit 293476148 / #6877 landed in * `packages/rest` (`readSingleQueryValue` / `repeatedQueryParamMessage`). * * ## The wording below is MODELLED ON theirs — it is not a verbatim copy @@ -4250,7 +4250,7 @@ function detectDestructiveObjectChanges(prev: any, next: any): Array<{ } /** - * [#11015] The remedy clause the Phase 3a-destructive refusal ends with — one + * [commit 82cb6e849] The remedy clause the Phase 3a-destructive refusal ends with — one * sentence per FACE, because the mechanism that lifts the refusal is not the * same on every door that raises it. * @@ -4271,7 +4271,7 @@ function detectDestructiveObjectChanges(prev: any, next: any): Array<{ * * ⛔ What is repaired is the CLAUSE, not the door. Giving the duplicate route a * `force` would widen a public surface and is a contract decision, deliberately - * NOT taken here. Nor is the clause deleted on that face: #10886 measured that + * NOT taken here. Nor is the clause deleted on that face: commit 809e61221 measured that * `duplicatePackage`'s `failed[].error` is the SOLE carrier of this * prescription, so deleting the remedy there deletes it from the wire outright. * Each face therefore states the remedy it actually has. @@ -4281,9 +4281,9 @@ function detectDestructiveObjectChanges(prev: any, next: any): Array<{ * on nothing else that reaches this gate today — see the `[#11095]` section of * `protocol.destructive-409-face-inventory.test.ts` for the full inventory. * - * ## [#11095] The two doors #11015 left open, and why they were split + * ## [#11095] The two doors commit 82cb6e849 left open, and why they were split * - * #11015's note recorded two further faces that reached this gate and never + * Commit 82cb6e849's note recorded two further faces that reached this gate and never * threaded `force`, and filed the disposition as a contract question rather * than guessing it. The ruling was a SPLIT — one door repaired by threading the * parameter, the other by telling the truth — and the split is the decision, @@ -4312,7 +4312,7 @@ function detectDestructiveObjectChanges(prev: any, next: any): Array<{ * dispatcher is not the third member of that pair. */ /** - * [#11015 / #10888] Which write door a `saveMetaItem` refusal is being + * [commit 82cb6e849 / commit d806081dd] Which write door a `saveMetaItem` refusal is being * rendered FOR. Stated by the SERVER — either by the protocol's own internal * call ({@link ObjectStackProtocolImplementation.duplicatePackage}) or by the * in-process HTTP boundary that owns the response envelope — never by a remote @@ -4428,7 +4428,7 @@ export interface UninstallCleanupOutcome { error?: string; /** * [#12536] The user-facing refusal text the failing cleanup MARKED with - * `userMessage` (#9934) — absent unless it declared one. This outcome is + * `userMessage` (commit 79c46da90) — absent unless it declared one. This outcome is * response DATA riding inside a `PACKAGE_DELETE_PARTIAL` 400's `details`, * so no HTTP boundary reads a `userMessage` on its behalf; the channel has * to exist here or the mark has nowhere to go. Read it with @@ -4495,7 +4495,7 @@ export interface DeletePackageResponse { failedCount: number; deleted: Array<{ type: string; name: string; state: string }>; /** - * Per-item failures. [#12536] `userMessage` is the #9934 mark the item's + * Per-item failures. [#12536] `userMessage` is the mark (commit 79c46da90) the item's * own failure declared — present exactly when a producer marked its * refusal, so a caller can tell an application refusal apart from a store * failure on a path where no HTTP boundary can do it for them. @@ -5694,7 +5694,7 @@ export class ObjectStackProtocolImplementation implements * that narrows on a guess and no branch that skips rules: the failure * direction is more validation input, never less. A "skip when N is large" * fast path is the fail-open at scale this card was explicitly forbidden to - * build (#9798 declared-but-unenforced, #9261 an outage read as emptiness, + * build (commit c7655d472 restored a declared-but-unenforced refusal, #9261 an outage read as emptiness, * ADR-0110 D3 — a miss and a fault are different facts). */ private resolveWritePackageScope( @@ -6262,7 +6262,7 @@ export class ObjectStackProtocolImplementation implements * scope is returned unchanged, so a genuinely absent draft still raises the * same `NO_DRAFT` refusal, from the scope the caller asked about. * - * [#11003] `packageId` — the ADR-0048 package dimension, threaded into BOTH + * [commit c74aefe63] `packageId` — the ADR-0048 package dimension, threaded into BOTH * probes exactly as {@link promoteDraftForPublish} threads it into * `repo.promoteDraft`: stated (string, or `null` pinning the unbound row), * each probe adds `package_id` to its `where`, so the scope probes ask the @@ -6271,7 +6271,7 @@ export class ObjectStackProtocolImplementation implements * the historical package-agnostic probes — the promote is then * package-agnostic too, so the two questions still agree. * - * Maintainer ruling 2026-08-22 (#11003, option A — recorded on the issue): + * Maintainer ruling 2026-08-22 (option A — recorded in commit c74aefe63): * a package-stating publish resolves the scope of the draft it NAMED. * Without the dimension, probe 1 could match ANOTHER package's row in the * caller's org, name a scope the package-exact promote then finds empty, @@ -6307,8 +6307,8 @@ export class ObjectStackProtocolImplementation implements // promote hides a draft the promote can see; a probe WIDER names a // scope it cannot. // - // [#11003] That rule is what threads the package dimension in: since - // #10063 the per-item door names a package whenever its HTTP caller + // [commit c74aefe63] That rule is what threads the package dimension in: since + // commit 9e04c3e35 the per-item door names a package whenever its HTTP caller // does (`?package=PKG_ID`), and the promote's `whereFor` then // constrains `package_id` — so a package-agnostic probe here was the // WIDER shape, naming a scope off another package's row (ADR-0048 keys @@ -6316,7 +6316,7 @@ export class ObjectStackProtocolImplementation implements // same-name drafts coexist in different scopes). `undefined` spreads // NOTHING — the caller stated no package, the promote matches any // package, and these probes keep asking that same question. See the - // docblock above for the #11003 ruling and its accepted narrowing. + // docblock above for the ruling commit c74aefe63 records and its accepted narrowing. const packageDim = packageId !== undefined ? { package_id: packageId } : {}; const inOrg = await this.engine.findOne('sys_metadata', { where: { organization_id: requestOrgId, type: singularType, name, state: 'draft', ...packageDim }, @@ -6838,7 +6838,7 @@ export class ObjectStackProtocolImplementation implements const authFamilies = readAuthFamilies(registeredServices.get('auth')); return { - // [#11235] The serving system's identity, DERIVED — an injected + // [commit 376c70f98] The serving system's identity, DERIVED — an injected // `OS_RUNTIME_VERSION` stamp, falling back to this package's own // resolved version. It was the literal `'1.0'` while the other // `DiscoverySchema` producer (`HttpDispatcher.getDiscoveryInfo()` @@ -7302,14 +7302,14 @@ export class ObjectStackProtocolImplementation implements * * A non-benign failure is classified once more before it is wrapped, by * {@link metadataReadFailureError}: a metadata app's hook may have REFUSED - * this read and marked its refusal with `userMessage` (#9934), and that is + * this read and marked its refusal with `userMessage` (commit 79c46da90), and that is * an application refusal, not a dependency outage. Handing it to the 503 * below destroyed the mark at the producer — the two failures left this * guard as the same envelope with the same sentence. The classification * splits them; neither category's wording changes. * * @throws {@link markedApplicationRefusalError} — [#12536] FIRST, when the - * failure carried a producer's `userMessage` mark (#9934): the + * failure carried a producer's `userMessage` mark (commit 79c46da90): the * author's text verbatim, in its own refusal category, with the * cause still carried for the operator and nothing else quoted. * @throws {@link metadataStoreUnavailableError} — a 503 carrying the driver @@ -7322,7 +7322,7 @@ export class ObjectStackProtocolImplementation implements * the overlay as absent. */ private rethrowUnlessMetadataStoreUnprovisioned(error: unknown, readObject: string): void { - // [#13324] `readObject` is REQUIRED, deliberately. This helper serves + // [commit 4cda78c9b] `readObject` is REQUIRED, deliberately. This helper serves // callers that read four different tables (`sys_metadata`, // `sys_metadata_audit`, `sys_metadata_commit`, `sys_metadata_history`), // so a default would silently answer about the wrong one for three of @@ -7953,7 +7953,7 @@ export class ObjectStackProtocolImplementation implements audience: 'served' | 'execution', ) { const { packageId } = request; - // ── [#14683] The registry read gate, resolved ONCE, HERE ────────────────── + // ── [commit 96326040f] The registry read gate, resolved ONCE, HERE ────────────────── // // {@link organizationIdForMetaRead} — the predicate the REST `/meta` // read doors have applied since #9454, twin of the write side's @@ -8043,7 +8043,7 @@ export class ObjectStackProtocolImplementation implements // ⛔ Gate AFTER the fold, never before it. `declaresOrgOverride` // tolerates the MANIFEST plurals and not the URL-only ones // (`translations` / `email_templates` have no manifest key), and - // #10340 measured what that costs when the raw segment reaches the + // commit 26f3588fb measured what that costs when the raw segment reaches the // predicate: one item in two partitions, addressed by spelling. Folding // happens at the boundary and only there; this line reads what the // boundary produced. @@ -8576,18 +8576,18 @@ export class ObjectStackProtocolImplementation implements // #4432 — CANONICAL TYPE KEY. See {@link canonicalMetaType}. request = canonicalizeMetaRequestType(request); let item: unknown; - // ── [#14770] The registry read gate, resolved ONCE, HERE ──────────────────── + // ── [commit d5cbb44f3] The registry read gate, resolved ONCE, HERE ──────────────────── // // {@link organizationIdForMetaRead} — the read-side twin of // `organizationIdForMetaWrite` (#6190 / #7018), which the REST `/meta` - // read doors have applied since #9454 and which #14683 moved INSIDE the + // read doors have applied since #9454 and which commit 96326040f moved INSIDE the // plural verb, `getMetaItems` above. Until this line the SINGULAR verb // applied no gate of its own: whatever organization arrived was spent on // whatever type arrived. // // ⭐ THE SHARPER HALF, and why the plural verb's fix did not cover it. // `getMetaItems` UNIONs its two `queryByOrg` reads, so an ungated - // organization can only ADD rows — the resurrection #14683 is about. + // organization can only ADD rows — the resurrection commit 96326040f closed. // The two `findOverlay` reads below combine with `??`, which is // PRECEDENCE: an ungated organization can SUBSTITUTE. On a type the // registry declares `allowOrgOverride: false`, a pre-#6190 phantom @@ -8615,7 +8615,7 @@ export class ObjectStackProtocolImplementation implements // document per overlay row, so a layering would have nothing to // layer. The field-level patch model that would have given // "layering" a meaning was retired and deleted whole under ADR-0049 - // (#13185, PR #13186, maintainer ruling 2026-08-29), recorded as a + // (commit 9e0ba21a1, maintainer ruling 2026-08-29), recorded as a // correction inside principle 3 itself, with ADR-0126 §6 ruling out // the phase it was held for. // • {@link organizationIdForMetaRead}'s own docblock quotes THIS @@ -8679,7 +8679,7 @@ export class ObjectStackProtocolImplementation implements // `runtime/src/domains/packages.ts`, `type: 'seed'`, equally // non-overridable. It hand-rolled an org-then-env ladder that this gate // had turned into a byte-identical repeat — both rungs asking the - // engine the same predicates and serving the same answer. #15068 + // engine the same predicates and serving the same answer. Commit 8744de9e9 // measured that (ablation: neutering the second rung reddened nothing // on a pinned publish-then-read path) and collapsed it to a single read // naming no organization at all, so it now belongs to the bucket below. @@ -8695,7 +8695,7 @@ export class ObjectStackProtocolImplementation implements // // ⛔ Gate AFTER the fold, never before it. `declaresOrgOverride` // tolerates the MANIFEST plurals and not the URL-only ones - // (`translations` / `email_templates` have no manifest key); #10340 + // (`translations` / `email_templates` have no manifest key); commit 26f3588fb // measured what that costs when a raw segment reaches the predicate. const orgId = organizationIdForMetaRead(request.type, request.organizationId); // Studio's editor opens a draft buffer with `state: 'draft'`; @@ -9093,7 +9093,7 @@ export class ObjectStackProtocolImplementation implements * the one the lock/affordance flags are derived from. * * @throws {@link markedApplicationRefusalError} — [#12536] FIRST, when the - * failure carried a producer's `userMessage` mark (#9934): an + * failure carried a producer's `userMessage` mark (commit 79c46da90): an * application refusal in the author's own words, classified at the * producer and NOT the 503 below. See {@link * metadataReadFailureError}. @@ -9137,7 +9137,7 @@ export class ObjectStackProtocolImplementation implements // `'overlay'` arm this annotation used to carry was dead: the one // `lockSource: 'overlay'` producer in this file belongs to // `getEffectiveLock`, a write/delete-door helper that never feeds - // this response (#9740). + // this response (commit 11b779e0f). lockSource?: MetadataLockSource; lockDocsUrl?: string; provenance?: MetadataProvenance; @@ -9152,19 +9152,19 @@ export class ObjectStackProtocolImplementation implements // `overlay` can be read from two. request = canonicalizeMetaRequestType(request); - // ── [#14907] The registry read gate, resolved AFTER the fold ───────── + // ── [commit e1d4f9e3f] The registry read gate, resolved AFTER the fold ───────── // // {@link organizationIdForMetaRead} — the predicate the REST `/meta` // read doors have applied since #9454, twin of the write side's // `organizationIdForMetaWrite` (#6190 / #7018) and the same gate - // `getMetaItems` (#14683) and `getMetaItem` (#14770) now carry. Until + // `getMetaItems` (commit 96326040f) and `getMetaItem` (commit d5cbb44f3) now carry. Until // this line `getMetaItemLayered` — the third `/meta` read verb — // applied NO gate of its own: whatever organization arrived was spent // on whatever type arrived. // // ⛔ THE BINDING MOVED, and that reorder IS the fix. It used to sit // ABOVE the fold, so dropping the sibling verbs' one-liner in place - // would have gated on the RAW type. #10340 measured what that costs: + // would have gated on the RAW type. Commit 26f3588fb measured what that costs: // `declaresOrgOverride` tolerates the MANIFEST plurals but not the // URL-only ones (`translations` / `email_templates` have no manifest // key), so a raw segment splits one item across two partitions. Both @@ -9189,8 +9189,8 @@ export class ObjectStackProtocolImplementation implements // Let `f(t, o) = organizationIdForMetaRead(t, o)`. `f` answers `o` when // the registry declares `t` per-org overridable and `undefined` // otherwise, so `f(t, undefined) === undefined` and - // `f(t, f(t, o)) === f(t, o)` for every `t` and `o`. #14683's and - // #14770's proofs do NOT carry: the #14683 ruling discharges this per + // `f(t, f(t, o)) === f(t, o)` for every `t` and `o`. Commit 96326040f's and + // commit d5cbb44f3's proofs do NOT carry: the ruling behind commit 96326040f discharges this per // door over that door's OWN caller population, and this verb's is a // different set. Enumerated by grepping every `getMetaItemLayered(` // invocation in the repo and tracing each `organizationId` argument to @@ -9546,7 +9546,7 @@ export class ObjectStackProtocolImplementation implements * all of them as an empty trail is what this closes. * * @throws {@link markedApplicationRefusalError} — [#12536] FIRST, when the - * failure carried a producer's `userMessage` mark (#9934): an + * failure carried a producer's `userMessage` mark (commit 79c46da90): an * application refusal in the author's own words, classified at the * producer and NOT the 503 below. See {@link * metadataReadFailureError}. @@ -9733,7 +9733,7 @@ export class ObjectStackProtocolImplementation implements // spelling guards on `Number.isNaN(value.getTime())`, all five // arms in ONE change, because a guard on some arms and not // others re-opens the drift the single spelling closed. - // Reachability is MEASURED (#14409, `3ecb7dc1a`): mysql2 3.23.1 + // Reachability is MEASURED (commit `3ecb7dc1a`): mysql2 3.23.1 // hands back a constant literally named `INVALID_DATE` for a // zero `DATETIME`, and postgres-date 1.0.7 builds // `new Date(NaN)` for every year in 275760..294276, which @@ -9811,7 +9811,7 @@ export class ObjectStackProtocolImplementation implements // 2. Limit to 6 columns by default const priorityFields = ['name', 'title', 'label', 'subject', 'email', 'status', 'type', 'category', 'created_at']; - // [#13259] `!fields[k].hidden` belongs on BOTH passes. It used to + // [commit 2a75270b1] `!fields[k].hidden` belongs on BOTH passes. It used to // sit on the fill pass alone, so a field declared `hidden: true` // was dropped for eight of nine spellings and SERVED — label and // all — for the ninth: whenever the author happened to name it one @@ -10348,7 +10348,7 @@ export class ObjectStackProtocolImplementation implements // axis' formula refusal (#6994), with only the verb changed to // name this axis. One vocabulary across the doors: an author // refused on two axes must not be sent two different ways. - // [#8648] The SEARCH axis (#6673) agrees in SUBSTANCE and words it + // [commit e5eeb499c] The SEARCH axis (#6673) agrees in SUBSTANCE and words it // its own way — "Mirror the computed value onto a stored text // field on '' and search that instead." Same prescription, // narrowed to the column type that axis can scan; claiming @@ -10566,7 +10566,7 @@ export class ObjectStackProtocolImplementation implements // Deliberately the same remedy, in the same words, as the // dotted refusal above: one vocabulary across the doors, so an // author refused twice is not sent two different ways. - // [#8648] #6673's SEARCH-axis correction agrees in SUBSTANCE, + // [commit e5eeb499c] #6673's SEARCH-axis correction agrees in SUBSTANCE, // in its own words ("Mirror the computed value onto a stored // text field on '' and search that instead") — the // same prescription with a TEXT target, not the same sentence. @@ -11947,7 +11947,7 @@ export class ObjectStackProtocolImplementation implements } /** - * Validate-only (#6037 — #4633 ruling D): report the write path's verdict + * Validate-only (commit 18189983d — #4633 ruling D): report the write path's verdict * on candidate rows without persisting any of them. * * Deliberately thin. The verdict comes from `engine.validate()`, which @@ -13378,7 +13378,7 @@ export class ObjectStackProtocolImplementation implements if (deleted === false) throw recordNotFoundError(object, record.id); // [#19433] The SECOND half of this site, and the THIRD and // last of the by-id delete doors to learn it — the - // single-record face (#19306) and `deleteManyData` (#19412) + // single-record face (commit f9e16d856) and `deleteManyData` (#19412) // both already read the engine's answer. The paragraph // above fixed "no match"; this is "matched, and // deliberately NOT removed", where `success` was still a @@ -14222,8 +14222,8 @@ export class ObjectStackProtocolImplementation implements * (`allowOrgOverride`), and the registry keeps the two flags apart on * purpose: `supportsOverlay` is a CAPABILITY of the read path ("an overlay * row under this name changes what is served"), `allowOrgOverride` is a - * PERMISSION on the write path ("a tenant may author one"). #6483 / PR - * #6608 rolled the permission back for six types — `permission`, + * PERMISSION on the write path ("a tenant may author one"). Commit + * ee58392e1 rolled the permission back for six types — `permission`, * `position`, `page`, `app`, `dataset`, `book` — and deliberately left * the capability alone, which is exactly the state #6960 was filed about: * a row authored BEFORE the rollback still merges overlay-wins today. @@ -15193,7 +15193,7 @@ export class ObjectStackProtocolImplementation implements * `catch` below and {@link rethrowUnlessMetadataStoreUnprovisioned}. * * @throws {@link markedApplicationRefusalError} — [#12536] FIRST, when the - * failure carried a producer's `userMessage` mark (#9934): an + * failure carried a producer's `userMessage` mark (commit 79c46da90): an * application refusal in the author's own words, classified at the * producer and NOT the 503 below. See {@link * metadataReadFailureError}. @@ -16629,7 +16629,7 @@ export class ObjectStackProtocolImplementation implements } /** - * [#12194] The item-name grammar verdict — stage 1 of the #12176 + * [commit 311433f6b] The item-name grammar verdict — stage 1 of the * maintainer-ruled retirement of compound `
/` addressing * (2026-08-25). Refuse, on the doors that MINT or PROMOTE a `sys_metadata` * row, an item name outside the declared grammar: lowercase snake_case @@ -16637,7 +16637,7 @@ export class ObjectStackProtocolImplementation implements * `@objectstack/spec/shared` — the one segment source, shared with * `ViewItemNameSchema`'s dot-required arity). * - * What this closes, measured on the #12176 census before this landed: + * What this closes, measured before this landed (the census commit 311433f6b records): * `''`, `'//'`, `'a/b/c'`, `'Views/All Leads'` were all accepted and * stored as item names, and a slash in the name BYPASSED * {@link refuseUnmintableMetaType} entirely (`type=fieldz name='a'` → @@ -16645,7 +16645,7 @@ export class ObjectStackProtocolImplementation implements * REST/dispatcher arities still fold `:section/:name` into one * slash-joined string; a write arriving that way is now refused here with * the dotted spelling as the prescription (their retirement is D3, - * #12195 — this door does not wait for it). + * commit 7986d973f — this door does not wait for it). * * Scoping, deliberate and parallel to {@link refuseUnmintableMetaType}: * @@ -16713,14 +16713,14 @@ export class ObjectStackProtocolImplementation implements * permanently — turning the accumulation this card was filed about into * an accumulation nobody can clear. * - * ## …and why one shape reaching THIS door is exempt (#8421 rework, revised by #12194) + * ## …and why one shape reaching THIS door is exempt (#8421 rework, revised by commit 311433f6b) * * The first cut had TWO exemptions, both regressions measured on the three * consumer packages the first cut never ran. The FIRST — skip the verdict * when the name contains a slash, because the compound arity puts an * OBJECT name in the `:type` segment (`/metadata/lead/views/all_leads` is * `type='lead'`, `name='views/all_leads'`, and `lead` is runtime data no - * static contract can enumerate) — is GONE (#12194): the item-name + * static contract can enumerate) — is GONE (commit 311433f6b): the item-name * grammar verdict ({@link refuseUngrammaticalMetaItemName}) runs before * this probe and refuses every slash-bearing name outright, so no request * that needed the exemption can reach this door any more. That also @@ -16753,7 +16753,7 @@ export class ObjectStackProtocolImplementation implements const unrecognised = unrecognisedMetaTypeRefusal(request.type); if (!unrecognised) return; // The old exemption 1 (skip when the name contains a slash) was - // removed by #12194 — the grammar verdict upstream refuses every + // removed by commit 311433f6b — the grammar verdict upstream refuses every // slash-bearing name before this probe runs. See the header. // Exemption 2 — the namespace predates this write. if (await this.metaTypeNamespaceExists(unrecognised.type)) return; @@ -16800,7 +16800,7 @@ export class ObjectStackProtocolImplementation implements } async saveMetaItem(request: { type: string, name: string, item?: any, organizationId?: string, parentVersion?: string | null, actor?: string, force?: boolean, mode?: 'draft' | 'publish', packageId?: string | null, source?: string, writeFace?: MetadataWriteFace }) { - // [#8818] The ADR-0112 envelope this refusal always owed. Every OTHER + // [commit fd6bdf89f] The ADR-0112 envelope this refusal always owed. Every OTHER // refusal in this method declares `code` AND `status` // (`NOT_OVERRIDABLE`/403, `NOT_CREATABLE`/403, `ITEM_LOCKED`/403, // `OBJECT_OVERLAY_PACKAGE_MISMATCH`/422, the org-scope and @@ -16844,7 +16844,7 @@ export class ObjectStackProtocolImplementation implements } // #4432 — CANONICAL TYPE KEY. See {@link canonicalMetaType}. request = canonicalizeMetaRequestType(request); - // [#12194] The item-name grammar verdict — static, request-only, so it + // [commit 311433f6b] The item-name grammar verdict — static, request-only, so it // runs before the store-backed type probe below. Closes the measured // slash bypass: a slash-bearing name used to skip the #8421 refusal // entirely. See {@link refuseUngrammaticalMetaItemName}. @@ -16987,8 +16987,8 @@ export class ObjectStackProtocolImplementation implements // `allowOrgOverride: false`, i.e. the `if` immediately below) while // the identical argument had grown a second population: an // ARTIFACT-BACKED item of a type that kept `allowRuntimeCreate: true` - // and had its `allowOrgOverride` ROLLED BACK to `false` (#6483 / PR - // #6608 — `permission` / `position` / `page` / `app` / `dataset` / + // and had its `allowOrgOverride` ROLLED BACK to `false` (commit + // ee58392e1 — `permission` / `position` / `page` / `app` / `dataset` / // `book`). Its loader still merges the overlay at read time // (`supportsOverlay: true`, untouched by the rollback), so a row // authored before the rollback keeps shaping the effective body while @@ -17002,7 +17002,7 @@ export class ObjectStackProtocolImplementation implements // artifact-backed refusal below it are UNCHANGED: create and update // on such an item stay refused exactly as today. Do not "restore // symmetry" in either direction — symmetrizing towards delete re-opens - // the write door #6483 closed, symmetrizing towards save re-traps the + // the write door commit ee58392e1 closed, symmetrizing towards save re-traps the // repair. And the relaxation is keyed on `supportsOverlay`, not on // `allowOrgOverride`, so it stops at the tier boundary: `object` // (`supportsOverlay: false`, its overlay a contributor LAYER per @@ -17088,7 +17088,7 @@ export class ObjectStackProtocolImplementation implements // caller has acknowledged the risk with `force: true`. The admin UI // surfaces the structured `issues` payload in a confirmation dialog. // - // [#11014] `object` ALONE. This condition used to read + // [commit 2d8b92ff1] `object` ALONE. This condition used to read // `(singularType === 'object' || singularType === 'field')`, and the // `field` limb could not produce a finding — two independent reasons, // BOTH RE-MEASURED through the real `saveMetaItem` before the trim: @@ -17125,7 +17125,7 @@ export class ObjectStackProtocolImplementation implements // the limb's only reachable behaviour, and it was a false alarm. // // ⛔ Do not "restore" the limb as missing coverage — that reading is - // precisely what this card was filed to prevent (#10886's face + // precisely what this card was filed to prevent (commit 809e61221's face // inventory had to chase a `field` face population that does not // exist). Giving `field` a real destructive diff only becomes // meaningful if `field` ever becomes runtime-writable, and returns @@ -17143,7 +17143,7 @@ export class ObjectStackProtocolImplementation implements if (prev) { const issues = detectDestructiveObjectChanges(prev, request.item); if (issues.length > 0) { - // [#10886] Deliberately NOT trimmed to a headline, and + // [commit 809e61221] Deliberately NOT trimmed to a headline, and // this is a MEASURED verdict rather than an oversight — // the same one the sibling `INVALID_METADATA` message // below carries, reached the same way (#10524's @@ -17160,7 +17160,7 @@ export class ObjectStackProtocolImplementation implements // involved there, so `details.issues` never exists; the // array is typed inline as `{ type, name, error }` with // no `issues` slot; and unlike `publishPackageDrafts` — - // whose `failed[]` #10895 could extend because it HAS a + // whose `failed[]` commit a79bd3561 could extend because it HAS a // response schema — `duplicatePackage` has none in // `packages/spec` at all. Declaring a channel there is a // spec change, and until it lands a trim would delete @@ -17181,7 +17181,7 @@ export class ObjectStackProtocolImplementation implements // and no structured channel on any face carries the // remedy. // - // [#11015] Which remedy that IS depends on the face — + // [commit 82cb6e849] Which remedy that IS depends on the face — // `?force=true` names a query parameter only the // single-segment REST `PUT` reads, and prescribing it // to a caller who has no way to set it sends them in a @@ -17362,7 +17362,7 @@ export class ObjectStackProtocolImplementation implements const parsed = schema.safeParse(request.item); if (!parsed.success) { const issues = zodIssuesToMetadataIssues(parsed.error.issues); - // [#10524 → #10888] The findings clause is rendered PER + // [#10524 → commit d806081dd] The findings clause is rendered PER // FACE — see {@link specValidationFindings}. #10524's // headline is applied on the faces that carry the same // findings structurally beside the message (the `/meta` @@ -18447,19 +18447,19 @@ export class ObjectStackProtocolImplementation implements actor?: string; message?: string; /** - * [#10350] ADR-0048 — the software package the draft being promoted was + * [commit 490879ad0] ADR-0048 — the software package the draft being promoted was * listed under, when the caller has one to state. Forwarded whole to * {@link promoteDraftForPublish}, which threads it into BOTH the #9612 * gate closure and `repo.promoteDraft`, so the gate and the write * resolve the draft under the SAME key it was listed by. * * Declared because it is REAL on this door, not merely tolerated: - * since #10063 `POST /meta/:type/:name/publish?package=PKG_ID` states it + * since commit 9e04c3e35 `POST /meta/:type/:name/publish?package=PKG_ID` states it * on every HTTP-driven promotion that names a package — which is * Studio's designer save-then-publish loop. Until it was declared the * value flowed correctly but was invisible to every typed caller, and * the only caller that states one reaches this method through a cast, - * so the binding was enforced by nothing. `#10350` added the pins in + * so the binding was enforced by nothing. Commit 490879ad0 added the pins in * `protocol-publish-drafts-package-scope.test.ts`. * * ⚠️ `null` is NOT the same as absent, and the difference is load @@ -18472,10 +18472,10 @@ export class ObjectStackProtocolImplementation implements * unfindable — a silent `no_draft` on the untouched path. */ packageId?: string | null; - // [#10350] `environmentId` is deliberately NOT declared here, although + // [commit 490879ad0] `environmentId` is deliberately NOT declared here, although // the REST door spreads it into this very request literal. It is the // multi-kernel ROUTING key, and it is out of the protocol request shape - // by explicit maintainer ruling (recorded 2026-08-18 on #9741): + // by explicit maintainer ruling (recorded 2026-08-18, landed as commit 2a29caa53): // `resolveProtocol(environmentId)` has already selected the target // kernel before this method is entered, and this class reads its // environment off the INSTANCE (`this.environmentId`, set at @@ -18614,7 +18614,7 @@ export class ObjectStackProtocolImplementation implements // rewrites it on upgrade). Different input class, different map; see // {@link canonicalMetaType}'s header for why the two are not one fold. request = canonicalizeMetaRequestType(request); - // [#12194] The item-name grammar verdict, same as `saveMetaItem`'s: + // [commit 311433f6b] The item-name grammar verdict, same as `saveMetaItem`'s: // the promotion door writes an `active` row under this name, so an // off-grammar name is refused here too rather than promoted. With the // save door closed no such draft can exist any more; for pre-grammar @@ -18632,7 +18632,7 @@ export class ObjectStackProtocolImplementation implements // the one the row is actually in. Resolving it later would gate against // a partition the promotion never touches. // - // [#11003] The package dimension rides along under the SAME + // [commit c74aefe63] The package dimension rides along under the SAME // present/absent contract `promoteDraftForPublish` spells as // `...('packageId' in request ? { packageId: request.packageId ?? null } // : {})`: an ABSENT key keeps the historical package-agnostic probes, @@ -18786,9 +18786,9 @@ export class ObjectStackProtocolImplementation implements * `undefined` (any caller with no binding to state) keeps the * historical "match any package" resolution. `null` pins the lookup to * the unbound row — so the field is passed through only when the caller - * actually has a binding to state. [#10350] That parenthetical used to + * actually has a binding to state. [commit 490879ad0] That parenthetical used to * read "the `publishMetaItem` path, which names no package"; since - * #10063 the per-item door names one whenever its HTTP caller does, so + * commit 9e04c3e35 the per-item door names one whenever its HTTP caller does, so * `undefined` is now about the ABSENCE of a binding, never about which * caller is on the other end. */ @@ -18896,14 +18896,14 @@ export class ObjectStackProtocolImplementation implements // below, so the gate and the write resolve the draft under one // key rather than two. BOTH callers can state it: // `publishPackageDrafts` always does (a package publish, which - // is exactly the write #9612 was about), and [#10350] since - // #10063 `publishMetaItem` does too — whenever the HTTP caller + // is exactly the write #9612 was about), and [commit 490879ad0] since + // commit 9e04c3e35 `publishMetaItem` does too — whenever the HTTP caller // named one on `POST /meta/:type/:name/publish?package=PKG_ID`. // An UNSTATED package still narrows nothing, and that remains // the correct answer rather than a gap — a promotion whose // package is unstated has no declared dependency set to bound // it. (This comment used to say the per-item door names no - // package at all, which stopped being true at #10063 and would + // package at all, which stopped being true at commit 9e04c3e35 and would // read the REST door's forwarding as dead code.) // // ⚠️ Deliberately NOT read off `draftForGate`: `rowToItem` @@ -21132,7 +21132,7 @@ export class ObjectStackProtocolImplementation implements item: rewritten, mode: 'publish', packageId: request.targetPackageId, - // [#11015] Which door the refusal below will be prescribing + // [commit 82cb6e849] Which door the refusal below will be prescribing // a remedy FOR. Stated by the server, never by the caller — // `duplicatePackage`'s own request type has no such field, // exactly as `source` is server-stated one gate down. The @@ -21507,7 +21507,7 @@ export class ObjectStackProtocolImplementation implements * platform once rather than re-spelled per seam. * * @throws {@link markedApplicationRefusalError} — [#12536] FIRST, when the - * failure carried a producer's `userMessage` mark (#9934): an + * failure carried a producer's `userMessage` mark (commit 79c46da90): an * application refusal in the author's own words, classified at the * producer and NOT the 503 below. See {@link * metadataReadFailureError}. @@ -22554,7 +22554,7 @@ export class ObjectStackProtocolImplementation implements * construction: a name that reaches for no declared type is a * possible plugin kind and is served, not refused (#7894). * @throws {@link markedApplicationRefusalError} — [#12536] FIRST, when the - * failure carried a producer's `userMessage` mark (#9934): an + * failure carried a producer's `userMessage` mark (commit 79c46da90): an * application refusal in the author's own words, classified at the * producer and NOT the 503 below. See {@link * metadataReadFailureError}. @@ -22789,7 +22789,7 @@ export class ObjectStackProtocolImplementation implements } } } - // [#8671] Diff RAW, then redact the EMITTED values — maintainer ruling + // [commit 75e66fc8e] Diff RAW, then redact the EMITTED values — maintainer ruling // (comment 5299845282), Option B. The comparison runs on the stored // bodies untouched, so a credential ROTATION still registers as a // changed path; only the values leaving this function are taken from @@ -22894,7 +22894,7 @@ export class ObjectStackProtocolImplementation implements // ⛔ DELETE ONLY, AND IT IS NOT AN OVERSIGHT. Create and update on // the same item stay refused exactly as before (`saveMetaItem`'s // sibling gate is untouched); a future tidy-up that "restores - // symmetry" here re-opens the write door the #6483 rollback closed. + // symmetry" here re-opens the write door the rollback in commit ee58392e1 closed. // The asymmetry is the ruling. // // THE TIER BOUNDARY, which is what makes this narrow enough to be @@ -22904,7 +22904,7 @@ export class ObjectStackProtocolImplementation implements // • `supportsOverlay: true` + `allowOrgOverride: false` — the // ROLLED-BACK OVERLAYABLE tier (`permission` / `position` / // `page` / `app` / `dataset` / `book`, and any type that lands - // in this shape later). #6483 / PR #6608 closed the write door + // in this shape later). Commit ee58392e1 closed the write door // and left the read path merging overlay-wins, so a row // authored before the rollback still shapes the effective body // and the ordinary "Reset to package default" flow answered 403 @@ -23170,7 +23170,7 @@ export class ObjectStackProtocolImplementation implements // its `status` made it out. See {@link carryCatalogedErrorCode} // for why an unconditional copy is the wrong shape here. carryCatalogedErrorCode(e, err); - // [#12536] …and the same for the #9934 mark. A hook that + // [#12536] …and the same for the mark (commit 79c46da90). A hook that // refused this delete in its own words wrote that text for the // END USER; dropping it here destroys the channel exactly the // way the store-unavailable wrapper used to, one exit over. @@ -23682,7 +23682,7 @@ export class ObjectStackProtocolImplementation implements * channel for, and until this method the skip was **completely silent**. * * The measured specimen is `flow`. `flow` is `allowOrgOverride: false` - * (rolled back in #6283 / PR #6478, matching ADR-0005:57) but + * (rolled back in #6283 / commit 474f131cf, matching ADR-0005:57) but * `allowRuntimeCreate: true`, so a tenant authoring a BRAND-NEW flow in * Studio still writes `sys_metadata.organization_id = ''` — the * runtime `PUT /metadata/:type/:name` threads `resolveActiveOrganizationId` @@ -24026,7 +24026,7 @@ export class ObjectStackProtocolImplementation implements // the URL cut mid-path, which is an instruction that 404s if the // operator follows it. `crm_opportunity_line_item_snapshot_v2` is 37 // characters, and nothing in `packages/spec` caps a metadata name at - // all (#12144: the ceiling is the storing column's `maxLength`, and the + // all (commit 3a04b0125: the ceiling is the storing column's `maxLength`, and the // widest is `sys_metadata.name` at 255). // // Front-loaded, truncation costs the EXPLANATION instead — the half an diff --git a/packages/metadata-protocol/src/protocol.ui-view-hidden-columns.test.ts b/packages/metadata-protocol/src/protocol.ui-view-hidden-columns.test.ts index c624c7d16dd..bfcd487732c 100644 --- a/packages/metadata-protocol/src/protocol.ui-view-hidden-columns.test.ts +++ b/packages/metadata-protocol/src/protocol.ui-view-hidden-columns.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// [#13259] `hidden` is a floor on BOTH passes of `getUiView`'s list branch. +// [commit 2a75270b1] `hidden` is a floor on BOTH passes of `getUiView`'s list branch. // // `FieldSchema` declares `hidden` as "Hidden from default UI" // (`packages/spec/src/data/field.zod.ts`). `getUiView` IS the default UI — it diff --git a/packages/metadata-protocol/src/protocol.unrecognised-meta-type.test.ts b/packages/metadata-protocol/src/protocol.unrecognised-meta-type.test.ts index 4bc49204f19..9a1205fa3b5 100644 --- a/packages/metadata-protocol/src/protocol.unrecognised-meta-type.test.ts +++ b/packages/metadata-protocol/src/protocol.unrecognised-meta-type.test.ts @@ -28,7 +28,7 @@ * - a DECLARED type still saves (`view`), and so does a type whose only write * channel is runtime (`hook`); * - a PLUGIN kind with no static registry entry still saves (`webhook`; - * `theme` was the specimen until #10485 retired that kind entirely) — the + * `theme` was the specimen until commit 35ad101bc retired that kind entirely) — the * operation option C would have broken, and the one this change must not; * - READS of an unrecognised type still answer, because the live type set * legitimately holds keys the static contract does not (`data`, `kind` and @@ -43,7 +43,7 @@ * minted by definition — `protocol.stored-residue-resave.test.ts` carries the * production paths that made it necessary) still passes, while the COMPOUND * arity exemption (skip the verdict when the name contains a slash) is GONE — - * #12194's item-name grammar refuses every slash-bearing name BEFORE this + * Commit 311433f6b's item-name grammar refuses every slash-bearing name BEFORE this * verdict runs, so the request that needed it can no longer arrive * (`protocol.item-name-grammar.test.ts` is that door's own suite). * @@ -169,7 +169,7 @@ describe('#8421 — an unrecognised `/meta` type is refused instead of minted', }); it("[#10485] `theme` is now on the refused side — the retired kind left the spelling contract", async () => { - // Until #10485, `theme` was a URL-map-only plugin kind and this suite's + // Until commit 35ad101bc, `theme` was a URL-map-only plugin kind and this suite's // ACCEPTED specimen. The retirement removed the `themes: 'theme'` fold // from `PLURAL_TO_SINGULAR`, so `/meta/theme` now earns the same // ADR-0112 refusal as any minted namespace — loud, and nothing stored. @@ -218,7 +218,7 @@ describe('#8421 — the traffic that must keep working', () => { item: { name: 'probe_item', object: 'task', events: ['beforeUpdate'] }, }, { - // `theme` held this slot until #10485 retired the themes surface + // `theme` held this slot until commit 35ad101bc retired the themes surface // (ADR-0049) and `theme` left the URL-spelling contract with it. type: 'webhook', why: 'PLUGIN kind — no static registry entry at all', @@ -245,7 +245,7 @@ describe('#8421 — the traffic that must keep working', () => { // plugin kind is untouched. const { protocol, rows } = makeProtocol(); // Spec-valid body — this control measures the STATIC-contract door, - // not the shape check. (`theme` was the specimen until #10485.) + // not the shape check. (`theme` was the specimen until commit 35ad101bc.) const result = await protocol.saveMetaItem({ type: 'webhook', name: 'first_hook', @@ -299,12 +299,12 @@ describe('#8421 — the refusal is scoped to the door that MINTS', () => { describe('#8421/#12194 — the COMPOUND arity is refused at the grammar gate, not exempted here', () => { // `/metadata/lead/views/all_leads` → `type='lead'`, `name='views/all_leads'`. - // Until #12194 this door EXEMPTED that shape (skip the type verdict when + // Until commit 311433f6b this door EXEMPTED that shape (skip the type verdict when // the name contains a slash) because `lead` is an OBJECT name no static // contract can enumerate — and the exemption's residue was that // `PUT /meta/fieldz/a/b` minted a namespace. The item-name grammar now // refuses every slash-bearing name BEFORE this verdict runs (maintainer - // ruling 2026-08-25, #12176 stage 1), so the exemption is gone and the + // ruling 2026-08-25, stage 1, commit 311433f6b), so the exemption is gone and the // compound write is refused outright — for the GRAMMAR reason, with the // dotted qualified spelling as the prescription. const VIEW_BODY = { name: 'all_leads', label: 'All Leads', columns: ['name'] }; diff --git a/packages/metadata-protocol/src/protocol.validate-data.test.ts b/packages/metadata-protocol/src/protocol.validate-data.test.ts index 472bc84ad65..591d6c6f1dd 100644 --- a/packages/metadata-protocol/src/protocol.validate-data.test.ts +++ b/packages/metadata-protocol/src/protocol.validate-data.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// [#6037 / #4633 ruling D] `validateData` — the DataProtocol's validate-only +// [commit 18189983d / #4633 ruling D] `validateData` — the DataProtocol's validate-only // operation. // // The ruling attached one clause to this operation specifically: DECLARATION diff --git a/packages/metadata-protocol/src/seed-loader-composite-key-diagnostic.test.ts b/packages/metadata-protocol/src/seed-loader-composite-key-diagnostic.test.ts index 0d883433f59..d897db91eb7 100644 --- a/packages/metadata-protocol/src/seed-loader-composite-key-diagnostic.test.ts +++ b/packages/metadata-protocol/src/seed-loader-composite-key-diagnostic.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #16488 — a composite `externalId`'s NUL joiner must never reach a diagnostic. + * Commit 460d4b807 — a composite `externalId`'s NUL joiner must never reach a diagnostic. * * ## The ruling this file protects on BOTH sides * diff --git a/packages/metadata-protocol/src/seed-loader-deferred-dropped.test.ts b/packages/metadata-protocol/src/seed-loader-deferred-dropped.test.ts index 2a34032ecb3..7114185ce00 100644 --- a/packages/metadata-protocol/src/seed-loader-deferred-dropped.test.ts +++ b/packages/metadata-protocol/src/seed-loader-deferred-dropped.test.ts @@ -6,7 +6,7 @@ import type { IDataEngine, IMetadataService } from '@objectstack/spec/contracts' import { assertEngineDeleteDispatch, assertEngineUpdateDispatch, assertEngineFindOnePredicate } from '@objectstack/metadata-core'; /** - * #5127 / #11674 — pass 2 RESOLVES the target; does it have a record to write + * #5127 / commit 9a884c6e4 — pass 2 RESOLVES the target; does it have a record to write * it onto? * * #5127's finding: `resolveDeferredUpdates()` looked the source record's @@ -16,7 +16,7 @@ import { assertEngineDeleteDispatch, assertEngineUpdateDispatch, assertEngineFin * `referencesDeferred` nothing explained. #5127 made both roads to that state * loud. * - * #11674 then removed one of the roads at the root. Pass 2 now writes back + * Commit 9a884c6e4 then removed one of the roads at the root. Pass 2 now writes back * through the internal id CAPTURED AT INSERT TIME, so a row this load actually * wrote can always be written back to — a natural key is no longer required. * What used to be the "PURE SILENT LOSS" (row written fine, composite @@ -155,7 +155,7 @@ describe('pass 2 heals a row whose natural key evaluated empty (#5127 → #11674 * What #5127 pinned here as "THE PURE SILENT LOSS" — row written fine, * composite externalId ['name', 'region'] evaluating to `''` because * `region` is blank, pass 2 resolving 'Alice' perfectly and then having no - * handle to write her id onto — is exactly the structural defect #11674 + * handle to write her id onto — is exactly the structural defect commit 9a884c6e4 * removed: pass 2 no longer re-resolves the source row through its * externalId at all. The id the row got when it was INSERTED is captured * then and written back through now, so the empty key costs nothing. @@ -243,7 +243,7 @@ describe('pass 2 heals a row whose natural key evaluated empty (#5127 → #11674 /** * The keyed sibling: same composite key, `region` filled in. The key * registers AND the internal id is captured, and the outcome is identical to - * the empty-key case above — which is the point of #11674: keyedness no + * the empty-key case above — which is the point of commit 9a884c6e4: keyedness no * longer decides whether a deferral can land, so the two paths are pinned to * the same healed outcome and cannot drift apart. */ @@ -368,10 +368,10 @@ describe('pass 2 finds no id because the source row failed in pass 1 (#5127)', ( /** * The same "source row never landed" failure on a record with NO usable - * natural key (#11674) — the composite key evaluates to `''` AND the pass-1 + * natural key (commit 9a884c6e4) — the composite key evaluates to `''` AND the pass-1 * insert fails, so neither the captured-internal-id channel nor the * natural-key fallback can name a row. This is the one way left to reach the - * empty-key drop branch: before #11674 that branch claimed "The row itself WAS + * empty-key drop branch: before commit 9a884c6e4 that branch claimed "The row itself WAS * seeded" and prescribed fixing the externalId components, both of which would * be lies now (a row that seeds heals; the key is not the problem). The * rewritten line names the record by INDEX — the only handle a keyless record diff --git a/packages/metadata-protocol/src/seed-loader-existing-records-read-failure.test.ts b/packages/metadata-protocol/src/seed-loader-existing-records-read-failure.test.ts index 7ee30da60e9..af1270817f1 100644 --- a/packages/metadata-protocol/src/seed-loader-existing-records-read-failure.test.ts +++ b/packages/metadata-protocol/src/seed-loader-existing-records-read-failure.test.ts @@ -66,7 +66,7 @@ function createLogger() { * is what turns "the seed proceeded" into "the seed proceeded AND the injected * throw fired". * - * [#13324] It also accepts a FUNCTION of the object name, because the loader + * [commit 4cda78c9b] It also accepts a FUNCTION of the object name, because the loader * reads more than one table on this path (`sys_organization` for the sole-org * probe, then the seeded object) and a missing-table fault names the table it * was raised for. A single fixed value phrased for one of them is a fault that diff --git a/packages/metadata-protocol/src/seed-loader-pointer-pair.test.ts b/packages/metadata-protocol/src/seed-loader-pointer-pair.test.ts index 76db8fa3899..66389d2073b 100644 --- a/packages/metadata-protocol/src/seed-loader-pointer-pair.test.ts +++ b/packages/metadata-protocol/src/seed-loader-pointer-pair.test.ts @@ -440,14 +440,14 @@ describe('seed pointer-pair resolution (#11339 — referenceVia)', () => { * and therefore has no case here; the verdict and its reasons are recorded at * the declaration site (`sys-automation-run.object.ts`, `trigger_record_id`). * - * ## Ordering: what heals, what still requires the target first (#11674) + * ## Ordering: what heals, what still requires the target first (commit 9a884c6e4) * * `sys_activity` heals an out-of-order pointer in pass 2 (the * order-independence case above). Whether these four inherit that was * measured rather than assumed, and the answer SPLIT — by dataset keyedness * first, then by the `required` flag on the id half: * - * - MEASURED, healed by #11674: all four are engine-owned rows with no + * - MEASURED, healed by commit 9a884c6e4: all four are engine-owned rows with no * natural key, so an honest seed dataset for them declares no * `externalId`. Pass 2 used to back-fill by looking the row up BY its * externalId, so a keyless deferral resolved the target and then had @@ -464,7 +464,7 @@ describe('seed pointer-pair resolution (#11339 — referenceVia)', () => { * DELETING the column from the row. The real engine enforces `required` * on seed inserts (SEED_OPTIONS skips only state_machine), so the * deferred insert is rejected before pass 2 can help — an independent, - * equally LOUD road that #11674's write-back does NOT clear. For those + * equally LOUD road that commit 9a884c6e4's write-back does NOT clear. For those * three, order the target dataset first; `sys_audit_log` (optional id * half) is genuinely order-independent now. */ @@ -562,12 +562,12 @@ describe('pointer-pair adoption per object (#11386)', () => { * authoring for an engine-owned ledger — no natural key) had no such * handle, so the deferral resolved the target and then dropped the link * LOUDLY ("Deferred reference DROPPED … empty externalId"). That - * order-dependence is the defect #11674 names: the declared deferral + * order-dependence is the defect commit 9a884c6e4 heals: the declared deferral * property ("a pointer pair contributes no static ordering edge, pass 2 * heals it") did not hold for exactly the datasets the four adopted * objects ship. * - * #11674's fix makes pass 2 write back through the internal id captured + * Commit 9a884c6e4's fix makes pass 2 write back through the internal id captured * at insert time, so the property now holds without requiring a key. * This case pins the healed behaviour; the keyed sibling below pins that * the pre-existing keyed path still heals identically (it was the @@ -868,7 +868,7 @@ describe('pointer-pair adoption per object (#11386)', () => { }); /** - * The load-time EARLY SIGNAL for a deferral on a `required` column — #11674's + * The load-time EARLY SIGNAL for a deferral on a `required` column — commit 1cba33f16, the * B half, ruled by triage on 2026-08-24 as "warn (loud) by default", scoped to * the required subset, and ⛔ NOT allowed to change the accept set. * diff --git a/packages/metadata-protocol/src/seed-loader-sole-organization-read-failure.test.ts b/packages/metadata-protocol/src/seed-loader-sole-organization-read-failure.test.ts index cc61f5e291a..348b7b22528 100644 --- a/packages/metadata-protocol/src/seed-loader-sole-organization-read-failure.test.ts +++ b/packages/metadata-protocol/src/seed-loader-sole-organization-read-failure.test.ts @@ -14,7 +14,7 @@ * organization" and "the read could not run" are different facts. * * The sibling probe on the objectql side, `ObjectQL.probeInstallOrganizations`, - * had the SAME shape and was repaired by PR #9817 to bind the parameter and ask + * had the SAME shape and was repaired by commit 855591fe7 to bind the parameter and ask * the declared predicate. This site was missed by that pass; the repair here is * that repair, copied. * diff --git a/packages/metadata-protocol/src/seed-loader.ts b/packages/metadata-protocol/src/seed-loader.ts index 07c291dd54b..41b999ca3ec 100644 --- a/packages/metadata-protocol/src/seed-loader.ts +++ b/packages/metadata-protocol/src/seed-loader.ts @@ -362,7 +362,7 @@ function localeScopeLabel(dataset: Seed): string { * - Topological dependency ordering (parents before children) * - Multi-pass loading for circular references — pass 2 writes a deferred * reference back through the source row's INTERNAL id captured at insert - * time (#11674), so it heals KEYLESS datasets (`mode: 'insert'`, no + * time (commit 9a884c6e4), so it heals KEYLESS datasets (`mode: 'insert'`, no * `externalId`) the same as keyed ones * - Dry-run validation mode * - Upsert support honoring SeedSchema mode @@ -438,7 +438,7 @@ export class SeedLoaderService implements ISeedLoaderService { */ private seedExternalIdByObject = new Map(); /** - * [#11674] Per seeded object, the fields the WRITE CONTRACT requires a value + * [commit 1cba33f16] Per seeded object, the fields the WRITE CONTRACT requires a value * for **on insert** — the subset a pass-1 deferral cannot survive. * * Pass 1 defers an unresolvable reference by DELETING the column from the @@ -613,7 +613,7 @@ export class SeedLoaderService implements ISeedLoaderService { // `referenceVia` on other types at authoring, and metadata at rest that // predates that check must not have non-text columns resolved as ids. // - // [#11674] The same pass also records which fields the write contract + // [commit 1cba33f16] The same pass also records which fields the write contract // requires on insert — the subset a deferral cannot survive. One // definition read answers both questions, so the early signal costs no // extra metadata round-trip. See {@link requiredOnInsertByObject}. @@ -832,7 +832,7 @@ export class SeedLoaderService implements ISeedLoaderService { const summariesStaleAtStart = this.summariesStale; const errors: ReferenceResolutionError[] = []; /** - * [#11674] The early signal's state, for this dataset only. + * [commit 1cba33f16] The early signal's state, for this dataset only. * * `requiredOnInsert` is what the write contract requires a value for on * insert (see {@link SeedLoaderService.requiredOnInsertByObject}); an @@ -888,7 +888,7 @@ export class SeedLoaderService implements ISeedLoaderService { // logical/validation failure. See framework#2678. const pendingInserts: Array<{ recordIndex: number; externalIdValue: string; record: Record }> = []; const opts = SeedLoaderService.SEED_OPTIONS as any; - // [#11674] Internal ids captured at write time, keyed by record index. + // [commit 9a884c6e4] Internal ids captured at write time, keyed by record index. // Every write site below records the id it learned here — unconditionally, // unlike the `insertedRecords` registrations, which need a non-empty // natural key. Once the dataset has fully written, the deferred updates it @@ -990,7 +990,7 @@ export class SeedLoaderService implements ISeedLoaderService { if (res.ok) { inserted++; const internalId = this.extractId(res.record); - if (internalId) internalIdByRecordIndex.set(recordIndex, internalId); // [#11674] + if (internalId) internalIdByRecordIndex.set(recordIndex, internalId); // [commit 9a884c6e4] if (externalIdValue && internalId) { insertedRecords.get(objectName)!.set(externalIdValue, internalId); } @@ -1077,7 +1077,7 @@ export class SeedLoaderService implements ISeedLoaderService { } const record = { ...(seedResult.value as Record) }; /** - * [#11674] Deferrals this row took on a column the write contract + * [commit 1cba33f16] Deferrals this row took on a column the write contract * requires on insert. Collected during resolution, reported once the * write ACTION for this row is known (below) — the deferral itself is * harmless on an update, where the deleted column is simply an omitted @@ -1351,7 +1351,7 @@ export class SeedLoaderService implements ISeedLoaderService { recordIndex: i, }); referencesDeferred++; - // [#11674] Deferring DELETED a column the write contract requires + // [commit 1cba33f16] Deferring DELETED a column the write contract requires // on insert. Note it now; the signal is emitted once this row's // write action is known — see `signalRequiredDeferrals` below. if (requiredOnInsert?.has(ref.field)) { @@ -1416,7 +1416,7 @@ export class SeedLoaderService implements ISeedLoaderService { continue; } - // [#11674] EARLY SIGNAL — emitted here, before this row reaches the + // [commit 1cba33f16] EARLY SIGNAL — emitted here, before this row reaches the // engine, for the deferrals it took on columns the write contract // requires on INSERT. // @@ -1476,7 +1476,7 @@ export class SeedLoaderService implements ISeedLoaderService { const externalIdValue = this.externalIdKey(record, externalId); const internalId = result.id; - if (internalId) internalIdByRecordIndex.set(i, String(internalId)); // [#11674] + if (internalId) internalIdByRecordIndex.set(i, String(internalId)); // [commit 9a884c6e4] if (externalIdValue && internalId) { insertedRecords.get(objectName)!.set(externalIdValue, String(internalId)); } @@ -1487,7 +1487,7 @@ export class SeedLoaderService implements ISeedLoaderService { // mapping alive for downstream reference resolution. const externalIdValue = this.externalIdKey(record, externalId); const existingId = this.extractId(existingRecords?.get(externalIdValue)); - if (existingId) internalIdByRecordIndex.set(i, existingId); // [#11674] + if (existingId) internalIdByRecordIndex.set(i, existingId); // [commit 9a884c6e4] if (externalIdValue && existingId) { insertedRecords.get(objectName)!.set(externalIdValue, existingId); } @@ -1510,7 +1510,7 @@ export class SeedLoaderService implements ISeedLoaderService { if (decision.action === 'skip') { skipped++; - if (decision.id) internalIdByRecordIndex.set(i, decision.id); // [#11674] + if (decision.id) internalIdByRecordIndex.set(i, decision.id); // [commit 9a884c6e4] if (decision.id && externalIdValue) { insertedRecords.get(objectName)!.set(externalIdValue, decision.id); } @@ -1522,7 +1522,7 @@ export class SeedLoaderService implements ISeedLoaderService { // sever downstream natural-key resolution — that cascade is what // turned one legitimate validation error into NULLed-out child // references on every dev-server restart. - if (decision.id) internalIdByRecordIndex.set(i, decision.id); // [#11674] same rationale + if (decision.id) internalIdByRecordIndex.set(i, decision.id); // [commit 9a884c6e4] same rationale if (externalIdValue) { insertedRecords.get(objectName)!.set(externalIdValue, decision.id); } @@ -1567,7 +1567,7 @@ export class SeedLoaderService implements ISeedLoaderService { await flushPendingInserts(); } - // [#11674] Annotate this dataset's deferred updates with the internal id + // [commit 9a884c6e4] Annotate this dataset's deferred updates with the internal id // their source row got when it was written — the id pass 2 writes the // resolved reference back through. Runs after the final flush so batched // inserts have reported their ids; datasets load sequentially, so the @@ -1624,7 +1624,7 @@ export class SeedLoaderService implements ISeedLoaderService { return id ? String(id) : undefined; } } catch (error) { - // [#12852] Discriminate by error TYPE, the same repair PR #9817 made to + // [#12852] Discriminate by error TYPE, the same repair commit 855591fe7 made to // `ObjectQL.probeInstallOrganizations` — the sibling probe with this // exact shape, on the other side of the engine boundary. This site was // missed by that pass. @@ -1827,7 +1827,7 @@ export class SeedLoaderService implements ISeedLoaderService { organizationId?: string, ): Promise { for (const deferred of deferredUpdates) { - // [#16488] How the messages below NAME this record. `recordExternalId` + // [commit 460d4b807] How the messages below NAME this record. `recordExternalId` // is a map KEY joined with `\u0000` (see {@link externalIdKey}) and stays // one — the `insertedRecords` fallback lookup below depends on it — but a // raw NUL in a log line turns the whole log binary for `grep`, so every @@ -1863,7 +1863,7 @@ export class SeedLoaderService implements ISeedLoaderService { const resolvedValue: unknown = deferred.multiple ? resolvedItems : resolvedItems[0]; if (!stillUnresolved && resolvedItems.length > 0) { - // [#11674] Write back through the internal id captured at insert time + // [commit 9a884c6e4] Write back through the internal id captured at insert time // — the handle that exists for every row this load actually wrote, // keyed or KEYLESS, so the declared deferral property ("pass 2 heals // an out-of-order reference") holds without requiring the dataset to @@ -1936,15 +1936,15 @@ export class SeedLoaderService implements ISeedLoaderService { `Failed to write deferred reference: ${deferred.objectName}.${deferred.field} = '${this.formatAttempted(deferred.attemptedValue)}' → ${deferred.targetObject}.${deferred.targetField}: ${quotableSeedFailureDetail(err) ?? WITHHELD_WRITE_REASON}`); } } else { - // THE TARGET RESOLVED BUT THE SOURCE ROW HAS NO ID (#5127, #11674). + // THE TARGET RESOLVED BUT THE SOURCE ROW HAS NO ID (#5127, commit 9a884c6e4). // // Pass 2 did its job — `resolvedValue` is a real internal id — and - // then found no internal id to write it ONTO. Since #11674 captures + // then found no internal id to write it ONTO. Since commit 9a884c6e4 captures // the internal id AT INSERT TIME for every row this load writes // (keyed or keyless), the one way left to get here is that the // source row NEVER LANDED: its pass-1 write failed (already // reported at `error` by the write site, #4729) or returned no id. - // The pre-#11674 "pure silent loss" — row written fine but its key + // The "pure silent loss" before commit 9a884c6e4 — row written fine but its key // evaluated empty, so pass 2's externalId re-resolution had no // handle — no longer exists: such a row now heals through its // captured internal id. @@ -2394,7 +2394,7 @@ export class SeedLoaderService implements ISeedLoaderService { * from the seed declaration and the record, never from the caught error, so * "which record, which key" is untouched by the withhold. For a single-field * key the authored prefix is unchanged byte for byte too (two runtime pins - * read it); #16488 renders the VALUE side of a COMPOSITE key — see + * read it); commit 460d4b807 renders the VALUE side of a COMPOSITE key — see * {@link externalIdDisplay} — so its `\u0000` joiner cannot reach the log. * What #8442 changes is only what follows the colon: a DECLARED refusal — a 4xx, or the data * engine's `VALIDATION_FAILED` shape, which is where "which field and why" @@ -2417,7 +2417,7 @@ export class SeedLoaderService implements ISeedLoaderService { field: '(write)', targetObject: objectName, targetField: label, - // [#16488] The STRUCTURED key keeps the real key — a datum a machine + // [commit 460d4b807] The STRUCTURED key keeps the real key — a datum a machine // reads, and JSON / util.inspect escape a control character rather than // emitting it. Only the message is rendered. attemptedValue: keyValue || null, @@ -2857,7 +2857,7 @@ export class SeedLoaderService implements ISeedLoaderService { * `grep` classify the whole server log as binary, so every later `grep -n` / * `grep -c` over it silently returns nothing until the reader remembers * `-a`: the reader's main instrument disabled by one byte, at the moment - * someone is diagnosing a failed boot (#16488, measured while investigating + * someone is diagnosing a failed boot (commit 460d4b807, measured while investigating * objectstack-ai/ats#20). * * A key with no `\u0000` in it — every single-field key — is returned @@ -2966,7 +2966,7 @@ interface DeferredUpdate { objectName: string; /** * The source record's INTERNAL id, captured at the moment its pass-1 write - * landed (#11674). This is the handle pass 2 writes the resolved reference + * landed (commit 9a884c6e4). This is the handle pass 2 writes the resolved reference * back through: it exists for every row this load actually wrote — * including rows of a KEYLESS dataset (`mode: 'insert'`, no `externalId`) * and rows whose composite key evaluated to the empty string — so the @@ -2986,13 +2986,13 @@ interface DeferredUpdate { * when {@link internalId} is absent, and the name error messages call the * record by. It is the KEY, `\u0000` joiner and all; the messages render it * through {@link SeedLoaderService.externalIdDisplay} rather than pasting it - * (#16488). + * (commit 460d4b807). * * May legitimately be `''`: `externalIdKey` returns the empty string when the * dataset declares no `externalId` and the row carries no `name`, when the * key field is absent or blank, and when ANY ONE component of a composite * externalId is. An empty key is never registered in `insertedRecords`, so - * it can never find a record — since #11674 that only matters when + * it can never find a record — since commit 9a884c6e4 that only matters when * `internalId` is ALSO absent (the row never landed). Carried verbatim (not * normalised to `undefined`) so pass 2 can address the record by index * rather than by a key it does not have. diff --git a/packages/metadata-protocol/src/sys-metadata-repository-14078-invalid-date-total-arm.test.ts b/packages/metadata-protocol/src/sys-metadata-repository-14078-invalid-date-total-arm.test.ts index a6625e57081..6ed75e18dfa 100644 --- a/packages/metadata-protocol/src/sys-metadata-repository-14078-invalid-date-total-arm.test.ts +++ b/packages/metadata-protocol/src/sys-metadata-repository-14078-invalid-date-total-arm.test.ts @@ -15,7 +15,7 @@ * * ## Reachability is measured, not argued * - * PR #14409 (landed `3ecb7dc1a`) drove both live client libraries: mysql2 + * Commit `3ecb7dc1a` drove both live client libraries: mysql2 * 3.23.1 returns a module constant literally named `INVALID_DATE` for a zero * `DATETIME`, and postgres-date 1.0.7 builds `new Date(NaN)` for every year in * 275760..294276 — a range Postgres itself stores. The shape is not diff --git a/packages/metadata-protocol/src/sys-metadata-repository-14938-list-drafts-updated-at.test.ts b/packages/metadata-protocol/src/sys-metadata-repository-14938-list-drafts-updated-at.test.ts index 6c03d74ab83..9931fb62d5a 100644 --- a/packages/metadata-protocol/src/sys-metadata-repository-14938-list-drafts-updated-at.test.ts +++ b/packages/metadata-protocol/src/sys-metadata-repository-14938-list-drafts-updated-at.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14938] `SysMetadataRepository.listDrafts` declares `updatedAt: string | + * [commit c383352cb] `SysMetadataRepository.listDrafts` declares `updatedAt: string | * null` and used to emit the raw `updated_at` column, so on Postgres and MySQL * it handed a JS `Date` through a field its own signature calls a string. * @@ -92,7 +92,7 @@ const PG_INSTANT = new Date('2026-03-04T05:06:07.089Z'); const PG_CREATED = new Date('2026-01-02T03:04:05.006Z'); /** - * Reachable on BOTH live dialects (#14409): mysql2 3.23.1 answers a module + * Reachable on BOTH live dialects (commit `3ecb7dc1a`): mysql2 3.23.1 answers a module * constant literally named `INVALID_DATE` for a zero `DATETIME`, and * postgres-date 1.0.7 builds `new Date(NaN)` for every year in 275760..294276 * — years Postgres itself stores. diff --git a/packages/metadata-protocol/src/sys-metadata-repository.contract.test.ts b/packages/metadata-protocol/src/sys-metadata-repository.contract.test.ts index 9ff51addda4..99ef73ef756 100644 --- a/packages/metadata-protocol/src/sys-metadata-repository.contract.test.ts +++ b/packages/metadata-protocol/src/sys-metadata-repository.contract.test.ts @@ -184,7 +184,7 @@ runRepositoryContractTests('SysMetadataRepository', makeRepo, { // type — is not, on purpose (packaged objects are locked); `'dashboard'` is. primaryType: 'view', secondaryType: 'dashboard', - // #10842 — the `declaredDivergences: { resumableWatch: '#10842' }` line that + // commit f334d662e — the `declaredDivergences: { resumableWatch: … }` line that // stood here is GONE, deleted by the PR that made invariant 6 true for this // implementation: `watch(filter, since)` now replays from // `sys_metadata_history` before going live. The pin clause the declaration @@ -252,7 +252,7 @@ describe('SysMetadataRepository — what the contract suite does and does not re }); /** - * #10842 — invariant 6's TWO halves, pinned where they are implementation + * Commit f334d662e — invariant 6's TWO halves, pinned where they are implementation * facts rather than table entries. * * The shared suite asserts the floor every `MetadataRepository` owes and @@ -451,7 +451,7 @@ describe('SysMetadataRepository — invariant 6, both halves (#10842)', () => { }); /** - * #11021 — what `close()` owes a pending iterator. + * Commit 7d81c889f — what `close()` owes a pending iterator. * * `close()` used to model shutdown as a metadata EVENT: it broadcast a * synthetic `{ seq: -1, ref: { org: '', type: 'view', name: '_close' } }` diff --git a/packages/metadata-protocol/src/sys-metadata-repository.ts b/packages/metadata-protocol/src/sys-metadata-repository.ts index 8e75991e4eb..58130dc596d 100644 --- a/packages/metadata-protocol/src/sys-metadata-repository.ts +++ b/packages/metadata-protocol/src/sys-metadata-repository.ts @@ -133,7 +133,7 @@ import { packagedBaseRegimePrescription, packagedBaseRegimeSentence } from './pa * because a guard on some arms and not others re-opens the drift the single * spelling closed. * - * Reachability is MEASURED, not assumed (#14409, landed `3ecb7dc1a`): mysql2 + * Reachability is MEASURED, not assumed (commit `3ecb7dc1a`): mysql2 * 3.23.1 returns a module constant literally named `INVALID_DATE` for a zero * `DATETIME`, and postgres-date 1.0.7 builds `new Date(NaN)` for every year in * 275760..294276 — years Postgres itself stores. Unguarded, @@ -145,7 +145,7 @@ import { packagedBaseRegimePrescription, packagedBaseRegimeSentence } from './pa * The terminal value is chosen **per call site**, and this one's is * `undefined`: every caller already carries such a chain — `getByHash` and * `rowToItem` end in `?? new Date(...).toISOString()`, `rowToEvent` (#16422) - * in `?? new Date(0).toISOString()`, `listDrafts` (#14938) in `?? null` — + * in `?? new Date(0).toISOString()`, `listDrafts` (commit c383352cb) in `?? null` — * the branch an absent column takes at each of them today. * The ruling assigns `undefined` exactly where "the field is optional and the * caller already carries a `?? default` chain". ⛔ NOT the visible text @@ -366,7 +366,7 @@ export function resetEnvWritableMetadataTypes(): void { * Both halves live together because SHUTDOWN NEEDS THE SECOND ONE. A registry * of event sinks can only express shutdown as "send an event", and an event is * precisely what a filtered or numeric-`since` subscriber is entitled to drop - * (#11021). + * (commit 7d81c889f). */ interface WatchSubscription { /** Receives every broadcast event; applies this subscriber's own filters. */ @@ -1165,7 +1165,7 @@ export class SysMetadataRepository implements MetadataRepository { name: row.name, organizationId: row.organization_id ?? null, packageId: row.package_id ?? null, - // [#14938] `updated_at` / `created_at` are the BUILTIN audit columns, + // [commit c383352cb] `updated_at` / `created_at` are the BUILTIN audit columns, // and on Postgres and MySQL they used to arrive here as a JS `Date`: // the audit repair and the declared-datetime fold both sat inside // `SqlDriver#formatOutput`'s `if (this.isSqlite)` arm. #13973 @@ -1310,7 +1310,7 @@ export class SysMetadataRepository implements MetadataRepository { * * ## `since` — invariant 6, both halves * - * **Numeric `since`** (#10842): every logged event with `seq > since` is + * **Numeric `since`** (commit f334d662e): every logged event with `seq > since` is * replayed out of `sys_metadata_history` before any live event is yielded. * `since` used to be nothing but a DROP filter on live events, so an event * that had already committed was unreachable through `watch()` however low @@ -1346,7 +1346,7 @@ export class SysMetadataRepository implements MetadataRepository { * it and {@link close} runs the identical routine. Either settles a parked * `next()` with `{ done: true }` and no value. A consumer therefore never * has to recognise a shutdown *event* — there is not one to recognise, which - * is the #11021 repair; see `close()` for what modelling it as an event cost. + * is the repair in commit 7d81c889f; see `close()` for what modelling it as an event cost. * Anything still queued or unreplayed at that point is dropped, on both * paths alike. */ @@ -1459,7 +1459,7 @@ export class SysMetadataRepository implements MetadataRepository { /** * Shut down every live `watch()` iterator. * - * **Shutdown is not a metadata event** — #11021, and the reason this method + * **Shutdown is not a metadata event** — commit 7d81c889f, and the reason this method * no longer broadcasts anything. It used to push a synthetic * `{ seq: -1, ref: { org: '', type: 'view', name: '_close' } }` through the * same `dispatch` closure real events pass, then clear the registry. Both of @@ -1829,7 +1829,7 @@ export class SysMetadataRepository implements MetadataRepository { * kernel (`environmentId === undefined`) skips the protocol's own two-tier * block entirely and lands here instead. That made it the second of the two * refusal points #6960 measured: on an environment carrying an overlay row - * authored BEFORE #6483 / PR #6608 rolled `allowOrgOverride` back to + * authored BEFORE commit ee58392e1 rolled `allowOrgOverride` back to * `false`, the row kept merging overlay-wins at read time while the ordinary * "Reset to package default" answered 403 — the removal reachable only * through `OS_METADATA_WRITABLE`. Maintainer ruling, 2026-08-10: the delete @@ -1844,7 +1844,7 @@ export class SysMetadataRepository implements MetadataRepository { * - `supportsOverlay: true` — the loader merges the row, so a row under * this name really is a customization sitting on top of a code-declared * default, and subtracting it restores that default. This is the tier - * #6483 rolled back (`permission` / `position` / `page` / `app` / + * commit ee58392e1 rolled back (`permission` / `position` / `page` / `app` / * `dataset` / `book`). * - `supportsOverlay: false` — `object` above all, whose overlay registers * as its own contributor LAYER (ADR-0029 D9) rather than merging, and @@ -1857,7 +1857,7 @@ export class SysMetadataRepository implements MetadataRepository { * * - It does not touch `put`. Create and update on such an item stay refused * exactly as today; the asymmetry is the ruling, not an oversight, and - * "restoring symmetry" here re-opens the write door #6483 closed. + * "restoring symmetry" here re-opens the write door commit ee58392e1 closed. * - It does not widen `runtime-only`. That intent means "no artifact under * this name", which the `allowRuntimeCreate` tier already governs — so * the carve-out is scoped to the `override-artifact` intent, which is @@ -2065,7 +2065,7 @@ export class SysMetadataRepository implements MetadataRepository { subject: string, ): 1 { // Benign — and only benign: a fresh DB has no row to be inconsistent with. - // [#13324] Both callers read `this.historyTable`, so a failure naming any + // [commit 4cda78c9b] Both callers read `this.historyTable`, so a failure naming any // other relation is not evidence that THIS one is empty. if (isMissingTableError(error, this.historyTable)) return 1; diff --git a/packages/metadata-protocol/tsup.config.ts b/packages/metadata-protocol/tsup.config.ts index d14f44ac17a..3ce826683cc 100644 --- a/packages/metadata-protocol/tsup.config.ts +++ b/packages/metadata-protocol/tsup.config.ts @@ -12,7 +12,7 @@ export default defineConfig({ dts: !process.env.OS_SKIP_DTS, format: ['esm', 'cjs'], target: 'es2020', - // [#11235] LOAD-BEARING, and measured rather than assumed. `discovery- + // [commit 376c70f98] LOAD-BEARING, and measured rather than assumed. `discovery- // version.ts` reads its own `package.json` via // `createRequire(import.meta.url)` — correct as written for the ESM output. // `shims: true` makes tsup rewrite `import.meta.url` in the CJS build to a