refactor(coil): one scope-auth helper for every fork route - #131
Merged
Conversation
Both fork route modules carried their own paste of upstream's private `authenticateRawRouteWithScope`, and the two had already drifted: the auto-resume copy forwards the DPoP failure reason, the Web Push copy dropped it. Promote the parameterised form into `coil/http/auth.ts` and re-point both, so the next fork route calls the mirror instead of pasting a third one. Reconciled to the union of the two behaviours, which is also what upstream does: the shared helper forwards `dpopFailureReason` (previously only on auto-resume) and returns the session (previously only on Web Push). The error-tag map that renders the three typed failures moved with it, since it exists only because of them. Statuses, bodies and scopes are otherwise unchanged, and `CoilRoutesLive` is untouched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The predicate reads one field, `session`, which an `OrchestrationThreadShell` declares with the same `OrchestrationSession | null` type the full thread does. Asking for `Pick<OrchestrationThread, "session">` lets a shell-only caller reuse it instead of pasting a second copy of the driver-slug compare. Every other guard still takes the full thread, since they read `messages` and `activities`, which no shell carries. Behaviour is unchanged. Also drops two drifted line-number citations from the doc comment. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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 free
to 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.
Phase 0 of the loops plan (
docs/coil/loops-v2/PLAN.md§5, Phase 0): pay down two small fork-owned debts the feature would otherwise duplicate. Zero upstream files touched.Problem. The fork carried two independent mirrors of upstream's private HTTP scope-auth path —
autoResume/http.ts(authenticateWithOperateScope, scope hardcoded, forwards the DPoP failure reason) andwebPush/http.ts(authenticateWithScope(scope), parameterised, drops the DPoP reason). The loop routes would have been the third paste. Separately,isClaudeThreadonly accepted a fullOrchestrationThread, so a reactor holding anOrchestrationThreadShellcould not use it.Fix.
apps/server/src/coil/http/auth.tsexportingauthenticateWithScope(scope)androuteAuthErrorTags; both route modules call it and their local copies are gone. The promoted helper is the union of the two mirrors: it forwardsdpopFailureReason(as auto-resume did since 3bdf109) and returns the session (as web-push did). The one observable change: a DPoP-rejected credential on/api/coil/push/*now carriesdpopFailureReasonin its 401 body, matching the auto-resume route and upstream's ownauthenticateRawRouteWithScope.isClaudeThreadtakesPick<OrchestrationThread, "session">; a shell is structurally assignable with no cast, and the test literal is cast-free so reverting the widening fails typecheck.http/auth.test.tspins all three typed failures (401 / 403 / 500 shapes); newwebPush/http.test.tspins the push routes at the route level (the first test to import them); the shared test scaffolding moved intohttp/testAuth.ts;autoResume/http.test.tsnow asserts exact statuses instead of401 || 403.docs/coil/SEAMS.md: the logic-mirror row names the single mirror and its three intentional deltas from upstream.Verified in a worktree:
vp test run src/coil→ 17 files, 140 tests pass;tsgo --noEmit→ 0 errors;vp lintonapps/server/src/coilclean;vp fmt --checkclean.Work done by Claude Fable 5.1 orchestrating Claude Opus 5 subagents in Claude Code.