V48 Gate 1: Identity and authentication interactive QA#248
Conversation
…ost-auth on /packs GoTrue validates redirect_to with exact string matching against the Auth allow-list; the ?next= query the app appended defeated the match, so every auth code fell back to the Site URL origin (apex bitcode.exchange) where the PKCE verifier does not exist - no session was ever minted, from localhost or production www. Proven via /auth/v1/authorize + garbage-code /auth/v1/callback probes (matrix in BITCODE_V48_QA.md F5). - uapi/lib/supabase-auth-redirect.ts: redirect_to stays query-free; the post-auth destination travels via origin-local storage, consumed once by LoginCallbackClient (explicit ?next= still wins for back-compat) - Converted initiators: AuxillariesWalletConnectionPanel, SocialAccountLinker, SocialLoginButton - Wallet sign-in now lands on /packs instead of the legacy /terminal overlay route that buildAuxillariesRoutePath still targets (QA ledger F8) - Regression test tests/supabaseAuthRedirect.test.ts pins the query-free invariant; registered in jest.config.cjs - BITCODE_V48_QA.md: F5 root cause corrected and verified (session mints, last_sign_in_at set), F8 legacy /terminal finding added, Track 1 updated; open residual: wallet binding fields stay null after sign-in Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The canonical wallet sign-up signs on the prod /tps/wallet/authorize page, so nothing is staged in the initiating origin for WalletSessionPersistence- Bridge to replay, /api/wallet/authenticate (the only settings.walletBinding writer) was never called, and profiles stayed unbound after sign-in: Wallet Auxillary showed 'No Bitcoin wallet connected' and Profile readiness blocked on identity/binding. GoTrue also drops the provider's custom bitcoin_* claims from identity_data, so the proof material is unrecoverable client-side. - /api/wallet/authenticate: new source 'oauth-identity' mode derives the binding server-side from the GoTrue-verified custom:bitcode-bitcoin identity (address+network from the identity sub, provider from the userinfo label; no client-trusted wallet fields), writes settings.walletBinding (proofKind provider_session, status pending), user_connections (auth_source bitcoin_wallet_oauth_identity), and username; idempotent no-op when the binding already matches - WalletSessionPersistenceBridge: when a session exists with nothing replayable staged locally, triggers the identity-derived bind and mirrors the result into the local wallet identity so the Wallet Auxillary renders the connection - Route response now carries network; coverage in walletAuthenticateRoute and walletSessionPersistenceBridge tests (12 passing) - BITCODE_V48_QA.md: F5a trace + fix + retest steps recorded Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ators Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…o consumer Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… in V48 notes Records the accepted Gate 1 findings ledger (BITCODE_V48_QA.md F1-F10), the redirect_to exact-match law, identity-derived wallet binding, the /packs post-auth landing, and the specification intent queued for the full V48 draft family, which opens at Gate 1 closure per the V47 Gate 1 precedent. Notes-only posture and all draft-notes checker phrases preserved (check-bitcode-draft-notes + run-bitcode-spec-quality verified locally). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Regenerated .d.ts/tsbuildinfo outputs from the local workspace build during V48 QA environment setup; no source changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Auth App residue Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…OST handler Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The VCS connect redirect targeted the legacy /terminal overlay root (QA ledger F8). AuxillariesProvider reads the auxillary-open-to param on any route, so the callback now lands on /packs?auxillary-open-to=externals and the Externals pane opens over the canonical packs surface, making the new GitHub connection immediately visible. Ledger records the verified install (installation token, connection saved) after replacing placeholder GitHub App env values. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ipts - Externals Connected Scope hard-capped pills at 8 while announcing the full count (46); now renders every repository in a scrollable wrap - Adds supabase/queries/v48_qa_01..05: auth/identity, profile wallet binding, token-safe connections projection, repository inventory, and a one-row Track 1 readiness rollup — each self-targets the latest wallet-identity user and documents when to run it; ledger carries the run-after map - Ledger: GitHub connect + 46-repo inventory verified; token-exposure hygiene note (use the token-safe projection, never raw connection_data) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…l to /packs 'Add Email' (and every readiness repair CTA) navigated to the legacy /terminal overlay root, which renders no auxillary experience. All seven contract-emitted repair/recovery routes now target /packs?auxillary-open-to= <pane>; AuxillariesProvider opens the pane overlay on any route. The v40 browser-proof checker pins only bitcode-browser-proof.ts route states, which are untouched (QA ledger F8). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ty root Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Nothing in the codebase ever fetched a chain balance - btcFeeBalance was only read from profile fields nothing writes, so the 'BTC in wallet' card showed 'Binding pending' and the nav chip rendered null as 0 BTC. - New session-scoped GET /api/wallet/btc-balance derives the bound addresses server-side from the profile wallet binding (no client-trusted address), queries mempool.space, and returns confirmed/pending sats+BTC. The ambiguous 'testnet' binding label tries testnet4 first, then testnet3, so fauceted coins surface wherever they landed. - Wallet pane 'BTC in wallet' card now shows the live balance with network and pending-confirmation detail, falling back to posture text when the source is unavailable. - Ledger documents testnet4 faucets (coinfaucet.eu, altquick.com) and the mempool.space testnet4 explorer patterns. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ress repair path proven Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…uthoring moves to its own gate The signed-in Leather reconnect rewrites the wallet connection auth_source from bitcoin_wallet_oauth_identity to bitcoin_wallet_provider, so the rollup's wallet join now accepts both and surfaces payment_address, proof_kind, and auth_source. Notes clarify the full V48 draft family opens in a dedicated authoring gate; Gate 1 closes as the identity/auth QA gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 630ee980a3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const existingBinding = | ||
| asRecord(asRecord(settingsRecord?.bitcodeProfile)?.walletBinding) ?? | ||
| asRecord(settingsRecord?.walletBinding); | ||
| if (readNonEmptyString(existingBinding?.address) === address) { |
There was a problem hiding this comment.
Repair missing connection rows before idempotent no-op
If the OAuth-identity bind writes user_profiles successfully but the later user_connections upsert fails or is temporarily blocked, the profile now contains the same wallet address and every retry exits here before reattempting the connection write. That leaves the user with a wallet binding but no active wallet connection row even after the underlying failure is fixed, so the bridge cannot self-heal the state it is meant to backfill; the idempotency check should also verify/repair the connection record before returning.
Useful? React with 👍 / 👎.
Summary
Closes V48 Gate 1 — the identity/authentication interactive QA gate over promoted V47 canon. Sixteen commits of live-QA-driven repairs, evidence, and tooling; Track 1 of the V48 charter is complete and verified end-to-end on the staging-testnet deployment (ledger:
BITCODE_V48_QA.md).Functional repairs (all live-verified)
redirect_toby exact string match — the?next=query defeated the allow-list and stranded every auth code (and the PKCE verifier) on the Site URL origin; no session was ever minted, from localhost or production www.redirect_tois now query-free viauapi/lib/supabase-auth-redirect.ts; the post-auth destination travels through origin-local storage./api/wallet/authenticategains a server-derivedsource: 'oauth-identity'mode;WalletSessionPersistenceBridgetriggers it; the signed-in panel reconnect backfills payment address + signature proof.GET /api/wallet/btc-balance(mempool.space, testnet4-first) feeding the Wallet pane "BTC in wallet" card — previously no chain-balance source existed anywhere./terminallandings (F8 interim): wallet sign-in lands on/packs; GitHub connect lands on/packs?auxillary-open-to=externals; all seven contract repair/recovery routes retargeted to/packs.slice); now renders all.Evidence, tooling, posture
BITCODE_V48_QA.md: findings F1–F11 with root-cause traces, fixes, verification evidence, and the Track 1 checklist (complete; email deferred by decision — wallet+GitHub is the identity root).supabase/queries/v48_qa_01..05: committed QA SQL (auth/identity, binding, token-safe connections, repository inventory, Track 1 rollup) with run-after mapping.BITCODE_SPEC_V48_NOTES.md: Gate 1 reflection + specification intent for the eventual draft family (notes-only posture preserved; draft-notes checker green)..d.tsoutputs isolated in their own commit.Verification
run-bitcode-spec-quality+ draft-notes checker green locally and in pre-commit.🤖 Generated with Claude Code