feat(lint): require authored OWD at the runtime object door; retire ADR-0094 R2 external-wider arm; declare object in runtimeTypes - #8600
Conversation
…etire plugin-gate R2 external-wider arm The #8310 maintainer ruling (option A): an authored OWD is required at the runtime object door — an object publish with no authored sharingModel is refused with the 422 lint envelope (security-owd-unset). The plugin gate's R2 owd_external_wider arm is retired as duplicate of the lint door; R1 (env-tighten-only) stays. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 2 package(s): 14 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also reference the affected code. These are read-only:
|
…t meta-object-owd-gate to the ruled door order Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
…prose, changeset Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
|
How to clear the one red check — recording the exact cause, quoted from the failing job's log, so the merger doesn't have to dig. CI on head So the gate is not reporting a defect in the change — it is reporting that no approving review exists yet, which is exactly the human floor for an ADR-touching PR (the ruling it enforces: 「门禁改成只要求「APPROVED review 存在」」/「不要指定具体的人」, maintainer 2026-08-12, #8161). Its own message notes drafting and pushing were fine; only the MERGE is gated. Why this seat cannot clear it itself: every agent in this repo posts as Two ways forward, both the maintainer's:
Substance is unaffected either way: every test, build, typecheck, lint, dogfood and conformance job on this head is green, including the Generated by Claude Code |
Fixes #8310
HUMAN-MERGE ONLY (docs/adr touched) — per the reconciled ruling (issue comment 5287986058) this PR amends ADR-0094 text, so the PM reviews and the maintainer merges. Do not enable auto-merge. (
check-adr-merge-approvalis the CI guard for exactly this.)Implements the #8310 maintainer ruling (option A, reconciled scope, comments 5287702149 + 5287964032 + 5287986058), completing the #7891 flip set.
What changed
runtimeTypesgainsobjecton thevalidateSecurityPostureentry (packages/lint/src/authoring-rules.ts) — an active-state object publish with NO authoredsharingModelis now refused at the runtime door with the 422 lint envelope (INVALID_METADATA,security-owd-unsetinissues). Absence is not a decision. Whole-family registration, no bespoke check.packages/plugins/plugin-security/src/object-posture-gate.ts): the403 owd_external_widerarm is removed as the lint door's duplicate;403 owd_widening_forbidden(env-tighten-only over a packaged declaration) survives — no lint rule can judge the packaged baseline. ADR-0094 carries a dated amendment recording the retirement and its rationale, citing the ruling.packages/rest/src/meta-object-owd-gate.test.ts): the 422 lint door answers first (saveMetaItemrunsassertRuntimeAuthoringRulesbeforerunAuthoringGate— pinned including a body both doors would refuse); the 403 R1 door answers for writes that pass lint. The formera write with NO OWD keys SAVESpin (ADR-0094 absence-defaults-to-private) is overturned by the ruling and re-pinned as the 422 refusal. The former?mode=draft403 pin is re-pinned to the lint discipline ([runtime/metadata] 作者时规则只存在于 CLI:Studio/REST/MCP 的运行时授权面是第四扇门,26 条规则一条不跑——#4409 修完后最大的敞口 #4463 D1): the dirty draft saves; the draft→active promotion refuses 422.security-owd-unset) and 3 rest files (12 tests) measured red by PR feat(lint): permission/book cross the runtime publish gate; object measured dirty stays behind; security-role-word splits to stay behind whole (#8310) #8546 now authorsharingModel: 'private'on the object bodies they publish, each annotated[#8310].validate-security-posture.runtime-surface.test.ts: OWD-less object publish refused at the REAL gate; [1 of #7891]METADATA_CREATE_SEEDS.objectgains an authoredsharingModel— or an explicit default-OWD ruling (blocker A) #8308's create seed clean; clean write not blamed for pre-existing context defects; builder/gate parity; and the R2-retirement boundary pin (below).R2 shadowing measurement (the ruled falsification check)
Point 4's stop-condition was checked, not assumed. On the active publish path every semantically-correct R2 refusal is refused by the lint door first (
security-external-wider-than-internalwhen the internal side is orderable;security-owd-unset/security-owd-alias-or-unknownwhen it is not). Two literal divergence classes exist and both were judged NOT to falsify the retirement premise — flagged here for the maintainer's merge-time review:isSystem/sys_*) with unsetsharingModel+ explicit external: R2 refused them via its hardcoded private baseline, but the runtime's own default for exactly that shape is public (effectiveSharingModel, plugin-sharing) — R2's refusal contradicted the platform's runtime semantics (a false positive), andsecurity-owd-unsetdeliberately exempts system objects for the same reason. Pinned executable in the runtime-surface suite (the R2-retirement boundary).active, and nothing enforcement-reads a draft. Pinned in the rest suite (draft saves; promotion refuses 422).Declared surface (deltas vs the dispatch list)
content/docs/permissions/authorization.mdx— PM-relayed docs-drift fold-in: the governance section described the retired 403owd_external_widerarm; rewritten to the new door order. The other drift-bot pages carry noowd_external_wider/ R2 prose (greppedcontent/docs/permissions/,content/docs/kernel/runtime-services/sharing-service.mdx,docs/design/permission-model.md— the design doc's mention is the lint rule id, still accurate).content/docs/releases/**untouched.objectstack validateexits 0 on showcase / CRM / todo (every corpus object already authors its posture; remaining warnings are pre-existing advisories unrelated to OWD).Measurements
@objectstack/lint: build ✓, 72 files / 2018 tests ✓, typecheck ✓@objectstack/objectql: 202 files / 3559 tests ✓ (was 83 red / 13 files before repair, measured on this tree), typecheck ✓@objectstack/rest: 114 files / 1883 tests ✓ (was 8 red / 3 files before repair on this tree), typecheck ✓@objectstack/metadata-protocol: 84 files / 1261 tests ✓@objectstack/plugin-security: 55 files / 1075 tests ✓, typecheck ✓objectstack validateexit 0dispatch-gates.mjson the final diff run green locally (incl.check:nul-bytes,check:i18n,check:adr-anchors, changeset gates);check-adr-merge-approvalis CI-credential-bound (local 401) and is the human-merge guard itselfpackage-authorcarve-out pin stayed green (the ones that must not move). Restored and re-run green.Acceptance pins (ruling point → executable)
an OWD-less publish is refused — 422 security-owd-unset; lint:an OWD-less object publish is REFUSED at the real gatesharingModel, each annotated[#8310]; zero rule edits invalidate-security-posture.tsdoor ORDER: when lint AND R1 would both refuse, the 422 lint door answers first; R1 403 pins unchangedobjectdeclaredseed / permission / book / object all crossGenerated by Claude Code