fix(plugin-security): correct R1 door-order prose in object-posture-gate.ts - #10017
Conversation
…ate.ts 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
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 13 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 0a053d2ef28dcfbaef35c7f6c21bb773726ed236 && git checkout 0a053d2ef28dcfbaef35c7f6c21bb773726ed236
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 73cfddfa9ceed60537ae75605c529744b62f0567 674b0db8e7968e9ef6948afc72252d53f09fbe53 && git checkout -B drift-repro 73cfddfa9ceed60537ae75605c529744b62f0567 && git merge --no-ff 674b0db8e7968e9ef6948afc72252d53f09fbe53
node scripts/docs-audit/affected-docs.mjs --json 73cfddfa9ceed60537ae75605c529744b62f0567
|
Fixes #9957
Comment-only accuracy edit: the only file touched is
packages/plugins/plugin-security/src/object-posture-gate.ts, and the only change is the R1 header parenthetical at lines 93-94 (pre-edit). The executable guard (if (!ctx.isArtifactBacked) return;) is untouched.What was wrong
The parenthetical read: "the
OS_METADATA_WRITABLEescape-hatch path — the default deploy already 403s these before this gate runs." Measured false on a genuinely stock showcase boot (#9477, landed PR #9953, checklist item revision 3):saveMetaItemrunsrunAuthoringGate(which is R1) ahead of the overlay/package doors on the host-config kernel the showcase boots (environmentIdundefined, soprotocol.ts's env-partitionedNOT_OVERRIDABLEbranch never arms — that file's own #7674 note records this is the flagship showcase's boot shape). A widening body meets R1 first on every leg, hatch open or closed,?package=named or not. The "earlier" refusal the old prose named is real, but it answers later — only for bodies R1 lets through.What changed
Replaced the parenthetical with the measured mechanism:
403 NOT_OVERRIDABLE(no?package=) or403 ITEM_LOCKED(?package=naming the read-only base) on stock;200under the escape hatch.WRITABLE_PACKAGE_REQUIRED— the code the old prose implied — appeared on none of the six measured legs.code: PERMISSION_DENIEDwithdeclaredCode: owd_widening_forbidden, so a check keyed oncodealone misses it (dispatcher-error-vocabulary.ts'sowd_widening_forbiddenrow rationalizes its pending registration from a wire shape the live route does not produce (codevsdeclaredCode) #9958).Refs: #9477 (six-leg evidence table) · PR #9953 (revision-3 ledger entry) · #9958 (the
code/declaredCodewire-shape finding, same evidence base).Premise check
Re-verified at branch point (
73cfddfa9) that the parenthetical still reads as quoted — it wraps across two lines (a single-line grep for the tail alone misses it), confirmed atobject-posture-gate.ts:93-94immediately above theisArtifactBackedguard. Premise valid.Verification (comment-only diff — package suite/typecheck expected unchanged from main; final HEAD
674b0db8e)pnpm --filter @objectstack/plugin-security test -- --maxWorkers=2— 66 files / 1295 tests passed, no change in count from the pre-edit tree.pnpm --filter @objectstack/plugin-security typecheck— clean, exit 0.pnpm check:cross-package-test-inputs/node scripts/check-cross-package-test-inputs.mjs— OK (12 packages, all declared).pnpm check:slot-lookup— ratchet holds, 107 unswept sites in 25 files, none new.pnpm check:test-source-alias— OK, 72 packages scanned.pnpm check:type-source-resolution— OK, 76 packages scanned.node scripts/docs-audit/check-affected-docs.mjs— self-test 262 cases pass; sdk route bridge output unchanged (pre-existing baseline, unrelated to this diff).node scripts/pm/dispatch-gates.mjs(no paths, self-derived from the committed diff at674b0db8e) — same 6 named families as at dispatch time, plus one convention-triggered addition:pnpm check:i18n(the package owns ani18n-extract.config.ts). Ran it to completion (built@objectstack/clifirst per its own PREREQUISITE-NOT-MET message) — PASS, 9 packages, all bundles in sync, no undeclared authoring keys. No diff-review needed to predict "nothing to extract" since it was actually run: confirmed by the OK output.pnpm check:nul-bytes— OK, 6345 tracked text files scanned, no raw control bytes.No ablation applies — nothing executable changed, so there is no mutation/restoration pair to test.
Changeset
skip-changesetlabel applied (this repo's real mechanism — PR #9918 is the recent worked example for a comment-only diff in a published package;objectuiuses an empty-frontmatter changeset instead, not applicable here). Rationale: comment-only prose change, zero user-visible or runtime behavior change, nothing to release.Generated by Claude Code