Filing gate: ① a reproducible defect, class (a), an access guard that does not hold. Measured and pinned unchanged by #21912's build (PR #21939, os-dev-report 6008178930, out_of_scope_findings 0 and 1). Filed by domain:services seat 1 (#6021), session_011K3zqE8Pv1Evw5hc8tZCnN, for triage. ⛔ Classes, positions and functions only. ⛔ Not a claim.
The class: a guard that reads before deciding swallows a fault on its own read and lets the request through, instead of refusing it.
The two positions (on origin/main):
packages/runtime/src/http-dispatcher.ts, the environment-membership gate: the sys_environment_member read in the project-membership check. Its catch logs at debug level and returns null (allow). The code says so: "fail open rather than break the request. Tightening this is deferred to Phase 4." The same function also allows when no ObjectQL service resolves. The effect is that a signed-in non-member passes an environment-scoped door whenever that read faults.
packages/plugins/plugin-auth/src/auth-manager.ts, organizationHooks.beforeUpdateOrganization (the organization slug guard): both of its reads (sys_organization, sys_environment) end the hook without refusing when they throw. In the open-source composition sys_environment is not registered, so that read always throws there. The guard therefore never refuses in that composition (measured: a slug update answers 200).
Pinned today, behaviour unchanged: PR #21939 adds unit pins that state each catch's current answer. They are "a read that throws lets the request through" in the runtime file, and "an organization read / environment read that throws ends the hook without refusing" in plugin-auth. A fix turns those pins.
Why it matters now: #21908 (p1) will deny principal-less engine contexts. #21912 moved both reads to the explicit system opt-in, so that deny no longer trips these catches. Any other read fault still opens both guards.
Done when (proposed; triage decides): each guard refuses when its read cannot answer (fail closed), the pins turn to assert the refusal, and the open-source composition's slug guard either reads a registered object or states why it does not apply there.
Duplicate check (semantic issue search, closed included):
Generated by Claude Code
Filing gate: ① a reproducible defect, class (a), an access guard that does not hold. Measured and pinned unchanged by #21912's build (PR #21939,
os-dev-report6008178930,out_of_scope_findings0 and 1). Filed bydomain:servicesseat 1 (#6021),session_011K3zqE8Pv1Evw5hc8tZCnN, for triage. ⛔ Classes, positions and functions only. ⛔ Not a claim.The class: a guard that reads before deciding swallows a fault on its own read and lets the request through, instead of refusing it.
The two positions (on
origin/main):packages/runtime/src/http-dispatcher.ts, the environment-membership gate: thesys_environment_memberread in the project-membership check. Its catch logs at debug level and returnsnull(allow). The code says so: "fail open rather than break the request. Tightening this is deferred to Phase 4." The same function also allows when no ObjectQL service resolves. The effect is that a signed-in non-member passes an environment-scoped door whenever that read faults.packages/plugins/plugin-auth/src/auth-manager.ts,organizationHooks.beforeUpdateOrganization(the organization slug guard): both of its reads (sys_organization,sys_environment) end the hook without refusing when they throw. In the open-source compositionsys_environmentis not registered, so that read always throws there. The guard therefore never refuses in that composition (measured: a slug update answers200).Pinned today, behaviour unchanged: PR #21939 adds unit pins that state each catch's current answer. They are "a read that throws lets the request through" in the runtime file, and "an organization read / environment read that throws ends the hook without refusing" in
plugin-auth. A fix turns those pins.Why it matters now: #21908 (p1) will deny principal-less engine contexts. #21912 moved both reads to the explicit system opt-in, so that deny no longer trips these catches. Any other read fault still opens both guards.
Done when (proposed; triage decides): each guard refuses when its read cannot answer (fail closed), the pins turn to assert the refusal, and the open-source composition's slug guard either reads a registered object or states why it does not apply there.
Duplicate check (semantic issue search, closed included):
single; an unstamped write is derived there and refused everywhere else (ADR-0131 D3/D9/D11) #15195 (open, ADR-0131 default organization), seed-loaderresolveSoleOrganizationIdswallows everysys_organizationread failure behind a comment naming one benign cause, so a transient outage silently seeds org-less rows #12852 (closed, a seed-loader read swallowed) and [转移] 发布期护栏:多组织下「平台级 + schedule + create_record + 未显式 organization_id」拒绝——#6155 Q3=A 裁决的 lint 半边 #6285 (closed). None is this.Generated by Claude Code