Skip to content

fix(spec): scope the modifyAllRecords bypass declaration to what sharing enforces (#6698) - #6852

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-6698-modifyall-declaration
Aug 9, 2026
Merged

fix(spec): scope the modifyAllRecords bypass declaration to what sharing enforces (#6698)#6852
os-project-manager merged 1 commit into
mainfrom
claude/issue-6698-modifyall-declaration

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes #6698

Option A only。 本 PR 只动声明,不动任何运行时:plugin-sharing / plugin-security 一个文件都没有碰(改动文件共 4 个,见下)。option B(把 hasModifyAllBypass 探测提到 hasOwnerField 提前返回之前)明确不做,option C 按 #6564 §7 本来就被否掉。

缺陷

packages/spec/src/security/permission.zod.tsmodifyAllRecords 描述成 "Super-user write access. Bypasses Sharing Rules and Ownership checks",.describe() 则是 Modify All Data (Bypass Sharing)。在没有 owner 字段的对象上,这两样都不成立:

这一格是 #6684 明确测量并钉住的既定行为(plugin-security/src/row-write-widener-composition.test.ts:472,"an abstention does not become permission for a Modify-All holder either"),不是缺陷。缺陷在于声明比实现讲得多 —— ADR-0049 declared ≠ enforced 的那一类残留。

改法

.describe() 前后对照:

  • 之前:Modify All Data (Bypass Sharing)
  • 之后:Modify All Data (Bypass Sharing) — bypasses sharing rules and ownership on the objects record sharing enforces on; on an object with NO owner field sharing abstains, so the platform created_by write floor still applies (#6698).

旁边的文档注释同步改掉了它自己那句无限定的 "Bypasses Sharing Rules and Ownership checks" —— issue 正文引用的就是这句,只修 describe 会把被点名的原话留在文件里。文档注释属于同一处声明的散文,不进生成文档,也不影响接受集合。

刻意保留了另一半。 带 owner 字段的对象 —— 也就是授予这个位的常见场景 —— bypass 是真的,措辞里 "bypasses sharing rules and ownership" 原样留着,避免矫枉过正成相反的谎:读者不该以为这个位是空的。能力面没有增长,这是一次纯字符串改动。

接受集合逐字节不变

.describe() 不参与 parse。旁证:gen:schema 重跑后 authorable-surface/**json-schema.manifest/**authorable-defaults/(1308 个默认值)零 diff,check:authorable-surface 绿;permission.test.ts 原有 47 例(含 #4001 未知键拒绝套件)全绿。没有动任何 enum 成员、键或 refinement。

生成产物

.describe() 确实content/docs/references/**pnpm --filter @objectstack/spec gen:docs 重算后只有 content/docs/references/security/permission.mdx 变化,且只有两格(authoring 表 + EffectiveObjectPermissionSchema 响应侧表各一行)。check:generated 10/10 绿。⚠️ 首次跑 check:generatedapi-surface/ 陈旧,是脚本自己警告过的「未 build 就检查」幻影 —— pnpm --filter @objectstack/spec build 后复跑即绿,该产物无实际改动。

Pin 与反向验证(方向先预测,后测量)

新增 packages/spec/src/security/permission.test.ts[#6698] modifyAllRecords declares its bypass AND the limit of that bypass:把描述从 schema 里读回来再断言它必须承载的事实(idiom 匹配,不锁措辞),三条断言全为正向,因此清空 .describe() 必然变红。

方向 预测 实测
改回旧串 Modify All Data (Bypass Sharing) 断言 1 绿、2+3 红 一致:2 failed | 45 passed
.describe('')(反空转) 三条全红 一致:3 failed | 44 passed
矫枉过正串(删掉 "bypass" 只讲限制) 断言 1 红、2+3 绿 一致:1 failed | 46 passed
本 PR 的串 全绿 一致:47 passed

验证

  • pnpm --filter @objectstack/spec test —— Test Files 346 passed (346) / Tests 8880 passed (8880)
  • pnpm --filter @objectstack/spec typecheck —— tsc --noEmit + check:scripts-typecheck + check:test-typecheck 全绿(测试层 58 file / 266 error 的收缩型 ratchet 未变)
  • pnpm --filter @objectstack/spec check:generated —— ✓ All 10 generated artifacts are up to date.
  • npx eslint 两个改动 TS 文件 —— exit 0,无告警
  • check:type-check-coverage(spec 已在 @ts-expect-error 退役 pin 在 packages/spec 里是幽灵检查:tsconfig 把 **/*.test.ts 排除出唯一的 tsc --noEmit #5286 毕业,不在 DEBT/TEST_DEBT 台账内)、check:nul-bytescheck:doc-authoringcheck:role-wordcheck:quick-reference-countscheck:docs-audit-scopecheck:adr-anchorscheck:empty-changeset —— 全绿

改动文件(4)

  • packages/spec/src/security/permission.zod.ts(describe + 文档注释)
  • packages/spec/src/security/permission.test.ts(pin)
  • content/docs/references/security/permission.mdx(生成产物,未手改)
  • .changeset/modifyall-records-owner-less-declaration.md(@objectstack/spec: patch)

未触碰 content/docs/releases/


Generated by Claude Code

…aring enforces (#6698)

`ObjectPermissionSchema.modifyAllRecords` promised a bypass of "Sharing Rules
and Ownership checks". On an object with NO owner field it bypasses neither:
record sharing does not enforce there at all (`checkEdit`/`checkDelete` answer
`abstain` before the bypass is probed, #6428), so the platform's own row-level
write floor `created_by == current_user.id` (#1985) survives and the by-id write
is refused — measured and pinned in plugin-security's
`row-write-widener-composition.test.ts` by #6684.

Option A on #6698: only the DECLARATION moves. The describe now scopes the
bypass to the objects record sharing enforces on and discloses the surviving
platform floor, while keeping legible that on an owner-bearing object — the
common case this bit is granted for — the bypass is real. No runtime change; the
accepted/rejected metadata set is byte-for-byte unchanged; no `plugin-sharing`
or `plugin-security` file is touched.

`content/docs/references/security/permission.mdx` is regenerated by
`pnpm --filter @objectstack/spec gen:docs` (two table cells).

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:35am

Request Review

@github-actions github-actions Bot added the size/m 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.

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/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

modifyAllRecords still does not widen a by-id write on an object with NO owner field (sharing abstains, the platform created_by floor holds)

2 participants