Skip to content

Reuse Builderlab Settings login for embedded app viewers - #1594

Merged
nathan-thillairajah merged 17 commits into
mainfrom
codex/bbpublic-viewer-handoff
Oct 29, 2026
Merged

nathan-thillairajah merged 17 commits into
mainfrom
codex/bbpublic-viewer-handoff

Conversation

@nathan-thillairajah

@nathan-thillairajah nathan-thillairajah commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Buzz Settings already has a Builderlab login, while embedded apps require a viewer session. On macOS, exchange the CLI credential only with the configured canonical API and install the restricted HttpOnly/Secure viewer cookie before opening the guest. The credential never appears in a URL or reaches app code.

Keep browser login available when Settings login is unavailable, the target belongs to another tenant, or native exchange is unconfigured or returns 404. Other-tenant apps use the existing browser store without receiving the Settings credential. Authentication, ACL and transport failures from native exchange stay closed. Settings-backed guests stay blank until their account lifetime is checked; logout and account changes retire their live and parked guests. Closing a panel hides its guest immediately even while another app's exchange is pending, and re-adoption waits for that hide to finish.

Pair the login origin and exact Apps domain through trusted build configuration. The service prerequisites are the session schema, parent-bound viewer lifecycle and native exchange; native SSO becomes available after that service supports it. Existing consent requirements still apply. No backend activation or deployment is included.

After integrating main, all five Rust build-configuration tests, the Vite configuration test, and 14 Chromium/WebKit Apps-panel cases pass. Independent source review found no blockers, and normal commit/push hooks passed, including TypeScript, related unit tests, design checks and Clippy. Browser journeys substitute native I/O. Packaged native SSO and human acceptance remain pending; the author explicitly allowed review readiness before those checks. No acceptance attestation is claimed.

nathan-thillairajah and others added 8 commits October 23, 2026 16:22
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
@nathan-thillairajah
nathan-thillairajah marked this pull request as ready for review October 26, 2026 14:59
@nathan-thillairajah
nathan-thillairajah requested review from a team as code owners October 26, 2026 14:59

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source review via Wes’s account, integrating Rocket, Mantis and Groot.

Two changes requested: preserve app opening when native exchange is disabled (inline), and address the public-material issue below.

  • [P2] Remove internal deployment/coordination details from public material. The description’s “Review order” links point to a private service repository (visibility verified). Replace them with a public dependency/rollout summary. Newly added tenant maps in src-tauri/src/browser/builderlab.rs:26–27 and src/bundled/builderlab/apps/environment.ts:65–66, plus new test literals, also repeat employee/staging deployment hostnames. Supply those mappings through trusted build configuration and use generic test domains, preserving exact native tenant/host validation.

Optional: per-login persistent stores become unreachable when the login ends; view teardown does not erase them. Consider bounded cleanup separately. The tenant-mismatch state could offer an external-open action, and “Each sign-in” would describe panel-initiated login more accurately than “Each Settings sign-in.”

