docs(spec): describeHighPrivilegeBits 的裸通配符举例换成仍带 '*' 的 viewer_readonly (#6696) - #6846
Merged
os-project-manager merged 1 commit intoAug 9, 2026
Merged
Conversation
…ly (#6696) #5491(PR #6684)把平台基线收窄为 explicit-allow 之后,`member_default` 已经完全 不带 `'*'` 条目,而 JSDoc 仍拿它当"裸通配符不算高权限"的举例,读者照着去找会 一无所获,进而怀疑规则本身而不是这句举例。 规则未动,也从来没错:`describeHighPrivilegeBits` 不读 `member_default`,它评估 调用方递进来的任意集合,ADR-0090 D5 断言原样保留。只换举例,且举例是对着真实的 `defaultPermissionSets` 量出来的,不是抄的: - `viewer_readonly` 带 `'*': { allowRead: true }`,写入/VAMA/transfer/purge 位 全部显式 false,无 systemPermissions; - `describeHighPrivilegeBits(viewer_readonly)` 为 null, `describeAnchorForbiddenBits(viewer_readonly,'everyone')` 也为 null; - `describeAnchorForbiddenBits(viewer_readonly,'guest')` 恰恰因为通配符被拒 —— 于是同一个举例同时演示了这句话的两半:everyone 可绑,GUEST 层更严。 D5 的形状描述从"read/create/edit-own baseline"放宽为"read — or read/create/edit-own — baseline",因为 `viewer_readonly` 是只读的:只换名字不放宽 形状,等于把一个失效举例换成另一个失效举例。#2753 的历史保留,改写成 "then-wildcard-carrying default baseline" 让时态在新增的 #5491 从句旁边不产生歧义。 纯注释改动:无实现变更,无 schema 接受键集变化(check:authorable-surface 绿), 本文件不是 `.zod.ts`,不落到 content/docs/references/**;之所以仍带 changeset,是 因为该注释随 dist/security/index.d.ts 发布给使用方(编辑器悬停即读到)。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018ffcE95NaMJcL9XJ9VDYgk
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 112 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This was referenced Aug 9, 2026
os-project-manager
marked this pull request as ready for review
August 9, 2026 00:43
os-project-manager
deleted the
claude/issue-6696-high-privilege-stale-example
branch
August 9, 2026 01:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6696
问题
packages/spec/src/security/high-privilege.ts里describeHighPrivilegeBits的 JSDoc,拿平台自己的member_default当"裸'*'通配符本身不算高权限"的举例。#5491(PR #6684)按维护者裁定(2026-08-07)把平台基线收窄为 explicit-allow 之后,该集合完全不带'*'条目了,于是这句举例指着一个已经不是那个形状的集合。照着去找的读者一无所获,进而怀疑的是规则本身,而不是这句举例。规则没错,也没动。
describeHighPrivilegeBits从不读member_default,它评估调用方递进来的任意集合;ADR-0090 D5 断言原样保留,实现一行未改。前提复核(在
origin/main@c32944d67上量的)不是照抄 issue,而是拿真实的
defaultPermissionSets数组跑真实谓词量出来的 —— 因为"用另一个同样失效的举例替换失效举例"是同一个缺陷再犯一次,本 lane 今天已经为这个形状关掉过 #6628:最后一行是意外收获:
viewer_readonly比member_default当年更适合做这个举例 —— 同一个集合把这句话的两半同时演示了,everyone 可绑、GUEST 层恰恰因为通配符被拒。改动
一处注释,7 增 5 删,外加一个 changeset。有两点是刻意的:
viewer_readonly是只读的。只换名字不动形状,等于把一个失效举例换成另一个失效举例。故改为 "a read — or read/create/edit-own — baseline"。#5491从句旁边不产生歧义。同一段 JSDoc 后面还有第二处
member_default提及(allowExport那句),已复核仍然为真(该集合确实不带allowExport,且 everyone 可绑),故逐字节未动。验证
packages/spec下不存在覆盖high-privilege.ts的 prose pin(该函数的行为 pin 在plugin-security/src/audience-anchors.test.ts,它测行为不测文案),因此把改动回退不会让任何测试变红。此处不发明一次性的源码文本正则。真正有证伪力的检查是上面那次探针:若viewer_readonly没有通配符、或不是只读、或不可绑 anchor,探针会当场说出来 —— 它正是用来挡"同一个缺陷再犯一次"的。pnpm --filter @objectstack/spec check:generated→ 10/10 绿,含check:authorable-surface(任何 schema 接受的键集未移动)与check:docs。pnpm --filter @objectstack/spec typecheck→ 绿(TEST_DEBT 未动:未触碰任何测试文件,58 files / 266 errors 原样)。pnpm --filter @objectstack/spec test→ 346 test files passed / 8877 tests passed,exit 0。node scripts/check-nul-bytes.mjs→ OK(6362 文件);改动文件另做了越过该 gate 的控制字符自扫描,干净。参考文档触达结论(本次要求测的那一项)
不触达
content/docs/references/。packages/spec/scripts/build-docs.ts:186是if (!entry.name.endsWith('.zod.ts')) continue;—— 生成器只遍历.zod.ts,而high-privilege.ts不是。全文 grepcontent/docs/对该 JSDoc 的特征句零命中,check:docs亦无任何待重生成产物。所以本次属于今天两类测量中的不触达那一类(与.describe()字符串触达相反,与 TSDoc@example/ authorable key 的 JSDoc 不触达一致)。⛔ 无生成产物需要提交,也未手改任何生成输出。Changeset 判断(要求逐条论证的那一项)
加了,
@objectstack/spec: patch。packages/spec的files是["dist", "json-schema", "liveness", "prompts", "llms.txt", "README.md", "src/**/*.zod.ts", "CHANGELOG.md", "api-surface", "spec-changes.json"]。high-privilege.ts不是.zod.ts,源文件本身确实不随包发布。但结论不能停在这里:构建后实测dist在files里,所以这段文案是随 npm 包发布给使用方的,编辑器悬停describeHighPrivilegeBits读到的就是它 —— 也就是说被误导的不只是本仓库读者。先例支持同一条线:最贴近的结构同类
8ad609c69(packages/spec/src/contracts/metadata-service.ts,同为非.zod.ts的纯 JSDoc 改动)带了 patch changeset,其结语正是 "Documentation only — no implementation changed, and the doc comment ships in the package's.d.ts"。近期六个同类里四个带 changeset。非 breaking,故不需要 ADR-0087 disposition 标记。
范围
严格限于 issue。过程中发现同一处失效举例在
plugin-security/src/audience-anchors.test.ts:65的测试名里还有一份(以及 line 103 的弱实例),按 Prime Directive #10 另行归档为 #6842(observation-class,finding,无pm:queue,未指派),未在本 PR 修 —— 它在另一个包,且本卡是domain:spec-surface。该 issue 里也记了更值得 triage 的那一层:目前没有任何机制把"文案声称集合 X 是形状 Y"关联到defaultPermissionSets实际发布的内容,所以 #5491 一改,三处文案同时静默失效而没有一个 gate 动。Generated by Claude Code