Skip to content

feat(spec)!: system-data 默认 affordance 去掉 CSV import,改为按对象显式 opt-in (#4671) - #6152

Merged
qq9340100 merged 5 commits into
mainfrom
claude/issue-4671-system-data-import-optin
Aug 7, 2026
Merged

feat(spec)!: system-data 默认 affordance 去掉 CSV import,改为按对象显式 opt-in (#4671)#6152
qq9340100 merged 5 commits into
mainfrom
claude/issue-4671-system-data-import-optin

Conversation

@qq9340100

Copy link
Copy Markdown
Collaborator

Fixes #4671

按维护者 2026-08-03 裁决、2026-08-06 最终确认的「收窄」落地:system-data 桶的默认
affordance 去掉 import,改为按对象显式 opt-in。

一、前提复核(issue 立于 08-02,已过 5 天)

origin/main@6513c17 逐条重验,前提仍成立:

$ git show origin/main:packages/spec/src/data/object.zod.ts | sed -n '2249p'
  'system-data':  { create: true,  import: true,  edit: true,  delete: true,  exportCsv: true },

CRUD_AFFORDANCE_DEFAULTS['system-data'] 确实仍含 import: true;#4660 埋在 4 个包的
逐对象 before/after 等价 pin 也都还在原处。裁决评论(2026-08-06,session_011M7UwH25Unfi73UHim7ajY)
是本单的最终依据,认领评论会话 ID 一致、无更早他人认领。

二、改了什么

一行常量 + 随之为真的文字:

文件 改动
packages/spec/src/data/object.zod.ts CRUD_AFFORDANCE_DEFAULTS['system-data'].importfalse;桶注释、CrudAffordances.import 的 JSDoc、MANAGED_BY_SYSTEM_RETIRED 退役处方、assertSystemDataIsWritable 的报错文本同步(后两处原文都写着「默认 FULL CRUD / userActions 只用于 NARROW」,收窄后不再成立)
packages/spec/src/migrations/registry.ts v17 升级叙事补上这条,并写清「v16 system 对象本来就解析为 import: false,改名后仍是 false
docs/protocol-upgrade-guide.md 上一行的生成物,gen:upgrade-guide 重生成(未手改)
docs/adr/0103-...md 新增 Addendum (v17, #4671);并在 #3355 addendum 那句「CSV import resolves true where it resolved false」上就地标注被本 addendum revised
content/docs/data-modeling/objects.mdx 手写文档:桶表格、userActions 行、system-data 段落、代码示例、v16 升级 Callout;新增「CSV import on system-data is opt-in」小节
4 个包的 pin + packages/spec/src/data/object.test.ts 见下

未碰:授权/RLS/DelegatedAdminGate 任何逻辑(issue 明确 affordance 只管 UI 入口);
其它五个桶的默认;content/docs/releases/;.zod.ts 的类型别名区(#6072 在飞)。

三、8 个对象、16 条断言:pin 按 issue 预言直接变红

issue 说「它们会直接变红,不会静默通过」。先只改常量、不动 pin 跑了一遍,逐条记录:

对象 变红的断言
plugin-security sys_user_position / sys_user_permission_set / sys_position_permission_set 各 2 条
service-messaging sys_notification_template / _subscription / _preference 各 2 条
platform-objects sys_user_preference 2 条
plugin-approvals sys_approval_delegation 2 条
AssertionError: expected { create: true, import: false, …(3) } to deeply equal { create: true, import: true, …(3) }
AssertionError: expected false to be true // Object.is equality
 Tests  6 failed | 6 passed (12)   ← plugin-security
 Tests  6 failed | 6 passed (12)   ← service-messaging
 Tests  2 failed | 2 passed (4)    ← platform-objects
 Tests  2 failed | 5 passed (7)    ← plugin-approvals

8 对象 × 2 = 16,一条不漏,无覆盖缺口。「四动词等价」那条循环(create/edit/delete/exportCsv)
按预期保持绿 —— import 本来就不在它的枚举里,这正说明当初的 pin 把这条差异单独拎出来
是对的。

四、pin 的三种处置,不是批量改期望值

  • V17_EXPECTED:改期望值(import: truefalse)。两个常量保留为两条而不是合并成一个字面量 —— 现在两边字节相同,但合并会让将来任意一侧移动都看不出 diff。
  • 等价循环:扩 到五个动词(create/import/edit/delete/exportCsv),并追加 expect(v17).toEqual(v16)。收窄之后这条改名在任何动词上都不移动 affordance,这是比原来更强的陈述,不是更弱。
  • 「gains CSV import」:整条替换,不是改期望值。它 pin 的正是被删掉的那条 delta;把它改成「两边都 false」会变成一条因为什么都没产生而通过的空绿测试。替换为 keeps CSV import opt-IN,两半:
    • 桶默认为 false(删掉 system-data 那一行常量满足不了这半 —— fallback 是 platform,而 platformimport);
    • userActions: { import: true } 后为 true —— 该动词是变成 opt-in 而不是被删除,没有这半上一半就是空绿。

packages/spec/src/data/object.test.ts 另加 4 条桶级 pin,含「platform 是唯一仍默认给
import 的桶」和「其余五桶答案一致」。

五、反向验证(方向事先声明为「红」,与实测一致)

'system-data' 那行还原成 import: true 并重新构建 spec:

### packages/spec ###
× `system-data` defaults to writable CRUD ...      expected { import: true, … } to deeply equal { import: false, … }
× does not grant import by bucket default          expected true to be false
× is now the same answer every non-`platform` bucket gives   system-data: expected true to be false
 Tests  3 failed | 6 passed | 130 skipped

### plugin-security / service-messaging ###   各 Tests  9 failed | 3 passed (12)
### platform-objects / plugin-approvals ###   各 Tests  3 failed | 1 passed (4) / 3 failed | 4 passed (7)
  AssertionError: sys_user_position.import must not move: expected true to be false

27 条断言转红(4 包 8 对象 × 3 + spec 3),全部落在 import 上,还原后全绿。方向是标准的
「红」方向,没有出现反转或「诊断变多」的情形 —— 因为收窄后的判据是逐对象等值断言,不是计数。

六、仓内 opt-in 需求排查:零命中(附反查证伪)

排查是否有对象依赖 system-data 的默认导入。examples/ / skills/ / apps/ / core/
0 个 managedBy: 'system-data' 声明,因此没有对象需要补 userActions: { import: true }

零命中必须配控制:同一把扫描器在 examples/ 下确实能命中 managedBy 这个词
(app-showcase/test/no-startup-warnings.test.ts:24app-crm/test/smoke.test.ts:106,
两处都是 managedBy === 'better-auth')—— 扫描器工作正常,是真的没有声明,不是 grep 写错了。

仓内全部 8 个 system-data 对象都是平台自带的系统对象,按裁决一个都不 opt-in:它们在
v16 本来就没有导入入口。

七、生成物

check:generated 十门:改完 migrations/registry.ts 后唯一 stale 的是
docs/protocol-upgrade-guide.md,按它给的命令 gen:upgrade-guide 重生成(未手改、未整套重跑),
复跑 ✓ All 10 generated artifacts are up to date.

authorable-surface / api-surface / json-schema / content/docs/references/** /
strictness 台账 零变化 —— affordance 默认是运行时常量,不在可作者化面上,所以不涉及分片布局。
这是实测读数,不是预期。

八、验证

命令 结果
pnpm --filter @objectstack/spec test 326 files / 8367 tests passed
pnpm --filter @objectstack/plugin-security test 35 files / 768 passed
pnpm --filter @objectstack/service-messaging test 15 files / 162 passed
pnpm --filter @objectstack/platform-objects test 9 files / 266 passed
pnpm --filter @objectstack/plugin-approvals test 19 files / 446 passed
5 包 typecheck Done,spec 的 test-typecheck 债本未增长
pnpm --filter @objectstack/spec check:generated 10/10 ✓
check:doc-authoring / docs-audit-scope / adr-anchors / empty-changeset / role-word / error-code-casing / engine-double-contract / route-envelope 本地 8/8 OK
npx eslint(改动文件) ESLINT_EXIT=0
node scripts/check-nul-bytes.mjs OK(5861 文件);改动文件另按控制字符类自扫,0 命中

九、changeset

@objectstack/spec major(行为变化,搭 v17 rc 窗口)。正文按要求写清 FROM → TO、
三张 RBAC 关联表各自消失的是哪个管理台入口、以及如何逐对象显式恢复;并注明从 v16 升上来的
用户零影响(v16 就解析为 import: false)。

十、与在飞工作的关系


Generated by Claude Code

…in (#4671)

`CRUD_AFFORDANCE_DEFAULTS['system-data']` 默认保留 create/edit/delete/exportCsv,
不再包含 `import`;需要 CSV 导入向导的对象写 `userActions: { import: true }`。
`platform` 成为唯一默认授予 `import` 的桶。

授权边界未动 —— `import` 只决定 UI 入口是否渲染,CSV 导入写下的每一行仍逐条经过
DelegatedAdminGate / RLS / 权限集裁决。变的是杠杆:桶的三个 charter 成员是 RBAC
关联表(sys_user_position / sys_user_permission_set / sys_position_permission_set),
即整个权限模型的授予面,一份错 CSV 就是一次批量授权。批量授予入口应是显式声明,
而不是「被归进正确的桶」就继承的东西。

原「默认含 import」出自 #3355 上更早的 agent 会话,非维护者拍板;维护者 2026-08-03
裁决收窄、2026-08-06 最终确认。记录见 ADR-0103 的 #4671 addendum。

#4660 埋在 4 个包的逐对象等价 pin 按预言直接变红(8 对象 × 2 = 16 条,无覆盖缺口),
按新语义同步:等价循环扩到五个动词(改名现在在任何动词上都不移动 affordance),
「gains CSV import」整条替换为 `keeps CSV import opt-IN` —— 断言桶默认为 false
**且** opt-in 后可达,避免退化成因为什么都没产生而通过的空绿测试。

从 v16 升级零影响:v16 的 `system` 默认 LOCKED,8 个成员的 userActions 块只重开
create/edit/delete,CSV 导入本来就解析为 false。

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

vercel Bot commented Aug 7, 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 7, 2026 5:02am

Request Review

@github-actions github-actions Bot added the size/m label Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 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 protocol:data tests tooling labels Aug 7, 2026
claude added 4 commits August 7, 2026 03:55
merge 把生成物文本上干净地合上了,但相对合并后的 migrations/registry.ts 仍是 stale
(check:upgrade-guide 报红)。按门给的命令重生成,未手改。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY
reconcileManagedApiMethods 的 system-data 用例注释写着「the rename made full CRUD
the bucket default」,#4671 之后不再成立。import 不是 apiMethods 动词,不进这条
reconciliation,注释里一并写明,免得下一个读者以为该用例覆盖了它。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY
@qq9340100
qq9340100 marked this pull request as ready for review August 7, 2026 05:19
@qq9340100
qq9340100 added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit ce0cfe9 Aug 7, 2026
25 checks passed
@qq9340100
qq9340100 deleted the claude/issue-4671-system-data-import-optin branch August 7, 2026 05:34
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 protocol:data size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

decide: system-data 默认 affordance 是否应包含 CSV import(RBAC 关联表批量绑定)

2 participants