Skip to content

Commit c3e58aa

Browse files
wip v28
1 parent f56bd89 commit c3e58aa

42 files changed

Lines changed: 161 additions & 236 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

BITCODE_SPEC_V28_NOTES.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ Fresh-nuke onboarding then exposed a timing gap: Supabase Auth and the empty tri
7474

7575
Live staging OAuth also exposed two callback hardening requirements. First, the custom wallet authorize page must not rely on a single provider scan at first render because browser wallet extensions can inject provider globals after the route has already hydrated; `/tps/wallet/authorize` must retry discovery, expose an explicit rescan, and preserve the provider hint fallback so Leather/Xverse can still open even when the first scan is empty. Second, the Supabase callback exchange must be idempotent: if the first exchange succeeds and hydration recovery or remount tries to exchange the same code again after the PKCE verifier was consumed, the callback must prefer the already-established session over redirecting to a false login error. Staging URL configuration must also allow both `https://bitcode.exchange` and `https://www.bitcode.exchange` callback routes until a single canonical host redirect is enforced.
7676

77+
The same clean-deploy pass removed Auxillaries as a standalone page destination. Supabase and GitHub callbacks, retained `/auxillaries/*` compatibility paths, and retained `/orbitals/*` paths must land on `/terminal?auxillary-open-to=<pane>` so Auxillaries opens as the global overlay and never renders the retired late-Engi workspace page or left-sidebar navigation. The left execution sidebar and disabled AssetPacks tab are not part of the V28 website application surface; retained sidebar components may remain for future repurposing but must not be mounted by the active layout.
78+
7779
### Deterministic Model Boundary
7880

7981
V28 must remove the idea that a user can choose ledgerized Bitcode synthesis models.
@@ -248,8 +250,8 @@ The Profile onboarding order is now:
248250
Implementation must therefore keep wallet auth enabled and top-most in Wallet, avoid the Ethereum provider path for Bitcoin identity, persist wallet-provider binding only through the wallet-auth route when backend session state is available, keep Profile from accepting unverifiable provider-managed signer assertions, and surface staging prerequisites clearly.
249251
The live wallet selector must also be provider-explicit: the Wallet pane should disclose detected Bitcoin wallets and expose direct Xverse and Leather actions when both are installed. This avoids the observed QA failure where a silent or stalled Xverse handoff could make the single generic connect button appear inert while Leather was also available.
250252
Non-mock QA requires a browser with Xverse and/or Leather installed and unlocked for the first pass; Xverse should be tested first on Testnet4, then Leather on its documented testnet lane. If only MetaMask's injected Ethereum provider is available, Bitcode must not open an Ethereum account prompt and may only stage the displayed Bitcoin address manually until a Bitcoin provider API is available. The `user_connections` provider-constraint migration and GitHub OAuth or GitHub personal-access-token credentials remain required for backend persistence and the second step.
251-
The contained Auxillaries product routes are not the progressive onboarding wizard.
252-
Wallet connection inside `/auxillaries/wallet` must remain on Wallet, must not auto-advance to Externals, and must not call `/api/auxillaries/onboarding` when the route is being used as the commercial contained settings surface.
253+
The contained Auxillaries overlay is not the progressive onboarding wizard.
254+
Wallet connection inside `/terminal?auxillary-open-to=wallet` must remain on Wallet, must not auto-advance to Externals, and must not call `/api/auxillaries/onboarding` when the overlay is being used as the commercial contained settings surface.
253255
If Supabase staging credentials are missing or placeholder values, the wallet proof remains locally staged and the UI may show backend persistence pending, but the client must not emit noisy failed Supabase signup requests.
254256

255257
The May 9 follow-up QA tightened the connected-wallet chrome and ownership boundaries.
@@ -266,7 +268,7 @@ The provider authorization page is `/tps/wallet/authorize`; it detects Bitcoin-c
266268
The machine endpoints are `/api/wallet/oauth/token` and `/api/wallet/oauth/userinfo`.
267269
Token exchange validates the configured OAuth client secret, allowed Supabase callback origin, and PKCE challenge when present.
268270
UserInfo returns a stable Bitcoin subject and wallet claims (`bitcoin_address`, provider, network, auth/payment address, proof kind) with email optional.
269-
After Supabase creates the session, Profile synchronizes the captured local wallet proof into `/api/wallet/authenticate` so the Supabase data realm can project wallet identity from the ledger-facing signed proof.
271+
After Supabase creates the session, the global wallet session bridge synchronizes the captured local wallet proof into `/api/wallet/authenticate` so the Supabase data realm can project wallet identity from the ledger-facing signed proof even when the callback lands on Terminal.
270272
Sign-out clears both the Supabase auth session and the local staged wallet identity.
271273

