Skip to content

feat(spec)!: 六个注册类型收紧,skill 的 permissions 不再假装是权限门(#4001 批 4) - #4528

Merged
os-zhuang merged 1 commit into
mainfrom
claude/strict-schema-authz-surface-s8vnok
Aug 1, 2026
Merged

feat(spec)!: 六个注册类型收紧,skill 的 permissions 不再假装是权限门(#4001 批 4)#4528
os-zhuang merged 1 commit into
mainfrom
claude/strict-schema-authz-surface-s8vnok

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

#4001 批 4(清单)。批 1–3b = #4514 / #4519 / #4522 / #4527,均已合并。

注册类型线上的机械工作,用 strictObjectreport · dataset · email_template · skill · job · book。每个一次调用,加上贴合各自词汇表的别名——book 的 sections/chapters/tocgroups,job 的 cron/intervalschedule,email template 的 title/content/htmlsubject/body

但其中一个不是机械工作,而且正是这场战役存在的理由

skill 接受一个 permissions 键,然后把它丢掉。

技能调用从来就没有权限门。 一个写下 permissions: ['order.manage'] 的作者,以为自己限制了谁能调用这个技能——实际上没有

这是一个静默失效的权限漏洞,和 #3746 里的 visibleWhenvisible 同形:别名表里最值钱的那条从来不是错别字,而是一个读起来像安全控制、实际不是的键。

有个测试把这个剥离钉成了正确行为。它的注释里甚至写着正确答案——在 agent 层用 access/permissions 门控(自 #1884 起真正生效)——但一句写在测试文件里的注释,能到达所有人,除了写错的那个作者

现在拒绝信息带上这句处方,测试改为断言拒绝。

一个已经四次的模式

这是本战役第四个被发现把「strip 时代的假象」固化成预期行为的测试:

测试断言的 实际是
position.parent 被接受 层级根本不存在(ADR-0090 D3 定了扁平)
object.namespace 被剥离是对的 对象会以错误的名字发布
退役的 compactLayout 被剥离是对的 作者拿不到 highlightFields,也拿不到任何提示
skill.permissions 被剥离是对的 一个不存在的权限门

规律稳定到可以陈述:一个 schema 只要默认宽松,它的测试最终会断言那份宽松,而那条断言读起来就像「这是有意为之」。

进度

注册类型顶层已关闭:16 / 25(这条线开始时是 9)

仍剥离:action · agent · dashboard · field · mapping · page · translation · view

告警层覆盖的根从 12 降到 6——这是解析接管,不是覆盖腐烂。被关闭的根下面那些仍是 strip 的嵌套站点照常告警(那是 #4522 修掉的回归)。

验证

  • @objectstack/spec284 文件 / 7187 用例通过(对合并后的 main 重跑),tsc --noEmit 干净
  • 8 个生成物闸门 up-to-date15 个 check:* 全绿

参考

🤖 Generated with Claude Code

https://claude.ai/code/session_01WnqGjQFQMqd5k81LYV8SCY


Generated by Claude Code

…s` stops pretending to be a gate (#4001)

Mechanical work on the registered-type line with `strictObject`: `report`,
`dataset`, `email_template`, `skill`, `job`, `book`. One call each, plus the
aliases that fit the surface's own vocabulary — `sections`/`chapters`/`toc` →
`groups` on a book, `cron`/`interval` → `schedule` on a job, `title`/`content`/
`html` → `subject`/`body` on an email template.

One of the six is not mechanical, and it is the class this campaign exists for.

`skill` accepted a `permissions` key and dropped it. Skill invocation was never
permission-gated, so an author who wrote `permissions: ['order.manage']`
believed they had restricted who could invoke the skill, and had not. A silent
permission hole — the same shape as `visibleWhen` → `visible` in #3746, where
the most valuable alias was not a typo but a key that READS as a security
control and silently is not one.

A test pinned that strip as correct behaviour. Its comment even carried the
right answer — gate at the AGENT via `access`/`permissions`, enforced since
#1884 — but a comment in a test file reaches everyone except the author who got
it wrong. The rejection now carries the prescription; the test asserts the
rejection.

That is the fourth test in this campaign found codifying a strip-era fiction as
expected behaviour (`position.parent`, `object.namespace`, the retired
`compactLayout` alias, and now this one). The pattern is consistent enough to
state: when a schema is silently lenient, its tests eventually assert the
leniency, and the assertion then reads as intent.

Registered types closed at the top level: 16 of 25, up from 9 when this line
started. Still open: action, agent, dashboard, field, mapping, page,
translation, view.

The warning layer's covered population drops 12 roots → 6, which is the parse
taking over rather than coverage rotting; nested strip sites under a closed root
still report, unchanged.

Verified: spec 284 files / 7187 tests, `tsc --noEmit` clean, all 8 generated
artifacts current, all 15 `check:*` gates green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WnqGjQFQMqd5k81LYV8SCY
@vercel

vercel Bot commented Aug 1, 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 1, 2026 5:09pm

Request Review

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

107 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 packages/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/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 packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/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 packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/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/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/kernel/runtime-capabilities.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/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants