Skip to content

docs(spec): describeHighPrivilegeBits 的裸通配符举例换成仍带 '*' 的 viewer_readonly (#6696) - #6846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-6696-high-privilege-stale-example
Aug 9, 2026
Merged

docs(spec): describeHighPrivilegeBits 的裸通配符举例换成仍带 '*' 的 viewer_readonly (#6696)#6846
os-project-manager merged 1 commit into
mainfrom
claude/issue-6696-high-privilege-stale-example

Conversation

@os-project-manager

@os-project-manager os-project-manager commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Fixes #6696

问题

packages/spec/src/security/high-privilege.tsdescribeHighPrivilegeBits 的 JSDoc,拿平台自己的 member_default 当"裸 '*' 通配符本身不算高权限"的举例。#5491(PR #6684)按维护者裁定(2026-08-07)把平台基线收窄为 explicit-allow 之后,该集合完全不带 '*' 条目了,于是这句举例指着一个已经不是那个形状的集合。照着去找的读者一无所获,进而怀疑的是规则本身,而不是这句举例。

规则没错,也没动。 describeHighPrivilegeBits 从不读 member_default,它评估调用方递进来的任意集合;ADR-0090 D5 断言原样保留,实现一行未改。

前提复核(在 origin/main @ c32944d67 上量的)

不是照抄 issue,而是拿真实的 defaultPermissionSets 数组跑真实谓词量出来的 —— 因为"用另一个同样失效的举例替换失效举例"是同一个缺陷再犯一次,本 lane 今天已经为这个形状关掉过 #6628:

=== member_default ===
  has '*' entry:         false          ← 前提成立,举例确实失效
  describeHighPrivilegeBits             -> null
  describeAnchorForbiddenBits(everyone) -> null

=== viewer_readonly ===
  ships:                 yes ("Viewer — Read-Only")
  has '*' entry:         true
  '*' value:             {"allowCreate":false,"allowRead":true,"allowEdit":false,
                          "allowDelete":false,"allowTransfer":false,"allowRestore":false,
                          "allowPurge":false,"viewAllRecords":false,"modifyAllRecords":false}
  '*' 非 read 的 true 位:  []            ← 名副其实的只读
  systemPermissions:     null
  describeHighPrivilegeBits             -> null   ← 确实不是高权限
  describeAnchorForbiddenBits(everyone) -> null   ← 确实可绑 everyone
  describeAnchorForbiddenBits(guest)    -> "a '*' wildcard grant (guest bindings admit explicit objects only)"

最后一行是意外收获:viewer_readonlymember_default 当年更适合做这个举例 —— 同一个集合把这句话的两半同时演示了,everyone 可绑、GUEST 层恰恰因为通配符被拒。

改动

一处注释,7 增 5 删,外加一个 changeset。有两点是刻意的:

  1. D5 的形状描述必须跟着放宽。 原句是"a read/create/edit-own baseline ... 正是这个形状",而 viewer_readonly只读的。只换名字不动形状,等于把一个失效举例换成另一个失效举例。故改为 "a read — or read/create/edit-own — baseline"。
  2. Builtin member_default carries anchor-forbidden bits — every boot logs 'refusing to bind fallback set to everyone' (platform baseline violates its own D5 tier) #2753 的历史保留(issue 明确要求),改写成 "the then-wildcard-carrying default 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,探针会当场说出来 —— 它正是用来挡"同一个缺陷再犯一次"的。
  • Lane 准入(acceptance 逐字节不变): pnpm --filter @objectstack/spec check:generated10/10 绿,含 check:authorable-surface(任何 schema 接受的键集未移动)与 check:docs
  • pnpm --filter @objectstack/spec typecheck → 绿(TEST_DEBT 未动:未触碰任何测试文件,58 files / 266 errors 原样)。
  • pnpm --filter @objectstack/spec test346 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:186if (!entry.name.endsWith('.zod.ts')) continue; —— 生成器只遍历 .zod.ts,而 high-privilege.ts 不是。全文 grep content/docs/ 对该 JSDoc 的特征句零命中,check:docs 亦无任何待重生成产物。所以本次属于今天两类测量中的不触达那一类(与 .describe() 字符串触达相反,与 TSDoc @example / authorable key 的 JSDoc 不触达一致)。⛔ 无生成产物需要提交,也未手改任何生成输出。

Changeset 判断(要求逐条论证的那一项)

加了,@objectstack/spec: patch

packages/specfiles["dist", "json-schema", "liveness", "prompts", "llms.txt", "README.md", "src/**/*.zod.ts", "CHANGELOG.md", "api-surface", "spec-changes.json"]high-privilege.ts 不是 .zod.ts,源文件本身确实不随包发布。但结论不能停在这里:构建后实测

$ grep -rln "high-privilege by itself" packages/spec/dist/
dist/security/index.d.ts
dist/security/index.d.mts
dist/security/index.js.map
dist/security/index.mjs.map

distfiles 里,所以这段文案是随 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

…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
@vercel

vercel Bot commented Aug 9, 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 9, 2026 12:18am

Request Review

@github-actions github-actions Bot added the size/s label Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

112 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/apps.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Aug 9, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 9, 2026 00:43
@os-project-manager
os-project-manager added this pull request to the merge queue Aug 9, 2026
Merged via the queue into main with commit 73b7234 Aug 9, 2026
27 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6696-high-privilege-stale-example branch August 9, 2026 01:00
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 size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

describeHighPrivilegeBits's doc comment still cites member_default as the "plain wildcard baseline" example, which it no longer is

2 participants