272274
The May 13 Leather documentation ingestion formalizes Leather as a tested first-class V28 wallet adapter.

BITCODE_V28_QA.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,17 @@ For every staging-testnet pass, paste back:
161161

162162
### Live Staging Host And Callback Checks
163163

164-
For wallet onboarding on the deployed staging-testnet host, Supabase Auth must accept both hostnames until Bitcode enforces one canonical host:
164+
For wallet onboarding on the deployed staging-testnet host, Supabase Auth must accept both callback hostnames until Bitcode enforces one canonical host:
165165

166166
- `https://bitcode.exchange/tps/supabase/callback`
167167
- `https://www.bitcode.exchange/tps/supabase/callback`
168-
- `https://bitcode.exchange/auxillaries/wallet`
169-
- `https://www.bitcode.exchange/auxillaries/wallet`
168+
169+
The app-internal `next` target after the callback must be `/terminal?auxillary-open-to=wallet`.
170+
Auxillaries must never arrive as `/auxillaries/<pane>` in the active product. Retained `/auxillaries/*` and `/orbitals/*` paths are compatibility redirects into `/terminal?auxillary-open-to=<pane>`.
170171

171172
When Wallet opens `/tps/wallet/authorize`, the page should show Leather and Xverse if both extensions are installed and unlocked. If it initially says no provider was detected, wait a few seconds or click `Rescan wallets`; provider injection after hydration is a V28-observed browser-extension timing behavior. The fallback button may still open the hinted provider, but the expected MVP state is explicit Leather/Xverse choices plus a working fallback.
172173

173-
After signing, a transient root URL containing `loginError=server_error` and `both auth code and code verifier should be non-empty` is a callback idempotency failure if the session nevertheless exists. V28 expects the callback to treat an already-established Supabase session as success and continue to Wallet without showing a false login error.
174+
After signing, a transient root URL containing `loginError=server_error` and `both auth code and code verifier should be non-empty` is a callback idempotency failure if the session nevertheless exists. V28 expects the callback to treat an already-established Supabase session as success and continue to `/terminal?auxillary-open-to=wallet` without showing a false login error.
174175

175176
### Supabase SQL Checks
176177

@@ -365,7 +366,7 @@ V28 distinction for this pass:
365366
| Finding type | V28 action |
366367
| --- | --- |
367368
| A visible `Connect Wallet` control opens an account/access pane but does not invoke a wallet extension or clearly say wallet-extension signing is staged. | V28 MVP bug: label/copy/action mismatch must be fixed before continuing deeper QA. |
368-
| A wallet extension prompt appears and connection succeeds, but BTC/BTD/top-chrome/Auxillaries/Profile/Wallet panes do not reflect the connected address or readiness. | V28 MVP bug: connected identity and readiness state are not coherent. |
369+
| A wallet extension prompt appears and connection succeeds, but BTC/BTD/top-chrome/Auxillaries Wallet does not reflect the connected address or readiness. | V28 MVP bug: connected identity and readiness state are not coherent. |
369370
| A wallet extension prompt appears but fails because testnet provider/network/permission is absent, while the app reports the blocker clearly and remains usable. | Acceptable V28 blocked-readiness outcome; V29/V34 may deepen live wallet and deployment operations. |
370371
| Source truth confirms wallet-provider signing is intentionally staged and only manual wallet identity is active. | V28 must make that explicit wherever `Connect Wallet` appears; actual extension integration becomes a near-term V29/V34-boundary requirement unless the user elevates it into V28. |
371372

@@ -464,18 +465,18 @@ Non-mock prerequisites for the next QA3.1 pass:
464465
- GitHub OAuth callback configured for the staging origin, or a GitHub personal access token available for the VCS panel fallback.
465466
- Public mock flags disabled for the non-mock lane.
466467

467-
QA3.1 Profile onboarding script:
468+
QA3.1 prerequisite onboarding script:
468469

469470
| Lane | Step | Manual action | Expected V28 observation |
470471
| --- | --- | --- | --- |
471-
| Mock | 1 | Open `/terminal`, then open Auxillaries and select Profile. | The contained Auxillaries shell opens with the same selector order and visual language as non-mock. Profile shows Bitcoin wallet identity first, GitHub second, optional email third. Mock fields may already be populated, but the order must remain visible. |
472-
| Mock | 2 | Scroll Profile from first open without switching panes first. | The right pane scrolls immediately, no first-render scroll dead zone appears, and no visible Save/Continue controls are required for auxillary edits. |
472+
| Mock | 1 | Open `/terminal`, then open Auxillaries and select Wallet. | The contained Auxillaries shell opens with the same selector order and visual language as non-mock. Wallet owns Bitcoin wallet identity, Externals owns GitHub, and Profile owns optional email/account metadata. Mock fields may already be populated, but the order must remain visible. |
473+
| Mock | 2 | Scroll Wallet/Profile from first open without switching panes first. | The right pane scrolls immediately, no first-render scroll dead zone appears, and no visible Save/Continue controls are required for auxillary edits. |
473474
| Mock | 3 | Confirm Wallet pane and top chrome remain hydrated. | BTC/BTD values show the mock wallet posture after the loading state, BTD activity is visible through the shared Terminal/Protocol table grammar, and no console errors appear. |
474-
| Non-mock | 1 | Open `/terminal` on the staging/testnet lane with mock flags disabled. | Top chrome is anonymous until a wallet session exists. `Connect Wallet` or Auxillaries/Profile opens the contained Auxillaries shell, not the retired onboarding shell. |
475-
| Non-mock | 2 | In Profile with Xverse and Leather unlocked on Testnet4, confirm the provider status line says `Detected Xverse, Leather` or accurately names the installed Bitcoin wallets. Click `Connect Xverse` first. | Xverse/Sats Connect requests wallet connection for payment plus ordinals addresses and then requests a BIP322 message proof. The app must not ask for email first and must not open an Ethereum account prompt. If no prompt appears, capture the exact provider status line and inline message, then click `Rescan wallets`. |
475+
| Non-mock | 1 | Open `/terminal` on the staging/testnet lane with mock flags disabled. | Top chrome is anonymous until a wallet session exists. `Connect Wallet` or Auxillaries opens the contained Auxillaries overlay on Wallet, not the retired direct-route shell. |
476+
| Non-mock | 2 | In Wallet with Xverse and Leather unlocked on Testnet4, confirm the provider status line says `Detected Xverse, Leather` or accurately names the installed Bitcoin wallets. Click `Connect Xverse` first. | Xverse/Sats Connect requests wallet connection for payment plus ordinals addresses and then requests a BIP322 message proof. The app must not ask for email first and must not open an Ethereum account prompt. If no prompt appears, capture the exact provider status line and inline message, then click `Rescan wallets`. |
476477
| Non-mock | 3 | Approve the Xverse connection and proof. | The Wallet state becomes connected, the Taproot/ordinals auth address appears in the wallet field when available, refresh preserves website-side wallet state, and the console remains free of product errors. If backend persistence is unavailable, the UI should say server persistence is pending while local staging remains visible. Capture the exact inline message and Network response for `/api/wallet/authenticate` when a backend request occurs. |
477-
| Non-mock | 4 | Return to Profile and click `Connect Leather` directly. Do this even if Xverse is installed so the Leather path is verified independently. | Leather returns addresses through `getAddresses`, Bitcode selects the BTC Taproot address when present without relying on array indexes, signs with `signMessage`, and stores the Native SegWit payment address separately from the auth address. |
478-
| Non-mock | 5 | If only MetaMask BTC is available, paste the displayed `bc1...`/`tb1...` address and click `Stage Bitcoin address`. | No Ethereum prompt opens. Profile shows locally staged Bitcoin identity and clearly marks backend/provider proof as pending/manual. |
478+
| Non-mock | 4 | Return to Wallet and click `Connect Leather` directly. Do this even if Xverse is installed so the Leather path is verified independently. | Leather returns addresses through `getAddresses`, Bitcode selects the BTC Taproot address when present without relying on array indexes, signs with `signMessage`, and stores the Native SegWit payment address separately from the auth address. |
479+
| Non-mock | 5 | If only MetaMask BTC is available, paste the displayed `bc1...`/`tb1...` address in Wallet and click `Stage Bitcoin address`. | No Ethereum prompt opens. Wallet shows locally staged Bitcoin identity and clearly marks backend/provider proof as pending/manual. |
479480
| Non-mock | 6 | Connect GitHub from Externals using OAuth or the staging token fallback. | GitHub becomes connected for Give/Need readiness. Terminal read-only orientation must not be blocked by GitHub, but Terminal Give/Need actions should reflect repository scope once connected. |
480481
| Non-mock | 7 | Optionally add email from Profile. | Email is presented only as notifications/updates/recovery posture. It must not replace wallet authentication, and the user can leave it blank without breaking wallet, GitHub, or Terminal readiness. |
481482

