Uh oh!
There was an error while loading. Please reload this page.
docs(qa): name the condition that selects the OWD gate's answering layer (#9477) - #9953
Merged
Merged
Conversation
…yer (#9477) `access-security.owd-save-gate` predicted that on a stock deploy a runtime meta PUT to a packaged object is refused by the writable-package gate (WRITABLE_PACKAGE_REQUIRED) BEFORE plugin-security's R1 can answer, and that R1 `owd_widening_forbidden` is reachable only through the OS_METADATA_WRITABLE=object escape hatch. Re-measured against a genuinely stock showcase boot: both halves are wrong, and #9453 CF-3 — rejected by the revision-2 note as contradicting the gate's source — was right. What the deploy posture does NOT decide, and what does: posture body → status code stock widening → 403 owd_widening_forbidden (R1) stock tightening → 403 NOT_OVERRIDABLE (overlay door) stock+package widening → 403 owd_widening_forbidden (R1) stock+package tightening → 403 ITEM_LOCKED (package door) hatch=object widening → 403 owd_widening_forbidden (R1) hatch=object tightening → 200 admitted The DIRECTION of the submitted body selects the answering layer, not the posture. `saveMetaItem` runs `runAuthoringGate` ahead of the overlay and package doors on the host-config kernel the showcase boots (environmentId undefined, so the env-partitioned NOT_OVERRIDABLE branch never arms — the #7674 note in protocol.ts records that the showcase is exactly that shape), so a widening body meets R1 first on every leg. The door the knownGap called "earlier" is in fact later, and WRITABLE_PACKAGE_REQUIRED appeared on none of the six legs. Also recorded: the wire shape. The dispatcher answers `code: PERMISSION_DENIED` with the ledgered spelling in `declaredCode`, so a check keyed on `code` alone misses the gate it is looking for. Not a product defect — no code change. Every widening leg refused and the object stayed byte-identical; object-posture-gate.ts behaved exactly as its executable guard (`if (!ctx.isArtifactBacked) return`) specifies. Only the prose mispredicted the ordering — in this item, and in that file's header parenthetical, which is left for the owning lane. Fixes#9477 Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Aug 19, 2026
os-warren
marked this pull request as ready for review
August 19, 2026 10:57
Uh oh!
There was an error while loading. Please reload this page.
os-warren pushed a commit
that referenced
this pull request
Aug 19, 2026
…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
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 freeto 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.
Fixes#9477
Measurement-first card: the deliverable is the differential diagnosis, and the only file touched is
docs/qa/platform-checklist/areas/access-security.json. Noplugin-securitycode was edited.Outcome 3. Both refusals are real on the same stock deploy; the checklist's
knownGapnamed the wrong one as "earlier". #9453 CF-3 was right, and the revision-2 note that rejected it is overturned.The three answers
1. Was
OS_METADATA_WRITABLEset? — No. Proven from the server process's own environ.The stock leg was booted with
pnpm -C examples/app-showcase exec objectstack dev --ui --seed-admin -p 3477 -d file:<tmp>/data.db, then its/proc/<pid>/environwas read directly rather than trusting the shell:No
.env/.env.localexists at the repo root or inexamples/app-showcase. Framework90417a8, objectui pin82a9417.2. Was the target artifact-backed? — Yes. Read from the protocol's own layered answer.
isArtifactBackedresolves throughlookupArtifactItem→SchemaRegistry.getArtifactItem, which is the same source the layered read reports as itscodelayer.GET /api/v1/meta/object/showcase_announcement?layers=true→ 200:A populated
codelayer with a genuine package id is exactly the conditionisArtifactBackedreturnstruefor;overlay: nullconfirms nothing had been overlaid first. The shipped source agrees (announcement.object.ts:sharingModel: 'public_read',externalSharingModel: 'private').3. Which layer produced the 403? —
object-posture-gate.ts's R1, on the stock deploy.PUT /api/v1/meta/object/showcase_announcementwith the packaged body andsharingModelwidenedpublic_read→public_read_write(externalSharingModelleft'private', so the D11 lint cannot answer instead):Reproduced twice on fresh requests.
GETbefore and after is byte-identical, so the refused write is inert.The control leg — what makes this a diagnosis rather than one observation
A gate that fires proves the probe arrived, but not that the layer the checklist named is absent. So the same body was re-sent tightened (
public_read→private), which R1 passes by construction — whatever answers next is the next door:?package=owd_widening_forbiddenobject-posture-gate.tsR1NOT_OVERRIDABLESysMetadataRepository.assertAllowed, registry limbowd_widening_forbiddenobject-posture-gate.tsR1ITEM_LOCKEDSysMetadataRepository.readOnlyBaseOverrideError, package doorOS_METADATA_WRITABLE=objectowd_widening_forbiddenobject-posture-gate.tsR1OS_METADATA_WRITABLE=objectThe hatch leg was a second, independently booted server on port 3478 with its own DB; its
/proc/<pid>/environshowsOS_METADATA_WRITABLE=object.Three things fall out, none of which the old text allowed for:
knownGapcalled "earlier" is in fact later. It answers only for bodies R1 lets through.WRITABLE_PACKAGE_REQUIRED— the code theknownGapnames — appeared on none of the six legs. The real codes areNOT_OVERRIDABLEandITEM_LOCKED.The mechanism is already recorded in the framework, one file over:
saveMetaItemcallsrunAuthoringGateahead of the overlay and package doors, and its#7674note states that the CLI's host-config assembler leavesenvironmentIdundefined and that this "is the flagship showcase's own boot shape". WithenvironmentIdundefined the env-partitionedNOT_OVERRIDABLEbranch never arms, so nothing stands between a stockPUTand R1.Why this is not a product defect
Every widening leg refused, and the object was byte-identical after each.
object-posture-gate.tsbehaved exactly as its executable guard specifies —if (!ctx.isArtifactBacked) return;did not return because the target is artifact-backed. Nothing was admitted that should have been refused, and the gate's verdict is the correct one. What was wrong is a prose prediction about door ordering, in two places: this checklist item (fixed here) and the gate header's parenthetical "the default deploy already 403s these before this gate runs", which belongs to theplugin-securitylane and is left untouched per the dispatch.The change
access-security.owd-save-gaterevision 2 → 3:fixtures.knownGaps[1]— the deliverable. Now names the distinguishing condition (body direction), the mechanism, all six measured legs, and the fact thatWRITABLE_PACKAGE_REQUIREDis not among them.steps[4]andacceptance[3](clause +verify) — carried the identical wrong posture→code mapping; corrected so the item is not self-contradictory.steps[4]also gains the tightening control leg, so the next runner can tell "gate didn't fire" from "probe didn't arrive".declaredCode, notcode. The dispatcher answers{code: 'PERMISSION_DENIED', declaredCode: 'owd_widening_forbidden'}on the live REST route, so a check keyed oncodealone misses the gate it is looking for.history— a revision-3 entry recording the overturn of the revision-2 note.pnpm check:platform-checklist→OK — 15 areas, 190 items (190 active); coverage: 30 kinds mapped, 0 waived.Generated by Claude Code