Skip to content

Commit a757cee

Browse files
V48 Gate 3 (specification-implementation): confirm the reconnect fix live; harden button types; log the button-hang bug found along the way (V48-Gate3-F36)
Live-confirmed F35: disconnected via a direct fetch() DELETE from the console (the UI Disconnect button was blocked — see F36), then reconnected through Bitcode's normal Connect GitHub flow. Result: Connected/Valid. This confirms the stuck row's installation id belonged to the other Bitcode GitHub App and reconnecting against the currently-configured app resolves it, no GitHub-side action needed. Along the way, found a real, separate, still-open bug: the Refresh and Disconnect buttons on this card don't respond to clicks at all (no dialog opens, no console error, no network request, a brief whole-tab hang then normal again) — ruled out as a server/API issue by confirming the exact same endpoint works instantly when called directly. Documented the investigation and ruled-out theories as V48-Gate3-F36 (open) so it isn't re-investigated from scratch later. Applied one zero-risk hardening regardless of root cause: both buttons now set type="button" explicitly, since shadcn's Button doesn't default it and a bare <button> falls back to the browser's native type="submit". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 80efc99 commit a757cee

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

BITCODE_V48_QA.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,15 @@ Track 3-4 scripts (BTD ledger, settlement, pack journaling) get added when those
546546
- Refined cause: per the Environments section above (`## Environments`, corrected 2026-07-06), there are genuinely TWO separate Bitcode GitHub App registrations — `bitcode-github-auxillary` (production-mainnet) and `bitcode-github-auxillary-stag-test` (`GITHUB_APP_ID=4224019`) — and, per the 2026-07-05 "production == staging" decision, the stag-test app's credentials were pushed to ALL THREE Vercel targets (`staginglocal-testnet`, `production`, `preview`). A connection whose stored installation id was minted under `bitcode-github-auxillary` (e.g. from before that unification, or from a flow that used the production app's install link) is invisible to a JWT signed for `bitcode-github-auxillary-stag-test` — GitHub returns 404 for "this app doesn't own that installation id," which reads identically to "the installation was removed" even though the app is very much still installed (just the OTHER one). Confirmed can't rule this out by comparing `GITHUB_APP_ID` values directly: `vercel env pull` returns encrypted vars as empty strings under this session's CLI permissions (confirmed non-sensitive vars pull fine, so this is a permission gate, not empty config).
547547
- Repair: corrected `VCSConnectionCard.tsx`'s 40x hint — it no longer claims "the installation was removed, reinstalling will fix it" (unverifiable and, in this case, wrong). It now says a 40x means this connection's stored installation isn't one the CURRENT deployment's app can use, even if GitHub still shows an app installed, and suggests Disconnect (in Bitcode) + reconnect — which re-runs the install/authorize flow against whichever app this deployment is actually configured with (already shown as installed in GitHub's list) and writes a fresh installation id, with no GitHub-side action needed. Updated `uapi/tests/vcsConnectionCard.test.tsx` to match. Verified: `tsc --noEmit` 0; `vcsConnectionCard.test.tsx` 4/4 green.
548548
- Not yet done: confirming from the Supabase side which specific `connectionId`/app the existing stuck row actually points to (would need direct DB access, out of reach here) — Disconnect + reconnect is the actionable next step for the live account; if it does NOT resolve to Valid, the next lead is confirming this Preview deployment's actual `GITHUB_APP_ID`/`SUPABASE_URL` pairing against the documented map above.
549+
- **CONFIRMED (2026-07-08, live)**: disconnected via a direct `fetch(..., {method:'DELETE'})` from the browser console (the UI Disconnect button itself was blocked — see F36), then reconnected through Bitcode's normal Connect GitHub flow. Result: **Connected / Valid.** This confirms the diagnosis — the stuck row's installation id belonged to the OTHER Bitcode GitHub App; reconnecting against the currently-configured app resolved it, no GitHub-side action needed. `/deposits`' Branch/Commit reconnect-required banner (F32) should now be gone for this account too, since it shares the same `connectionStatus.valid` gate.
549550

550-
## Track 1 — Identity / Authentication / Auxillaries — COMPLETE 2026-06-12 (email deferred by decision; F2/F9 and legacy eradication queued for gates)
551+
### V48-Gate3-F36 — Refresh and Disconnect buttons on the GitHub connection card don't respond to clicks; the underlying API works fine (OPEN)
552+
553+
- Severity: medium (workaround exists — the same actions can be driven directly via `fetch()` from the console — but the UI affordances for two of the four card actions are dead).
554+
- Observed (2026-07-08, live): clicking **Disconnect** never opened its confirmation `AlertDialog` at all (confirmed explicitly — no dialog appeared). Clicking **Refresh** produced no visible change either. Both: no console errors, no Network tab entries for the click (not even a pending request), a brief whole-tab "hang" that self-resolves, then the page is normally responsive again. A hard reload did not change the behavior. Incognito (rules out an interfering browser extension) was not tested at the user's judgment call.
555+
- Ruled out during investigation: NOT a server/API problem — calling the exact same endpoint directly from the console (`fetch('/api/vcs/github/connection', {method:'DELETE'})`) succeeded instantly with a clean response. This isolates the bug to the click → handler path in the browser for these two specific buttons (both plain `<Button onClick=...>` and the `AlertDialogTrigger`-wrapped one), not to `handleRefresh`/`handleDisconnect`'s own logic or the route they call.
556+
- Investigated and NOT confirmed as the cause (documented so this isn't re-litigated): (a) Radix `AlertDialog` nested inside Auxillaries' own custom `createPortal`-based overlay — plausible stacking/portal interaction, but Auxillaries can also render as a dedicated non-modal route, unconfirmed which applies here; (b) neither the "Refresh" nor "Disconnect" `<Button>` sets an explicit `type="button"` (shadcn's `Button` does not default it, so a bare `<button>` inside a `<form>` defaults to `type="submit"`) — but no `<form>` ancestor was found in this card's actual render tree (`VCSIntegrationPanel` → `Tabs` → this card; the sibling "Personal Access Token" tab does have its own `<form>`, but as a sibling `TabsContent`, not an ancestor, so it shouldn't matter — worth setting `type="button"` explicitly anyway as a zero-risk hardening, defensive habit regardless of whether it's the cause here); (c) `AnalyticsEventsClient.tsx`'s global capture-phase `document.addEventListener('click', handler, true)` GA4 click tracker — a plausible collision point for a delegated capture-phase listener, but its own logic is a small bounded DOM walk + a defensively-wrapped no-op-when-unloaded `gtag()` call, nothing that should itself hang.
557+
- Next steps (not done — needs live repro access this session didn't have): reproduce with React DevTools Profiler recording to see if a render is actually happening during the "hang" window; check whether the same card, freshly mounted after a full reconnect-triggered page reload, still exhibits the same behavior (untested — the user's remaining verification was done via the direct-fetch workaround, not by retrying the buttons post-reconnect); check Chrome's Task Manager (Shift+Esc) for CPU during the hang to confirm/deny a compute-bound cause vs. something else entirely. — Identity / Authentication / Auxillaries — COMPLETE 2026-06-12 (email deferred by decision; F2/F9 and legacy eradication queued for gates)
551558

552559
- [x] Sign up / sign in via Connect Wallet (nav CTA → SignUpWindow → wallet signature on testnet4 → `custom:bitcode-bitcoin` session → `/tps/supabase/callback`) — verified 2026-06-12 after F5 fix; lands on `/packs`. Re-verified from fully nuked state (purged user + cleared site data): created 19:29:21 → session 19:29:25 → binding auto-written 19:29:29 by the bridge on `/packs` mount with no Auxillaries visit; UI consistent across nav, Wallet, and Profile panes.
553560
- [x] Wallet binding persisted after sign-in — verified 2026-06-12: identity-derived bind populated `username` (`wallet_tb1p6x70u8ag`) and the full `walletBinding` (address, provider `leather`, network `testnet`, status `pending`, `proofKind: provider_session`, `boundAt` stamped on bridge mount). `payment_address`/`addressType` stay null in identity-derived binds (GoTrue drops the custom claims); they backfill via the in-panel signature flow, which settlement-adjacent actions require anyway.

uapi/components/base/bitcode/vcs/VCSConnectionCard.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,15 @@ export function VCSConnectionCard({
263263
)}
264264

265265
<div className="flex gap-2">
266+
{/* V48-Gate3-F36: explicit type="button" — shadcn's Button doesn't
267+
default one, so a bare <button> falls back to the browser's
268+
native type="submit". No <form> ancestor was found for this
269+
card, so this shouldn't currently matter, but it's a
270+
zero-risk hardening against exactly that class of bug (a
271+
click "doing nothing"/submitting instead of firing onClick)
272+
regardless of whether it's the cause of the live hang. */}
266273
<Button
274+
type="button"
267275
variant="outline"
268276
size="sm"
269277
onClick={handleRefresh}
@@ -272,10 +280,11 @@ export function VCSConnectionCard({
272280
<RefreshCw className={`mr-2 h-4 w-4 ${isRefreshing ? 'animate-spin' : ''}`} />
273281
Refresh
274282
</Button>
275-
283+
276284
<AlertDialog>
277285
<AlertDialogTrigger asChild>
278286
<Button
287+
type="button"
279288
variant="outline"
280289
size="sm"
281290
disabled={isDisconnecting}

0 commit comments

Comments
 (0)