Repository navigation
Commit 9494dd8
feat(spec)!: retire PositionGrantVia 'name' and the Setup by-name grant readers (#26398)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} -->
_Requested by **Yibo Wang** · [project
thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwB6HyysmaMsguGWxWciWzUMt)_
Fixes #26022
Clause-②: no (narrowing)
Metadata-protocol: none
## 维护者速读
- **改了什么**:`PositionGrantVia` 收窄为只剩 `'definition'`;Setup
岗位列表去掉「(同名)」徽标及其两个 i18n 键;托管环境 Users 页的「未授权」标记不再按岗位同名推算权限集。
- **为什么改**:#24757 已让运行时不再按岗位名授予同名权限集,服务端再也不会返回 `via: 'name'`;spec
和界面却还在描述这种已不存在的授权(#13419 裁决 B,18.x 直接退役)。
- **风险与回滚**:风险低。线上返回值不变(本来就全是 `'definition'`);TS 消费方若比较 `via === 'name'`
会编译报错,删掉该分支即可。回滚 = revert 本 PR。
-
**先看**:`ui/packages/app-shell/src/views/managedEnvironmentUsers.tsx`(判定逻辑变化:同名岗位的持有人现在会被标「未授权」);`packages/spec/src/contracts/security-service.ts`(公开类型收窄);`packages/spec/src/migrations/entries/semantic/18.position-grant-via-name-retired.ts`(ADR-0087
登记)。
- **两分钟验证**:`cd ui && pnpm exec vitest run
packages/app-shell/src/views/__tests__/managedEnvironmentUsers-13330.test.tsx`,预期
16 个用例全绿,其中「a position grants nothing by sharing its name with a
permission set」为新判定。
- **需要你做的**:无,席位落地(落地前欠一次 `CONTRACT_REVIEW_TIER` 契约复核)。
## What changes
- **`@objectstack/spec`**: `PositionGrantVia`
(`packages/spec/src/contracts/security-service.ts`) is now
`'definition'`. The docblock no longer describes the position-name fold.
The security plugin already serves only `via: 'definition'`
(`security-plugin.ts` `describePositionGrants`), so the wire answer does
not change.
- **ADR-0087**: a new D3 semantic entry
`position-grant-via-name-retired` registers the retirement. The type
describes a served answer, not a stack collection or a metadata type, so
there is no D2 conversion source. The changeset carries the `registered`
disposition.
- **Setup → Positions** (`PositionGrantCells.tsx`): the granted-sets
cell shows each set's name alone. The "(by name)" / 「(同名)」 badge, its
hint, and the i18n keys `engine.position.grants.byName` and
`engine.position.grants.byNameHint` (en and zh) are removed. The
served-entry filter accepts only `via: 'definition'`.
- **Setup → Users on a managed environment**
(`managedEnvironmentUsers.tsx`): the client-side name fold is retired. A
held position now counts only by the sets its definition lists. The
permission-set catalogue read, `catalogueRead`, and
`PositionRegistrySource.getTypeStatus` existed only for the fold.
Measured: no other reader in the file or in its one caller,
`objectViewIdentity.tsx`. All three are removed, including the caller's
`getTypeStatus` line. The observable change: a holder of a position
whose name matches a permission set the definition does not list is now
marked Not authorized, unless something else grants them a set beyond
the baseline. That matches what the server enforces.
- **Docblock**: `packages/rest/src/meta-item-read-gate.ts`
(`describeMetaPositionList`) now says `via: 'definition'`.
- **Fixture triage** (consumer radius of the narrowed value, respelled
to a declared set):
`packages/runtime/src/domains/meta-list-projection-parity.test.ts` and
`ui/packages/data-objectstack/src/metadata-client.listInclude-25333.test.ts`
still served `via: 'name'` from their doubles. Both now serve `{ name:
'forecasting', via: 'definition' }`.
## Tests
- `managedEnvironmentUsers-13330.test.tsx`: the name-fold pin is
inverted. A holder of `closer` (a position that shares its name with a
set but lists only a baseline set) reads `baseline-only`. The control
holder of `sales_rep` reads `beyond-baseline`. The registry is asked
only for `position`. The "catalogue cannot be read" case is deleted
because the read it covered is gone.
- `ResourceListPage.positionGrants-25333.test.tsx`: the fixture serves
only declared sets. Each badge's text is exactly the set name and
carries no `title`.
- Ablation, one-time: re-adding a name-based count,
`beyondBaseline(position) ||` in the position branch, turns three cases
red, the new one among them. The file was restored, and its blob equals
HEAD (`044d3b83d42f`).
<details><summary>Local readings (head 1efc50f, then merged head
1a70ed5)</summary>
- `pnpm --filter @objectstack/spec build`: exit 0. `check:generated`:
exit 0, all 14 artifacts up to date. The api-surface is unchanged
because the export name stays.
- `pnpm --filter @objectstack/spec test`: 726/726 files, 21984 tests
passed.
- `cd ui && vitest run` on the three touched test files: 3/3 files,
25/25 tests. Ablation run: 3 failed / 13 passed, as intended, then
restored.
- `cd ui && vitest run` on `app-shell/src/views/__tests__/`,
`metadata-admin/ResourceListPage*`, `zh-base-term`, all of
`data-objectstack`, and `i18n` `objectView-config-keys-retired-4730`:
182/182 files, 1871/1871 tests, on both heads.
- `packages/runtime` `meta-list-projection-parity.test.ts`: 1/1 file,
878/878 tests.
- Type checks: `@object-ui/app-shell type-check` (both heads),
`@object-ui/data-objectstack type-check`, `@objectstack/spec typecheck`,
`@objectstack/rest typecheck` and `@objectstack/runtime typecheck`: exit
0. Runtime first reported TS2307 for `@objectstack/driver-turso`, an
unbuilt dist. It was green after building that package.
- `dispatch-gates --commands` on the final head 1a70ed5: 94 commands,
all exit 0. `--ran` reconciliation: 94 derived, 94 run, 0 NOT-MEASURED,
a derived zero.
</details>
<details><summary>Full dogfood battery (final head 1a70ed5)</summary>
`pnpm --filter @objectstack/dogfood test` under the verify lock: 302
files (2 failed, 297 passed, 3 skipped), 2549 tests (10 failed, 2521
passed, 18 skipped). VERDICT command-exit 1.
All 10 failures are in `test/authz-probe-blind-spot.test.ts` (4) and
`test/authz-conformance.test.ts` #17111 (6). They count text in
`packages/rest/src/rest-server.ts` and
`packages/rest/src/rest-route-ledger.ts`, for example the control
`this.routeManager.register(` is expected at 62 and found at 63. This PR
does not touch either file or `packages/qa/dogfood`. `git diff
origin/main` on all three is empty, so the same counts fail on
`origin/main` (e931621). They are main's, not this change's.
10 reds in authz-conformance.test.ts and authz-probe-blind-spot.test.ts
are main's at origin/main abb9046 (same 10, measured on a detached
worktree), anchored on #26400; not this PR's.
</details>
## Acceptance notes
- `packages/plugins/plugin-security/src/security-plugin.ts` (docblock of
`describePositionGrants`, around line 3535) still says "the contract's
`'name'` member is no longer served". The member is now gone, so the
sentence goes stale. It is left alone because PR #26337 holds that file.
Carrier: the seat.
- `.changeset/24757-retire-position-name-fold.md` (pending, from #24757)
says the `'name'` member is "retired separately in #26022; until then
the value is published but never served". It stays accurate as a record
of that change and is not edited here.
- The full app-shell suite (about 1,800 files) was narrowed locally to
the modules this diff reaches, listed above. CI's UI jobs run the rest.
- The full-battery dogfood reds above are pre-existing on `origin/main`
(see the dogfood block). They are reported to the seat as a main-red
finding, not fixed here.
## Verification
- Requires one `CONTRACT_REVIEW_TIER` contract review before the queue,
as the claim records.
- No governed surface is touched. Changed lines are about 203, under the
3,000 threshold.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01WGufzgKsGKQ8LMfpA72sns)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent d1a2e71 commit 9494dd8
14 files changed
Lines changed: 119 additions & 107 deletions
File tree
- .changeset
- packages
- rest/src
- runtime/src/domains
- spec/src
- contracts
- migrations/entries/semantic
- ui
- content/docs/guide
- packages
- app-shell/src/views
- __tests__
- metadata-admin
- data-objectstack/src
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3373 | 3373 | | |
3374 | 3374 | | |
3375 | 3375 | | |
3376 | | - | |
| 3376 | + | |
| 3377 | + | |
3377 | 3378 | | |
3378 | 3379 | | |
3379 | 3380 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
344 | 344 | | |
345 | 345 | | |
346 | 346 | | |
347 | | - | |
| 347 | + | |
348 | 348 | | |
349 | 349 | | |
350 | 350 | | |
| |||
676 | 676 | | |
677 | 677 | | |
678 | 678 | | |
679 | | - | |
| 679 | + | |
680 | 680 | | |
681 | 681 | | |
682 | 682 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
129 | 130 | | |
130 | | - | |
| 131 | + | |
131 | 132 | | |
132 | 133 | | |
133 | 134 | | |
| |||
727 | 728 | | |
728 | 729 | | |
729 | 730 | | |
730 | | - | |
731 | | - | |
| 731 | + | |
| 732 | + | |
732 | 733 | | |
733 | 734 | | |
734 | 735 | | |
| |||
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
69 | | - | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
70 | 72 | | |
71 | 73 | | |
72 | | - | |
73 | 74 | | |
74 | 75 | | |
75 | 76 | | |
| |||
83 | 84 | | |
84 | 85 | | |
85 | 86 | | |
86 | | - | |
| 87 | + | |
87 | 88 | | |
88 | 89 | | |
89 | | - | |
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
| |||
138 | 138 | | |
139 | 139 | | |
140 | 140 | | |
141 | | - | |
| 141 | + | |
142 | 142 | | |
143 | 143 | | |
144 | 144 | | |
| |||
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
209 | | - | |
| 209 | + | |
210 | 210 | | |
211 | | - | |
| 211 | + | |
| 212 | + | |
212 | 213 | | |
213 | 214 | | |
214 | 215 | | |
215 | 216 | | |
216 | 217 | | |
217 | | - | |
| 218 | + | |
218 | 219 | | |
219 | 220 | | |
220 | 221 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
31 | 30 | | |
32 | 31 | | |
33 | 32 | | |
| |||
37 | 36 | | |
38 | 37 | | |
39 | 38 | | |
40 | | - | |
41 | | - | |
| 39 | + | |
42 | 40 | | |
43 | 41 | | |
44 | 42 | | |
| |||
124 | 122 | | |
125 | 123 | | |
126 | 124 | | |
127 | | - | |
| 125 | + | |
| 126 | + | |
128 | 127 | | |
129 | 128 | | |
130 | 129 | | |
131 | | - | |
| 130 | + | |
132 | 131 | | |
133 | 132 | | |
134 | 133 | | |
135 | 134 | | |
136 | 135 | | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
161 | 143 | | |
162 | 144 | | |
163 | 145 | | |
| |||
0 commit comments