Head 6a79d38fd3991a8a1d834007f54c9a62a5764846; base c40dfdf4c81aabe759f3a4329c3e77f854746a59. Source-only: no tests or app execution. Packaged native SSO, server enforcement and rendered/focus behavior remain unverified; the one CI snapshot still had running browser jobs. The documented native-acceptance waiver is respected.

});
return createElement(View, {
url: target,
builderlab: session.viewerSession(),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [P2] Preserve app opening while native exchange is unavailable

This always passes the viewer credential, so browser_attach must complete builderlab::prepare before creating a guest. A 404 from the documented default-off endpoint returns “viewer sign-in is not enabled yet”; the host displays the error and Reload repeats the same attach. The base opened a guest that could perform browser login, so installing this client before server enablement removes that working path.

Gate native SSO until the capability is available, or handle a typed feature-unavailable response with an account-isolated browser-login fallback. Keep auth/ACL denials closed. Add coverage showing that an exchange-disabled installation can still open an app.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket, Mantis and Groot. One P2 remains inline: builds without a Settings login URL cannot reach browser login; source assessment 8/10 until that fallback works. The previous 404-path and public-material findings are addressed for configured-login builds.

Head b06251497a661b7eea8200a2de4e8b02f6dd9807; base c40dfdf4c81aabe759f3a4329c3e77f854746a59. Source-only, no tests/app execution; packaged native SSO and human acceptance remain pending, and the single CI snapshot shows WebKit 1/12 and CI required failing (cause unverified).

Comment thread src/bundled/builderlab/apps/index.ts Outdated
"This app uses a different Builderlab environment than this Buzz build.",
});
if (state.status !== "signed-in")
return createElement(Login, {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [P2] Reach browser login when Settings login is unconfigured

With BUZZ_BUILDERLAB_URL unset/empty (the documented default for local builds), applyApps still registers this panel and viewerAppDomain() skips the tenant gate, but this branch demands a Settings session. Clicking Sign in calls oauthTarget(), which always throws because no URL is configured, so the new native fallback is never reached. The base opened the browser view directly and let the app perform its own login.

Pass the Settings-login availability into this panel and preserve a credential-free browser-login path when it is unavailable, while retaining the existing account-lifetime checks whenever a Settings session is used. Add a case with the login URL unset; the new unconfigured-exchange test supplies a login URL and signs in first, so it misses this path.

Co-authored-by: nthilly_hosted <noreply@buzz.local>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>

Copy link
Copy Markdown
Contributor Author

Thanks @wesbillman. Pushed 4dfe3a5f3 for the remaining P2 ("Reach browser login when Settings login is unconfigured").

  • applyApps now takes loginAvailable (browserLoginAvailable() && !unavailable, the same value the Settings card uses). When false, the App panel opens the app credential-free under the original builderlab-apps storage, so the app's own browser login is reachable as on the base. When true, the Settings sign-in and account-lifetime checks are unchanged.
  • Added a case with the login URL and apps domain unset: no sign-in prompt, no credential/viewer session passed, login never started.
  • Locally: tsc and the builderlab Vitest suite pass. Browser journeys and Rust tests were not run locally.

The previous run's only failure was agent-search-chat.spec.mjs ("search opens a new Solo chat…") on WebKit 1/12: the "Owned Honey" agent result did not render within 10s. That spec and the search UI are not touched by this PR, and it passed on the run before. Waiting on the run for this head to confirm.

Not addressed (optional items): bounded cleanup of per-login stores, an external-open action for the tenant-mismatch state, and the "Each sign-in" wording.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket, Mantis and Groot. No further changes requested: the previous unconfigured-login P2 is repaired by restoring credential-free browser login when Settings login is unavailable; configured account-lifetime handling remains intact.

Head 4dfe3a5f39324ace4a9475600f2ca9bc11d0e3ba; base c40dfdf4c81aabe759f3a4329c3e77f854746a59. Reviewed the five-file follow-up and affected callers. Source-only: no tests or app execution, and CI was not assessed; packaged native SSO, rendered focus behavior and human acceptance remain unverified.

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Two remaining regressions: slow authenticated attaches delay hiding closed guests, and other-tenant app links end in an actionless panel. The previously reported 404 and unconfigured-login fallbacks are repaired.

}
while (this.live.length >= MAX_GUESTS) await this.close(this.victim());
const sessionId = await this.platform.attach(url, bounds, storage);
const sessionId = await this.platform.attach(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [P2] Hide closed guests without waiting for another app’s exchange

Open app A, start opening app B while its authenticated attach is pending, then return to A and close its tab. This queue holds A’s detach/hide behind B’s platform.attach, which now includes the native network exchange (15-second deadline plus up to five seconds for cookie installation). A’s DOM disappears while its native child retains its previous visible bounds.

Reproduced in the actual app in Chromium and WebKit with modeled native IPC: after closing A, the production platform boundary recorded {guestStillOwned:true,lastPresentation:true,detached:false} until B’s attach was released. Native pixels were not rendered. Sign-out bypasses this queue, but ordinary tab close does not.

Hide on unmount outside the slow attach queue while preserving ownership/adoption guards, or move exchange outside the queue. Add a regression asserting A is hidden before B’s pending attach resolves.

Comment thread src/bundled/builderlab/apps/index.ts Outdated
storage: "builderlab-apps",
label: appName(target),
});
if (viewerAppDomain() && !isViewerTarget(target))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [P2] Preserve a usable path for other-tenant app links

With Settings login and an Apps domain configured, matches still claims links to other supported app tenants, but this branch replaces the app with an actionless “Open this app with its Builderlab environment” state. The base opened these links in the shared browser store so the destination could perform its own login. The current actual-app harness also confirms rejection before native IPC.

The earlier review mentioned an external-open action as optional; the additional regression is that previously usable links are intercepted with no route forward. Preserve the credential-free View used for unavailable Settings login, or decline these targets in matches so ordinary link handling can open them. Neither path should forward the Settings credential to another tenant.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket, Mantis and Groot. The previous delayed-hide and other-tenant-login P2s are repaired; one low-priority cleanup regression remains inline.

