Skip to content

Commit 6154165

Browse files
docs(spec): re-anchor the dead tracker citations left in data/ to the commits that decided them (stage 4) (#20548)
Part of #20234 Clause-②: no ## What changed This is stage 4 of the staged sweep: the `data/` remainder. It covers the six `packages/spec/src/data/` files stage 3 (PR #20533, landed `03b19d9cfd`) left out because an open PR held them, and nothing else. They are `object.zod.ts`, `filter-logic-conformance.ts`, `object.form.ts`, `data-engine.zod.ts`, `data-engine.test.ts` and `hook.form.ts`. Later stages cover the other areas, so this PR says `Part of`. The census below measured all six. Three of them carry comment or docblock sites that cite a tracker number answering 404. `data-engine.zod.ts`, `data-engine.test.ts` and `hook.form.ts` carry none, so they are not in the diff. Every such site has been rewritten in ruling C+D's form C (comment 5749154545 on #19123). That is **19 sites on 19 lines in 3 files, covering 9 numbers**. Each rewritten line now cites the commit in `origin/main` history that decided what the line describes, and it says in its own words what that commit decided. Where a PR number was already on the line (`PR #13529`), it stays beside the commit as the link. No ADR or ruling-record file in `docs/adr/` or `scripts/adr-anchors/` records the decision behind any of the 9 numbers: a search for each number, with and without `#`, finds nothing there. So every anchor is a commit: **9 distinct shas**. Stage 3 had already read these commits and recorded them in PR #20533's body. They were not copied from there. Each one was re-read against the current line it anchors: its own message or diff names the number it replaces, and it made the change the line describes. `object.zod.ts` and `filter-logic-conformance.ts` moved on `main` after stage 3 read them (PRs #20521 and #20523). Each site was therefore re-read at this base, `03b19d9cfd`. Only comments changed. Every source file keeps its line count (20 lines out, 20 in, over 3 files), so no line citation into these files moves. One of the 20 lines held no dead citation: `filter-logic-conformance.ts:249`, the first half of a sentence reflowed onto `:250`. No code token moves (see the guard below). **No tracker number is added.** Every tracker number on an added line was already in the hunk it replaces. `PR #13529` stands on three added lines, and on the three removed lines of the same hunks. It is the link beside commit `9dac1ae01`, which stage 3 recorded the same way. No reference page under `content/docs/references/` moved: none of the rewritten docblocks projects into one (`check:docs` at the head: `226 generated files in sync`). The PR adds one `patch` changeset for `@objectstack/spec` (see Changeset below). ## Census: the six files, before and after **Instrument.** This is the instrument of stages 1 to 3. It sends REST `GET /repos/objectstack-ai/objectstack/issues/N` without following redirects, for every distinct number cited in `packages/spec/src/data`. The population is: - the citation gate's own exported `CITATION_RE` and `NON_CITATION_HEADS`, kept when the qualifier is none, `objectstack`, `objectstack-ai/objectstack`, `framework`, `pre-` or `post-`; - widened case-insensitively to `Pre-`, `POST-` and `Framework`, as in stage 3; - N of 100 or more, excluding `summon` heads. Each site is classified by the TypeScript parser as a line comment, a docblock, a block comment or a string. Two cross-checks close the population. First, a raw `#N` count in each of the six files equals the census rows plus the cross-repo rows in five files. In the other two it is one higher, and the extra is a second number after a slash inside a string (`#5322/#5134` in a `note`, `#6262/#6433` in a test title). Both answer 200. Second, no spelled citation (`issue N`, `PR N`, `card N`) occurs in any of the six. **Controls.** The lit controls were `#16862`, `#16847` and `#17698`. The dead controls were `#16714`, `#16715` and `#16697`. They were probed at the start, after every 100 numbers and at the end: 24 of 24 lit (200) and 24 of 24 dead (404) over 8 checkpoints in the base run, and 21 of 21 lit and 21 of 21 dead over 7 checkpoints in the head run. | reading | tree | numbers probed | 200 | 404 | 301 or other | dead sites, all of `data/` | dead sites, the six files | lines | files | numbers | |---|---|---|---|---|---|---|---|---|---|---| | before | base `03b19d9cfd`, probed 2026-09-29T01:11:59Z to 01:15:49Z | 601 | 572 | 29 | 0 | **77** | 19 | 19 | 3 | 9 | | after | head `53c9070dfd`, probed 2026-09-29T01:25:55Z to 01:29:35Z | 597 | 572 | 25 | 0 | **58** | 0 | 0 | 0 | 0 | The head probe found no number newly dead since the base probe: the same 572 numbers answer 200. The base reading of 77 equals stage 3's after reading at `96fd49caa2`. **Per file.** Cited sites here are every in-repo citation the population reads, live or dead. | file | cited sites (base) | dead sites before | by class | dead sites after | |---|---|---|---|---| | `object.zod.ts` | 120 | 15 | 8 docblock, 7 line comment | 0 | | `filter-logic-conformance.ts` | 97 | 3 | 2 docblock, 1 line comment | 0 | | `object.form.ts` | 31 | 1 | 1 line comment | 0 | | `data-engine.zod.ts` | 48 | 0 | | 0 | | `data-engine.test.ts` | 29 | 0 | | 0 | | `hook.form.ts` | 0 | 0 | | 0 | None of the 19 sites is a string, so this stage leaves no string token behind. ## Per-number table | number | sites / lines | anchor: what it decided | |---|---|---| | `#8772` | 4 / 4, `object.zod.ts:2718`, `:2731`, `:2744`, `:2910` | `75b7c240a`: Direction 2 of the 2026-08-16 maintainer ruling. `ObjectSchema.create()` forces `required: true` on a `master_detail` reference under `controlled_by_parent` and refuses an explicit `required: false`. Raw parse stays tolerant, and runtime tolerance is the ruling's other half. Its changeset records the measurement that only the security gate closed that shape while the declaration surface accepted it (`:2731`). ADR-0055 stays cited beside it. It is the same anchor stage 3 gave `object.test.ts` | | `#10165` | 2 / 2, `object.zod.ts:818`, `:1036` | `801296050`: `ttl.onlyWhen` with the canonical null predicate (maintainer ruling 2026-08-20, option A). One shared `onlyWhen` union, and both of `retention.onlyWhen`'s conflicts mirrored. Its diff wrote both `[#10165]` blocks | | `#10347` | 3 / 3, `object.zod.ts:1006`, `:1042`, `:1049` | `530c1df65`: the Archiver honours a declared `ttl`. It selects by the ttl cutoff on `ttl.field` when `ttl` is declared, and by `created_at` / `archive.after` otherwise (maintainer ruling 2026-08-20) | | `#10527` | 1 / 1, `object.zod.ts:1005` | `5649efbf9`: refuses a diverging retention + ttl + archive triple at parse time. Its diff wrote this very paragraph | | `#11195` | 1 / 1, `object.zod.ts:1791` | `b37231883`: `UserActionsConfigSchema` adopts `group` / `hideFields` / `rowColor` (the "last three" the line names) | | `#11408` | 1 / 1, `object.zod.ts:2189` | `f11fc61c5`: declares `editMode` on the object document (maintainer ruling 2026-08-24, the `#10144` declare-or-rule-out family, which stays cited) | | `#13608` | 3 / 3, `object.zod.ts:2317`, `:2354`, `:2366` | `fc9ba76a5`: `publicSharing.eligibility` is held at redemption, not only at mint, fail-closed, with the undifferentiated `null` refusal. Its changeset heads with #13608. It is the same anchor stage 1 gave `contracts/share-link-service.ts` | | `#13195` | 3 / 3, `filter-logic-conformance.ts:190`, `:250`, `:525` | `9dac1ae01`, PR #13529's squash commit, which stays as the link: `$exists` means has-a-value on driver-memory's live mingo path, its analytics face and driver-mongodb's `translateFilter` (the "last three key-presence exits") | | `#12868` | 1 / 1, `object.form.ts:256` | `c459da6bc`: narrows the per-option `default` key out of the form-view options vocabulary, which offered a key nothing on that surface read. Commit `e808890958`, which wrote this line, names #12868 as the same offer-vs-door class | The shas were checked at the base and again at `origin/main` `288611e3e5`. Every one matches exactly one commit (`git rev-parse --disambiguate`, count 1). Every one is an ancestor (`git merge-base --is-ancestor`, exit 0 for 9 of 9). The control leg `e9584681a4` also exits 0, and the repository is not shallow. For each commit, a grep of its own message or diff finds the number it replaces. Seven of the nine name it in the message. `fc9ba76a5` names it in its diff (20 lines, including its changeset heading), and so does `c459da6bc` (8 lines, including its changeset heading). Wordings to check, each true of its commit: - `object.zod.ts:2731` now reads 「closes that shape, and commit 75b7c24 records that the declaration and the enforcement disagree」. The measurement was the card's. The commit's changeset records it: "only the security gate closed that shape while the declaration surface accepted it". - `object.zod.ts:2189` reads 「Declared here by commit f11fc61's maintainer ruling」, and `:2744` reads 「the other half of commit 75b7c24's ruling」. This is stage 3's wording for the same relation (`object.test.ts`, 「the other half of commit 75b7c24's ruling」): the commit that landed the ruling and quotes it. - `object.zod.ts:1049` reads 「That is the whole of what [commit 530c1df] changed here」. Commit `52db1d1f2a` wrote the paragraph. `530c1df65` is the change it describes. ## Mechanical guard: no code token moves The check compares leaf tokens with comments stripped, base `03b19d9cfd` against head `53c9070dfd`. It uses the TypeScript parser's leaf tokens (TypeScript from the head's lockfile), so template literals are scanned in context, and it excludes JSDoc nodes. It ran over all 3 touched `.ts` files. It is the stage-3 instrument, unchanged. - Real run: 13,624 base tokens (object.zod.ts 8,774, object.form.ts 3,226, filter-logic-conformance.ts 1,624), **0 files with a token change** (exit 0). - Comment-insertion control (`object.form.ts`): 0 files changed, as expected (exit 0). - Positive control (a declaration inserted into `object.zod.ts`): 1 file reads DIFFER at token 1629 (exit 1). - Positive control (one digit changed inside the `#5322/#5134` `note` string in `filter-logic-conformance.ts`): 1 file reads DIFFER at token 889 (exit 1). Line balance: `object.zod.ts` +15 / -15, `filter-logic-conformance.ts` +4 / -4, `object.form.ts` +1 / -1. Line counts are equal at base and head: 3,240, 621 and 751. ## Changeset This change ships bytes, so a `patch` changeset for `@objectstack/spec` is included. It says only that the provenance comments were re-anchored. `Clause-②: no`: no export, key, value or type moves (the guard above). Measured on the head's built package: `object.zod.ts` is `src/**/*.zod.ts`, which `files[]` ships verbatim. The rewritten comments also reach `dist`: - `9dac1ae01` appears in `dist/data/index.d.ts` (the `filter-logic-conformance.ts` docblock) and in 4 bundled `.js` files; - `fc9ba76a5`, `f11fc61c5` and `b37231883` each appear in 22 bundled `.js` files, and `c459da6bc` in 12; - the positive control, the pre-existing `object.zod.ts` sentence 「Fail-CLOSED at both points」, appears in 11 bundled `.js` files. ## Gates (head `53c9070dfd`) - **Citation judging pass, run as CI runs it:** `pnpm check:issue-citations && node scripts/check-issue-citations.mjs` exits 0. The self-test passes 73 cases in 7 batteries. The live run judged 6 citations across 3 files: 3 resolve (`#9138` twice, `#11410`) and 3 resolve as a pull request (`#13529`, the link). - **Doc authoring:** `pnpm check:doc-authoring` exits 0. - **Derived gates:** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at the head derived 79 families, and all 79 exit 0. `--ran` reports 79 run, 0 NOT MEASURED, 0 unrun, and exits 0. A full `turbo run build` of `./packages/*` ran first, under the shared verify lock: 71 of 71 tasks, VERDICT command-exit 0. So no gate met an unbuilt prerequisite. - `pnpm --filter @objectstack/spec run check:generated`: under the lock against that build, `All 15 generated artifacts are up to date`, VERDICT command-exit 0. - **Tests and typecheck:** - `pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/data` under the lock: Test Files 107 passed (107), Tests 3527 passed, 1 todo (3528), VERDICT command-exit 0. It covers every test in `data/`, among them `object.test.ts`, which reads these schemas. - The 13 spec suites outside `src/data` that read the touched files' source text or pin their line numbers, under the lock: Test Files 13 passed (13), Tests 544 passed (544). They are stage 3's 12 (`scripts/{file-description,root-index,skill-map-guards,strictness-ledger}.test.ts`, `src/api/api-entry-graph.pin.test.ts`, `src/contracts/scoped-context.test.ts`, `src/shared/{alias-integrity,evaluated-slot-population,retired-key-migrate-sentence}.test.ts`, `src/system/constants/platform-object-names.test.ts`, `src/type-alias-convention.pin.test.ts`, `src/ui/dashboard.test.ts`) plus `src/shared/union-author-message-pins.test.ts`, which pins `data/object.zod.ts:855`. - `pnpm --filter @objectstack/spec typecheck` under the lock exits 0, including `check:test-typecheck` (53 files, 251 errors, 138 pinned signatures held). - **Lint, as a proven narrowing at the head:** `eslint --no-inline-config --format json` over the 3 touched `.ts` files gives 3 files, 0 errors and 0 warnings. All 3 are in eslint's own population (`isPathIgnored` is false for each). `eslint.config.mjs` never enables type-aware linting (no `parserOptions.project`, which its own line 328 states), so a comment edit here cannot move the verdict on any untouched file. The repo-wide `pnpm lint` is CI's run. ## Acceptance notes - **Base.** The branch forked from `03b19d9cfd`, stage 3's landing. `origin/main` then moved two commits (`05077d4c26`, PR #20532, and `288611e3e5`, PR #20536), and neither touches `data/`. `dispatch-gates` flagged its derivation as stale because `scripts/regen-artifacts.mjs` had moved, so `origin/main` was merged in (`53c9070dfd`, a clean merge with no driver-deferred path) before the gates ran. The PR's delta against `origin/main` is exactly its 4 files. `origin/main` has since moved two more commits: `7e36a3cd7c` (PR #20531) and `ba5927f714` (PR #20460). Neither touches `data/` or anything the gate derivation reads, and a re-derivation prints the same 79 commands. A no-driver `merge-tree` of the head onto `ba5927f714`, from a bare shared clone, exits 0. So there is no second merge. - **Open PRs, re-read at 2026-09-29T02:01Z:** 9 open PRs, and none touches any of the six files. The `data/` files open PRs touch are #20458's `analytics*` files, #20504's `driver/turso.*`, and #20545's `filter-number-comparand-declared-type.*`, which is disjoint. Since the claim, PR #20460 has landed (`ba5927f714`) without touching `filter-subtree-provenance.ts`. That file's 3 dead sites are outside this claim's fence, so they are left for a later stage. - **The rung.** Two anchored changes also have ADR-0087 entries in `packages/spec/src/migrations`: `cbp-master-detail-required-forced` for #8772, and `form-view-option-default-retired` for #12868. The second entry's own header names commit `c459da6bc`. This PR takes the commit rung, as stages 1 to 3 did. The D3 id is the more durable in-repo record, if the ruling's first rung is later read to include those entries. - **What stays in `data/` after this stage: 58 dead sites.** - **12 comment sites in files other open work still holds.** `analytics.zod.ts`, `analytics-strictness-batchd.test.ts` and `analytics-date-range-two-bound-window.test.ts` hold 5 (#20300, PR #20458). `driver/turso.zod.ts` and `driver/turso.test.ts` hold 4 (#20437, PR #20504). `filter-subtree-provenance.ts` holds 3. It was held by #20367 and is now free (see above). - **3 comment sites stage 3 left on purpose.** They are the test-read `[#6259]` marker at `api-derivation.ts:163`, the test comment at `api-derivation.test.ts:232` that names it, and `field.zod.ts:370`, whose `#6111` is objectui's number. - **43 string sites**, left as tokens: 41 test strings (2 of them in the held analytics and turso test files) and the 2 exported `AGGREGATION_CASES` note strings in `aggregation-conformance.ts` (`:398`, `:407`, #11065), which #20489's claim holds. - **Outside `data/`,** the card's other remaining items are unchanged: the migrations and ui areas, the `liveness/**` notes, the `why` strings, the `PROVENANCE_WAIVERS` reason, and `rest-server.zod.ts`. - **The citation gate's reach.** It defers `packages/**/*.test.ts`. No test file is touched here, so all 3 touched files are in its judging population. --- _Generated by [Claude Code](https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 92ea760 commit 6154165

4 files changed

Lines changed: 32 additions & 20 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
Provenance comments in the rest of `data/` were re-anchored
6+
7+
Comment and docblock lines in `src/data/object.zod.ts`,
8+
`src/data/filter-logic-conformance.ts` and `src/data/object.form.ts` that cited
9+
tracker numbers which no longer resolve on GitHub now cite the commit in this
10+
repository's history that decided the matter, and say in their own words what
11+
was decided. Comments only: no type, schema, export or runtime behaviour
12+
changes.

‎packages/spec/src/data/filter-logic-conformance.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@
187187
* - **`$exists` means "has a value"** (`!= null`), never key-presence — cell 2,
188188
* the leg of the 07:33Z ruling that was never in conflict with #5298 and had
189189
* already shipped in PR #5962 on the surfaces the ruling named. It stands —
190-
* and since PR #13529 (#13195) moved the last three key-presence exits, it
190+
* and since commit 9dac1ae01 (PR #13529) moved the last three key-presence exits, it
191191
* is enforced here too: enrolled in {@link FILTER_LOGIC_CASES} in BOTH
192192
* directions (#13531).
193193
*
@@ -246,8 +246,8 @@
246246
* path, its analytics face (a third divergent exit the earlier prose never
247247
* named; measured in PR #13420), and `driver-mongodb`'s `translateFilter`.
248248
* The #5499 investment freeze that once excused the lag dissolved on
249-
* 2026-08-11 (recorded in `./aggregation-conformance.ts`), and PR #13529
250-
* (#13195) moved all three to has-value — the gap is closed, the stated
249+
* 2026-08-11 (recorded in `./aggregation-conformance.ts`), and commit
250+
* 9dac1ae01 (PR #13529) moved all three to has-value — the gap is closed, the stated
251251
* blocker on enrolment is gone with it, and the two `$exists` rows below are
252252
* enrolled in BOTH directions (#13531).
253253
*
@@ -522,7 +522,7 @@ export const FILTER_LOGIC_CASES: readonly FilterLogicCase[] = [
522522
},
523523

524524
// [#13531] The value-presence predicate, enrolled in BOTH directions once
525-
// PR #13529 (#13195) moved the last three key-presence exits to has-value.
525+
// commit 9dac1ae01 (PR #13529) moved the last three key-presence exits to has-value.
526526
// The stored-null seeding is what makes these rows discriminating: a
527527
// key-presence reading answers MATCH on rows 3-4 for `$exists: true`
528528
// precisely because every harness stores `d: null` with the key present —

‎packages/spec/src/data/object.form.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ export const objectForm = defineForm({
253253
// the option shape is strict and has never declared `icon`, so a
254254
// Lucide name typed there was an `unrecognized_keys` refusal at
255255
// publish — the author found out at the 422, the same
256-
// offer-vs-door class #11410 and #12868 retired elsewhere.
256+
// offer-vs-door class #11410 and commit c459da6bc retired elsewhere.
257257
//
258258
// Remove rather than declare, on a premise measured for THIS
259259
// surface rather than inherited from #5016's action-param reading:

‎packages/spec/src/data/object.zod.ts‎

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ const lifecycleDuration = (what: string) =>
815815
z.string().regex(LIFECYCLE_DURATION_REGEX, `${what} must be a duration literal like '6h', '14d', '12w' or '7y'`);
816816

817817
/**
818-
* [#10165] The `onlyWhen` row-filter value union, shared by
818+
* [commit 801296050] The `onlyWhen` row-filter value union, shared by
819819
* `retention.onlyWhen` and `ttl.onlyWhen` — ONE shape on purpose: the two
820820
* blocks are mirrors (maintainer ruling 2026-08-20, option A: give `ttl` an
821821
* `onlyWhen` mirroring `retention`'s), and the runtime enforces them through
@@ -1002,8 +1002,8 @@ export const LifecycleSchema = lazySchema(() => strictObject({
10021002
message: `lifecycle.archive.after ('${lc.archive.after}') must equal retention.maxAge ('${lc.retention.maxAge}') — the hot window ends where the archive begins`,
10031003
});
10041004
}
1005-
// [#10527] The retention + ttl + archive triple — the alignment above, one
1006-
// policy wider. Since [#10347] the Archiver selects the rows it moves by the
1005+
// [commit 5649efbf9] The retention + ttl + archive triple — the alignment above, one
1006+
// policy wider. Since [commit 530c1df65] the Archiver selects the rows it moves by the
10071007
// ttl cutoff (`ttl.field` older than `ttl.expireAfter`) whenever `ttl` is
10081008
// declared, and by `created_at`/`archive.after` only when it is not — so on
10091009
// this triple the age bound (`retention.maxAge`, pinned equal to
@@ -1033,20 +1033,20 @@ export const LifecycleSchema = lazySchema(() => strictObject({
10331033
message: 'lifecycle.retention.onlyWhen cannot be combined with archive — the Archiver moves rows by age alone and would archive rows the filter protects',
10341034
});
10351035
}
1036-
// [#10165] ttl.onlyWhen mirrors both of retention.onlyWhen's conflicts, from
1036+
// [commit 801296050] ttl.onlyWhen mirrors both of retention.onlyWhen's conflicts, from
10371037
// the Reaper's actual semantics rather than by symmetry alone:
10381038
// - rotation: the Rotator DROPs whole physical shards; a shard is dropped by
10391039
// age with no row read, so rows the filter protects go down with it.
10401040
// - archive: `reapObject` returns into `archiveObject` before the ttl reap
10411041
// ever runs, so with `archive` declared the filter guards a code path that
1042-
// is never executed (declared ≠ enforced). Since [#10347] the Archiver does
1042+
// is never executed (declared ≠ enforced). Since [commit 530c1df65] the Archiver does
10431043
// apply the declared ttl window itself — it selects candidates by
10441044
// `ttl.field` past `ttl.expireAfter` instead of `created_at` past
10451045
// `archive.after` — but its candidate read is that cutoff and nothing else
10461046
// (`where: { [ttl.field]: { $lt: cutoff } }`, no `onlyWhen` spread the way
10471047
// `reap()` spreads it into its scope), so every due row is copied and
10481048
// hot-deleted whether or not the filter names it. That is the whole of what
1049-
// [#10347] changed here: the WINDOW an author declares now carries over to
1049+
// [commit 530c1df65] changed here: the WINDOW an author declares now carries over to
10501050
// the Archiver, the FILTER still does not — so the refusal stands, on a
10511051
// narrower reason than the "moves rows by age alone" this bullet used to
10521052
// give. Whether `onlyWhen` should become meaningful under `archive` (the
@@ -1788,7 +1788,7 @@ const ObjectSchemaBase = strictObject(
17881788
// `ui/view.zod.ts` declares its own `userActions` with a completely
17891789
// disjoint vocabulary (sort/search/filter/refresh/rowHeight/group/
17901790
// addRecordForm/editInline/hideFields/rowColor/buttons — the last three
1791-
// adopted at #11195), so an author who learned that block writes these
1791+
// adopted by commit b37231883), so an author who learned that block writes these
17921792
// here. `group`/`hideFields`/`rowColor` were refused by name but without
17931793
// a curated pointer until #11459 gave them one too, mirroring the other
17941794
// four.
@@ -2186,7 +2186,7 @@ const ObjectSchemaBase = strictObject(
21862186
* `recordFormNavigation.ts` branches on `editMode !== 'page'`, and
21872187
* `AppContent`'s `handleEdit` dispatcher routes on it).
21882188
*
2189-
* Declared here by the #11408 maintainer ruling (the measured residue of the
2189+
* Declared here by commit f11fc61c5's maintainer ruling (the measured residue of the
21902190
* #10144 declare-or-rule-out census): objectui had published the key to
21912191
* authors (CHANGELOG + live runtime read) while this strict parse rejected
21922192
* it. objectui's `ObjectSchemaClientExtensions.editMode` mirror retires in a
@@ -2314,7 +2314,7 @@ const ObjectSchemaBase = strictObject(
23142314
/**
23152315
* Master switch — a STANDING policy held at every redemption, not a
23162316
* mint-time check (#14033; the same shape as the `eligibility` predicate
2317-
* below, #13608).
2317+
* below, commit fc9ba76a5).
23182318
*
23192319
* When false (default), no share links can be issued for this object AND
23202320
* no share link on it resolves: `resolveToken` re-reads this switch on
@@ -2351,7 +2351,7 @@ const ObjectSchemaBase = strictObject(
23512351
/**
23522352
* Optional CEL predicate over the candidate record. It is a STANDING
23532353
* policy about which records may be reached anonymously, and the platform
2354-
* holds it at BOTH points in a link's life (#13608):
2354+
* holds it at BOTH points in a link's life (commit fc9ba76a5):
23552355
*
23562356
* - **at mint** — `createLink` refuses with 422 when the predicate is
23572357
* false (e.g. "draft records cannot be shared") and writes no link row;
@@ -2363,7 +2363,7 @@ const ObjectSchemaBase = strictObject(
23632363
* ⚠️ Tightening this policy therefore cuts off already-minted links, on
23642364
* purpose — no revocation step, no grace period. That is the point of a
23652365
* standing policy, and it is a behaviour change for deployments that
2366-
* shipped before #13608.
2366+
* shipped before commit fc9ba76a5.
23672367
*
23682368
* Fail-CLOSED at both points: a predicate that does not compile, that
23692369
* faults on the record, or that answers anything other than `true` refuses
@@ -2715,7 +2715,7 @@ function assertReferenceViaSiblingDeclared(objectName: unknown, fields: unknown)
27152715
}
27162716

27172717
/**
2718-
* [#9138 — #8772 maintainer ruling, Direction 2 / ADR-0055] Under
2718+
* [#9138 — commit 75b7c240a, maintainer ruling Direction 2 / ADR-0055] Under
27192719
* `sharingModel: 'controlled_by_parent'` the builder FORCES `required: true`
27202720
* on every `master_detail` reference, and REFUSES an explicit
27212721
* `required: false` there, loudly.
@@ -2728,7 +2728,7 @@ function assertReferenceViaSiblingDeclared(objectName: unknown, fields: unknown)
27282728
* `masterFK IN (accessible master ids)` can never match null — the row is
27292729
* invisible to everyone — and every later by-id write answers
27302730
* `422 MISSING_REQUIRED_FIELD`. Today only the security gate
2731-
* (`assertControlledByParentWrite`) closes that shape, and #8772 measured that
2731+
* (`assertControlledByParentWrite`) closes that shape, and commit 75b7c240a records that
27322732
* the declaration and the enforcement disagree. This makes the unsafe shape
27332733
* impossible to NEWLY declare:
27342734
*
@@ -2741,7 +2741,7 @@ function assertReferenceViaSiblingDeclared(objectName: unknown, fields: unknown)
27412741
* Lives at `create()` — the authoring surface (ADR-0077) — beside
27422742
* {@link assertSystemDataIsWritable}, and deliberately NOT in raw
27432743
* `.parse()`/`.safeParse()`: metadata already at rest must keep loading.
2744-
* Runtime tolerance is the other half of the #8772 ruling — the security
2744+
* Runtime tolerance is the other half of commit 75b7c240a's ruling — the security
27452745
* gate's fallbacks stay, and the lint rule stays `warning` until v18 — so
27462746
* publish-time refuses new declarations while runtime tolerates old ones.
27472747
*
@@ -2907,7 +2907,7 @@ export const ObjectSchema = lazySchema(() => {
29072907
// declared can never resolve — refuse at the authoring seam, beside its
29082908
// sibling assertions, rather than one error per seeded row at load time.
29092909
assertReferenceViaSiblingDeclared(cfg.name, cfg.fields);
2910-
// [#9138 — #8772 ruling, Direction 2] A `controlled_by_parent` object's
2910+
// [#9138 — commit 75b7c240a, ruling Direction 2] A `controlled_by_parent` object's
29112911
// `master_detail` reference is forced `required: true` (an explicit
29122912
// `required: false` throws, loudly) so the unsafe shape cannot be newly
29132913
// declared. Raw `.parse()`/`.safeParse()` stay tolerant for metadata at

0 commit comments

Comments
 (0)