@@ -874,6 +875,7 @@ Deployment judgment:
874875
- The matching Bitcode application projection exists in `public.user_profiles` under `settings.bitcodeProfile.walletBinding`, with the same user UUID as `auth.users.id`, and `public.user_connections` has a matching `provider='leather'` wallet row.
875876
- The saved `v28_qa_03_user_profiles_wallet_binding` query was corrected to read wallet binding from JSON settings rather than nonexistent flat `wallet_address`, `wallet_provider`, and `wallet_binding_status` columns.
876877
- Fresh staging nuke/re-onboarding showed the intended first two Auth rows immediately but left `user_profiles.settings` empty until the app replayed the signed wallet proof from local storage. V28 now treats this as a first-run integrity gap: any active route must persist the signed local wallet proof once a Supabase session exists, so a callback-to-root landing still converges on `settings.bitcodeProfile.walletBinding` and `user_connections` before GitHub onboarding.
878+
- The next clean deploy showed correct wallet-provider discovery and data projection, but the callback still targeted `/auxillaries/wallet`. V28 now requires the callback `next` target and compatibility routes to use `/terminal?auxillary-open-to=wallet`; `/auxillaries/*` must only redirect and must never render the retired direct-route page, old Terminal navigation, or disabled AssetPacks sidebar tab.
877879
878880
## Issue Template
879881

supabase/config.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ enabled = true
4545
site_url = "https://bitcode.exchange"
4646
additional_redirect_urls = [
4747
"https://bitcode.exchange/tps/supabase/callback",
48-
"https://bitcode.exchange/auxillaries/wallet",
4948
"https://www.bitcode.exchange/tps/supabase/callback",
50-
"https://www.bitcode.exchange/auxillaries/wallet",
5149
"http://localhost:3000/tps/supabase/callback",
5250
"http://localhost:3001/tps/supabase/callback",
5351
]

uapi/app/(root)/components/MarketingSetupForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ const MarketingSetupForm = () => {
1313
</p>
1414
</div>
1515
<div className="space-y-2 text-sm text-slate-300">
16-
<p>1. Connect wallet posture in /auxillaries/profile and keep BTC fee liquidity readable.</p>
17-
<p>2. Connect GitHub and SSO policy in /auxillaries/externals.</p>
16+
<p>1. Connect wallet posture in the Wallet auxillary and keep BTC fee liquidity readable.</p>
17+
<p>2. Connect GitHub and SSO policy in the Externals auxillary.</p>
1818
<p>3. Acquire $BTD through Terminal Need minting or Exchange purchase planning.</p>
1919
</div>
2020
<div className="rounded-xl border border-emerald-400/20 bg-emerald-400/8 px-4 py-3 text-sm text-emerald-100">

uapi/app/ClientLayoutInner.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,10 @@ const prefetchHeavyComponents = () => {
6161
}
6262
}, 2000);
6363

64-
// Prefetch sidebars after 3 seconds
64+
// Prefetch the retained Conversations sidebar after 3 seconds.
6565
setTimeout(() => {
6666
if (!window.__sidebarsPrefetched) {
6767
window.__sidebarsPrefetched = true;
68-
import('@/components/base/bitcode/layout/sidebars/left-sidebar').catch(() => {});
6968
import('@/components/base/bitcode/layout/sidebars/right-sidebar').catch(() => {});
7069
}
7170
}, 3000);
@@ -79,11 +78,6 @@ declare global {
7978
}
8079
}
8180

82-
// Dynamically import sidebar components with lazy loading
83-
const LeftSidebar = dynamic(
84-
() => import('@/components/base/bitcode/layout/sidebars/left-sidebar'),
85-
{ ssr: false, loading: () => null }
86-
)
8781
const RightSidebar = dynamic(
8882
() => import('@/components/base/bitcode/layout/sidebars/right-sidebar'),
8983
{ ssr: false, loading: () => null }
@@ -235,11 +229,8 @@ export default function ClientLayoutInner({ children }: { children: ReactNode })
235229
<PageContent>{children}</PageContent>
236230
{pathname !== '/' && !hideFooter && <Footer />}
237231
<React.Suspense fallback={null}>
238-
{/* Sidebars on desktop (md+): left runs/items and right Conversations chat */}
232+
{/* Desktop supporting overlays. Auxillaries stays portal-only for V28. */}
239233
<div className="hidden laptop:block">
240-
{authLoaded && user && !mockMode && FEATURE_FLAGS.SIDEBAR_LEFT && (
241-
<LeftSidebar />
242-
)}
243234
{authLoaded && user && !mockMode && pathname !== '/terminal' && pathname !== '/conversations' && isOnboardingComplete && FEATURE_FLAGS.CONVERSATIONS_WIDGET && (
244235
<>
245236
<Conversation

0 commit comments

Comments
 (0)