Head 4e13a8a36fb9fb8ffcb3bbb60fdcd8c76829275f; base c40dfdf4c81aabe759f3a4329c3e77f854746a59. Reviewed the four-file follow-up and affected callers. Source-only: no tests, app execution or CI assessment; packaged native SSO, rendered focus and human acceptance remain unverified. The author’s readiness waiver is preserved.

Comment thread src/features/browser/sessions.ts Resolved
A detach whose native hide rejected stopped before close ran, so the guest
stayed live or visible until eviction. Close it in that case, for both
plain and parked detaches, while the hide error still reaches the caller.

Signed-off-by: Bill Gao <bgao@squareup.com>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket, Mantis and Groot. No further changes requested: the previous hide-failure cleanup P3 is repaired for both parked and non-parked guests, preserving error propagation and re-adoption ordering.

Head f2a7213f01da334852c914731a3f6e90a3a1b942; base c40dfdf4c81aabe759f3a4329c3e77f854746a59. Reviewed the two-file follow-up and affected callers. Source-only: no tests, app execution or CI assessment; packaged native SSO, rendered focus and human acceptance remain unverified. The author’s readiness waiver is preserved.

Signed-off-by: Bill Gao <bgao@squareup.com>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket, Mantis and Groot. No further changes requested: the merge preserves the prior login-fallback and guest-cleanup fixes, and the broader app-link matcher retains the exact-tenant credential boundary.

Head 3e70dcd6492906786d5dbb6a35fb1e8b99c5032f; base 11dd17bb7775a2932ca2466235354105edf2041b. Reviewed merge integration and affected callers. Source-only: no tests, app execution or CI assessment; packaged native SSO, rendered focus and human acceptance remain unverified. The author’s readiness waiver is preserved.

Keep main's production Builderlab default and explicit opt-out alongside the viewer's trusted Apps-domain mapping. Retain both configuration regression suites and assert the paired default/disabled behavior.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket, Mantis and Groot. No further changes requested: the merge preserves the production default, explicit disable option, exact-tenant credential boundary and prior browser-login/guest-cleanup fixes. Both configuration regression suites remain intact.

Head 70981fddcab0697e706466ea63c0c019142f6640; base a65463acb6b1a5b6b2e1727a223becdfd7f67f3d. Reviewed merge integration and affected callers. Source-only: no tests, app execution or CI assessment; packaged native SSO, rendered focus and human acceptance remain unverified. The author’s readiness waiver is preserved.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>

@kazemek21 kazemek21 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kyle reviewed this PR and the Nexus review-tracker notes and approved with the non-blocking comment below.

Posted by Codex (gpt-6.1-sol) on behalf of kylez

// A lost auth/consent page must bootstrap again from the app, never replay its one-use ticket.
if (
next.url &&
(!builderlab || new URL(next.url).origin === new URL(url).origin)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve ordinary app destinations when restoring an evicted guest

This guard also excludes navigation from one app to another app in the same tenant. After this tab is evicted from the four-guest pool, reopening it therefore returns to the original app rather than the destination the user was viewing. Could we retain safe app destinations while continuing to exclude temporary login/consent URLs?

Posted by Codex (gpt-6.1-sol) on behalf of kylez

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket, Mantis and Groot. No further changes requested: the login inset uses the shared panel spacing token while preserving cancellation, retry, tenant isolation and unpadded browser content.

Head 00c8ef542f5646c8148ae5b325c5a11434f0e84f; base a65463acb6b1a5b6b2e1727a223becdfd7f67f3d. Reviewed the one-file follow-up and affected callers. Source-only: no tests or app execution; rendered layout/focus, packaged native SSO and human acceptance remain unverified. The author’s readiness waiver is preserved; the single CI snapshot still had running browser jobs.

nathan-thillairajah and others added 2 commits October 29, 2026 13:31
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Nathan Thillairajah <nthillairajah@squareup.com>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket, Mantis and Groot. No further changes requested: eviction now restores the last approved app destination while excluding temporary login/consent URLs and retaining native tenant and account-lifetime checks.

Head 3567a53e583459beeb402d6994a69701396e986b; base a65463acb6b1a5b6b2e1727a223becdfd7f67f3d. Reviewed the five-file follow-up and affected callers. Source-only: no tests, app execution or CI assessment; packaged native SSO, rendered focus, performance and human acceptance remain unverified. The author’s readiness waiver is preserved.

@nathan-thillairajah
nathan-thillairajah merged commit 1c39857 into main Oct 29, 2026
71 of 73 checks passed
@nathan-thillairajah
nathan-thillairajah deleted the codex/bbpublic-viewer-handoff branch October 29, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants