You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
finding: context.authGate is read by REST's enforceAuth but is not declared on ExecutionContextSchema — an undeclared field outside every closure gate #7280
Found while implementing #6216 (PR #7259). Filed unassigned; deliberately not fixed there, because declaring a field on ExecutionContextSchema is a spec change with its own review surface, not a refactor rider.
The fact
The ADR-0069 authentication-policy gate rides on the execution context:
written in packages/rest/src/rest-server.tscomputeExecCtx — the assembled envelope is spread with ...(authGate ? { authGate } : {}) behind an as any;
read in the same file's enforceAuth (const gate = context?.authGate;), which blocks protected resources for a gated user;
not declared anywhere in packages/spec/src/kernel/execution-context.zod.ts — grep -n authGate packages/spec/src returns nothing.
Why it matters now specifically
#6216's whole point is that the ExecutionContext field set is closed by type, so a field cannot reach one transport and miss another. That closure is derived from keyof ExecutionContext, i.e. from the schema. A field that lives only in an as any spread is, by construction, outside the closure: ENTRY_EXECUTION_CONTEXT_FIELDS cannot list it, ExecutionContextEntryFields cannot demand it, and the runtime pin that reconciles the closed set against ExecutionContextSchema.shape cannot see it either. It is exactly the blind spot the new gate is meant to remove, sitting one as any outside the gate.
Nothing is broken today: the producer and the consumer are ten lines apart in one file, so they cannot drift the way #6071's two files did. The cost is that a second transport wiring up the ADR-0069 gate has nothing to tell it the field exists.
Suggested shape if it is taken up
Declare authGate on ExecutionContextSchema (shape: { code, message } per packages/core/src/security/auth-gate.ts), drop the as any, and let #6216's closed set pick it up — at which point every face must decide it, which is the intended outcome. Note the ADR-0087 / authorable-surface consequences of adding a key: pnpm --filter @objectstack/spec build regenerates packages/spec/authorable-surface/kernel.json, and that regeneration is itself gated.
CLAIM — spec-lane PM seat (#6017), session session_01PiRUoQkTSBBmpyXBY3cVn2. Branch: claude/issue-7280-declare-auth-gate. Dispatching a cloud dev session (model: Opus) under the maintainer's standing acceleration instructions (2026-08-10, latest verbatim: 「再看看有没有新任务可以批量派」).
Direction (the card's own suggested shape, adopted): declare authGate on ExecutionContextSchema (shape { code, message } per packages/core/src/security/auth-gate.ts), drop the as any spread in computeExecCtx, and let #6216's closed field set pick it up — at which point every transport face must decide it, which the card names as the intended outcome. The field is live (written and read ten lines apart in rest-server.ts); declaring it is the ENFORCE leg on a field the closure gate was built to see. Premise-first guards: re-measure that authGate is still undeclared and still spread behind as any; census every face the #6216 closed set forces a decision on and decide each explicitly in the PR (no silent undefined pass-through without a stated reason). ADR-0087/authorable-surface consequences per the card: build before regen, gated regeneration.
CLAIM WITHDRAWN — held to the recorded restart condition. Two facts the race-check surfaced against my claim: (1) triage's routing comment names the natural restart as "#6216/PR #7259 landing makes the closed-set pin the enforcement channel this key would join" — PR #7259 is still open, so the closed set this declaration is meant to join is not on main yet; (2) #7259 itself touches rest-server.ts's computeExecCtx region from another seat — dispatching this now would collide mid-flight with the very PR that creates the enforcement channel. Assignee cleared; the claim comment above is void. This seat re-claims when PR #7259 merges (recorded on the seat post #6017 as a gated card, same treatment as #7297).
RE-CLAIM — recorded restart condition met. Spec-lane PM seat (#6017), session session_01PiRUoQkTSBBmpyXBY3cVn2. Branch: claude/issue-7280-declare-auth-gate. Dispatching a local dev agent (model: Opus — well-scoped declaration + face census; the #6216 closed-set machinery this key joins is now on main).
The 06:56Z withdrawal held this card to "re-claims when PR #7259 merges". PR #7259 MERGED 2026-08-10T05:41:32Z (verified by direct read), so both blockers are gone: the closed-set enforcement channel exists on main, and the computeExecCtx region is no longer being edited mid-flight by another seat.
Direction unchanged from the 06:55Z claim: declare authGate on ExecutionContextSchema (shape { code, message } per packages/core/src/security/auth-gate.ts), drop the as any spread in computeExecCtx, and let #6216's closed field set force every transport face to decide it explicitly — no silent undefined pass-through without a stated reason at the call site (the accessToken precedent in PR #7259's body is the template). Premise-first: re-measure that authGate is still undeclared (git grep authGate packages/spec/src = zero hits) and still spread behind as any — all line numbers post-#7259 will have moved, re-anchor by content. ADR-0087/authorable-surface consequences: build before regen, gated regeneration, dual-snapshot rule if exports move.
Activity
os-zhuang commentedon Aug 10, 2026
Findings triage — route repair only:
domain:specappended.findinggrade unchanged, no ownership taken.authGateonExecutionContextSchema—git grep -rn authGate packages/spec/srconorigin/main@397e731returns zero hits (counterprobe: the same grep onpackages/rest/src/rest-server.tshits:2122/:2125/:2575, so the scanner is live). Adding a key toExecutionContextSchemachanges the acceptance face ⇒domain:specper the standing red line (any acceptance/rejection change, however small, isspec, precedents meta: bind Zod schemas for webhook / connector / sharing_rule WITHOUT registering the kinds — close the unvalidatedPUT /metawrite hole (#2657 audit, option A) #6245/feat(spec): action param 的 options[] 声明逐选项 visibleWhen (#5016) #6235).findingper the card's own honest framing: producer and consumer are ten lines apart in one file, nothing drifts today; the cost materializes when a second transport wires the ADR-0069 gate. Natural restart: finding: ExecutionContext 在 dispatcher / REST / share-link 三处独立组装 —— 收敛为单一共享装配函数前,先裁决匿名面分歧 #6216/PR refactor(core,runtime,rest): one ExecutionContext assembler, two named anonymous entries (#6216) #7259 landing makes the closed-set pin the enforcement channel this key would join.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-zhuang commentedon Aug 10, 2026
CLAIM — spec-lane PM seat (#6017), session
session_01PiRUoQkTSBBmpyXBY3cVn2. Branch:claude/issue-7280-declare-auth-gate. Dispatching a cloud dev session (model: Opus) under the maintainer's standing acceleration instructions (2026-08-10, latest verbatim: 「再看看有没有新任务可以批量派」).Direction (the card's own suggested shape, adopted): declare
authGateonExecutionContextSchema(shape{ code, message }perpackages/core/src/security/auth-gate.ts), drop theas anyspread incomputeExecCtx, and let #6216's closed field set pick it up — at which point every transport face must decide it, which the card names as the intended outcome. The field is live (written and read ten lines apart inrest-server.ts); declaring it is the ENFORCE leg on a field the closure gate was built to see. Premise-first guards: re-measure thatauthGateis still undeclared and still spread behindas any; census every face the #6216 closed set forces a decision on and decide each explicitly in the PR (no silentundefinedpass-through without a stated reason). ADR-0087/authorable-surface consequences per the card: build before regen, gated regeneration.Generated by Claude Code
os-zhuang commentedon Aug 10, 2026
CLAIM WITHDRAWN — held to the recorded restart condition. Two facts the race-check surfaced against my claim: (1) triage's routing comment names the natural restart as "#6216/PR #7259 landing makes the closed-set pin the enforcement channel this key would join" — PR #7259 is still open, so the closed set this declaration is meant to join is not on
mainyet; (2) #7259 itself touchesrest-server.ts'scomputeExecCtxregion from another seat — dispatching this now would collide mid-flight with the very PR that creates the enforcement channel. Assignee cleared; the claim comment above is void. This seat re-claims when PR #7259 merges (recorded on the seat post #6017 as a gated card, same treatment as #7297).Generated by Claude Code
os-zhuang commentedon Aug 10, 2026
RE-CLAIM — recorded restart condition met. Spec-lane PM seat (#6017), session
session_01PiRUoQkTSBBmpyXBY3cVn2. Branch:claude/issue-7280-declare-auth-gate. Dispatching a local dev agent (model: Opus — well-scoped declaration + face census; the #6216 closed-set machinery this key joins is now onmain).The 06:56Z withdrawal held this card to "re-claims when PR #7259 merges". PR #7259 MERGED 2026-08-10T05:41:32Z (verified by direct read), so both blockers are gone: the closed-set enforcement channel exists on
main, and thecomputeExecCtxregion is no longer being edited mid-flight by another seat.Direction unchanged from the 06:55Z claim: declare
authGateonExecutionContextSchema(shape{ code, message }perpackages/core/src/security/auth-gate.ts), drop theas anyspread incomputeExecCtx, and let #6216's closed field set force every transport face to decide it explicitly — no silentundefinedpass-through without a stated reason at the call site (theaccessTokenprecedent in PR #7259's body is the template). Premise-first: re-measure thatauthGateis still undeclared (git grep authGate packages/spec/src= zero hits) and still spread behindas any— all line numbers post-#7259 will have moved, re-anchor by content. ADR-0087/authorable-surface consequences: build before regen, gated regeneration, dual-snapshot rule if exports move.Generated by Claude Code
feat(spec,core,rest,runtime): declare ExecutionContext.authGate so th…
test(spec): kernel test titles state each cited decision in words ins…