Repository navigation
Commit e9c88f7
docs(adr): ADR-0145 — ui
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8JeHddgk25VvfwwsRzoP6xU)_
Fixes #25912
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:新增一篇 ADR-0145(根 `docs/adr/`)并重生成 ADR 索引:ui 授权面上的 `?: never` 墓碑按
spec 自己的窗口退场,退役后再保留一个 major,到 R+2 major 切出时到期,绝不更长;只立规则,不删任何墓碑、不改代码。
- 为什么改:执行本卡的维护者字母 A(裁决 6407810703);ui 授权面只增不减,每个墓碑都成了永久义务。
- 风险与回滚:只有文档,无发布面;风险在规则措辞本身(容器豁免、R 的读法),回滚即 revert 本 PR。
- 先看:ADR 的 D1(规则)、D2(R 怎么读,含早于 ADR-0087 与只属 ui 的退役)、D3(删墓碑不能把拒绝变成静默接收)。
- 两分钟验证:`pnpm check:adr-index && pnpm check:adr-anchors && node
scripts/check-adr-links.mjs`,应全部 exit 0。
- 需要你做的:Tier H,等契约复核 PASS 与席位 ACCEPT 后由您批准合并;在那之前本 PR 保持草稿。
## What changes
- **New record**
`docs/adr/0145-ui-deprecation-tombstones-retire-on-the-spec-window.md`
(Proposed; becomes Accepted by the maintainer's merge). It records
letter A and states:
- **D1, the rule.** A `?: never` tombstone leaves the ui authoring face
in the first release after the spec major in which its ADR-0087
conversion expires: carried through protocol major R + 1, due from the
cut of R + 2, the same cut at which ADR-0087's 2026-10-26 addendum
removes the spec's kit. One clock (the protocol major, never the npm
major). The window binds both ways: a ui tombstone neither leaves before
nor outlives the spec kit for the same key.
- **D2, reading R.** Spec-named retirements read R from the spec
(`RETIRED_KEYS_BY_MAJOR`, else the release-tag clock the spec's deletion
gate uses). A retirement that predates ADR-0087 is counted as if its
conversion had run the one-major window from the major it retired in, so
no such tombstone gets a fresh window. A ui-only retirement runs the
same window from the first `@object-ui/types` release that carried it.
Undated means not due, never guessed.
- **D3, the container carve-out.** A deletion must leave a refusal: the
TS member stays while its container is open (an index signature); the
zod twin stays where its container is `.passthrough()` or strips, which
is ADR-0087's own strip-container rule and the posture
`agedOutSpecKeyRefusal` already takes. Derived faces move together.
- **D4, the changeset.** `minor` (never `major`), a **Breaking** note
naming each `Type.key` and its remedy, plus the declaration lines and
ADR-0087 disposition marker the gates require, not restated.
- **Applying the rule.** How the first batch enumerates, dates (`git log
-S` on a full clone; pre-merge ui history is in
`objectstack-ai/objectui`, not here), judges and re-pins.
- **Regenerated index** `docs/adr/README.md` (`pnpm adr:index`).
## Why
Ruling 6407810703 (maintainer letter A, 2026-10-25T01:46Z) over seat
options 6407810621. Not taken: B (remove when the spec retires the key)
and C (no rule).
## Tests
None. This PR declares a rule and changes no code, so there is no
behaviour to pin or ablate.
## Acceptance notes
- **Registry.** The record is in the root `docs/adr/`: #26080 ruling A
keeps `ui/docs/adr/` as the frozen ObjectUI import (indexed under `ui-`,
files untouched), and `scripts/check-adr-anchors.mjs` resolves only the
root registry, so a new ui decision lands here; Prime Directive #13
places an ADR in the repository whose code it governs. No written rule
continues new ui decisions in `ui/docs/adr/`. Number 0145: open PR
#27239 holds 0144, and no other open PR adds a root record at or above
it (the file lists of all 20 open PRs, read through REST before
numbering).
- **Premise readings** (`origin/main` `9dec0545`,
`ui/packages/types/src`, tests excluded): 520 `@deprecated` tags and 675
`?: never` lines (the card read 574 and 640 on 2026-10-24 objectui). The
card's "16 `z.never` tombstones" does not hold: the zod tombstones are
now spelled through the helpers in `zod/tombstone.zod.ts`
(`retirementTombstone`, `agedOutSpecKeyRefusal`, `aliasKeyRefusal`,
`handlerKeyRefusal`, `retiredNodeType`), several hundred call sites, so
the ADR names the zod twin by what it mirrors rather than by a count.
Per ui/AGENTS.md #9 the ADR records no count; the instrument is in
"Applying the rule".
- **Reading for the contract review.** The ruling's text keys the window
to a spec retirement. Most ui tombstones name a ui-only retirement (an
objectui card) with no spec key behind them. D2 runs the same window
from the ui's own retirement release. This is the narrowest reading
consistent with "the window the spec itself runs, never a longer one",
and the review should confirm it.
- **D3 and the "two faces retire together" facet.** The ruling's facet ①
has the zod and `.d.ts` faces retire together. D3 keeps that wherever a
deletion leaves a refusal. Where the zod container is `.passthrough()`
(everything derived from `BaseSchemaCore`), deleting the twin would make
the tolerant face keep the key silently. That is the Prime Directive #12
defect ADR-0087's 2026-10-26 addendum refused for the spec's 58
strip-container tombstones, so the twin stays there until its container
closes.
- **Not here.** The ui/AGENTS.md #0.1 pointer line rides #25919's
AGENTS.md PR, as the ruling's item 3 says. No sweep: the first
application batch is its own card after this merge.
- **Tier H.** `docs/adr/**` is the register row `adr` (`glob:
'docs/adr/**', tier: GOVERNED_TIER_H` in
`scripts/pm/check-governed-merges.mjs`). `dispatch-gates --tier` derives
the mandatory ceiling model tier for `docs/adr/**`, with the effort
floor at xhigh. This card ran at TIER_DEFAULT under the measured quota
exemption the claim records ("ceiling tier unavailable, contract review
handed to triage at review time"). Changed lines 160 (+157 / −3) against
the 3,000 threshold: under.
- **How this PR was opened** (#26617: relay `pr_create` requests the
governed approvers on a diff touching a governed path). `11b3e687` adds
the record, `98dcc57e` reverts it so the PR opened with an empty net
diff and no approver requested, and `01db9123` re-applies it, so the
head's tree equals `11b3e687`'s. The seat requests approvers after the
contract review PASS and its ACCEPT.
## Verification
At `d3e67407` (the head after the contract-review rework; `01db9123` was
tree-identical to `11b3e687`), branch point `origin/main` `8d79bbd7`.
<details><summary>Gates</summary>
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at `11b3e687`: 21 commands, each exit
captured before any pipe:
- `node scripts/check-adr-links.mjs` :: exit 0
- `node scripts/check-adr-links.mjs --self-test` :: exit 0
- `node scripts/check-closing-keyword-parity.mjs` :: exit 0
- `node scripts/check-closing-keyword-parity.mjs --self-test` :: exit 0
- `node scripts/check-comment-mask-corpus.mjs` :: exit 0
- `node scripts/ci/plan-test-core-shards.mjs --self-test` :: exit 0
- `pnpm --filter @objectstack/lint run check:doc-formula-expressions` ::
exit 0
- `pnpm check:adr-anchors` :: exit 0
- `pnpm check:adr-index` :: exit 0
- `pnpm check:adr-symbol-anchors` :: exit 0
- `pnpm check:ci-filter-parity` :: exit 0
- `pnpm check:closed-ceremony-text` :: exit 0
- `pnpm check:cross-package-test-inputs` :: exit 0
- `pnpm check:doc-authoring` :: exit 0
- `pnpm check:driver-memory-census` :: exit 0
- `pnpm check:gitlink-declared` :: exit 0
- `pnpm check:nul-bytes` :: exit 0
- `pnpm check:pm-governed-merges` :: exit 0
- `pnpm check:pm-prior-rulings` :: exit 0
- `pnpm check:refd-timer-probe` :: exit 0
- `pnpm check:watch-hint-literal` :: exit 0
- `check:doc-formula-expressions` first exited 3 (prerequisite not met:
nothing measured) and exited 0 after `pnpm exec turbo run build
--filter=@objectstack/formula --filter=@objectstack/lint` (under the
verification lock, exit 0).
- `--ran`: "21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED
(a DERIVED zero — all 21 recorded an exit code and none of them is 3)".
- `pnpm --dir ui run check:new-line-citations`: "0 new citation(s)",
exit 0.
- Not run locally, CI's: the type-check lanes and the Plan Test Core
shards step `--commands` lists as NOT MEASURED (no TypeScript changes
here).
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbYznNtcYGX8apHQPtk)_
---------
Co-authored-by: Claude <noreply@anthropic.com>?: never tombstones retire on the spec's one-major window (#27251)1 parent c59b1bf commit e9c88f7
2 files changed
Lines changed: 171 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| |||
211 | 211 | | |
212 | 212 | | |
213 | 213 | | |
| 214 | + | |
214 | 215 | | |
215 | 216 | | |
216 | 217 | | |
| |||
0 commit comments