Repository navigation
Commit 778aedf
fix(platform-objects, lint): the Business Unit page and the readScope hint say what needs the enterprise edition (#30622)
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgQCCAGJ1VCZe1N15s2gYhCQ)_
domain:server#6 · os-bill · session_01Utp6CXCS98uhsFQYk64epE (dev: card
thread session_01Utp6CYwoPbRRkiyph2ufCw)
## 维护者速读
-
改了什么:业务单元页面说明改成「开源版里共享规则可以按业务单元共享、成员离开即失去;按业务单元读取全部记录需要企业版」;业务单元时区帮助不再声称日期按它计算;`os
validate` 的 `security-private-no-readscope` 提示在项目没声明
`hierarchy-security` 时只建议 `org`,并写明另外三个范围需要企业包。
- 为什么改:管理员照页面和提示去配,结果开源版编译直接拒绝(#30210 第 1、2 行);时区帮助说的事运行时根本没人读。
- 风险与回滚:只改说明文字和一条 info 级提示的 hint,编译拒绝、规则触发条件与级别都不变;回滚即 revert 本 PR。
-
先看:`packages/lint/src/validate-security-posture.ts`(`hierarchyScopesCompile`
那段)、`packages/platform-objects/src/identity/sys-business-unit.object.ts`(description
与 timezone)、`zh-CN.objects.generated.ts` 两处中文。
- 两分钟验证:`pnpm --filter @objectstack/lint exec vitest run
src/validate-security-posture.test.ts -t hierarchy-security`,预期 2 条通过;无
`requires` 时 hint 只建议 `'org'` 并点名 `@objectstack/security-enterprise`。
- 需要你做的:无,席位落地。
Refs #30210 (rows 1, 2)
Clause-②: no
Metadata-protocol: none
Skills-docs: none (`git grep` of `skills/**` for business unit,
readScope and security-private-no-readscope: 6 hits in
`skills/objectstack-data` — SKILL.md lines 73 and 388, rules/security.md
lines 178 and 252, one eval; none states a sentence this diff makes
false)
## What changes
- **Row 1 — Business Unit page.** `sys_business_unit.description` (the
page text) said units are "used to scope data and reports". It now says
what a unit does in the open edition (a sharing rule can share records
with a unit, or a unit and the units under it; members get that access
and lose it when they leave — measured on the card) and that letting a
permission set read every record of a unit (read scope `unit`) needs the
enterprise edition. The compile refusal
(`validateHierarchyScopeCapability` in `stack.zod.ts`) is unchanged, as
the card asks. zh-CN value hand-written; `en` regenerated by `pnpm
i18n:extract`.
- **Seat amendment 6662593558 — Business unit Timezone help.** It said
date boundaries are computed in this zone; nothing reads
`sys_business_unit.timezone` (same reading as
`sys_organization.timezone`, corrected in #25347). The help now says it
changes no date calculation and names Settings → Localization → Default
timezone, mirroring the organization's help. en + zh-CN. No field
change.
- **Row 2 — `security-private-no-readscope` hint** (`packages/lint`, run
by `os validate` / `os lint`). The rule now reads the stack's `requires`
— the same declaration `defineStack` reads before refusing a hierarchy
scope. With `hierarchy-security` declared, the hint is unchanged.
Without it, the hint offers `readScope: 'org'` or widening
`sharingModel`, and says `'own_and_reports'`, `'unit'` and
`'unit_and_below'` need `requires: ['hierarchy-security']`, which
`@objectstack/security-enterprise` provides. A stack with no `requires`
(the runtime metadata door hands none) gets the requirement named too.
Same grants fire, same `info` severity.
Not built here: **row 3** (Timezone on Edit organization) is measured
only, per the order — removing a `sys_organization` field narrows an
accept set and is the owning lane's ADR-0049 removal. **Row 4** (hide
Parent Organization / Sort Order on one organization) stopped as
`needs_decision`: field and field-group `visibleWhen` bind only `record`
/ `previous` / `parent` at authoring (`FIELD_RULE_BOUND_ROOTS`,
`packages/lint/src/validate-expressions.ts`), and fields carry no
`requiresFeature`, so hiding needs a new metadata capability. Both
readings and the row 4 options are in the os-dev-report on the card.
## Tests
-
`packages/platform-objects/src/identity/sys-business-unit-edition-copy.test.ts`
(new): the description names sharing rules and the enterprise edition
and drops the scoping claim; the zh-CN description says 共享规则 / 企业版; the
Timezone help (en, zh-CN) says it changes no date calculation and names
Localization's Default timezone.
- `packages/lint/src/validate-security-posture.test.ts`: two cases in
the existing `security-private-no-readscope` block — without
`hierarchy-security`, the hint offers `'org'` before any hierarchy scope
and names the requirement in the same sentence as all three; with it,
every scope is offered and the enterprise package is not named. The
#5017 key-surface meta-test now lists `requires` among the keys read off
`stack` (declared by `ObjectStackSchema`).
<details><summary>Red on main 2ffdb64, green on the fix</summary>
```text
red (main 2ffdb64, tests only):
lint × without hierarchy-security, offers org and names the requirement beside the hierarchy scopes Tests 1 failed | 1 passed
platform-objects × all 4 cases Tests 4 failed (4)
green (fe3d2a1):
@objectstack/lint test Test Files 195 passed (195) Tests 8105 passed (8105)
@objectstack/platform-objects test Test Files 114 passed (114) Tests 1567 passed (1567)
both typechecks exit 0
```
</details>
<details><summary>Ablation (once): the requires read replaced by
true</summary>
```text
ablation-replace: ok mutation landed: anchor 1 -> 0, blob d877152 -> 6eded5d4c050
× without hierarchy-security, offers org and names the requirement beside the hierarchy scopes
× every key read off 'stack' is declared by 'ObjectStackSchema'
restored: git hash-object == HEAD blob d877152, git diff HEAD empty
```
</details>
## Acceptance notes
- The order's file surface named `packages/cli/src/**` for the advisory;
it lives in `packages/lint`. The seat's amendment 6662593558 added
`packages/lint/src/validate-security-posture.ts` and its tests.
- `pnpm i18n:extract` rewrote only `en`; ja-JP / es-ES kept their
existing values (their source-hash ledgers do not cover these keys), and
`check:i18n` / `check:i18n-stale-fill` are green.
- `sys_business_unit`'s docblock lists a `bu:` approver prefix in the
approval engine; `plugin-approvals` has no such prefix on `main`. A code
comment, not admin-facing — left alone.
## Verification
All local readings on head fe3d2a1 (after merging origin/main bdbaf80,
which carries #30551; the delta vs main is exactly the 7 files of this
PR). `pnpm i18n:extract` after the merge wrote no change.
<details><summary>dispatch-gates: 59 derived families, 59 run, 0
NOT-MEASURED; plus both packages' test and typecheck and pnpm lint —
64/64 exit 0</summary>
```text
node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0
node scripts/check-adr-0087-registration.mjs --self-test :: exit 0
node scripts/check-changeset-no-major.mjs --base origin/main :: 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-adoption.mjs :: exit 0
node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-dts-emitted.mjs --self-test :: exit 0
node scripts/check-empty-changeset.mjs --base origin/main :: exit 0
node scripts/check-empty-changeset.mjs --self-test :: exit 0
node scripts/check-issue-citations.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0
node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0
node scripts/docs-audit/check-affected-docs.mjs :: exit 0
node scripts/docs-audit/check-drift-comment.mjs :: exit 0
node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0
node scripts/release-pending-publish.mjs --self-test :: exit 0
pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
pnpm check:changeset-gate-self-tests :: 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:docs-transcript-drift :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:dts-closure :: exit 0
pnpm check:dual-build-cjs-loads :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:i18n :: exit 0
pnpm check:i18n-stale-fill :: exit 0
pnpm check:issue-citations :: exit 0
pnpm check:keyed-text-bounds :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:logger-receiver-detach :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:objectql-double-limit :: exit 0
pnpm check:org-identifier :: exit 0
pnpm check:page-declaration-shape :: exit 0
pnpm check:platform-object-tenancy-census :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:registry-log-declared :: exit 0
pnpm check:rest-log-spy-declared :: exit 0
pnpm check:slot-lookup :: exit 0
pnpm check:sourcemap-no-sources-content :: exit 0
pnpm check:system-context-census :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
pnpm --filter @objectstack/lint test :: exit 0
pnpm --filter @objectstack/lint typecheck :: exit 0
pnpm --filter @objectstack/platform-objects test :: exit 0
pnpm --filter @objectstack/platform-objects typecheck :: exit 0
pnpm lint :: exit 0
dispatch-gates --ran: 59 derived famil(ies) accounted for — 59 run, 0 NOT-MEASURED
```
</details>
CI families are read from this PR's check-runs, not re-run here.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CYwoPbRRkiyph2ufCw)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 740edc5 commit 778aedf
7 files changed
Lines changed: 139 additions & 11 deletions
File tree
- .changeset
- packages
- lint/src
- platform-objects/src
- apps/translations
- identity
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
792 | 792 | | |
793 | 793 | | |
794 | 794 | | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
795 | 831 | | |
796 | 832 | | |
797 | 833 | | |
| |||
1762 | 1798 | | |
1763 | 1799 | | |
1764 | 1800 | | |
1765 | | - | |
| 1801 | + | |
| 1802 | + | |
| 1803 | + | |
1766 | 1804 | | |
1767 | 1805 | | |
1768 | 1806 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1372 | 1372 | | |
1373 | 1373 | | |
1374 | 1374 | | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
1375 | 1384 | | |
1376 | 1385 | | |
1377 | 1386 | | |
| |||
1390 | 1399 | | |
1391 | 1400 | | |
1392 | 1401 | | |
1393 | | - | |
1394 | | - | |
1395 | | - | |
| 1402 | + | |
| 1403 | + | |
| 1404 | + | |
| 1405 | + | |
| 1406 | + | |
| 1407 | + | |
1396 | 1408 | | |
1397 | 1409 | | |
1398 | 1410 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
984 | 984 | | |
985 | 985 | | |
986 | 986 | | |
987 | | - | |
| 987 | + | |
988 | 988 | | |
989 | 989 | | |
990 | 990 | | |
| |||
1010 | 1010 | | |
1011 | 1011 | | |
1012 | 1012 | | |
1013 | | - | |
| 1013 | + | |
1014 | 1014 | | |
1015 | 1015 | | |
1016 | 1016 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
984 | 984 | | |
985 | 985 | | |
986 | 986 | | |
987 | | - | |
| 987 | + | |
988 | 988 | | |
989 | 989 | | |
990 | 990 | | |
| |||
1010 | 1010 | | |
1011 | 1011 | | |
1012 | 1012 | | |
1013 | | - | |
| 1013 | + | |
1014 | 1014 | | |
1015 | 1015 | | |
1016 | 1016 | | |
| |||
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
34 | | - | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
35 | 44 | | |
36 | 45 | | |
37 | 46 | | |
| |||
189 | 198 | | |
190 | 199 | | |
191 | 200 | | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
192 | 206 | | |
193 | 207 | | |
194 | 208 | | |
195 | 209 | | |
196 | 210 | | |
197 | 211 | | |
198 | | - | |
| 212 | + | |
199 | 213 | | |
200 | 214 | | |
201 | 215 | | |
| |||
0 commit comments