braid
GH-42 · Add OAuth login
ARArjun Rao

Add OAuth login

GH-42
surfaced · 3 threads woven
◆ braid claim GH-423 threads dispatched from here, disjoint scopes
thread_afailed
Backendsrc/auth/
Intent — replay-safe token exchange under concurrent logins
agent_start · Claude Code
edit + go test ×9
2 attempts rejected
verify failed · 12/14
thread_bpassed
Frontendweb/login/
Intent — sign-in page that starts OAuth + handles callback
agent_start · Codex
build login page
kept: rendered sign-in
verify passed · e2e
thread_cpassed
Teststest/oauth/
Intent — cover valid / expired / replayed / malformed codes
agent_start · Claude Code
table-driven tests
kept: exchange + errors
verify passed · 14/14
Promote → octopus-merge b + c
thread_a woven in as evidence (not merged) · sign · git note → refs/notes/braid

Add OAuth login

GH-42
4 agents3 threads636k tokens$7.03 cost18m wall-clock

Every agent dispatched from braid claim GH-42, on one clock. Bar length is wall-clock; colour is the harness that ran it. A thread can fan out to more than one agent — thread_a raced two approaches in parallel, both rejected. The right column is each thread's total tokens and estimated API cost.

Claude Code Codex verify passed verify failed approach dropped
thread / agents
0 3m 6m 9m 12m 15m 18m
tokens · cost
thread_afailed
Backend src/auth/
2 agentsCCCC
Claude Code · refresh-token rotation
Claude Code · single-token reuse
347k $4.57
142k + 205k
thread_bpassed
Frontend web/login/
1 agentCx
Codex · login page · redirect flow
168k $1.34
1 agent
thread_cpassed
Tests test/oauth/
1 agentCC
Claude Code · table-driven tests
121k $1.12
1 agent
Converged at 16m → octopus-merge b + c
4 agents across 3 threads · 636k tokens · $7.03 total · thread_a's 2 agents kept as evidence (not merged) — their 347k / $4.57 bought the two dead ends

Add OAuth login

GH-42
✓ Ready to promote
All gates clear · 2 of 3 threads passed · 1 failed and kept as evidence · 0 scope violations.

Threads

Each thread is reconstructed from its signed event stream — IntentDeclaration · Attempt · Decision · Verification. Expand one to see why an approach was favored and the others dropped.

Backend · token exchange
src/auth/CClaude Code · Arjun
verify failed
IntentIntentDeclaration
Add server-side OAuth token exchange that stays replay-safe when the same user signs in from two devices at once.
ApproachesAttempt ×2
rejectedIn-memory refresh-token rotation

Rotating the token in a process-local map races under concurrent logins — both sessions read the same token before either writes it back, so one gets logged out. Failed the concurrent-login test.

rejectedOptimistic single-token reuse

Drops rotation entirely, so a captured token can be replayed and still authenticates. Failed the replay-safety assertion.

No approach held — kept as evidence so the two dead ends aren't retried. Follow-up in GH-49 (replay-safe token store).
VerdictVerification
verify failed · 12 / 14 tests
Frontend · login page
web/login/xCodex · Arjun
verify passed
IntentIntentDeclaration
Add a sign-in page that kicks off the OAuth flow and handles the provider callback.
ApproachesAttempt ×2 · Decision
rejectedPopup-window flow

The auth popup is blocked by default in Safari and loses state on mobile browsers. Dropped.

favoredFull-page redirect + callback route

Works across every browser with no popup permission, carrying state in the OAuth state param. Chosen for cross-browser reliability over the popup's smoother feel.

VerdictVerification
verify passed · e2e green
Tests · integration
test/oauth/CClaude Code · Arjun
verify passed
IntentIntentDeclaration
Cover the token-exchange endpoint across valid, expired, replayed and malformed codes.
ApproachesAttempt ×2 · Decision
rejectedOne test function per case

Five near-identical functions duplicated the exchange setup — harder to extend as cases grow.

favoredTable-driven cases

Single setup, one row per code state — trivial to add cases. Chosen to keep the suite maintainable as OAuth grows.

VerdictVerification
verify passed · 14 / 14 · coverage 91%

Add OAuth login

GH-42

The diff, traced back to the braid. Every hunk shows which thread wrote it and whether that thread's verdict held — so you read what changed and why it survived in one place.

src/auth/token.goevidence · not mergedthread_a — 2 attempts rejected, verify failed
- func Exchange(code string) (*Token, error) {- t := refreshInMemory(code) // race under concurrent logins- return t, nil- }
web/login/LoginPage.tsxmergedthread_b — kept, e2e passed
+ export function LoginPage() {+ return <SignInButton onSuccess={handleCallback} />+ }
test/oauth/exchange_test.gomergedthread_c — 14/14
+ func TestExchange_ReplaySafe(t *testing.T) {+ // table-driven: valid, expired, replayed, malformed+ }

Developer dashboard

Decision queue · 1 braid ready to promote · 1 intervention · 1 live run.

$11.83 open · $0.69/min live
main · braidkit/Prototype

Lifecycle

4 items
Active2
Surfaced1
Promoted1
Dropped0
No dropped braids

Ready to promote

1
Add OAuth login GH-42ready
all gates clear3 threads terminal · 2 passed · 1 evidence thread · $7.03

Needs intervention

1
!
Replay-safe token store GH-49goal pending
reconfirmstale 1dfollow-up from GH-42 thread_a · scope not dispatched

Running / spending

1
caching GH-51active
projected $8.90thread_b running · thread_c queued · no event for 48s

Scratch sessions

Unsigned local work waiting to attach into a braid.

3 sessions · 86% cluster
local · unsigned

Scratch to attach

3
CSV export work
src/reports · web/reports · test/reports — 3 unsigned local sessions.
cluster confidence86%
3 selectedsigns on attach · mints threads a · b · c

All braids

Full braid inventory across scratch, active, surfaced, promoted, and dropped lifecycle states.

5 tracked · 1 ready
main · braidkit/Prototype
sorted by last activity
Issue
Lifecycle
Threads
Gate
Activity
caching GH-51
src/cache · invalidation thread running, tests queued
active
3 threads
1 passed · 1 running · 1 queued
blockedterminal boundary open
48s ago
382k · $4.80 / ~$8.90
CSV export work GH-58
src/reports · web/reports · test/reports · unsigned local sessions
scratch
3 sessions
86% cluster confidence
attachneeds signed braid claim
5m ago
2,020 events · local
Add OAuth login GH-42
web/login · callback flow · failed backend evidence retained
surfaced
3 threads
2 passed · 1 evidence
readyall promote gates clear
18m ago
636k · $7.03
Replay-safe token store GH-49
follow-up discovered from GH-42 thread_a
active
0 threads
dispatch not started
reconfirmgoal pending
1d ago
4 events · $0.00
rate limits GH-38
src/ratelimit · middleware · tests merged with git note
3 threads
3 passed · merged
sealedgit note verified
3d ago
376k · $3.81