Skip to content

feat(spec,plugin-security): A5 — 包级 capability 声明 API (#2920) - #2932

Merged
os-zhuang merged 3 commits into
mainfrom
claude/authz-a5-capability-declaration
Jul 15, 2026
Merged

os-zhuang merged 3 commits into
mainfrom
claude/authz-a5-capability-declaration

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

A5 — 包级 capability 声明 API (tracking #2920)

给包/应用一个正式、显式的 capability 声明入口,让包自带的授权 capability 带 managed_by:'package' + package_id provenance 流入 sys_capability registry,而不是依赖「从 permission set 的 systemPermissions[] 隐式派生一个无标题 placeholder」这条暗道。呼应 ADR-0066 D1("packages declare their capabilities")与 ADR-0094 D5(逐步退役隐式 managed_by 猜测)。

⚠️ 对 issue 原描述前提的修正

原 issue 说「应用声明 capability 又复制进 framework spec」——核实后该重复不存在:capability 早已是单一真源 packages/spec/src/security/capabilities.ts(PLATFORM_CAPABILITIES)。真正缺的是包的显式声明入口 + provenance,本 PR 补齐的是这条链路,而非去重。契约保持 requiredPermissions(资源引用)/ systemPermissions(权限集授出);capability 不是 contract,没有 inputs。

新 API 形状

import { defineCapability } from '@objectstack/spec';

export const ExportDataCapability = defineCapability({
  name: 'export_data',
  label: 'Export Data',
  description: 'Bulk-export records to CSV/XLSX.',
  scope: 'org', // 'platform' | 'org'
});

defineStack({
  capabilities: [ExportDataCapability],                 // DEFINE(包定义)
  permissions: [{ name: 'billing_admin', objects: {}, systemPermissions: ['export_data'] }], // GRANT
  // 资源: requiredPermissions: ['export_data']          // REQUIRE
});

设计与改动

  • @objectstack/spec:defineCapability / CapabilityDeclarationSchema({ name, label?, description?, scope, packageId? });stack 定义新增 capabilities 数组(并入 composeStacks concat)。
  • @objectstack/plugin-security:
    • sys-capability.object.ts 新增 package_id provenance 字段 + 索引。
    • 新 bootstrapDeclaredCapabilities:把声明 seed 进 sys_capability,managed_by:'package' + package_id。幂等、升级感知;拒绝劫持 curated 平台 capability、拒绝写入他包的行、从不覆盖 admin 行;对既有「派生 placeholder」行执行 claim(升级为 package provenance + 作者元数据)。
    • bootstrapSystemCapabilities 新增 declaredCapabilityNames:back-compat 的派生路径跳过已显式声明的名字,避免用 humanized placeholder 覆盖作者元数据。
    • boot 顺序:先 bootstrapDeclaredCapabilities(拿到 declaredNames),再 bootstrapSystemCapabilities 带 declaredNames。
  • @objectstack/runtime:app-plugin.ts 把 stack 声明的 capabilities 注册进 metadata registry(类型 capability),供 boot seeder 读取(复用 permissions→permission 的既有机制)。
  • @objectstack/lint:validateCapabilityReferences 把 stack.capabilities 计入已知 capability 来源集(对已声明 capability 不再误报)。
  • 文档:content/docs/permissions/authorization.mdx 新增「Package capability declaration」小节 + 三分法澄清;ADR-0066 D1 补注 landed 状态。
  • 示例:examples/app-showcase 声明 showcase.export_data 并在 OpsPermissionSet.systemPermissions 授出,演示 define→grant 全链(access-matrix 快照不含 systemPermissions,无 drift)。

向后兼容

隐式派生路径保留:无声明的引用仍解析为 managed_by:'platform' placeholder;显式声明优先并接管既有 placeholder。

验证

  • @objectstack/spec build ✅;spec stack 测试 132 通过、新 capabilities 测试 6 通过。
  • plugin-security 新 bootstrap-declared-capabilities + 更新的 bootstrap-system-capabilities 测试 14 通过;rbac-objects 15 通过(新字段不破坏断言)。
  • lint validate-capability-references 9 通过(含新「declared capability 不误报」用例)。
  • 端到端:defineStack({ capabilities: [...] }) strict parse 保留字段(已跑通)。
  • 受影响包 tsc 仅剩 worktree 未构建依赖的 module-not-found(非本改动)。

存疑/取舍

  • 命名:stack 上的 capabilities(授权 capability)与 requires(平台 service capability,如 ai/automation)及运行时 ObjectStackCapabilities 描述符是不同概念,已在字段/文档 doc 注中显式区分。
  • 「claim 派生 placeholder」仅对 managed_by:'platform' 且非 curated 名字生效(curated 名字在入口即被拒),admin 行永不动。

Closes part of #2920.

🤖 Generated with Claude Code


Generated by Claude Code

… API (#2920)

Give packages a formal, EXPLICIT entry point to DEFINE their own authorization
capabilities, so package-owned capabilities flow into the sys_capability
registry with managed_by:'package' + package_id provenance instead of relying on
the implicit "derive an untitled capability from a permission set's
systemPermissions[]" back-door (ADR-0066 D1; aligns with ADR-0094 D5).

- spec: new defineCapability / CapabilityDeclarationSchema
  ({ name, label?, description?, scope, packageId? }); new `capabilities`
  field on the stack definition (+ compose concat).
- plugin-security: new bootstrapDeclaredCapabilities seeds declared capabilities
  with package provenance (new package_id field + index on sys_capability).
  Idempotent, upgrade-aware; refuses to hijack curated platform capabilities or
  a foreign package's rows, never clobbers admin rows, and CLAIMS a pre-existing
  derived placeholder. bootstrapSystemCapabilities gains declaredCapabilityNames
  so its back-compat derivation skips (never clobbers) declared capabilities.
- runtime: stack-declared `capabilities` registered into the metadata registry
  (type `capability`) for the boot seeder to read.
- lint: validateCapabilityReferences treats stack.capabilities as a known source.
- docs: authorization.mdx + ADR-0066 D1 note; app-showcase example (define +
  grant the showcase.export_data capability).

Note: corrects the tracking issue's premise — capability was already a single
source of truth (no app→framework duplication); this task adds the missing
explicit package DECLARATION path + provenance, not a de-dup.

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

vercel Bot commented Jul 14, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 15, 2026 12:00am

Request Review

@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation tests tooling and removed size/l labels Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/lint, @objectstack/plugin-security, @objectstack/runtime, @objectstack/spec.

108 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/runtime, @objectstack/spec)
  • content/docs/api/wire-format.mdx (via @objectstack/runtime)
  • content/docs/automation/approvals.mdx (via packages/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via @objectstack/runtime, 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/runtime, packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/runtime, @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/index.mdx (via @objectstack/runtime)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/runtime)
  • content/docs/deployment/single-project-mode.mdx (via @objectstack/runtime)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/vercel.mdx (via @objectstack/runtime)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-security, @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/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/runtime, @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/permissions/access-recipes.mdx (via packages/plugins/plugin-security)
  • content/docs/permissions/authentication.mdx (via @objectstack/runtime)
  • content/docs/permissions/authorization.mdx (via @objectstack/lint, packages/plugins/plugin-security, @objectstack/spec)
  • content/docs/permissions/explain.mdx (via @objectstack/plugin-security)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via packages/plugins/plugin-security, @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/plugin-security, @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/plugin-security, @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-security, @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/http-protocol.mdx (via @objectstack/runtime)
  • content/docs/protocol/objectos/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/index.mdx (via @objectstack/runtime)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/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 packages/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/plugin-security, @objectstack/runtime, @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/v9.mdx (via @objectstack/spec)
  • content/docs/ui/audience-based-interfaces.mdx (via packages/plugins/plugin-security)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.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.

…orts

The A5 branch added defineCapability + CapabilityDeclaration* exports but did
not commit the regenerated api-surface snapshot; CI check:api-surface flagged
6 unregistered exports. Regenerated against a fresh dts build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QRUvVfpvSycAHMMF2xTxs
@os-zhuang
os-zhuang marked this pull request as ready for review July 14, 2026 23:46
…ility-declaration

# Conflicts:
#	packages/spec/api-surface.json

This branch was successfully deployed

1 active deployment
Preview — 68e09e84 Deployed Jul 15, 2026 by vercel[bot]
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/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants