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-manageros-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

vercelBot commented Aug 9, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 9, 2026 12:18am

Request Review

@github-actions

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-actionsgithub-actionsBot 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 queueAug 9, 2026
Merged via the queue into main with commit 73b7234Aug 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 freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/stooling

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

@os-project-manager@claude