From 674b0db8e7968e9ef6948afc72252d53f09fbe53 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 19 Aug 2026 14:53:41 +0000 Subject: [PATCH] fix(plugin-security): correct R1 door-order prose in object-posture-gate.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The R1 header parenthetical claimed "the default deploy already 403s these before this gate runs" for the OS_METADATA_WRITABLE escape-hatch path. Measured false on a stock showcase boot (#9477, landed PR #9953 revision 3): what selects the answering layer is the direction of the submitted body, not the deploy posture. A widening body meets R1 first on every leg, hatch open or closed, `?package=` named or not, because saveMetaItem runs runAuthoringGate ahead of the overlay/package doors on the host-config kernel the showcase boots. The "earlier" refusal the old prose named answers only later, and only for non-widening bodies. Comment-only — the executable guard (`if (!ctx.isArtifactBacked) return;`) is untouched. Refs: #9957, #9477, PR #9953, #9958 --- .../plugin-security/src/object-posture-gate.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/plugins/plugin-security/src/object-posture-gate.ts b/packages/plugins/plugin-security/src/object-posture-gate.ts index 2237ab1de3..aa47f2560e 100644 --- a/packages/plugins/plugin-security/src/object-posture-gate.ts +++ b/packages/plugins/plugin-security/src/object-posture-gate.ts @@ -90,8 +90,21 @@ export function objectPostureGate(ctx: ObjectPostureGateContext): void { // R1 — ADR-0086 D1: an environment may only TIGHTEN a packaged object's // posture. Applies only to overlay writes over an artifact-backed object - // (the OS_METADATA_WRITABLE escape-hatch path — the default deploy already - // 403s these before this gate runs). + // (`ctx.isArtifactBacked`, the OS_METADATA_WRITABLE escape-hatch path). + // The answering layer is picked by the body's DIRECTION, not by deploy + // posture: a widening body meets R1 first on every leg — hatch open or + // closed, `?package=` named or not. On the host-config kernel the + // showcase boots, `saveMetaItem` runs `runAuthoringGate` ahead of the + // overlay/package doors (`environmentId` undefined, so protocol.ts's + // env-partitioned NOT_OVERRIDABLE branch never arms — see that file's own + // #7674 note). A non-widening body passes R1 and only then meets the + // overlay door: 403 NOT_OVERRIDABLE (no `?package=`) or 403 ITEM_LOCKED + // (`?package=` naming the read-only base) on stock, 200 under the escape + // hatch — WRITABLE_PACKAGE_REQUIRED appears on none of these paths. + // Measured on a stock showcase boot, six legs: #9477 (PR #9953, revision + // 3). Wire shape is `code: PERMISSION_DENIED` with `declaredCode: + // owd_widening_forbidden`, so a check keyed on `code` alone misses it + // (#9958). if (!ctx.isArtifactBacked) return; const declared = ctx.declaredBody as Record | null; if (!declared || typeof declared !== 'object') return;