Skip to content

docs(ui): App 页补 ## Areas 一节 —— 含服务端/客户端闸门不对称 (#4880) - #5890

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-4880-apps-areas-docs
Aug 6, 2026
Merged

docs(ui): App 页补 ## Areas 一节 —— 含服务端/客户端闸门不对称 (#4880)#5890
os-zhuang merged 1 commit into
mainfrom
claude/issue-4880-apps-areas-docs

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes #4880

content/docs/ui/apps.mdx 此前一次都没有提到 areas[] —— 一个真实可作者化、且带权限相邻语义的键,文档覆盖为零;而 17.0.0 窗口里有三处改动正好落在它上面。只读这一页的作者不但不知道 areas 存在,更不知道他第一反应会去写的那个闸门(visible)恰恰是服务端强制的那个。

新增 ## Areas 一节

措辞蓝本

按 issue 的「谁先做谁定调」约定,配对单 #4749(PR #5336)与相邻单 #5337 均已 closed-completed,本节措辞对齐它们落地后的口径:packages/spec/src/ui/app.zod.tsAREA_REQUIRED_PERMISSIONS_RETIRED / AREA_VISIBLE_RETIRED 处方正文,以及 packages/spec/liveness/app.jsonareas.navigation note。

实测核对(逐条对 origin/main 验过,非照抄 issue)

断言 证据
项级闸门两棵树服务端强制 packages/rest/src/rest-server.ts filterAppForUser:filterAreas 对每个 areas[].navigation 复用同一个 filterNav
滤空的 area 被剥离 / 作者写空的透传 同上 filterAreas:kids.length === 0continue;anav.length === 0out.push(a)
visible / requiresObject 仅客户端 同函数的 "NOT gated here" 注释
areas 按作者顺序迭代、无排序 objectui AppSidebarAppSchemaRenderer 均为 areas.filter(...),无 sort
area 树取代顶层树、顶层为兜底 activeArea?.navigation || activeApp?.navigation || []
area 可见性由内部项派生 两处 hasVisibleNavigationItems(area.navigation, ...)(objectui#3311 / #3319)

一处据实测修正了 issue 的隐含表述:issue 只说 areas「按作者顺序迭代」,实测还有一条它没提、但对作者更要紧的事实 —— area 的可见性是从内部项派生的(全被 gate 掉就整个消失且不会被选中)。这正是 #4651 退役 area 级 visible 后仍能保住「整个 area 消失」这一 UX 的机制,已写入本节。

检查

  • tsx packages/spec/scripts/check-skill-examples.ts206 prose examples type-check against @objectstack/spec(新样例登记为 content/docs/ui/apps.mdx:339,205 → 206)
  • check-doc-authoring.mjs(含 --self-test)→ 362 files clean
  • docs-audit/affected-docs.mjs --self-test + check-audit-scope.mjs(含 --self-test)→ 全绿,178 hand-written doc(s) in sync
  • check-nul-bytes.mjs → OK;另做超出门禁的自扫 grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' 零命中
  • check-role-word.mjs → OK
  • MDX 语法:用 @mdx-js/mdx + remark-gfm 实编译该页通过(门禁的 lychee 设了 include_fragments = false,所以页内锚点不受 CI 保护 —— 因此把被引用的小节标题改成无标点的 ### Retired area-level keys,锚点不再依赖 17.0.0 / 破折号的 slug 化行为)

边界

docs-only:仅改 content/docs/ui/apps.mdx(+197 行)。⛔ 未动 packages/** 源码(spec 处方与其 pin 只读不改),⛔ 未动 content/docs/releases/**。不发布任何包,故无 changeset,PR 自带 skip-changeset 标签。


Generated by Claude Code

…#4880)

`content/docs/ui/apps.mdx` never mentioned `areas[]` — an authorable key with
permission-adjacent semantics at zero doc coverage, while three changes landed
on it in the 17.0.0 window. An author reading only this page could not learn
that areas exist, let alone that the gate they reach for first is the one the
server does not enforce.

New `## Areas` section:

- when an area beats a top-level `group` (a group keeps siblings on screen; an
  area REPLACES the sidebar, so it fits contexts a user switches between);
- the area property table — the whole strict key set, with `description` marked
  as the annotation no surface renders today;
- how `areas[].navigation` relates to the top-level tree: areas take precedence
  and the top-level tree is the fallback when no area is visible; declaration
  order IS display order (nothing sorts areas); the switcher appears only above
  one visible area; area visibility is DERIVED from the items inside, never
  authored;
- the server/client gate asymmetry as the section's safety point: item-level
  `requiredPermissions` / `requiresService` are stripped server-side in BOTH
  trees since #4722 and re-checked in the shell, while `visible` (CEL) and
  `requiresObject` stay client-only at every level — so anything that must never
  reach the browser goes in `requiredPermissions`, never in `visible`;
- the 17.0.0 retirements (`order` #4667, `visible` / `requiredPermissions`
  #4651) as parse-time rejections, with the fail-open history that motivated
  them and the note that they do not read back onto item-level gating;
- a Complete-Example-grade sample marked `{/* os:check */}` so the gate
  type-checks it against the built spec (206 prose examples, was 205), showing
  both gate kinds side by side and carrying none of the three retired keys.

Wording follows the corrected `AREA_REQUIRED_PERMISSIONS_RETIRED` /
`AREA_VISIBLE_RETIRED` prescriptions and the `areas.navigation` note in
`packages/spec/liveness/app.json`; nothing under `packages/**` is touched.

Closes #4880

Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 6, 2026 11:02am

Request Review

@github-actions github-actions Bot added the size/m label Aug 6, 2026
@os-zhuang os-zhuang added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/m labels Aug 6, 2026 — with Claude
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 6, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review August 6, 2026 11:14
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit 6dc6576 Aug 6, 2026
28 of 29 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-4880-apps-areas-docs branch August 6, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

content/docs/ui/apps.mdx 完全没有 areas[] —— 一个带权限语义的可作者化键零文档覆盖

2 participants