feat(plugin-security): ADR-0094 follow-ups — package sets customize via env overlay (D5 revised) + projection dogfood proof + Setup UI alignment#2905
Merged
Conversation
…on sets + projection dogfood proof (ADR-0094 D5) Closes the last inert-metadata hole from the ADR-0094 pure-projection refactor (#2898), and binds the invariants into the liveness proof registry. - metadata-protocol: new registerAuthoringGate(type, fn) seam — a per-type gate run inside saveMetaItem before persistence; a returned rejection becomes a thrown Error (code/status). Fail-open on a gate error (this closes an inert-metadata hole, not a hard boundary — the data-plane two-doors gate + the projector's refusal already protect the record). - plugin-security: registers a `permission` gate that refuses an env-scope saveMetaItem targeting a managed_by:package sys_permission_set record — previously such an overlay persisted but neither projected nor enforced (ADR-0049 violation). The package door (save carries the owning packageId) and env-authored/new sets are unaffected. Error `package_owned` (403). - dogfood: showcase-permission-projection proves the ADR-0094 invariants on the real stack (write-through, awaited projection, declared-set edit → enforced overlay, delete-as-reset, and this authoring gate), registered in the ADR-0054 proof registry (unbound — a storage invariant has no authorable ledger property to ratchet, kept honest with a blockedReason). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SXjD7g2JkEsdqhZFZgAo1Q
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 3 package(s): 101 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…document projection UX (ADR-0094) Setup UI alignment for the ADR-0094 pure-projection behavior. The Setup surface is SDUI-driven by the object metadata, so both affordances are object-metadata changes objectui already honors (ObjectForm forwards `readonlyWhen` to fieldRules; the engine also strips such writes server-side) — no objectui code change needed: - sys_permission_set.name gains `readonlyWhen: record.id != null` — the name is the metadata identity the record projects from, so the create form accepts it but the edit form locks it, matching the data-door's 400 rename rejection. Verified the meta API surfaces the CEL predicate and the boot stack loads it cleanly. - permission-sets.mdx documents the one-authoritative-store model: Setup edits of declared sets now enforce, the API name is immutable (clone to rename), and deleting a packaged set resets it to the shipped definition while a self-created set is removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SXjD7g2JkEsdqhZFZgAo1Q
…e to sibling two-store types Promote the permission-set-specific decision to a classification rule for every declared-metadata ↔ queryable-record two-store type (sys_position, sys_sharing_rule, sys_capability), keyed on which store enforcement reads at request time: - metadata-authoritative → record is a projection (this ADR's machinery, reusable via registerMutationProjector / registerAuthoringGate); - record-authoritative → the record is the authority and declared metadata is a boot SEED only (seed-not-clobber; do NOT project — that would invert the real authority). Records the per-type findings (sys_sharing_rule is record-authoritative — evaluation reads the row live; sys_position needs the seed-vs-authority audit), so the follow-up is scoped, not rediscovered. Tracked in framework#2909. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SXjD7g2JkEsdqhZFZgAo1Q
…he standard env metadata overlay (ADR-0094 D5 revised) Direction confirmed by the maintainers 2026-07-14, reversing the #2898 authoring-time rejection: an env-scope overlay of a package-owned set is the platform's standard ADR-0005 customization, made FIRST-CLASS instead of refused — rejecting it would make `permission` the one type whose declared allowOrgOverride:true is a lie, and clone-to-customize forks away from vendor baseline updates (including security tightenings). - projector: a package-owned record's facets follow the EFFECTIVE (overlay-wins) body; managed_by:'package' + package_id provenance preserved. - write-through: a data-door edit of a packaged set translates into that overlay (no more flat 403); data-door "delete" removes the overlay and RESETS the record to the shipped declaration. Single-store kernels (no metadata overlay layer) keep the legacy two-doors refusal, now asserted by the write-through itself. - two-doors gate narrows to what stays structurally true: provenance forging refused (insert/update, single/array), and transfer/restore/purge on package rows refused (no overlay translation exists for them). - metadata-protocol: the registerAuthoringGate seam is removed again — with the rejection gone it had no consumer, and an unconsumed seam is exactly the inert surface ADR-0049 forbids. - docs: ADR-0094 TL;DR/D2/D5 revised (including the whole-document-overlay upgrade-pinning trade and its mitigations); authorization.mdx + permission-sets.mdx updated; dogfood proofs flipped to the new semantics (overlay customize/reset on showcase_contributor, live). Closes #2898 (resolved by support, not rejection). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SXjD7g2JkEsdqhZFZgAo1Q
…dx (ADR-0090 D3) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SXjD7g2JkEsdqhZFZgAo1Q
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ADR-0094 的收尾(承接已合并的 #2901),Closes #2898 —— 以"支持"而非"拒绝"的方式解决(维护者 2026-07-14 确认方向反转)。
1. 包集定制走标准元数据覆盖(ADR-0094 D5 修订版)
#2898 最初提议在授权时点拒绝对包持有权限集的环境 overlay。方向反转的理由:拒绝会让
permission成为唯一一个声明了allowOrgOverride: true却说谎的类型;而"克隆再改"是 fork——克隆体永远收不到 vendor 后续的基线更新(含安全收紧),也丢失分层 diff。现在:managed_by:'package'+package_idprovenance 保留——包仍拥有该行,overlay 是对它的定制。transfer/restore/purge在包行上仍拒绝(无 overlay 翻译)。managed_by:'user'游离类别可逐步退役。registerAuthoringGateseam 随拒绝方向一并移除(无消费者的 seam 正是 ADR-0049 禁止的 inert 面)。如实记录的取舍(已写入 ADR-0094 D5 修订版):ADR-0005 overlay 是整文档替换——overlay 钉住期间,vendor 的后续基线变更(含收紧)不生效,直到重置或重新编辑;缓解:Studio 分层 diff、升级时提示已定制的包集、ADR-0091 再认证覆盖。这是所有可覆盖类型共同的取舍,权限集不再被特殊化。
2. Projection dogfood proof + liveness ledger 绑定
showcase-permission-projection.dogfood.test.ts在真实 showcase 栈证明全部不变量(7 项全绿):数据门 create→元数据+awaited 投影;edit→锁步;声明集编辑→可强制执行 overlay;runtime-only 删除→退役 / artifact-backed 删除→重置;包集 overlay 定制+重置全生命周期(showcase_contributor实测)。two-doors-permission.dogfood同步翻转为新语义(5 项全绿)。已注册进 ADR-0054 proof registry(bound:false+ 如实blockedReason)。check:livenessexit 0。3. Setup UI 对齐(框架对象元数据,objectui 原生 honor)
sys_permission_set.name加readonlyWhen: record.id != null——create 可填、edit 锁定,匹配数据门 400 改名拒绝(实测 meta API 返回该 CEL 谓词)。permission-sets.mdx/authorization.mdx更新为 one-authoritative-store + overlay 定制模型。readonlyWhen(ObjectForm→fieldRules),无需 objectui 侧改动。附带
sys_sharing_rule记录权威勿投影、sys_position待判定),跟进 Audit sibling declared-metadata↔record two-store types (sys_position, sys_sharing_rule, sys_capability) per ADR-0094 addendum #2909。验证
🤖 Generated with Claude Code
https://claude.ai/code/session_01SXjD7g2JkEsdqhZFZgAo1Q