From 6c4cc1cb89b5c8e61abbd9d672fa1d0db94eef03 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 1 Oct 2026 07:39:55 +0000 Subject: [PATCH 1/2] test(metadata-core,driver-mongodb): shipped case labels and mongod test-harness text state each case in words instead of a tracker number The shared engine case tables (delete / update dispatch, findOne predicate), the repository contract suite's serialized-form describe title, the object-schema FLS contract's `why` texts and driver-mongodb's mongod gate (skip reason, abandoned-download warning, acquisition timeout) cited tracker numbers where the case belonged. Each label that already stated its case loses only the citation; each that leaned on the number now says the rule. The two mongod gate pins assert the sentence that replaced the number. Ledger recomputed with --census-ledger: the six files leave it (32 occurrences), 653 -> 621 overall; no other row moves. Text only: no code, export, status or control flow changes. Claude-Session: https://claude.ai/code/session_01Ujdtvqs7ree7WyQmEDwEnG Co-authored-by: Claude --- .../src/mongodb-memory-server-gate.test.ts | 6 ++-- .../drivers/driver-mongodb/src/test-mongod.ts | 10 +++---- packages/metadata-core/src/contract-suite.ts | 2 +- .../src/engine-delete-dispatch.ts | 8 ++--- .../src/engine-findone-predicate.ts | 6 ++-- .../src/engine-update-dispatch.ts | 30 +++++++++---------- .../src/object-schema-fls-contract.ts | 4 +-- scripts/doc-authoring-prose-id.baseline.json | 25 ---------------- 8 files changed, 34 insertions(+), 57 deletions(-) diff --git a/packages/drivers/driver-mongodb/src/mongodb-memory-server-gate.test.ts b/packages/drivers/driver-mongodb/src/mongodb-memory-server-gate.test.ts index 999fccd1dcb..2ff5b54845a 100644 --- a/packages/drivers/driver-mongodb/src/mongodb-memory-server-gate.test.ts +++ b/packages/drivers/driver-mongodb/src/mongodb-memory-server-gate.test.ts @@ -97,7 +97,9 @@ describe('[#5517] the mongod opt-in gate', () => { expect(mongod).toBeUndefined(); expect(warnings).toHaveLength(1); - expect(warnings[0]).toContain('#5517'); + expect(warnings[0]).toContain( + 'retired from default test runs because concurrent downloads made green runs exit 1', + ); expect(warnings[0]).toContain(MONGOD_TESTS_ENV); expect(warnings[0]).toContain('SKIP gate probe'); // The property that makes the skip cost nothing: the module that would @@ -202,7 +204,7 @@ describe('[#5517] the abandoned-download rejection guard', () => { listeners[0](renameEnoent()); expect(reraised).toEqual([]); expect(warned).toHaveLength(1); - expect(warned[0]).toContain('#5517'); + expect(warned[0]).toContain('download abandoned by a concurrent-download race'); const real = new Error('a genuine unhandled rejection'); listeners[0](real); diff --git a/packages/drivers/driver-mongodb/src/test-mongod.ts b/packages/drivers/driver-mongodb/src/test-mongod.ts index d6c96f6ffa0..22a95643c85 100644 --- a/packages/drivers/driver-mongodb/src/test-mongod.ts +++ b/packages/drivers/driver-mongodb/src/test-mongod.ts @@ -152,7 +152,7 @@ export function printMongodNotice( write(`${message}\n`); } -/** The one line a gated-off suite prints. Names the issue and the switch. */ +/** The one line a gated-off suite prints. Names the reason and the switch. */ export function mongodSkipReason(suite: string, env: NodeJS.ProcessEnv = process.env): string { const raw = env[MONGOD_TESTS_ENV]; const misset = raw === undefined || raw === '' @@ -160,8 +160,8 @@ export function mongodSkipReason(suite: string, env: NodeJS.ProcessEnv = process : ` (${MONGOD_TESTS_ENV} is set to "${raw}", which does NOT enable it — only "1" does)`; return ( `[driver-mongodb] SKIP ${suite} — needs a real mongod, and mongodb-memory-server would ` - + 'download a ~123 MB binary; retired from default test runs by #5517 (concurrent downloads ' - + `made green runs exit 1). Set ${MONGOD_TESTS_ENV}=1 to run it${misset}.` + + 'download a ~123 MB binary; retired from default test runs because concurrent downloads ' + + `made green runs exit 1. Set ${MONGOD_TESTS_ENV}=1 to run it${misset}.` ); } @@ -246,7 +246,7 @@ export function installAbandonedDownloadGuard(options: RejectionGuardOptions = { return; } warn( - '[driver-mongodb] Ignoring the abandoned MongoDB binary download of #5517 ' + '[driver-mongodb] Ignoring the MongoDB binary download abandoned by a concurrent-download race ' + `(${(reason as Error).message}). Another worker won the race and renamed the archive; ` + 'the suite that lost it has already degraded to a named skip, and this rejection must ' + 'not fail an otherwise green run.', @@ -299,7 +299,7 @@ export async function createTestMongod(suite: string): Promise reject(new Error( `timed out after ${ACQUIRE_TIMEOUT_MS / 1000}s waiting for the MongoDB binary ` + '(fastdl.mongodb.org unreachable or hanging, or another worker holds the ' - + 'download — #5517)', + + 'download)', )), ACQUIRE_TIMEOUT_MS, ); diff --git a/packages/metadata-core/src/contract-suite.ts b/packages/metadata-core/src/contract-suite.ts index 7e648496f33..e4e878b39c7 100644 --- a/packages/metadata-core/src/contract-suite.ts +++ b/packages/metadata-core/src/contract-suite.ts @@ -254,7 +254,7 @@ export function runRepositoryContractTests( // Asserting only one face would have left the other implementation's // divergence unpinned, which is the whole reason this lives in the // shared contract suite rather than beside either bug. - describe('serialized-form identity (#7856)', () => { + describe('serialized-form identity', () => { for (const shape of SERIALISATION_SHAPES) { it(`version identifies the stored bytes — ${shape.label}`, async () => { const repo = await factory(); diff --git a/packages/metadata-core/src/engine-delete-dispatch.ts b/packages/metadata-core/src/engine-delete-dispatch.ts index c0e0a9ce0b4..e60095dc676 100644 --- a/packages/metadata-core/src/engine-delete-dispatch.ts +++ b/packages/metadata-core/src/engine-delete-dispatch.ts @@ -271,14 +271,14 @@ export const ENGINE_DELETE_DISPATCH_CASES: readonly EngineDeleteDispatchCase[] = // there is no predicate the by-id path could drop, and LifecycleService's // guarded reap relies on this shape for per-record cascade handling // (`engine-data-events.test.ts` pins the event contract of the same shape). - { what: 'scalar where.id with multi:true and NOTHING else in where — still one by-id delete (#11009)', options: { where: { id: 'rec_1' }, multi: true }, expect: 'by-id' }, + { what: 'scalar where.id with multi:true and NOTHING else in where — still one by-id delete', options: { where: { id: 'rec_1' }, multi: true }, expect: 'by-id' }, { what: 'multi with a predicate', options: { where: { rule_id: 'r1' }, multi: true }, expect: 'multi' }, { what: 'multi with no predicate at all', options: { multi: true }, expect: 'multi' }, { what: 'multi alongside an $in id set', options: { where: { id: { $in: ['a', 'b'] } }, multi: true }, expect: 'multi' }, // [#11009] The compare-and-set spelling: a scalar `where.id` beside real // predicate keys WITH a declared `multi` is a predicate call — every key // rides the AST to `driver.deleteMany`, so the condition is honoured. - { what: 'scalar where.id + extra predicate keys + multi:true — the predicate path honours ALL of it (#11009)', options: { where: { id: 'rec_1', status: 'stale' }, multi: true }, expect: 'multi' }, + { what: 'scalar where.id + extra predicate keys + multi:true — the predicate path honours ALL of it', options: { where: { id: 'rec_1', status: 'stale' }, multi: true }, expect: 'multi' }, // ── The FALSY scalars (objectstack#5747). `0` and `''` are scalars, so // `scalarDeleteId` returns them — but the engine's `if (input.id)` is a // truthiness test, so neither identifies a row. With a declared bulk @@ -317,6 +317,6 @@ export const ENGINE_DELETE_DISPATCH_CASES: readonly EngineDeleteDispatchCase[] = // update-side cases. Each used to dispatch `by-id` and silently DISCARD // every `where` key other than `id`; now the refusal names the dropped // keys and prescribes the predicate path (`multi: true`). - { what: 'scalar where.id alongside other predicates, NO multi — the guard would be silently dropped (#11009)', options: { where: { id: 'rec_1', tenant: 't1' } }, expect: 'reject' }, - { what: 'scalar where.id + a CAS operator predicate, multi explicitly false (#11009)', options: { where: { id: 'rec_1', status: { $in: ['done'] } }, multi: false }, expect: 'reject' }, + { what: 'scalar where.id alongside other predicates, NO multi — the guard would be silently dropped', options: { where: { id: 'rec_1', tenant: 't1' } }, expect: 'reject' }, + { what: 'scalar where.id + a CAS operator predicate, multi explicitly false — refused, the by-id path would drop the CAS guard', options: { where: { id: 'rec_1', status: { $in: ['done'] } }, multi: false }, expect: 'reject' }, ]; diff --git a/packages/metadata-core/src/engine-findone-predicate.ts b/packages/metadata-core/src/engine-findone-predicate.ts index b9c9b430a4c..dda37ec1226 100644 --- a/packages/metadata-core/src/engine-findone-predicate.ts +++ b/packages/metadata-core/src/engine-findone-predicate.ts @@ -263,7 +263,7 @@ export const ENGINE_FINDONE_PREDICATE_CASES: readonly EngineFindOnePredicateCase { what: 'an operator predicate', query: { where: { id: { $in: ['a', 'b'] } } }, expect: 'selective' }, // The alias the engine folds on every entry point (#4346). Before the fold, // `findOne({ filter })` matched the first row of the WHOLE table. - { what: "the 'filter' alias alone — folded into 'where' before the guard (#4346)", query: { filter: { status: 'open' } }, expect: 'selective' }, + { what: "the 'filter' alias alone — folded into 'where' before the guard", query: { filter: { status: 'open' } }, expect: 'selective' }, { what: "an explicit null 'where' beside a real 'filter' — null is a withdrawal, not a value", query: { where: null, filter: { status: 'open' } }, expect: 'selective' }, // A FilterArray that is a well-formed AST lowers to a condition. { what: 'a non-empty FilterArray — lowered to a condition before the guard', query: { where: ['status', '=', 'open'] }, expect: 'selective' }, @@ -274,12 +274,12 @@ export const ENGINE_FINDONE_PREDICATE_CASES: readonly EngineFindOnePredicateCase // a running server throws on — which is the whole of #11957. { what: 'no query at all', query: undefined, expect: 'reject' }, { what: 'an empty query bag', query: {}, expect: 'reject' }, - { what: "an empty 'where' object — the match-every-row shape (#3896's reading)", query: { where: {} }, expect: 'reject' }, + { what: "an empty 'where' object — read as match-every-row, so NOT a predicate", query: { where: {} }, expect: 'reject' }, { what: "an explicitly null 'where'", query: { where: null }, expect: 'reject' }, // THE #11767 SHAPE. An empty FilterArray is truthy, so every hand-written // `if (!query?.where)` copy accepts it; the engine's lowering deletes the key // and the guard refuses. This one row is what the card was filed for. - { what: "an empty FilterArray 'where: []' — truthy, and NOT a predicate (#11767)", query: { where: [] }, expect: 'reject' }, + { what: "an empty FilterArray 'where: []' — truthy, and NOT a predicate", query: { where: [] }, expect: 'reject' }, { what: "a null 'filter' alias — a withdrawal, so nothing folds", query: { filter: null }, expect: 'reject' }, { what: 'an empty orderBy array', query: { orderBy: [] }, expect: 'reject' }, { what: 'a projection and a limit but nothing selective', query: { fields: ['id', 'name'], limit: 1 }, expect: 'reject' }, diff --git a/packages/metadata-core/src/engine-update-dispatch.ts b/packages/metadata-core/src/engine-update-dispatch.ts index 16bb4e51fc4..0f90408d5ee 100644 --- a/packages/metadata-core/src/engine-update-dispatch.ts +++ b/packages/metadata-core/src/engine-update-dispatch.ts @@ -593,7 +593,7 @@ export const ENGINE_UPDATE_DISPATCH_CASES: readonly EngineUpdateDispatchCase[] = // [#11009] A PURE-id `where` stays by-id even under a declared `multi` — // there is no predicate the by-id path could drop, and LifecycleService's // guarded reap relies on this shape taking the per-record path. - { what: 'scalar where.id with multi:true and NOTHING else in where — still one by-id write (#11009)', data: { title: 'x' }, options: { where: { id: 'rec_1' }, multi: true }, expect: 'by-id', expectId: 'rec_1' }, + { what: 'scalar where.id with multi:true and NOTHING else in where — still one by-id write', data: { title: 'x' }, options: { where: { id: 'rec_1' }, multi: true }, expect: 'by-id', expectId: 'rec_1' }, // ── by-id via the PAYLOAD. A SCALAR `data.id` still outranks `where` and // `multi` alike — that is the common, legal `update(o, { id, …fields })` // spelling and objectstack#5748 left it exactly as it was. @@ -606,16 +606,16 @@ export const ENGINE_UPDATE_DISPATCH_CASES: readonly EngineUpdateDispatchCase[] = // predicate the by-id path would silently discard — the last silent member // of the #5748/#11009 dropped-declaration family. The pin flips, it does // not disappear; the EQUAL spelling keeps its own passing pin right below. - { what: 'a SCALAR data.id beside a DIFFERENT scalar where.id — refused, no longer silently wins (#11142 reverses the #5748 pin for the unequal shape)', data: { id: 'rec_1', title: 'x' }, options: { where: { id: 'rec_2' } }, expect: 'reject' }, + { what: 'a SCALAR data.id beside a DIFFERENT scalar where.id — refused; the payload id no longer silently wins over a where.id naming another row', data: { id: 'rec_1', title: 'x' }, options: { where: { id: 'rec_2' } }, expect: 'reject' }, // [#11142] The equal-ids spelling stays honoured: the REST ingress folds // the path id into the payload (`{ ...data, id: request.id }` beside // `where: { id: request.id }`), so redundant-but-agreeing is a NORMAL // spelling, not a conflict. - { what: 'data.id === where.id — the redundant-but-agreeing spelling (REST folds the path id into the payload) stays by-id (#11142)', data: { id: 'rec_1', title: 'x' }, options: { where: { id: 'rec_1' } }, expect: 'by-id', expectId: 'rec_1' }, + { what: 'data.id === where.id — the redundant-but-agreeing spelling (REST folds the path id into the payload) stays by-id', data: { id: 'rec_1', title: 'x' }, options: { where: { id: 'rec_1' } }, expect: 'by-id', expectId: 'rec_1' }, // [#11142] `multi: true` cannot rescue the conflict: the payload id outranks // `multi` (#5748), so the call is still a by-id write carrying a where.id it // can never honour. - { what: 'a SCALAR data.id beside a DIFFERENT scalar where.id and multi:true — still refused, the payload id outranks multi (#11142)', data: { id: 'rec_1', title: 'x' }, options: { where: { id: 'rec_2' }, multi: true }, expect: 'reject' }, + { what: 'a SCALAR data.id beside a DIFFERENT scalar where.id and multi:true — still refused, the payload id outranks multi', data: { id: 'rec_1', title: 'x' }, options: { where: { id: 'rec_2' }, multi: true }, expect: 'reject' }, // [#11230] The OTHER half of the reversed #5748 pin, and the last silent arm // of this family: a DECLARED but NON-SCALAR `where.id` beside a scalar // payload id. It never had a row of its own in this case-set — the assertion @@ -623,19 +623,19 @@ export const ENGINE_UPDATE_DISPATCH_CASES: readonly EngineUpdateDispatchCase[] = // data.id still outranks where and multi", first expectation) and is flipped // there. It gets rows HERE now, so every double bound to this case-set // inherits the refusal rather than each one re-deriving it. - { what: 'a SCALAR data.id beside an $in where.id and multi:true — refused; the row SET and the declared bulk intent were BOTH silently dropped (#11230 reverses the remaining half of the #5748 pin)', data: { id: 'rec_1', title: 'x' }, options: { where: { id: { $in: ['a', 'b'] } }, multi: true }, expect: 'reject' }, - { what: 'a SCALAR data.id beside an $in where.id, no multi — refused (#11230)', data: { id: 'rec_1', title: 'x' }, options: { where: { id: { $in: ['a', 'b'] } } }, expect: 'reject' }, + { what: 'a SCALAR data.id beside an $in where.id and multi:true — refused; the row SET and the declared bulk intent were BOTH silently dropped', data: { id: 'rec_1', title: 'x' }, options: { where: { id: { $in: ['a', 'b'] } }, multi: true }, expect: 'reject' }, + { what: 'a SCALAR data.id beside an $in where.id, no multi — refused; the by-id write would silently drop the declared row SET', data: { id: 'rec_1', title: 'x' }, options: { where: { id: { $in: ['a', 'b'] } } }, expect: 'reject' }, // [#19757] A 'SCALAR data.id beside an ARRAY where.id' row sat here. The // shared comparand-shape face now refuses an ARRAY in the equality slot at // the engine's lowering seam, BEFORE this dispatch runs (ruled 2026-09-23), // so the real engine answers it with the face's INVALID_FILTER / 400 and no // #11230 verdict for it is observable. Retired, not re-spelled: the two `$in` // rows above carry the #11230 "declared non-scalar where.id" refusal. - { what: 'a SCALAR data.id beside a NULL where.id — refused (#11230)', data: { id: 'rec_1', title: 'x' }, options: { where: { id: null } }, expect: 'reject' }, + { what: 'a SCALAR data.id beside a NULL where.id — refused; a declared where.id that is not one primary key is never silently dropped', data: { id: 'rec_1', title: 'x' }, options: { where: { id: null } }, expect: 'reject' }, // [#11230] The boundary that does NOT move: a FALSY scalar `where.id` IS a // scalar, so it is not this refusal's shape at all and keeps the #11142 // verdict. Pinned so the reversal cannot creep over the truthiness rule. - { what: 'a SCALAR data.id beside a FALSY scalar where.id (0) — still by-id, a falsy id identifies no row (the #11142 boundary, untouched by #11230)', data: { id: 'rec_1', title: 'x' }, options: { where: { id: 0 } }, expect: 'by-id', expectId: 'rec_1' }, + { what: 'a SCALAR data.id beside a FALSY scalar where.id (0) — still by-id, a falsy id identifies no row (it is a scalar, so neither the different-row nor the non-scalar refusal applies)', data: { id: 'rec_1', title: 'x' }, options: { where: { id: 0 } }, expect: 'by-id', expectId: 'rec_1' }, // ── The payload's scalar test (objectstack#5748). A non-scalar `data.id` // names no row, so it stops shadowing everything under it: the decision // falls through to `where.id`, then `multi`, then `reject`. Before #5748 @@ -650,9 +650,9 @@ export const ENGINE_UPDATE_DISPATCH_CASES: readonly EngineUpdateDispatchCase[] = // predicate keys WITH a declared `multi` is a predicate call — every key // (the id included, as an equality term) rides the AST to // `driver.updateMany`, so the declared condition is honoured in full. - { what: 'scalar where.id + extra predicate keys + multi:true — the predicate path honours ALL of it (#11009)', data: { title: 'x' }, options: { where: { id: 'rec_1', status: 'draft' }, multi: true }, expect: 'multi' }, + { what: 'scalar where.id + extra predicate keys + multi:true — the predicate path honours ALL of it', data: { title: 'x' }, options: { where: { id: 'rec_1', status: 'draft' }, multi: true }, expect: 'multi' }, { what: 'multi with a FALSY data.id (0 does not identify a row)', data: { id: 0, title: 'x' }, options: { multi: true }, expect: 'multi' }, - { what: 'operator object in data.id WITH multi:true — the declared bulk intent is honoured (#5748)', data: { id: { $in: ['a', 'b'] }, title: 'x' }, options: { multi: true }, expect: 'multi' }, + { what: 'operator object in data.id WITH multi:true — the declared bulk intent is honoured', data: { id: { $in: ['a', 'b'] }, title: 'x' }, options: { multi: true }, expect: 'multi' }, { what: 'array data.id with multi:true', data: { id: ['a', 'b'], title: 'x' }, options: { multi: true }, expect: 'multi' }, // ── The rejects. Every one of these is a call a fake that mirrors the rule // by hand tends to accept, and a running server answers 500 to. @@ -672,7 +672,7 @@ export const ENGINE_UPDATE_DISPATCH_CASES: readonly EngineUpdateDispatchCase[] = // ── The typo shape #5748's B option was worried about, pinned LOUD: an // operator object in the payload with NO declared bulk intent is a // rejection, never a silent promotion to a bulk write. - { what: 'operator object in data.id, NO multi — rejected, NOT silently promoted to a bulk write (#5748)', data: { id: { $in: ['a', 'b'] }, title: 'x' }, options: undefined, expect: 'reject' }, + { what: 'operator object in data.id, NO multi — rejected, NOT silently promoted to a bulk write', data: { id: { $in: ['a', 'b'] }, title: 'x' }, options: undefined, expect: 'reject' }, { what: 'operator object in data.id, multi explicitly false', data: { id: { $in: ['a', 'b'] }, title: 'x' }, options: { multi: false }, expect: 'reject' }, { what: 'array data.id, no multi', data: { id: ['a', 'b'], title: 'x' }, options: undefined, expect: 'reject' }, { what: 'null data.id, no multi', data: { id: null, title: 'x' }, options: undefined, expect: 'reject' }, @@ -682,12 +682,12 @@ export const ENGINE_UPDATE_DISPATCH_CASES: readonly EngineUpdateDispatchCase[] = // exactly like a working conditional write. Now they are loud: the // refusal names the dropped keys and prescribes the predicate path // (`multi: true`), which honours the full `where`. - { what: 'scalar where.id alongside other predicates, NO multi — the guard would be silently dropped (#11009)', data: { title: 'x' }, options: { where: { id: 'rec_1', tenant: 't1' } }, expect: 'reject' }, - { what: 'scalar where.id + a CAS operator predicate, multi explicitly false (#11009 — the redeliver shape)', data: { title: 'x' }, options: { where: { id: 'rec_1', status: { $in: ['done'] } }, multi: false }, expect: 'reject' }, - { what: 'scalar data.id + extra where predicate, no multi — same drop through the payload door (#11009)', data: { id: 'rec_1', title: 'x' }, options: { where: { tenant: 't1' } }, expect: 'reject' }, + { what: 'scalar where.id alongside other predicates, NO multi — the guard would be silently dropped', data: { title: 'x' }, options: { where: { id: 'rec_1', tenant: 't1' } }, expect: 'reject' }, + { what: 'scalar where.id + a CAS operator predicate, multi explicitly false — the redeliver shape, refused rather than dropping its CAS guard', data: { title: 'x' }, options: { where: { id: 'rec_1', status: { $in: ['done'] } }, multi: false }, expect: 'reject' }, + { what: 'scalar data.id + extra where predicate, no multi — refused; the by-id write would silently drop the predicate, through the payload door', data: { id: 'rec_1', title: 'x' }, options: { where: { tenant: 't1' } }, expect: 'reject' }, // The payload id outranks `multi` (#5748), so a declared `multi: true` // cannot re-route it onto the predicate path — and the unhonourable // predicate is REFUSED rather than silently dropped (the pre-#11009 // behaviour) or silently promoted to a bulk write. - { what: 'scalar data.id + extra where predicate + multi:true — refused, the payload id cannot take the predicate path (#11009)', data: { id: 'rec_1', title: 'x' }, options: { where: { tenant: 't1' }, multi: true }, expect: 'reject' }, + { what: 'scalar data.id + extra where predicate + multi:true — refused, the payload id cannot take the predicate path', data: { id: 'rec_1', title: 'x' }, options: { where: { tenant: 't1' }, multi: true }, expect: 'reject' }, ]; diff --git a/packages/metadata-core/src/object-schema-fls-contract.ts b/packages/metadata-core/src/object-schema-fls-contract.ts index 809598f1efd..4f9b2438225 100644 --- a/packages/metadata-core/src/object-schema-fls-contract.ts +++ b/packages/metadata-core/src/object-schema-fls-contract.ts @@ -129,7 +129,7 @@ export const OBJECT_SCHEMA_MASK_CASES: readonly ObjectSchemaMaskCase[] = [ }, { id: 'empty-readable-set/no-empty-fields-200', - why: 'D6 — `getReadableFields` answers `[]` only where its own posture read failed closed (#3545). An empty-fields 200 is "silently wrong UI AND cacheable poison", so the exit refuses instead.', + why: 'D6 — `getReadableFields` answers `[]` only where its own posture read failed closed. An empty-fields 200 is "silently wrong UI AND cacheable poison", so the exit refuses instead.', context: { userId: 'u_portal', systemPermissions: [] }, readable: [], expect: { kind: 'fault' }, @@ -150,7 +150,7 @@ export const OBJECT_SCHEMA_MASK_CASES: readonly ObjectSchemaMaskCase[] = [ }, { id: 'write-capable-caller/exempt', - why: '[#7020] D4 is DERIVED from the #6603 write gate — whoever may write a schema sees all of it, by construction. A `manage_metadata`-only caller passes every write gate, so a projected GET here is the round trip that PUTs the invisible fields away. Holds NEITHER builder capability on purpose: that is the shape the two hand-kept sets used to separate.', + why: 'D4 is DERIVED from the schema write gate (`manage_metadata`) — whoever may write a schema sees all of it, by construction. A `manage_metadata`-only caller passes every write gate, so a projected GET here is the round trip that PUTs the invisible fields away. Holds NEITHER builder capability on purpose: that is the shape the two hand-kept sets used to separate.', context: { userId: 'u_author', systemPermissions: ['manage_metadata'] }, readable: ['id'], expect: { kind: 'unmasked' }, diff --git a/scripts/doc-authoring-prose-id.baseline.json b/scripts/doc-authoring-prose-id.baseline.json index 60d7708df9f..64707dde93d 100644 --- a/scripts/doc-authoring-prose-id.baseline.json +++ b/scripts/doc-authoring-prose-id.baseline.json @@ -65,9 +65,6 @@ "packages/connectors/connector-mcp/src/mcp-provider.ts": { "#3055": 2 }, - "packages/drivers/driver-mongodb/src/test-mongod.ts": { - "#5517": 3 - }, "packages/lint/src/authoring-rules.ts": { "#4463": 3, "#4716": 2, @@ -187,28 +184,6 @@ "packages/lint/src/validate-widget-bindings.ts": { "#2501": 1 }, - "packages/metadata-core/src/contract-suite.ts": { - "#7856": 1 - }, - "packages/metadata-core/src/engine-delete-dispatch.ts": { - "#11009": 4 - }, - "packages/metadata-core/src/engine-findone-predicate.ts": { - "#11767": 1, - "#3896": 1, - "#4346": 1 - }, - "packages/metadata-core/src/engine-update-dispatch.ts": { - "#11009": 6, - "#11142": 4, - "#11230": 4, - "#5748": 4 - }, - "packages/metadata-core/src/object-schema-fls-contract.ts": { - "#3545": 1, - "#6603": 1, - "#7020": 1 - }, "packages/plugins/plugin-approvals/src/approval-service.ts": { "#10153": 1, "#10230": 1, From 2729901dbd0a00b0ba59c26bd3b0c13e8efc20c1 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 1 Oct 2026 07:44:37 +0000 Subject: [PATCH 2/2] chore(changeset): metadata-core case labels state the case in words (patch) driver-mongodb carries no entry: its test-mongod.ts is not in the published dist (measured after build: the module's strings and its mongodSkipReason symbol answer 0 files under dist, the MongoDBDriver positive control 4). Claude-Session: https://claude.ai/code/session_01Ujdtvqs7ree7WyQmEDwEnG Co-authored-by: Claude --- ...etadata-core-case-labels-state-the-case.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .changeset/20513-metadata-core-case-labels-state-the-case.md diff --git a/.changeset/20513-metadata-core-case-labels-state-the-case.md b/.changeset/20513-metadata-core-case-labels-state-the-case.md new file mode 100644 index 00000000000..c5d13115951 --- /dev/null +++ b/.changeset/20513-metadata-core-case-labels-state-the-case.md @@ -0,0 +1,24 @@ +--- +'@objectstack/metadata-core': patch +--- + +The shared engine case tables and the published contract suites in metadata-core no longer cite tracker numbers in their case labels; each label states its case in words + +Clause-②: no + +Several labels these tables and suites ship ended with an issue-tracker number where the case belonged. A +test driven from them printed that number as part of its name, and a failing assertion quoted it as the +reason. The number goes; where the label did not already say what the case is, it now does. + +- `ENGINE_DELETE_DISPATCH_CASES`, `ENGINE_UPDATE_DISPATCH_CASES` and `ENGINE_FINDONE_PREDICATE_CASES`: + the `what` labels of 22 rows. Among them, the compare-and-set rows now say the by-id path would drop the + CAS guard; the payload-id rows say which declared `where.id` would be silently dropped; and the falsy + `where.id` boundary says it is a scalar, so neither the different-row refusal nor the non-scalar refusal + applies. +- `@objectstack/metadata-core/testing`: the repository contract suite's `serialized-form identity` group + title, and two `why` texts of `OBJECT_SCHEMA_MASK_CASES` (the empty-readable-set refusal, and the + write-capable exemption, which now names the schema write gate, `manage_metadata`). + +Text only: no case is added, removed or re-ordered, and no `options`, `data`, `expect`, `expectId`, `id`, +`readable` or `context` value moves. A suite that selects or skips these cases by their label text (a +`-t` filter, a skip list) needs the new spelling.