From 7f9836c0eef5f50d668489393e79a592c0e0bfeb Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 2 Oct 2026 10:17:25 +0000 Subject: [PATCH 1/2] docs(metadata): re-anchor the dead tracker citations to the commits that decided them (stage 6 of #20595) Every comment or docblock site in packages/metadata that cited a tracker number answering 404 now cites the commit in this repository that decided it (ruling C+D, form C), or, for objectui's #6111, spells that repository's qualifier: 75 sites on 74 lines in 24 files, 18 numbers. Comment prose only; every file keeps its line count. Claude-Session: https://claude.ai/code/session_017xfMoEjKUuSh2xYB8sCozp Co-authored-by: Claude --- packages/metadata/src/errors.ts | 4 ++-- packages/metadata/src/index.ts | 4 ++-- .../src/loaders/ambiguous-metadata-stem.ts | 6 ++--- ...oader-14078-invalid-date-total-arm.test.ts | 2 +- .../metadata/src/loaders/database-loader.ts | 6 ++--- .../filesystem-loader-ambiguous-stem.test.ts | 14 +++++------ .../filesystem-loader-keyed-items.test.ts | 8 +++---- ...ilesystem-loader-list-reachability.test.ts | 12 +++++----- .../metadata/src/loaders/filesystem-loader.ts | 24 +++++++++---------- .../remote-loader-list-nameless.test.ts | 10 ++++---- .../metadata/src/loaders/remote-loader.ts | 4 ++-- ...metadata-manager-keyed-plural-read.test.ts | 4 ++-- packages/metadata/src/metadata-manager.ts | 16 ++++++------- .../metadata/src/metadata-route-ledger.ts | 2 +- .../metadata/src/metadata-service.test.ts | 2 +- packages/metadata/src/metadata.test.ts | 2 +- .../raw-exec-operator-detail-16657.test.ts | 2 +- ...lugin-unbound-form-predicate-roots.test.ts | 6 ++--- packages/metadata/src/plugin.ts | 6 ++--- .../src/routes/hmr-routes-dev-gate.test.ts | 2 +- packages/metadata/src/routes/hmr-routes.ts | 4 ++-- .../metadata/src/view-container-expansion.ts | 2 +- packages/metadata/src/view-container.ts | 4 ++-- packages/metadata/tsup.config.ts | 2 +- 24 files changed, 74 insertions(+), 74 deletions(-) diff --git a/packages/metadata/src/errors.ts b/packages/metadata/src/errors.ts index 00889a8cce8..059288f4c1e 100644 --- a/packages/metadata/src/errors.ts +++ b/packages/metadata/src/errors.ts @@ -24,7 +24,7 @@ * `@objectstack/spec/shared`). Architecturally attractive and explicitly * *not* precluded by this module — but out of scope on the round that * needed it (spec was frozen; types was under concurrent change). - * ⇒ **TAKEN, by the maintainer's 2026-08-30 ruling on #13279.** The + * ⇒ **TAKEN, by the maintainer's 2026-08-30 ruling (commit 6a180e42d).** The * predicate now lives in `@objectstack/types` * (`driver-error-classification.ts`); what forced it was a consumer this * file could never serve — `resolveAuthzContext` in `@objectstack/core`, @@ -37,7 +37,7 @@ * Option 2 is taken, so this is the compatibility seam it always said it would * become — "a single, greppable seam to delete if the maintainer later takes * option 2". It is NOT deleted: `@objectstack/metadata/errors` is a published - * subpath with out-of-repo consumers, and #13279 is a fix, not a removal. It + * subpath with out-of-repo consumers, and commit 6a180e42d is a fix, not a removal. It * re-exports the one symbol it always exported, from the new home. Everything * below still describes why the subpath exists and why it stays narrow. * diff --git a/packages/metadata/src/index.ts b/packages/metadata/src/index.ts index bd7532ce547..072b4b5b7b7 100644 --- a/packages/metadata/src/index.ts +++ b/packages/metadata/src/index.ts @@ -19,7 +19,7 @@ export { MemoryLoader } from './loaders/memory-loader.js'; export { RemoteLoader } from './loaders/remote-loader.js'; export { DatabaseLoader, type DatabaseLoaderOptions } from './loaders/database-loader.js'; -// [#14921] The ambiguous-stem refusal. Published from the ROOT entry, not only +// [commit c1d274de7] The ambiguous-stem refusal. Published from the ROOT entry, not only // from `./node` beside `FilesystemLoader`: the error reaches consumers through // `MetadataManager.listNames()` / `list()`, which live here, and a caller that // wants to tell "this deployment's metadata tree names one item twice" apart @@ -54,7 +54,7 @@ export { TypeScriptSerializer } from './serializers/typescript-serializer.js'; // View container binding // -// [#14399] `deriveViewContainerObject` is this package's ONE spelling of "which +// [commit 3c1bbd2a8] `deriveViewContainerObject` is this package's ONE spelling of "which // object does an aggregated `defineView` container bind to" — the container's // own top-level `object` first, then `list.data.object`, `form.data.object`, // and the row's own `name` last (its own docblock carries the ruling). It is diff --git a/packages/metadata/src/loaders/ambiguous-metadata-stem.ts b/packages/metadata/src/loaders/ambiguous-metadata-stem.ts index 0b5b3f36965..7f0d7600dad 100644 --- a/packages/metadata/src/loaders/ambiguous-metadata-stem.ts +++ b/packages/metadata/src/loaders/ambiguous-metadata-stem.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#14921] The refusal a metadata source tree earns by naming one item twice. + * [commit c1d274de7] The refusal a metadata source tree earns by naming one item twice. * * ## The invariant this restores * @@ -21,7 +21,7 @@ * diagnostic anywhere, and `MetadataManager.admitLoaderItems()`'s documented * "keep the first and say nothing" absorbs the collision a second time. * - * ## The ruling (maintainer, via the director seat on #14921, 2026-09-05) + * ## The ruling (maintainer, via the director seat, 2026-09-05; landed as commit c1d274de7) * * Option 1 of three: **refuse the ambiguous stem loudly at list time.** Two * files sharing a stem across the registered extensions is an AUTHORING ERROR, @@ -37,7 +37,7 @@ * * ## Why a brand and a predicate rather than bare `instanceof` * - * `MetadataManager`'s plural reads catch per loader on purpose (#5108/#14423): + * `MetadataManager`'s plural reads catch per loader on purpose (#5108 and commit a56baa2bd): * a storage outage must degrade to a short-but-served list rather than take the * whole enumeration down. This refusal is the opposite kind of fact — an * author's tree is malformed and no retry fixes it — so those seams have to diff --git a/packages/metadata/src/loaders/database-loader-14078-invalid-date-total-arm.test.ts b/packages/metadata/src/loaders/database-loader-14078-invalid-date-total-arm.test.ts index 0fdc5314593..e78fc5475c4 100644 --- a/packages/metadata/src/loaders/database-loader-14078-invalid-date-total-arm.test.ts +++ b/packages/metadata/src/loaders/database-loader-14078-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, which Postgres * itself stores. Ruled option B by the maintainer on 2026-09-02, on all five diff --git a/packages/metadata/src/loaders/database-loader.ts b/packages/metadata/src/loaders/database-loader.ts index e5420e91573..6a472096e20 100644 --- a/packages/metadata/src/loaders/database-loader.ts +++ b/packages/metadata/src/loaders/database-loader.ts @@ -27,7 +27,7 @@ import type { IDataDriver, IDataEngine, DriverQuery } from '@objectstack/spec/co import type { MetadataLoader, MetadataKeyedItem } from './loader-interface.js'; import { calculateChecksum } from '../utils/metadata-history-utils.js'; import { LRUCache } from '../utils/lru-cache.js'; -// [#13279] Both predicates moved to `@objectstack/types` — see its +// [commit 6a180e42d] Both predicates moved to `@objectstack/types` — see its // `driver-error-classification.ts` `## Home` section. The verdicts are // byte-identical; only the import path changed. import { isMissingTableError, isSchemaAlreadyExistsError } from '@objectstack/types'; @@ -79,7 +79,7 @@ import { migrateProjectIdToEnvironmentId } from '../migrations/migrate-project-i * 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, @@ -940,7 +940,7 @@ export class DatabaseLoader implements MetadataLoader { * with its empty value. */ private rethrowUnlessTableUnprovisioned(error: unknown): void { - // [#13324] Every caller of this helper reads `this.tableName`, so that is + // [commit 4cda78c9b] Every caller of this helper reads `this.tableName`, so that is // the relation whose emptiness they are about to trust — a failure naming // any OTHER relation (a view over a dropped base table) is not evidence // about it and stays loud. diff --git a/packages/metadata/src/loaders/filesystem-loader-ambiguous-stem.test.ts b/packages/metadata/src/loaders/filesystem-loader-ambiguous-stem.test.ts index b93ede0dd46..06270269dd2 100644 --- a/packages/metadata/src/loaders/filesystem-loader-ambiguous-stem.test.ts +++ b/packages/metadata/src/loaders/filesystem-loader-ambiguous-stem.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14921 — two files sharing one stem are REFUSED, never resolved by + * Commit c1d274de7 — two files sharing one stem are REFUSED, never resolved by * extension precedence. * * --------------------------------------------------------------------------- @@ -25,7 +25,7 @@ * set. * * --------------------------------------------------------------------------- - * The rule this pins (maintainer ruling on #14921, via the director seat, + * The rule this pins (maintainer ruling, landed as commit c1d274de7, via the director seat, * 2026-09-05 — option 1 of three, verbatim 「同意」) * --------------------------------------------------------------------------- * Two files sharing a stem across the REGISTERED extensions is an authoring @@ -123,7 +123,7 @@ beforeAll(async () => { await fs.writeFile(path.join(cleanDir, rel), body, 'utf-8'); } // Nested twin of a FLAT name. Not a collision: a nested file is neither - // listed nor resolvable (#14486), so it derives no name to collide with. + // listed nor resolvable (commit 4b4d5a331), so it derives no name to collide with. await fs.writeFile( path.join(cleanDir, 'crm', 'solo.json'), JSON.stringify({ name: 'nested-solo' }), @@ -242,7 +242,7 @@ describe('#14921 PIN 2 — one file per stem is still listed AND loadable', () = it('CONTROL: a NESTED file sharing a flat name is not a collision', async () => { // `crm/solo.json` sits beside a flat `solo.json`. A nested file derives no - // resolvable name at all (#14486), so there is nothing for it to collide + // resolvable name at all (commit 4b4d5a331), so there is nothing for it to collide // with — and treating basenames as the unit would refuse this good tree. const loader = loaderFor(cleanRoot); @@ -280,7 +280,7 @@ describe('#14921 PIN 3 — the loadMany() two-body symptom is gone', () => { const bodies = await loaderFor(cleanRoot).loadMany<{ name?: string }>(TYPE); // Flat AND nested, exactly as before: this walk was never narrowed to the - // listed set (#14486 RECORD), and this card does not narrow it either. + // listed set (commit 4b4d5a331's RECORD), and this card does not narrow it either. expect(bodies.map(b => b.name).sort()).toEqual(['alpha', 'beta', 'nested-solo', 'solo']); }); }); @@ -288,7 +288,7 @@ describe('#14921 PIN 3 — the loadMany() two-body symptom is gone', () => { describe('#14921 CONTROL — the refusal reads the REGISTERED extension set', () => { it('`dual.json` + `dual.js` is NOT ambiguous under the default set', async () => { // `.js` carries no registered serializer there, so it derives no name — - // the same reason #14486 stopped listing it. + // the same reason commit 4b4d5a331 stopped listing it. const loader = loaderFor(probeRoot); expect(await loader.list(TYPE)).toEqual(['dual']); @@ -349,7 +349,7 @@ describe('#14921 CONTROL — a storage OUTAGE still degrades, it is not swept up const manager = new MetadataManager({ formats: ['json'], loaders: [] }); manager.registerLoader(new OutageLoader()); - // Degraded, exactly as #14423 left it: an array, short and served. + // Degraded, exactly as commit a56baa2bd left it: an array, short and served. expect(await manager.listNames(TYPE)).toEqual([]); }); diff --git a/packages/metadata/src/loaders/filesystem-loader-keyed-items.test.ts b/packages/metadata/src/loaders/filesystem-loader-keyed-items.test.ts index 8de12162ec2..5daf666261b 100644 --- a/packages/metadata/src/loaders/filesystem-loader-keyed-items.test.ts +++ b/packages/metadata/src/loaders/filesystem-loader-keyed-items.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14341 — `FilesystemLoader.loadManyKeyed()`: a file-held item is keyed by the + * Commit 2e471e362 — `FilesystemLoader.loadManyKeyed()`: a file-held item is keyed by the * name this loader can actually RESOLVE for it, and by nothing else. * * --------------------------------------------------------------------------- @@ -15,7 +15,7 @@ * while `listDiagnosed()` called the short answer complete. * * --------------------------------------------------------------------------- - * The rule this pins (PM ruling on #14341, 2026-09-02 — option D) + * The rule this pins (PM ruling of 2026-09-02 — option D, landed as commit 2e471e362) * --------------------------------------------------------------------------- * An item is keyed by this loader's own name-to-path derivation (the basename * minus extension, the same derivation `list()` reports) ONLY where that @@ -39,7 +39,7 @@ * --------------------------------------------------------------------------- * `RECORD:` cases pin behaviour this ruling deliberately LEAVES ALONE — the * nested nameless file is still dropped. They exist so the derivation repair - * (#14486: one shared name-to-path function for `list()`, `findFile()` and + * (the card commit 4b4d5a331 took in part: one shared name-to-path function for `list()`, `findFile()` and * `loadManyKeyed()`) inverts them deliberately, with the change visible in a * diff, instead of silently. * @@ -177,7 +177,7 @@ describe('#14341 FilesystemLoader.loadManyKeyed() keys by the resolvable name', it('RECORD: a nested NAMELESS file is still dropped — the honest drop, #14486', async () => { // Not a repair this ruling makes: there is no name for it that any other - // door reports. #14486 (one shared name-to-path derivation) is where this + // door reports. The card commit 4b4d5a331 took in part (one shared name-to-path derivation) is where this // inverts, deliberately. const keyed = await loader().loadManyKeyed(TYPE); diff --git a/packages/metadata/src/loaders/filesystem-loader-list-reachability.test.ts b/packages/metadata/src/loaders/filesystem-loader-list-reachability.test.ts index 5b121bf9734..ece4830e2f8 100644 --- a/packages/metadata/src/loaders/filesystem-loader-list-reachability.test.ts +++ b/packages/metadata/src/loaders/filesystem-loader-list-reachability.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14486 — `FilesystemLoader.list()` reports only names the resolve trio can + * Commit 4b4d5a331 — `FilesystemLoader.list()` reports only names the resolve trio can * open: one shared name-to-path derivation for `list()`, `findFile()` and * `loadManyKeyed()`. * @@ -23,7 +23,7 @@ * author (human or AI) reads it as their own typo and retries the same word. * * --------------------------------------------------------------------------- - * The rule this pins (maintainer ruling on #14486, via the director seat, + * The rule this pins (maintainer ruling recorded in commit 4b4d5a331, via the director seat, * 2026-09-02 — option A, narrow) * --------------------------------------------------------------------------- * `list()` reports a file only where this loader's derivation is a bijection @@ -47,8 +47,8 @@ * divergence that remains is visible in a diff rather than implicit. Both of * them are the same half of the ruling — "a file that does not fit is neither * listed NOR resolvable" — which could not be taken here: each would invert a - * landed #14341 pin in `filesystem-loader-keyed-items.test.ts`, a file under a - * concurrent claim (PR #14627) when this landed. + * landed pin of commit 2e471e362 in `filesystem-loader-keyed-items.test.ts`, a file under a + * concurrent claim (squashed as commit ac8ed476f) when this landed. * * `CONTROL:` cases pin the things that must NOT move, and one of them * (`javascript` registered) is the reverse verification that the narrowing @@ -232,10 +232,10 @@ describe('#14486 the repair reaches MetadataManager', () => { describe('#14486 RECORD: the half of the ruling this PR could not take', () => { it('RECORD: loadMany() still returns bodies for files list() no longer names', async () => { // The ruling also pinned "nothing unlisted is returned by `loadMany()` - // either". Filtering the shared walk would invert three landed #14341 pins + // either". Filtering the shared walk would invert three pins commit 2e471e362 landed // — `filesystem-loader-keyed-items.test.ts:113`, `:167`, `:187` — and its // `loadMany()` CONTROL at `:196` ("with every file", length 7), in a file - // held by a concurrent claim (PR #14627). Recorded, not repaired. + // held by a concurrent claim (squashed as commit ac8ed476f). Recorded, not repaired. const bodies = await loader().loadMany<{ name?: string; label?: string }>(TYPE); expect(bodies).toContainEqual({ name: 'account', label: 'Account' }); diff --git a/packages/metadata/src/loaders/filesystem-loader.ts b/packages/metadata/src/loaders/filesystem-loader.ts index b2313f272f2..9cb56cd6daa 100644 --- a/packages/metadata/src/loaders/filesystem-loader.ts +++ b/packages/metadata/src/loaders/filesystem-loader.ts @@ -166,7 +166,7 @@ export class FilesystemLoader implements MetadataLoader { } /** - * [#14341] The keyed half of {@link loadMany} — see {@link MetadataKeyedItem} + * [commit 2e471e362] The keyed half of {@link loadMany} — see {@link MetadataKeyedItem} * for why the store's key travels BESIDE the body instead of being folded * into it. * @@ -178,7 +178,7 @@ export class FilesystemLoader implements MetadataLoader { * this same file); every other shape keeps the pre-#14205 behaviour verbatim, * keyed by `body.name` when it has one and dropped when it has none. * - * Why the rule stops there (PM ruling on #14341, 2026-09-02, knowingly over + * Why the rule stops there (PM ruling of 2026-09-02, landed as commit 2e471e362, knowingly over * triage's "a nested path keeps whatever `list()` reports for it today"): * `list()` and `findFile()` DISAGREE outside that shape. For * `ROOT/TYPE/crm/account.json`, `list()` reports the bare `account`, but @@ -194,17 +194,17 @@ export class FilesystemLoader implements MetadataLoader { * unsettled, and is pinned as a RECORD in * `filesystem-loader-keyed-items.test.ts`. * - * [#14486, partial] `list()` and {@link findFile} have since converged on + * [commit 4b4d5a331, partial] `list()` and {@link findFile} have since converged on * {@link resolvableNameForPath} — the derivation this method already used — * so a nested or extension-less file is now neither listed nor resolvable. * What did NOT change is the WALK behind this method: `loadManyEntries()` * still READS those files, so `loadMany()` still returns their bodies and * this method still falls back to `body.name` for them. That half of the - * #14486 ruling ("nothing unlisted is returned by `loadMany()` either") is - * deliberately NOT taken here: it would invert the three landed #14341 pins + * ruling in commit 4b4d5a331 ("nothing unlisted is returned by `loadMany()` either") is + * deliberately NOT taken here: it would invert the three pins commit 2e471e362 landed * in `filesystem-loader-keyed-items.test.ts:113,167,187` and the * `loadMany()` CONTROL at `:196`, and that file was under a concurrent - * claim (PR #14627) when this landed. The remaining divergence — listed ⊂ + * claim (squashed as commit ac8ed476f) when this landed. The remaining divergence — listed ⊂ * loaded — is pinned as a RECORD in * `filesystem-loader-list-reachability.test.ts` rather than left implicit. * @@ -261,7 +261,7 @@ export class FilesystemLoader implements MetadataLoader { path.join(typeDir, pattern) ); - // [#14921] Matched first, read second. The two-body answer this card + // [commit c1d274de7] Matched first, read second. The two-body answer this card // names is produced HERE, not by `list()`: the walk reads both files of // a colliding stem and hands back both bodies while only one of them can // ever be addressed. The refusal therefore has to sit in front of the @@ -351,7 +351,7 @@ export class FilesystemLoader implements MetadataLoader { } /** - * [#14486] The names this loader can be asked for, and ONLY those: a file + * [commit 4b4d5a331] The names this loader can be asked for, and ONLY those: a file * directly under `ROOT/TYPE/` carrying an extension one of this instance's * REGISTERED serializers claims. Every name it reports resolves back through * {@link findFile}, so `listNames()` and `get()` give the same answer. @@ -365,7 +365,7 @@ export class FilesystemLoader implements MetadataLoader { * silent failure an author (human or AI) reads as their own typo, so they * retry the same word: the list and the door now agree instead. * - * Ruling (maintainer, via the director seat on #14486, 2026-09-02): narrow + * Ruling (maintainer, via the director seat, 2026-09-02, recorded in commit 4b4d5a331): narrow * the list — direction A, over B (reverse-unify: report `crm/account` and * teach `findFile()` path-shaped names), which would have made a slash inside * a metadata name every consumer's permanent obligation with no measured @@ -392,7 +392,7 @@ export class FilesystemLoader implements MetadataLoader { return []; } - // [#14921] Derived OUTSIDE that `catch`, deliberately: the walk failing is + // [commit c1d274de7] Derived OUTSIDE that `catch`, deliberately: the walk failing is // a degradation this method has always swallowed into `[]`, while an // ambiguous stem is an authoring error the caller must see. Left inside, // this method's own diagnostic would eat the refusal and answer `[]` — @@ -526,7 +526,7 @@ export class FilesystemLoader implements MetadataLoader { ]; /** - * [#14486] The extensions a name can be resolved under, for THIS instance: + * [commit 4b4d5a331] The extensions a name can be resolved under, for THIS instance: * the ones belonging to the serializer set it was constructed with. Shared by * {@link findFile}, {@link resolvableNameForPath} and therefore {@link list}, * so the set a name can be RESOLVED under cannot drift from the set that is @@ -591,7 +591,7 @@ export class FilesystemLoader implements MetadataLoader { } /** - * [#14921] The names this loader reports for `files` — and the ONE place an + * [commit c1d274de7] The names this loader reports for `files` — and the ONE place an * ambiguous stem is refused. * * Shared by {@link list} and {@link loadManyEntries} so the two can never diff --git a/packages/metadata/src/loaders/remote-loader-list-nameless.test.ts b/packages/metadata/src/loaders/remote-loader-list-nameless.test.ts index 182f1034eee..5055c559a13 100644 --- a/packages/metadata/src/loaders/remote-loader-list-nameless.test.ts +++ b/packages/metadata/src/loaders/remote-loader-list-nameless.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #15037 — `RemoteLoader.list()` declares `Promise` and maps a + * The defect commit efc5447ee fixed — `RemoteLoader.list()` declares `Promise` and maps a * nameless body straight through, so `listNames()` can hand a caller a literal * `undefined` where the type says a `string`. * @@ -31,7 +31,7 @@ * DatabaseLoader `rows.map(row => row.name as string)` * `.filter(name => typeof name === 'string')` — guarded * MemoryLoader `Array.from(typeStore.keys())` — store keys - * FilesystemLoader narrowed by #14486 to names `findFile()` resolves + * FilesystemLoader narrowed by commit 4b4d5a331 to names `findFile()` resolves * RemoteLoader `items.map(i => i.name)` — unguarded * * So the repair is `DatabaseLoader`'s guard, one file away: same directory, @@ -39,7 +39,7 @@ * "Refuse loudly" was NOT taken, and that is a landed decision rather than a * preference — `DatabaseLoader`'s guard is a silent `.filter()`, and * `FilesystemLoader`'s narrowing carries a maintainer ruling (via the director - * seat on #14486, 2026-09-02, direction A, with B explicitly refused) whose + * seat, 2026-09-02, recorded in commit 4b4d5a331, direction A, with B explicitly refused) whose * own reasoning is this card's: * * 「A name in the list that `get()` answers `null` for is the silent failure @@ -193,7 +193,7 @@ describe('#15037 RemoteLoader.list() keeps the `string[]` its signature declares describe('#15037 the repair reaches MetadataManager', () => { it('listNames() and get() give the same answer for every name', async () => { - // The #14486 shape, reused on the `RemoteLoader` face as triage asked. + // Commit 4b4d5a331's shape, reused on the `RemoteLoader` face as triage asked. // Before the guard, `listNames()` carried `undefined`, and `get()` for it // fetched `.../object/undefined` and answered `undefined` — the list and // the door disagreeing, which is the failure an author reads as their own @@ -225,7 +225,7 @@ describe('#15037 RECORD: what this repair deliberately leaves alone', () => { it('RECORD: loadMany() still returns the bodies list() no longer names', async () => { // The guard narrows `list()` only. Filtering the body read would change // what `MetadataManager.loadMany()` aggregates — a different direction - // (#14341/#14205 fixed items going MISSING; this card is about one + // (commit 2e471e362 and #14205 fixed items going MISSING; this card is about one // APPEARING as `undefined`) and not this card's. `loadMany` keys nothing, // so a nameless body is still legitimately served there. const bodies = await loader().loadMany>(TYPE); diff --git a/packages/metadata/src/loaders/remote-loader.ts b/packages/metadata/src/loaders/remote-loader.ts index 2a7b5dce51a..360eda6759c 100644 --- a/packages/metadata/src/loaders/remote-loader.ts +++ b/packages/metadata/src/loaders/remote-loader.ts @@ -111,7 +111,7 @@ export class RemoteLoader implements MetadataLoader { } /** - * [#15037] Report only the names that ARE names. + * [commit efc5447ee] Report only the names that ARE names. * * This read used to be `loadMany<{ name: string }>(type)` mapped straight to * `items.map(i => i.name)`. That type argument is an ASSERTION about bodies @@ -127,7 +127,7 @@ export class RemoteLoader implements MetadataLoader { * spelling, one `typeof` filter behind it. Silently dropping is the landed * direction, not a preference — `DatabaseLoader` drops rather than throws, * and `FilesystemLoader`'s narrowing carries a maintainer ruling (via the - * director seat on #14486, 2026-09-02) that chose narrowing (A) over + * director seat, 2026-09-02, recorded in commit 4b4d5a331) that chose narrowing (A) over * refusing loudly (B), because a name in the list that the door answers * `null` for is the silent failure an author reads as their own typo. An * `undefined` here is the extreme form of that name. diff --git a/packages/metadata/src/metadata-manager-keyed-plural-read.test.ts b/packages/metadata/src/metadata-manager-keyed-plural-read.test.ts index f18a0775c51..ed1cbc024fb 100644 --- a/packages/metadata/src/metadata-manager-keyed-plural-read.test.ts +++ b/packages/metadata/src/metadata-manager-keyed-plural-read.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * #14423 items 1 and 2 — the two plural reads that disagreed, made to agree. + * Items 1 and 2 of the card commit a56baa2bd answered — the two plural reads that disagreed, made to agree. * * --------------------------------------------------------------------------- * The defects @@ -353,7 +353,7 @@ describe('#14423 item 2 — `MetadataManager.loadManyKeyed`: the plural read und }); it("COST of the audit's by-name rung: `loadDiagnosed` is exactly ONE `findOne` per name", async () => { - // The other half of the #14423 cost question (the ruling's item 6). + // The other half of the cost question commit a56baa2bd answered (the ruling's item 6). // The keyed enumeration above is `{find:1, findOne:0}`; the by-name // rung the audit adds costs one `findOne` per name PROBED — and it // probes only the handlers still unaccounted for after set diff --git a/packages/metadata/src/metadata-manager.ts b/packages/metadata/src/metadata-manager.ts index 72a71acd9d5..8cf73463b77 100644 --- a/packages/metadata/src/metadata-manager.ts +++ b/packages/metadata/src/metadata-manager.ts @@ -1174,7 +1174,7 @@ export class MetadataManager implements IMetadataService { await this.admitLoaderItems(loader, type, items); this.reportLoaderReadRecovered(loader.contract.name); } catch (e) { - // [#14921] Same discrimination as `listNames`, and needed for the same + // [commit c1d274de7] Same discrimination as `listNames`, and needed for the same // reason: `admitLoaderItems` refuses an ambiguous stem BEFORE it // contributes anything, so absorbing it here would drop every item // this loader holds into a `degraded` partial set — an authoring error @@ -1586,7 +1586,7 @@ export class MetadataManager implements IMetadataService { /** * List all names of metadata items of a given type * - * ## [#14423] One loader's fault does not take the whole enumeration down + * ## [commit a56baa2bd] One loader's fault does not take the whole enumeration down * * This loop used to be bare — `const result = await loader.list(type)` with * no `try`, while the two sibling plural reads (`list()` via @@ -1630,7 +1630,7 @@ export class MetadataManager implements IMetadataService { result.forEach(item => names.add(item)); this.reportLoaderReadRecovered(loader.contract.name); } catch (e) { - // [#14921] PROPAGATE, never absorb: an ambiguous metadata stem is an + // [commit c1d274de7] PROPAGATE, never absorb: an ambiguous metadata stem is an // authoring error, not an outage. Degrading it here would answer with // a set that silently omits every name this loader holds while the // server keeps reporting healthy — precisely the silence the refusal @@ -1638,7 +1638,7 @@ export class MetadataManager implements IMetadataService { if (isAmbiguousMetadataStemError(e)) { throw e; } - // [#14423] Parity with `loadMany` and `list()` — see this method's + // [commit a56baa2bd] Parity with `loadMany` and `list()` — see this method's // docblock. Same seam, same verdict, same helper. this.reportLoaderReadFailure(loader.contract.name, type, e); } @@ -2341,7 +2341,7 @@ export class MetadataManager implements IMetadataService { } // ========================================== - // Overlay / Customization Management — REMOVED (#13135, ADR-0049) + // Overlay / Customization Management — REMOVED (commit 9e0ba21a1, ADR-0049) // ========================================== // // The in-memory overlay limb (`getOverlay` / `saveOverlay` / `removeOverlay` @@ -2765,7 +2765,7 @@ export class MetadataManager implements IMetadataService { } /** - * [#14423] {@link loadMany}, read under the identity the STORE holds each + * [commit a56baa2bd] {@link loadMany}, read under the identity the STORE holds each * item by — the keyed plural read, beside the unkeyed one. * * ## Why a second method and not a widened `loadMany` @@ -2790,7 +2790,7 @@ export class MetadataManager implements IMetadataService { * `register()` registry; a caller wanting that set has those. Reading the * loaders alone is also what makes this the enumerable twin of * {@link loadDiagnosed}, which walks the same loaders by name — that pairing - * is the point on the audit side of #14423, where an enumeration and a + * is the point on the audit side of commit a56baa2bd, where an enumeration and a * by-name read that disagree about a population make one subsystem accuse * another of a defect neither has. * @@ -2838,7 +2838,7 @@ export class MetadataManager implements IMetadataService { * own key for each item — {@link loadManyKeyed}'s per-loader body. * * Distinct from {@link admitLoaderItems} on exactly one axis, and that axis - * is the whole of #14423: the fallback for a loader with no + * is the whole of the defect commit a56baa2bd fixed: the fallback for a loader with no * `loadManyKeyed`. `admitLoaderItems` falls back to `loadMany` keyed by * `data.name` — the pre-#14205 behaviour, verbatim, which drops a nameless * body. Here the fallback is `list()` + a per-name `load()`, so a loader diff --git a/packages/metadata/src/metadata-route-ledger.ts b/packages/metadata/src/metadata-route-ledger.ts index 03c5e9007ed..5ea1847ba1c 100644 --- a/packages/metadata/src/metadata-route-ledger.ts +++ b/packages/metadata/src/metadata-route-ledger.ts @@ -22,7 +22,7 @@ * filing: two routes, one registrar module, one wire path served by both verbs. * * BOTH ROWS ARE NOW CONDITIONAL, and the condition is part of each row's - * disposition rather than a footnote to it (#12140). `registerMetadataHmrRoutes` + * disposition rather than a footnote to it (commit f4e7ae5c7). `registerMetadataHmrRoutes` * refuses to mount anything unless the process runs an explicit * `NODE_ENV=development` posture, so on every production-shaped boot this * package's mounted-route census is EMPTY. A census that describes what is diff --git a/packages/metadata/src/metadata-service.test.ts b/packages/metadata/src/metadata-service.test.ts index 53dfae2c9c3..012a1ddce76 100644 --- a/packages/metadata/src/metadata-service.test.ts +++ b/packages/metadata/src/metadata-service.test.ts @@ -297,7 +297,7 @@ describe('MetadataManager — IMetadataService Contract', () => { }); // ========================================== - // Overlay / Customization — REMOVED (#13135, ADR-0049) + // Overlay / Customization — REMOVED (commit 9e0ba21a1, ADR-0049) // ========================================== // // The `overlay management` cases left with the manager's paper-protocol diff --git a/packages/metadata/src/metadata.test.ts b/packages/metadata/src/metadata.test.ts index 14d48f664a3..4311be00a2d 100644 --- a/packages/metadata/src/metadata.test.ts +++ b/packages/metadata/src/metadata.test.ts @@ -443,7 +443,7 @@ describe('MetadataManager', () => { }); // (The `saveOverlay()` / `overlayWritable` cases left with the manager's - // paper-protocol overlay limb — #13135, ADR-0049. These tests were the + // paper-protocol overlay limb — commit 9e0ba21a1, ADR-0049. These tests were the // limb's only callers; `persistence.overlayWritable` is a retiredKey // tombstone on the spec side now.) diff --git a/packages/metadata/src/migrations/raw-exec-operator-detail-16657.test.ts b/packages/metadata/src/migrations/raw-exec-operator-detail-16657.test.ts index 4502cb811d1..090be652c5f 100644 --- a/packages/metadata/src/migrations/raw-exec-operator-detail-16657.test.ts +++ b/packages/metadata/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 per-table `error` these migrations return names the DIALECT. + * [commit 5a95b0e93] The per-table `error` these migrations return names the DIALECT. * * Every migration in this directory reports per table rather than throwing, and * the caller stores or prints that report. Since #16019 the raw-SQL seam diff --git a/packages/metadata/src/plugin-unbound-form-predicate-roots.test.ts b/packages/metadata/src/plugin-unbound-form-predicate-roots.test.ts index ebff6af382c..14e0a7e68ac 100644 --- a/packages/metadata/src/plugin-unbound-form-predicate-roots.test.ts +++ b/packages/metadata/src/plugin-unbound-form-predicate-roots.test.ts @@ -91,7 +91,7 @@ describe('artifact door — unbound form-predicate roots are announced to the op // …and the fixture also carries the SILENT controls: a `record.`-rooted // predicate whose string literal contains identifier-shaped text, a // FIELD-level `current_user` predicate (which resolves there since - // objectui#6010 — and, since objectui#6110 + #6111, resolves at SECTION + // objectui#6010 — and, since objectui#6110 + objectui#6111, resolves at SECTION // level too — so it must never be flagged), and a second view that is // entirely healthy. expect(leadFields.at(-2).visibleWhen.source).toBe('record.note != "status unqualified"'); @@ -220,11 +220,11 @@ describe('artifact door — unbound form-predicate roots are announced to the op }); it('says NOTHING about a SECTION-level current_user predicate either', async () => { - // ⚠️ INVERTED IN PLACE (#13072). This case read "DOES flag the same + // ⚠️ INVERTED IN PLACE (commit 200d255e7). This case read "DOES flag the same // root at section level, and prints the section vocabulary there", and // asserted one warning quoting `bound roots on a form SECTION: // 'record', 'previous', 'parent', 'data'`. That vocabulary was derived - // from the section contract sentence #12914 replaced: objectui#6110 + // from the section contract sentence commit f887e5249 replaced: objectui#6110 // threads the host shell's predicate scope into `isSectionVisible` // where it used to pass `undefined`, and objectui#6111 evaluates the // authored section `visibleWhen` on the `section-divider` pseudo-field diff --git a/packages/metadata/src/plugin.ts b/packages/metadata/src/plugin.ts index 55d8f93dd94..09d622b5c29 100644 --- a/packages/metadata/src/plugin.ts +++ b/packages/metadata/src/plugin.ts @@ -128,7 +128,7 @@ const ARTIFACT_FIELD_TO_TYPE: Record = { dashboards: 'dashboard', reports: 'report', actions: 'action', - // `themes: 'theme'` removed at #10485 (ADR-0049): the carrier key is + // `themes: 'theme'` removed by commit 35ad101bc (ADR-0049): the carrier key is // retired, so a parsed artifact can no longer carry the field — and the // ingest half of the dead pipeline (items stored, read by nothing) goes // with the authoring half rather than surviving it as drift. @@ -564,7 +564,7 @@ export class MetadataPlugin implements Plugin { // external watch-recompile pipeline POSTs to the same endpoint // after rebuilding the artifact, and we reload it here before // broadcasting. - // [#12140] PRODUCTION BOOTS DO NOT GET THIS DOOR, and that is now + // [commit f4e7ae5c7] PRODUCTION BOOTS DO NOT GET THIS DOOR, and that is now // enforced rather than predicted. This comment used to read // "production deployments simply won't have a CLI POSTing to this // endpoint and won't surface the route to clients" — a claim about who @@ -913,7 +913,7 @@ export class MetadataPlugin implements Plugin { // operator is never shown a rule their artifact has no instance of. // ⚠️ The two lists are the SAME list today: a field bound the // `current_user` family at objectui#6010 and a section did at - // objectui#6110 + #6111, so the per-surface split is currently empty + // objectui#6110 + objectui#6111, so the per-surface split is currently empty // (`@objectstack/metadata-core`, `BOUND_FORM_VIEW_PREDICATE_ROOTS`, // carries the mechanism and the two times this claim went stale). The // arms stay per surface because the QUESTION is per surface — two diff --git a/packages/metadata/src/routes/hmr-routes-dev-gate.test.ts b/packages/metadata/src/routes/hmr-routes-dev-gate.test.ts index cc08bc44d76..15289930cf6 100644 --- a/packages/metadata/src/routes/hmr-routes-dev-gate.test.ts +++ b/packages/metadata/src/routes/hmr-routes-dev-gate.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * The environment gate on the metadata HMR door (#12140). + * The environment gate on the metadata HMR door (commit f4e7ae5c7). * * ## What was wrong, measured rather than inferred * diff --git a/packages/metadata/src/routes/hmr-routes.ts b/packages/metadata/src/routes/hmr-routes.ts index 2f25839ec91..9625ebac99f 100644 --- a/packages/metadata/src/routes/hmr-routes.ts +++ b/packages/metadata/src/routes/hmr-routes.ts @@ -25,7 +25,7 @@ * pipelines (e.g. `os dev` watching TS sources) to invalidate * previews after rebuilding the artifact. * - * ## The `/dev/` in the path is ENFORCED, not merely declared (#12140) + * ## The `/dev/` in the path is ENFORCED, not merely declared (commit f4e7ae5c7) * * `registerMetadataHmrRoutes` mounts NOTHING and returns `null` unless the * process is running an explicit `NODE_ENV=development` posture — see @@ -108,7 +108,7 @@ export interface MetadataHmrHub { } /** - * The one decision behind this module's dev-only posture (#12140): may this + * The one decision behind this module's dev-only posture (commit f4e7ae5c7): may this * process serve `/api/v1/dev/metadata-events` at all? * * ## Only a literal `development` opens it — everything else is closed diff --git a/packages/metadata/src/view-container-expansion.ts b/packages/metadata/src/view-container-expansion.ts index 219f269a567..36d098afd99 100644 --- a/packages/metadata/src/view-container-expansion.ts +++ b/packages/metadata/src/view-container-expansion.ts @@ -49,7 +49,7 @@ import { deriveViewContainerObject } from './view-container.js'; /** * Re-exported from {@link ./view-container.ts}, which is also the - * `@objectstack/metadata/view-container` LEAF entry point (#14680). The + * `@objectstack/metadata/view-container` LEAF entry point (commit 3bd9b3498). The * derivation moved there so a cross-package consumer can reach it without the * two `@objectstack/spec` imports below, which esbuild keeps in any bundle * that includes this module — it tree-shakes the unused function, not an diff --git a/packages/metadata/src/view-container.ts b/packages/metadata/src/view-container.ts index cbb12676f95..1479bc09334 100644 --- a/packages/metadata/src/view-container.ts +++ b/packages/metadata/src/view-container.ts @@ -15,10 +15,10 @@ * The consumer that forced it is `packages/objectql`'s ADR-0076 lean entry. * `@objectstack/objectql/core` re-exports `engine.ts`, whose boot-loop * registrar has to mint the same registry key as this package's registrars - * (#14399), so it imports {@link deriveViewContainerObject} rather than + * (commit 3c1bbd2a8), so it imports {@link deriveViewContainerObject} rather than * hand-copying the chain a fifth time — and reaching it through the root entry * made that lean closure load the manager and the filesystem machinery for a - * function that touches neither. Measured on the built artifacts (#14680): + * function that touches neither. Measured on the built artifacts (commit 3bd9b3498): * through the root entry that call site loaded SIX extra modules into * `@objectstack/objectql/core`'s module-init closure — * `packages/metadata/dist/index.js`, `js-yaml`, `glob`, `chokidar` (two diff --git a/packages/metadata/tsup.config.ts b/packages/metadata/tsup.config.ts index 4e7657cefb3..730430bbcc7 100644 --- a/packages/metadata/tsup.config.ts +++ b/packages/metadata/tsup.config.ts @@ -14,7 +14,7 @@ export default defineConfig({ // predicate does not load the manager, the loaders and their deps. 'src/errors.ts', // `@objectstack/metadata/view-container` — the shared "which object does - // this aggregated container bind to?" derivation (#14399/#14680). Its own + // this aggregated container bind to?" derivation (commits 3c1bbd2a8 and 3bd9b3498). Its own // entry for the same reason `errors` has one: objectql's ADR-0076 lean // entry needs the pure function, not the manager, the loaders or their deps. 'src/view-container.ts', From e56839f3f8f2b6713613bcf451ed9555802ded9e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 2 Oct 2026 10:27:19 +0000 Subject: [PATCH 2/2] chore(changeset): a patch for @objectstack/metadata, whose rewritten docblocks reach dist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clause-②: no Claude-Session: https://claude.ai/code/session_017xfMoEjKUuSh2xYB8sCozp Co-authored-by: Claude --- .changeset/20595-metadata-provenance-anchors.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .changeset/20595-metadata-provenance-anchors.md diff --git a/.changeset/20595-metadata-provenance-anchors.md b/.changeset/20595-metadata-provenance-anchors.md new file mode 100644 index 00000000000..8e628498753 --- /dev/null +++ b/.changeset/20595-metadata-provenance-anchors.md @@ -0,0 +1,17 @@ +--- +'@objectstack/metadata': patch +--- + +Provenance comments in `@objectstack/metadata` 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 now cites the commit in this repository's history that made the decision it describes, except two +that meant an objectui issue and now spell `objectui#6111`. Some of these +docblocks sit on exported members, so the reworded text appears in the published `index.d.ts` / +`index.d.cts`, `node.d.ts` / `node.d.cts` and `view-container.d.ts` / `view-container.d.cts`, and +comments that esbuild keeps appear in the JavaScript output (`index.js` / `index.cjs`, `node.js` / +`node.cjs`). + +Comment only: no export, type, error code, status, message text or runtime behaviour changes.