Repository navigation
feat(plugins): sign builderlab in through the native fi session in fi builds - #1461
Conversation
The fixture still imported the plugin Login and session modules after they moved to #1461, so the documented manual UI check no longer loaded. Storage failure now keeps the sign-in prompt so its recovery message is visible. Co-authored-by: Will Pfleger <[email protected]> Signed-off-by: Will Pfleger <[email protected]>
5aa02fa to
5b8e3da
Compare
784b650 to
dac3daa
Compare
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Source-only review found four P2 account/persistence/login defects and one P3 registration-recovery defect. No runtime validation was performed.
e4d2228 to
c228932
Compare
eedf236 to
7f13560
Compare
53c4034 to
8f47505
Compare
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Two P3 findings from source review; runtime validation was not performed.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account, with independent Rocket, Mantis and Groot coverage.
Reviewed head 8f4750547522ebe94bc086c76a38df6a3e6d0072 against base 8fdb02df62398c0fa4c8769507444f22df86a2c7 (merge-base 110a59145f826a6e157c12d76ec91b97f7a39d61). Findings are non-blocking review comments; this is not an approval.
Product findings are inline. Separately, [P2] Remove internal coordination details from the public PR description. The Backend paragraph includes three links to a private repository's implementation PRs. The destination repository is confirmed private. Replace these with a self-contained description of the required backend capabilities; keep private implementation tracking in the internal discussion. This is a public-material finding, not evidence of a leaked credential. No description images were attached.
Validation: source analysis only; no PR code, tests, builds or app workflows were executed. A single hosted-check snapshot showed CI required successful; Windows validation and browser flake checks were skipped. Live FI/backend interoperability, OS secure storage, account-switch timing, rendered keyboard/screen-reader behavior and performance remain unverified. The PR explicitly identifies backend prerequisites for the Apps viewer and automatic backup; their availability was not established by this review.
… builds an fi build (BUZZ_BUILD_FEDERATED_IDENTITY_CONFIG set) now signs the builderlab plugin in through the native nip-fi session instead of its in-memory oauth credential. the token stays in os secure storage and the session restores after restart; builds without fi keep the legacy oauth path unchanged. - plugin-manager grants builderlab a host.federatedIdentity grant of exact routes and no network origins or files in fi builds; BUZZ_BUILDERLAB_URL must be empty alongside fi - native federated_identity_request forwards granted routes with the session as a bearer token, fenced to the caller's live registration and the session revision the call started under; plugin change, reload and recover retire registrations and the service registers again once - registrations are cached by the calling plugin's fiber: each this.ctx access is a new object, so the previous context key never hit - builderlab consumers take a BuilderlabSession: the legacy oauth session or a native session that reads the account from v1/auth/me once per revision - the apps viewer and nsec backup hand native the public session revision; native resolves the token and exchanges or uploads with bearer - vite derives VITE_BUZZ_BUILDERLAB_URL from the fi descriptor so persisted adapter identities and registration keys keep their scope - apps agent tools stay on the legacy login and are absent in fi builds Signed-off-by: Kalvin Chau <[email protected]> Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> Co-authored-by: Hayt <211b96e6a2b7f45fd4047988976c7bbbeeda0c15f3ae7b32eec20834b5a55118@buzz.block.builderlab.xyz> Co-authored-by: Will Pfleger <[email protected]> Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <[email protected]>
- a granted fi request that answers 401 asks the adapter's `get /v1/session` once; only a refused session ends, as reauthentication-required. the caller still gets its own 401 - builderlab's native session shows that end as signed out with a sign-in prompt - fi builds drop builderlab's sign out: the login links to identity → organization sign-in, which ends the shared session Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Kalvin Chau <[email protected]>
fi builds have no builderlab sign-in of their own, so a stale fi revision or a 401 from the viewer exchange now names settings -> identity -> organization sign-in. legacy credential errors keep the builderlab settings destination. Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Kalvin Chau <[email protected]>
- ensuresignedin settles when the native sign-in attempt finishes, so an unchanged unavailable or unconfigured snapshot no longer leaves callers waiting - an expired fi viewer cookie points to identity -> organization sign-in - the bundled builderlab grant test asserts the federated grant and no file or network access in fi builds - the backup handoff test separates a refused hosted fi handoff from the foreign-source no-op, and pins that a backup root other than the fi identity root never stores a federated session Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Kalvin Chau <[email protected]>
8f47505 to
63bc021
Compare
- a registration native retires while federated_identity_register is pending now registers again once, like one retired after admission - a disposed fiber still rejects without a retry Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Kalvin Chau <[email protected]>
- a backup pass stops as signed out before the mapping read and the upload once native retires its fi revision, without waiting for the renderer handoff - the fixture can hold any route, to sign out mid-pass Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Kalvin Chau <[email protected]>
…ellable - the native session marks restore and account reads as checking; login and creation show a busy check instead of browser instructions and cancel - a successful fi retry moves focus to the identity link only when the retry button still had it Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Kalvin Chau <[email protected]>
|
🤖 Addressed the public-material finding: the description no longer links private backend PRs. It now states the backend capabilities this PR requires, notes that FI builds don't offer Builderlab decisions, and its Validation section is updated for f4eaf79. |
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source follow-up via Wes’s account, with independent Rocket, Mantis and Groot coverage.
Reviewed head f4eaf7991b15ea3b87bb48951d8a7ddfb2bfd0bb against base 89e2d157ed99b8797da65fca71c1785d40079b6b, comparing the previous review at 8f4750547522ebe94bc086c76a38df6a3e6d0072 through endpoint and range diffs.
No new actionable findings. The earlier backup revision fence, checking-versus-browser-sign-in state, and successful retry focus findings are addressed in source. The public description also removes the private backend coordination links. Registration-admission retirement now participates in the bounded retry while retaining the initiating session revision; the FI Decisions integration remains disabled as documented.
Validation: source analysis only. No tests, builds, app workflows or live adapter/backend operations were executed, and hosted CI was not assessed in this pass. The author's reported test results are not independent verification by this review. Native storage and backend interoperability, rendered keyboard/screen-reader behavior and performance remain unverified; the separately discussed FI-descriptor CI coverage follow-up remains outside this change. Cordis behavior when registration admission rejects after fiber disposal was not independently established; no concrete additional defect was demonstrated. No images are attached to the current description. This COMMENT is not an approval or merge authorization.
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 One lifecycle regression remains in registration retry; details inline. Native storage and live backend interoperability remain unverified.
- the registration disposal effect is installed before native admission, so a retry from a disposed fiber throws before any second register call and no registration is left without cleanup Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Kalvin Chau <[email protected]>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source follow-up via Wes’s account, with independent Rocket, Mantis and Groot coverage.
Reviewed head 52fd0acf2b7909b675f3537677ac4f8d0ba4794f against base 89e2d157ed99b8797da65fca71c1785d40079b6b, focusing on the two-file delta since f4eaf7991b15ea3b87bb48951d8a7ddfb2bfd0bb.
No new actionable findings. Installing the cleanup effect before native registration addresses the disposal/admission retry defect reported in comment 4428194332: disposed or unloading fibers fail before a second registration is allocated. The new deferred-admission test covers this ordering, and live-fiber retry remains bounded to one attempt under the initiating session revision. This is the dependency boundary our preceding review explicitly left unverified; the current source trace includes Cordis’s inactive-effect guard and native registration removal.
Validation: source analysis only; no tests, builds, app workflows or live adapter/backend operations were executed, and CI was not assessed. The inspected local Cordis source reports version 4.0.2, matching the lockfile, but its package integrity was not independently verified. Native IPC timing, storage/backend interoperability, rendered focus/accessibility and performance remain unverified. The public description and commit text were inspected; no description images are attached. This is a follow-up review, not a fresh whole-feature certification, approval or merge authorization.
| } catch (error) { | ||
| // Native retires registrations around every plugin lifecycle change, | ||
| // even a refused one or one still being admitted. Register again | ||
| // once; admission rechecks the artifact and grant. A disposed fiber |
There was a problem hiding this comment.
🤖 [P3] Align the retry comment with the disposal guard
This comment says a disposed fiber cannot be retried, but the new rejection-after-unload test exercises exactly that path: native admission rejects with the string Plugin registration retired, the catch retries, and registration() then stops admission when ctx.effect throws on the inactive context. The ordering comment below describes the actual safeguard. Update this comment to distinguish late fulfillment (Error, no retry) from late retirement rejection (retry stopped by the effect guard), so future changes preserve the lifecycle invariant that prevents the second registration.
Preserve the shared FI session in the new account recovery UI and test the FI build path in native CI. Co-authored-by: Sarnow <1894dcbafaa4df1ac607a9bf879ac0b7d77fbccb0e0f4619ecc252c8adbad8a2@buzz.block.builderlab.xyz> Signed-off-by: Brad Seiler <[email protected]>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source follow-up via Wes’s account, integrating independent Rocket, Mantis and Groot coverage.
Reviewed head 28a7ba42300fe9d15939a94dc14de28979b71d35 against base b5747efe32a7fc6df97714f8dd70dfe9a9fff907, following the earlier review at 52fd0acf2b7909b675f3537677ac4f8d0ba4794f.
No new actionable findings in the merge integration. The eight preceding feature patches are unchanged; the merge connects the upstream account-recovery sheet to Identity without ending the shared FI session, preserves the non-cancellable checking state, and adds FI-descriptor build/grant coverage. Reviewed the affected callers, session boundaries, source tests and host-owned focus recovery. The new CI assertions cover selected grants; they do not prove exhaustive client/route equivalence.
Validation is source-only: no tests, builds, app or live adapter/backend workflows were executed by this review. One snapshot of CI run 41137944771 (bound to this head; PR CI uses a synthetic merge tree) showed the new FI/native step still running. Final FI counts, summed test time, slowest-test evidence and completed duration were unavailable, so CI success and cost impact remain unverified. Native storage/backend interoperability, rendered keyboard/accessibility behavior and performance remain unverified. The public description and commit text were inspected; no description images are attached. This is a merge follow-up, not a fresh whole-feature certification, approval or merge authorization.
baxen
left a comment
There was a problem hiding this comment.
🤖 Approving for merge at 28a7ba4 on baxen's request. Packaged release builds are not FI builds: BUZZ_BUILD_FEDERATED_IDENTITY_CONFIG is empty in the current release run, so release.yml keeps the legacy BUZZ_BUILDERLAB_URL and the bundled plugin keeps its OAuth login. The merge-commit conflict resolution in SignInFooter/ModelSettings keeps the legacy branch identical when nativeBuilderlab() is false. CI is green at this head. Before the FI descriptor is set on any release, cash-server #139434 must be deployed.
Picks up the month-boundary StatusEditor test fix (#2064). Co-Authored-By: Claude Opus 5.5 <[email protected]> * origin/main: (56 commits) perf(sidebar): subscribe to selected live and list facts (#1966) feat(desktop): align the sign-in callback page with web branding (#2038) Show linked PRs in Solo headers and move idle huddles to Chat actions (#1968) feat(messages): mark edited messages with "(edited)" (#2020) feat(desktop): bundle the buzz CLI in every package (#2027) feat(plugins): open a plugin page from buzz://plugin links (#2053) feat(plugins): managed plugin sources (#2052) test(browser): prevent sampled clock pause races (#1955) test: fix month-boundary and Sonner mount races in StatusEditor and RelayStaff tests (#2064) test: stop tests leaving temp dirs and a flake-check fixture behind (#1977) fix(messages): release Virtua's held range when scrolling stops (#2032) test(mcp): allow protection checks in bundled help fixture (#2061) fix(emoji): recover transient image failures without reopening chats (#2000) test: wait for dialog focus, reach a reading position, re-sign pair() (#1975) feat(plugins): sign builderlab in through the native fi session in fi builds (#1461) feat(agents): offer bundled Buzz help (#2033) fix(github): show pull request status for anchors and subpages (#2055) fix(dialogs): focus safe controls and task inputs (#2021) fix(composer): truncate workspace names at narrow widths (#2043) AIDA-2287: Refresh public channel search incrementally (#2023) ... Signed-off-by: Alex Rosenzweig <[email protected]>
The owner's decision: block/buzz-app supports one Builderlab per build
for now, the public deployment (`app.builderlab.xyz`, hosting
`communities.buzz.xyz`). This supersedes `d2e2b7ee9`'s multi-deployment
routing.
- `builderlab-hosted.ts`: keeps only the `communities.buzz.xyz` row
(host, relay `self` key, portal) and drops the `block.builderlab.xyz`
and `test.blockstaging.build` rows. `builderlabHosting(found, build)`
(`{ portal, here } | undefined`) becomes
`hostedByThisBuilderlab(found, build): boolean`. It is true only when
the listed deployment hosts the relay (hostname exact or label-boundary
suffix on the default port, else its `self` key) and its portal is the
origin of `VITE_BUZZ_BUILDERLAB_URL`. An empty, invalid or other-origin
build URL, as in an unconfigured or federated-identity build, answers
false, so such builds never sign in at once. The table stays, so a
second deployment could be added later.
- `Welcome.tsx`: `onFound` signs in only when `hostedByThisBuilderlab`
holds and otherwise pauses on the connect choice. The `elsewhere` state
and prop are gone. `finishJoin` saves an admitted join to the account
as it did before `d2e2b7ee9`, without the other-Builderlab guard.
- `ConnectChoice.tsx`: back to its single layout. "Buzz relies on a key
for your identity.", prominent Sign in with email, small I already
have a key, and Back. The key-only layout and its "different
Builderlab" copy are gone.
So a community another Builderlab deployment runs, such as a
`block.builderlab.xyz` relay typed into a public build, now gets the
ordinary Connect to {host} choice.
Tests: `builderlab-hosted.test.ts` is rewritten for the boolean. It
covers the `communities.buzz.xyz` apex, subdomain, case, final-dot and
`:443` forms, and every lookalike and non-default-port refusal (now
including a bb-block host). It also covers build URLs of "", "not a
url", the API-path form and `https://block.builderlab.xyz`, and the
`self` fallback with bb-public's key, on the default port only. A new
assertion makes sure an unknown relay with no build URL never matches.
`identity.test.tsx`: the hosted journey runs once, with a public build
URL stubbed. The two key-only "another Builderlab" journeys and the
not-saved join journey are removed. A new 2-case journey covers a bb-block
URL in a public build and a bb-public URL in a build with no Builderlab
URL: each pauses on the ordinary choice (Sign in with email, I already
have a key, Back) with no sign-in started.
Docs: `docs/identity.md` describes one Builderlab per build and the
ordinary choice for every other community. It adds a note that
federated-identity builds do not yet support the first-run flow: Sign in
with email needs the bundled Builderlab plugin's own network grant,
which an FI build does not have (#1461), so sign-in fails after the
browser step. `docs/configuration.md` has the same note under the FI
build input. `docs/buzz-help.md` drops the "different Builderlab"
sentence.
Validation: `vitest run` of `builderlab-hosted.test.ts`,
`identity.test.tsx`, `first-run-join-handoff.test.tsx` and
`first-run-navigation.test.tsx` (4 files, 158 tests) pass.
`tsc --noEmit` and Biome on the changed source files pass. Not run: the
full suite, hooks, lint, `design:check` and native builds.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
The owner's decision: block/buzz-app supports one Builderlab per build
for now, the public deployment (`app.builderlab.xyz`, hosting
`communities.buzz.xyz`). This supersedes `d2e2b7ee9`'s multi-deployment
routing.
- `builderlab-hosted.ts`: keeps only the `communities.buzz.xyz` row
(host, relay `self` key, portal) and drops the `block.builderlab.xyz`
and `test.blockstaging.build` rows. `builderlabHosting(found, build)`
(`{ portal, here } | undefined`) becomes
`hostedByThisBuilderlab(found, build): boolean`. It is true only when
the listed deployment hosts the relay (hostname exact or label-boundary
suffix on the default port, else its `self` key) and its portal is the
origin of `VITE_BUZZ_BUILDERLAB_URL`. An empty, invalid or other-origin
build URL, as in an unconfigured or federated-identity build, answers
false, so such builds never sign in at once. The table stays, so a
second deployment could be added later.
- `Welcome.tsx`: `onFound` signs in only when `hostedByThisBuilderlab`
holds and otherwise pauses on the connect choice. The `elsewhere` state
and prop are gone. `finishJoin` saves an admitted join to the account
as it did before `d2e2b7ee9`, without the other-Builderlab guard.
- `ConnectChoice.tsx`: back to its single layout. "Buzz relies on a key
for your identity.", prominent Sign in with email, small I already
have a key, and Back. The key-only layout and its "different
Builderlab" copy are gone.
So a community another Builderlab deployment runs, such as a
`block.builderlab.xyz` relay typed into a public build, now gets the
ordinary Connect to {host} choice.
Tests: `builderlab-hosted.test.ts` is rewritten for the boolean. It
covers the `communities.buzz.xyz` apex, subdomain, case, final-dot and
`:443` forms, and every lookalike and non-default-port refusal (now
including a bb-block host). It also covers build URLs of "", "not a
url", the API-path form and `https://block.builderlab.xyz`, and the
`self` fallback with bb-public's key, on the default port only. A new
assertion makes sure an unknown relay with no build URL never matches.
`identity.test.tsx`: the hosted journey runs once, with a public build
URL stubbed. The two key-only "another Builderlab" journeys and the
not-saved join journey are removed. A new 2-case journey covers a bb-block
URL in a public build and a bb-public URL in a build with no Builderlab
URL: each pauses on the ordinary choice (Sign in with email, I already
have a key, Back) with no sign-in started.
Docs: `docs/identity.md` describes one Builderlab per build and the
ordinary choice for every other community. It adds a note that
federated-identity builds do not yet support the first-run flow: Sign in
with email needs the bundled Builderlab plugin's own network grant,
which an FI build does not have (#1461), so sign-in fails after the
browser step. `docs/configuration.md` has the same note under the FI
build input. `docs/buzz-help.md` drops the "different Builderlab"
sentence.
Validation: `vitest run` of `builderlab-hosted.test.ts`,
`identity.test.tsx`, `first-run-join-handoff.test.tsx` and
`first-run-navigation.test.tsx` (4 files, 158 tests) pass.
`tsc --noEmit` and Biome on the changed source files pass. Not run: the
full suite, hooks, lint, `design:check` and native builds.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
The owner's decision: block/buzz-app supports one Builderlab per build
for now, the public deployment (`app.builderlab.xyz`, hosting
`communities.buzz.xyz`). This supersedes `d2e2b7ee9`'s multi-deployment
routing.
- `builderlab-hosted.ts`: keeps only the `communities.buzz.xyz` row
(host, relay `self` key, portal) and drops the `block.builderlab.xyz`
and `test.blockstaging.build` rows. `builderlabHosting(found, build)`
(`{ portal, here } | undefined`) becomes
`hostedByThisBuilderlab(found, build): boolean`. It is true only when
the listed deployment hosts the relay (hostname exact or label-boundary
suffix on the default port, else its `self` key) and its portal is the
origin of `VITE_BUZZ_BUILDERLAB_URL`. An empty, invalid or other-origin
build URL, as in an unconfigured or federated-identity build, answers
false, so such builds never sign in at once. The table stays, so a
second deployment could be added later.
- `Welcome.tsx`: `onFound` signs in only when `hostedByThisBuilderlab`
holds and otherwise pauses on the connect choice. The `elsewhere` state
and prop are gone. `finishJoin` saves an admitted join to the account
as it did before `d2e2b7ee9`, without the other-Builderlab guard.
- `ConnectChoice.tsx`: back to its single layout. "Buzz relies on a key
for your identity.", prominent Sign in with email, small I already
have a key, and Back. The key-only layout and its "different
Builderlab" copy are gone.
So a community another Builderlab deployment runs, such as a
`block.builderlab.xyz` relay typed into a public build, now gets the
ordinary Connect to {host} choice.
Tests: `builderlab-hosted.test.ts` is rewritten for the boolean. It
covers the `communities.buzz.xyz` apex, subdomain, case, final-dot and
`:443` forms, and every lookalike and non-default-port refusal (now
including a bb-block host). It also covers build URLs of "", "not a
url", the API-path form and `https://block.builderlab.xyz`, and the
`self` fallback with bb-public's key, on the default port only. A new
assertion makes sure an unknown relay with no build URL never matches.
`identity.test.tsx`: the hosted journey runs once, with a public build
URL stubbed. The two key-only "another Builderlab" journeys and the
not-saved join journey are removed. A new 2-case journey covers a bb-block
URL in a public build and a bb-public URL in a build with no Builderlab
URL: each pauses on the ordinary choice (Sign in with email, I already
have a key, Back) with no sign-in started.
Docs: `docs/identity.md` describes one Builderlab per build and the
ordinary choice for every other community. It adds a note that
federated-identity builds do not yet support the first-run flow: Sign in
with email needs the bundled Builderlab plugin's own network grant,
which an FI build does not have (#1461), so sign-in fails after the
browser step. `docs/configuration.md` has the same note under the FI
build input. `docs/buzz-help.md` drops the "different Builderlab"
sentence.
Validation: `vitest run` of `builderlab-hosted.test.ts`,
`identity.test.tsx`, `first-run-join-handoff.test.tsx` and
`first-run-navigation.test.tsx` (4 files, 158 tests) pass.
`tsc --noEmit` and Biome on the changed source files pass. Not run: the
full suite, hooks, lint, `design:check` and native builds.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
…ion (FOUNDATION: App.tsx, services.ts) (#2249) ## Summary New users of FI builds (the internal Block build, 0.7.7) couldn't finish first run. **Sign in with email** opened the browser, and then the app showed *Couldn't sign in. Could not complete Builderlab sign-in.* Welcome exchanged the code through the bundled Builderlab plugin's network grant. FI builds don't have that grant: Builderlab calls go through the native NIP-FI session instead ([#1461](#1461)). [#1820](#1820) documented this as a known gap. With this change, Welcome in FI builds signs in through the native NIP-FI session and sends setup's account calls through its forwarder. Non-FI builds are unchanged. - **Sign-in:** `firstRunCredential` calls `federatedIdentity.signIn()`. The browser step, code exchange and token all stay native. It then reads `GET v1/auth/me` through the forwarder. The returned credential's value is the session's public revision. If a session already exists, it signs in again so the browser can choose the account. A renewal that doesn't finish (canceled or timed out in the browser) gets back the old session at the same revision, so first run refuses rather than continuing as the old account. Native's bare failure codes map to the same copy as the community sign-in. - **Account calls:** identity check, link and unlink, owned communities, and known communities use the same routes through the forwarder via `federatedBuilderlabAccount`. Each call is checked against the session revision that sign-in returned, so a session that changed refuses without sending anything. - **Acting as the bundled installation:** native FI admission checks only the grant for the (id, revision) pair, not whether the plugin is running. So Welcome calls as `block.builderlab`/`bundled` through `ctx.extend({ pluginOwner })`, the same installation `bundledHost` already acts as. No native or grant changes. - **Backup:** `backUpWith` hands the uploader the FI session revision (`handoffFederatedBackupSession`). Backup status returns "unavailable". The forwarder has no route for it, and the FI plugin doesn't read one either, so Welcome back offers no restore and an imported key is offered a backup. The Block build has no backup configured today. - **After Welcome:** the native session persists, so `LaunchSignIn` finds it already signed in and doesn't prompt again. **Known gap:** after a first-run backup, `backUpWith` clears the uploader's `builderlab` slot as it does today. The plugin shares the FI session, so it won't hand that slot off again until the session changes. This only matters where backup is configured, and the Block build doesn't configure it. **FOUNDATION:** `services.ts` gets one line to create the bundled-owner FI view, only in FI builds. `App.tsx` gets one prop to pass that view to Welcome. Out of scope: `browser.ts` still hides native error strings. This is deliberate, so provider bodies are never forwarded. The "Sign in with email" label also stays as is in FI builds. ## Validation - Full `vitest run`: 873 files and 15,427 tests passed (7 files and 21 tests skipped). `tsc --noEmit` and `biome check` are clean. These ran on the tree committed as `41388fb64`. - New tests: - `first-run.test.ts`: the bundled-owner view registers and requests as `block.builderlab`/`bundled` with a real cordis `Context`. The FI sign-in reads the account and never opens the plugin's browser handoff. Failures map to the right copy, including a renewal that doesn't finish, a native failure code, and an account read that isn't JSON. Cancel calls `cancelSignIn`. - `builderlab-account.test.ts`: forwarder paths and headers, revision fencing, backup status "unavailable", and the federated backup handoff. - `identity.test.tsx`: Welcome's defaults route through the FI session. - I mutation-checked the owner and Welcome-wiring tests: each fails when the change is reverted. - **Real FI build, step 2 only:** I ran a debug desktop build with the production bb-block descriptor, on a fresh profile with its own HOME and keychain. Sign-in now reaches **Welcome back** (the test account already has a linked key). On `main`, the same binary shows *Couldn't sign in*. I didn't run steps 3–4 below (Create my key, Cancel sign-in) in a real FI build. ## Before and after Both runs use the same FI debug build (bb-block descriptor) on a fresh profile. Only the frontend differs. I cut the browser sign-in step, and blacked out the account's email and npub. ### Before: `main` (`90ce5e37a`) shows *Couldn't sign in* https://github.com/user-attachments/assets/3c04ff79-f020-4123-b226-09aeafa15c24 ### After: this PR (`373d7484d`) lands on Welcome back https://github.com/user-attachments/assets/b109f807-7a4a-4dd3-8fef-f199ec76523c ## Human test (FI build, bb-block staging) 1. Build and run with the staging descriptor from `squareup/buzz-releases` `scripts/build-macos-app-staging.sh`, and use a fresh profile with no key: `BUZZ_BUILD_FEDERATED_IDENTITY_CONFIG='<staging descriptor>' BUZZ_BUILDERLAB_URL= just desktop` 2. Click **Sign in with email** and finish the browser step. You should land on **Create my key** (or **Welcome back** for an account that already has a linked key), not *Couldn't sign in*. 3. Click **Create my key**. Setup should link the key and continue. The app should open without a second organization sign-in prompt. 4. Run it again on a fresh profile and on one already signed in to the organization. On each, click **Cancel sign-in** during the browser step. You should return to the landing page with no key created. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Matt Toohey <[email protected]> Co-authored-by: Jitter <2b2e6415e748c35180847a37aadae06a11e30dddc76b784e7fd9354c4eb42e7a@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <[email protected]>
…ion (FOUNDATION: App.tsx, services.ts) (block#2249) ## Summary New users of FI builds (the internal Block build, 0.7.7) couldn't finish first run. **Sign in with email** opened the browser, and then the app showed *Couldn't sign in. Could not complete Builderlab sign-in.* Welcome exchanged the code through the bundled Builderlab plugin's network grant. FI builds don't have that grant: Builderlab calls go through the native NIP-FI session instead ([block#1461](block#1461)). [block#1820](block#1820) documented this as a known gap. With this change, Welcome in FI builds signs in through the native NIP-FI session and sends setup's account calls through its forwarder. Non-FI builds are unchanged. - **Sign-in:** `firstRunCredential` calls `federatedIdentity.signIn()`. The browser step, code exchange and token all stay native. It then reads `GET v1/auth/me` through the forwarder. The returned credential's value is the session's public revision. If a session already exists, it signs in again so the browser can choose the account. A renewal that doesn't finish (canceled or timed out in the browser) gets back the old session at the same revision, so first run refuses rather than continuing as the old account. Native's bare failure codes map to the same copy as the community sign-in. - **Account calls:** identity check, link and unlink, owned communities, and known communities use the same routes through the forwarder via `federatedBuilderlabAccount`. Each call is checked against the session revision that sign-in returned, so a session that changed refuses without sending anything. - **Acting as the bundled installation:** native FI admission checks only the grant for the (id, revision) pair, not whether the plugin is running. So Welcome calls as `block.builderlab`/`bundled` through `ctx.extend({ pluginOwner })`, the same installation `bundledHost` already acts as. No native or grant changes. - **Backup:** `backUpWith` hands the uploader the FI session revision (`handoffFederatedBackupSession`). Backup status returns "unavailable". The forwarder has no route for it, and the FI plugin doesn't read one either, so Welcome back offers no restore and an imported key is offered a backup. The Block build has no backup configured today. - **After Welcome:** the native session persists, so `LaunchSignIn` finds it already signed in and doesn't prompt again. **Known gap:** after a first-run backup, `backUpWith` clears the uploader's `builderlab` slot as it does today. The plugin shares the FI session, so it won't hand that slot off again until the session changes. This only matters where backup is configured, and the Block build doesn't configure it. **FOUNDATION:** `services.ts` gets one line to create the bundled-owner FI view, only in FI builds. `App.tsx` gets one prop to pass that view to Welcome. Out of scope: `browser.ts` still hides native error strings. This is deliberate, so provider bodies are never forwarded. The "Sign in with email" label also stays as is in FI builds. ## Validation - Full `vitest run`: 873 files and 15,427 tests passed (7 files and 21 tests skipped). `tsc --noEmit` and `biome check` are clean. These ran on the tree committed as `41388fb64`. - New tests: - `first-run.test.ts`: the bundled-owner view registers and requests as `block.builderlab`/`bundled` with a real cordis `Context`. The FI sign-in reads the account and never opens the plugin's browser handoff. Failures map to the right copy, including a renewal that doesn't finish, a native failure code, and an account read that isn't JSON. Cancel calls `cancelSignIn`. - `builderlab-account.test.ts`: forwarder paths and headers, revision fencing, backup status "unavailable", and the federated backup handoff. - `identity.test.tsx`: Welcome's defaults route through the FI session. - I mutation-checked the owner and Welcome-wiring tests: each fails when the change is reverted. - **Real FI build, step 2 only:** I ran a debug desktop build with the production bb-block descriptor, on a fresh profile with its own HOME and keychain. Sign-in now reaches **Welcome back** (the test account already has a linked key). On `main`, the same binary shows *Couldn't sign in*. I didn't run steps 3–4 below (Create my key, Cancel sign-in) in a real FI build. ## Before and after Both runs use the same FI debug build (bb-block descriptor) on a fresh profile. Only the frontend differs. I cut the browser sign-in step, and blacked out the account's email and npub. ### Before: `main` (`90ce5e37a`) shows *Couldn't sign in* https://github.com/user-attachments/assets/3c04ff79-f020-4123-b226-09aeafa15c24 ### After: this PR (`373d7484d`) lands on Welcome back https://github.com/user-attachments/assets/b109f807-7a4a-4dd3-8fef-f199ec76523c ## Human test (FI build, bb-block staging) 1. Build and run with the staging descriptor from `squareup/buzz-releases` `scripts/build-macos-app-staging.sh`, and use a fresh profile with no key: `BUZZ_BUILD_FEDERATED_IDENTITY_CONFIG='<staging descriptor>' BUZZ_BUILDERLAB_URL= just desktop` 2. Click **Sign in with email** and finish the browser step. You should land on **Create my key** (or **Welcome back** for an account that already has a linked key), not *Couldn't sign in*. 3. Click **Create my key**. Setup should link the key and continue. The app should open without a second organization sign-in prompt. 4. Run it again on a fresh profile and on one already signed in to the organization. On each, click **Cancel sign-in** during the browser step. You should return to the landing page with no key created. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Matt Toohey <[email protected]> Co-authored-by: Jitter <2b2e6415e748c35180847a37aadae06a11e30dddc76b784e7fd9354c4eb42e7a@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <[email protected]>
These are §8 and the agent.rs memory-read row of §13 from the 23-30 Oct CI flake sweep. Before editing I checked origin/main (f3446e8) and the open PRs. Neither unit was fixed since the sweep: no commit on main touches media_spool.rs, media_stream_tests.rs or the agent test, and no open PR touches media_spool.rs or either test. Drafts #1461 and #967 rework relay_agent_memories_read, and #1461 also edits media_stream.rs. Neither changes the code paths fixed here. media_stream_tests.rs:277 a_failure_mid_stream_ends_the_response_short_of_its_length - CI runs: 39970306754 (job 120470903732), 40829345046 (job 123299699319) and 40958827040 (job 123745997146). All three fail at :300 with 502 where 200 is expected. That is the case of a whole 200 that sends 2 MiB of a 3 MiB Content-Length. - Cause: the spool publishes its progress through a tokio watch channel, which keeps only the latest value. The copy flushes the first MiB as Writing(n), then fails and replaces that value with Failed(502). A reader that polls only after both sends sees just Failed. read() then returned 502, although the bytes it asked for were already on disk, and the response's first block went out as a 502 head. A player's range request can hit the same race in the app. - Change: Failed now also carries the last count the copy reported, and read() answers from disk whenever that count covers its range. Otherwise it returns the failure status, as before. lookup() still drops a failed spool, so later reads fetch the video again, and a read past the written bytes still fails (truncated_whole_videos_fail_and_are_fetched_again is unchanged). - Verified: a new test, a_failed_spool_still_answers_the_bytes_it_wrote, opens a spool on that truncated 200. It first reads the tail, which can only return once the copy has failed, and then reads the first block. That second read never sees the Writing progress, so the ordering is forced rather than timed. Without the media_spool.rs change it fails on the first-block read with "called `Result::unwrap()` on an `Err` value: 502". With the change it passes. :277 and truncated_whole_videos_fail_and_are_fetched_again also pass. agent.rs memory_read_keeps_what_it_decoded_when_its_deadline_passes - CI run: 40877681973 (job 123460621816), which passed on re-run. It failed with 16 entries where 32 are expected. - Cause: the first case relied on real-clock slack. Each page took 120 ms against a 300 ms deadline, and page 1 is decoded before page 2 is requested, so page 2 only made the deadline if page 1's decode finished in about 60 ms. A slow decode on CI pushed page 2 past the deadline. - Change: read_through answers each page at once and leaves the request after the last page pending, so its fetch parameter is gone. The first case now has 32 events, two full pages, so the deadline always passes while the third page is awaited. The second case asserts the same as before. Its trailing request now pends instead of returning an empty page, but by then its deadline has already passed. - Verified: a temporary probe, not committed, injected a 100 ms decode stall after page 1 through the helper's stall parameter. The old test then failed with "left: 16, right: 32", the CI signature. The new test passed. Without the probe, the new test passes. - Hang guard: with the last request pending, a read that stopped honouring its deadline would hang this test rather than fail its `took` bound, and CI runs plain cargo test with no per-test timeout. read_through therefore bounds the read with a 5 s tokio::time::timeout that fails with "memory read outlived its deadline". This is a hang guard, not a flake fix; the `took` assertions still check the real bound. A temporary probe, not committed, set the read's deadline 1000 times later. The test then failed after 5.05 s with that message instead of hanging. Local checks: cargo fmt --check and cargo clippy --all-targets -D warnings on the Buzz crate, plus the four tests above, run by name. After the hang guard was added, cargo fmt --check and the memory-read test were re-run on this snapshot; clippy and the media tests were not. Deferred: the full Rust suite and hosted CI. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
These are §8 and the agent.rs memory-read row of §13 from the 23-30 Oct CI flake sweep. Before editing I checked origin/main (f3446e8) and the open PRs. Neither unit was fixed since the sweep: no commit on main touches media_spool.rs, media_stream_tests.rs or the agent test, and no open PR touches media_spool.rs or either test. Drafts #1461 and #967 rework relay_agent_memories_read, and #1461 also edits media_stream.rs. Neither changes the code paths fixed here. media_stream_tests.rs:277 a_failure_mid_stream_ends_the_response_short_of_its_length - CI runs: 39970306754 (job 120470903732), 40829345046 (job 123299699319) and 40958827040 (job 123745997146). All three fail at :300 with 502 where 200 is expected. That is the case of a whole 200 that sends 2 MiB of a 3 MiB Content-Length. - Cause: the spool publishes its progress through a tokio watch channel, which keeps only the latest value. The copy flushes the first MiB as Writing(n), then fails and replaces that value with Failed(502). A reader that polls only after both sends sees just Failed. read() then returned 502, although the bytes it asked for were already on disk, and the response's first block went out as a 502 head. A player's range request can hit the same race in the app. - Change: Failed now also carries the last count the copy reported, and read() answers from disk whenever that count covers its range. Otherwise it returns the failure status, as before. lookup() still drops a failed spool, so later reads fetch the video again, and a read past the written bytes still fails (truncated_whole_videos_fail_and_are_fetched_again is unchanged). - Verified: a new test, a_failed_spool_still_answers_the_bytes_it_wrote, opens a spool on that truncated 200. It first reads the tail, which can only return once the copy has failed, and then reads the first block. That second read never sees the Writing progress, so the ordering is forced rather than timed. Without the media_spool.rs change it fails on the first-block read with "called `Result::unwrap()` on an `Err` value: 502". With the change it passes. :277 and truncated_whole_videos_fail_and_are_fetched_again also pass. agent.rs memory_read_keeps_what_it_decoded_when_its_deadline_passes - CI run: 40877681973 (job 123460621816), which passed on re-run. It failed with 16 entries where 32 are expected. - Cause: the first case relied on real-clock slack. Each page took 120 ms against a 300 ms deadline, and page 1 is decoded before page 2 is requested, so page 2 only made the deadline if page 1's decode finished in about 60 ms. A slow decode on CI pushed page 2 past the deadline. - Change: read_through answers each page at once and leaves the request after the last page pending, so its fetch parameter is gone. The first case now has 32 events, two full pages, so the deadline always passes while the third page is awaited. The second case asserts the same as before. Its trailing request now pends instead of returning an empty page, but by then its deadline has already passed. - Verified: a temporary probe, not committed, injected a 100 ms decode stall after page 1 through the helper's stall parameter. The old test then failed with "left: 16, right: 32", the CI signature. The new test passed. Without the probe, the new test passes. - Hang guard: with the last request pending, a read that stopped honouring its deadline would hang this test rather than fail its `took` bound, and CI runs plain cargo test with no per-test timeout. read_through therefore bounds the read with a 5 s tokio::time::timeout that fails with "memory read outlived its deadline". This is a hang guard, not a flake fix; the `took` assertions still check the real bound. A temporary probe, not committed, set the read's deadline 1000 times later. The test then failed after 5.05 s with that message instead of hanging. Local checks: cargo fmt --check and cargo clippy --all-targets -D warnings on the Buzz crate, plus the four tests above, run by name. After the hang guard was added, cargo fmt --check and the memory-read test were re-run on this snapshot; clippy and the media tests were not. Deferred: the full Rust suite and hosted CI. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
#1970) ## Summary Fixes two Rust test flakes from the 23–30 Oct CI flake sweep. The first is a real defect in the media spool, so this PR changes product code. The second is test-only. This is one of six independent PRs split from the `flakey-tests` branch. Each is cut from `main` and can merge in any order. ### A failed spool still answers the bytes it wrote (`media_stream_tests.rs:277`) - **CI:** 39970306754 (job 120470903732), 40829345046 (job 123299699319), 40958827040 (job 123745997146). `a_failure_mid_stream_ends_the_response_short_of_its_length` fails at :300 with 502 where 200 is expected. The case is a 200 response that sends 2 MiB of a 3 MiB `Content-Length`. - **Cause:** the spool reports progress through a tokio `watch` channel, which keeps only the latest value. The copy flushes the first MiB as `Writing(n)`, then fails and overwrites that with `Failed(502)`. A reader that polls only after both sends sees just `Failed`. `read()` then returned 502, even though the bytes it asked for were already on disk, and the response's first block went out as a 502 head. A player's range request can hit the same race in the app. - **Change (`media_spool.rs`):** `Failed` also carries the last byte count the copy reported. `read()` answers from disk whenever that count covers its range, and otherwise returns the failure status as before. `lookup()` still drops a failed spool, so later reads fetch the video again. A read past the written bytes still fails, and `truncated_whole_videos_fail_and_are_fetched_again` is unchanged. ### The memory-read deadline test no longer depends on decode speed (`agent.rs`) - **CI:** 40877681973 (job 123460621816) got 16 entries where 32 were expected. It passed on re-run. - **Cause:** each page took 120 ms against a 300 ms deadline, and page 1 is decoded before page 2 is requested. Page 2 therefore made the deadline only if page 1's decode finished in about 60 ms, and a slow decode on CI pushed it past. - **Change:** `read_through` answers each page at once and leaves the request after the last page pending. The first case now has 32 events, two full pages, so the deadline always passes while the third page is awaited. The second case asserts the same as before. - **Hang guard:** because the last request now stays pending, a read that stopped honouring its deadline would hang instead of failing its `took` bound, and CI runs plain `cargo test` with no per-test timeout. `read_through` therefore wraps the read in a 5 s `tokio::time::timeout` that fails with "memory read outlived its deadline". The `took` assertions still check the real bound. ### Verification (local macOS) - The new test `a_failed_spool_still_answers_the_bytes_it_wrote` forces the ordering. It first reads the tail, which can only return after the copy has failed, and then reads the first block, so the second read never sees `Writing`. Without the `media_spool.rs` change it fails on the first-block read with ``called `Result::unwrap()` on an `Err` value: 502``. With the change it passes. `:277` and `truncated_whole_videos_fail_and_are_fetched_again` also pass. - Memory read: a temporary probe (not committed) added a 100 ms decode stall after page 1. The old test then failed with `left: 16, right: 32`, the CI signature, and the new test passed. A second probe moved the deadline 1000× later. The test failed after 5.05 s with the hang-guard message instead of hanging. - Ran `cargo fmt --check` and `cargo clippy --all-targets -D warnings` on the Buzz crate, plus the four tests above by name. After the hang guard was added, only `cargo fmt --check` and the memory-read test were re-run. Clippy and the media tests were not. ### Overlaps Drafts #1461 and #967 rework `relay_agent_memories_read`, and #1461 also edits `media_stream.rs`. Neither changes the code paths fixed here. ### Remaining gaps - The full Rust suite has not run locally. Hosted CI is its first full run. - A green run does not show that these flakes are gone. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Matt Toohey <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>
Builds on #1424, now on
main. In a build with the NIP-FI descriptor (BUZZ_BUILD_FEDERATED_IDENTITY_CONFIG), the bundled Builderlab plugin, including hosted communities, signs in through the native FI session. The adapter session stays in OS secure storage, so sign-in survives restart and reload, and the renderer never sees the token. Builds without FI keep the legacy in-memory OAuth login unchanged.Backend: Builderlab must accept the adapter session as
Authorization: BeareronGET v1/auth/meand the communities, nostr-identity, known-community and Beekeeper routes. The Apps viewer exchange (v1/auth/hosted-site/native-session) and the backup enroll/upload routes (v1/buzz/nsec-backups*) must accept it too; until they do, an FI build's Apps viewer and automatic backup fail closed. An FI build does not offer Builderlab as a Decisions API provider: nativedecidesends the legacy credential, which an FI build does not have.Native
federated_identity/access.rsforwards a granted route natively withAuthorization: Bearer <adapter session>to the identity origin only.Authorization,CookieorX-BB-Session-Credential. Redirects aren't followed.host.federatedIdentitygrant of its exact routes in FI builds, and no network origins or files. Plugin import lists the routes.BUZZ_BUILDERLAB_URLalongside FI, andrelease.ymlblanks it when FI is set.GET /v1/sessiononce (FederatedIdentity::recheck), for the revision the call ran under. Only a session the adapter refuses there (session_required/session_expired) ends, asreauthentication-required, the same way an assertion refusal ends it. A recheck that sees a newer revision does nothing.Plugin
session.tsadds aBuilderlabSessionseam with two implementations:createOAuthSessioncreateNativeSessionoverfederatedIdentity, which reads the account (subject, email,can_use_remote_agents) fromGET v1/auth/meonce per session revision and fails closed with a retrysession.request()and no longer take the host or a credential.VITE_BUZZ_BUILDERLAB_URLfrom the FI identity origin and API base. Persisted adapter identities, registration replay keys and the account subject keep the same scope in both modes, so nothing migrates.navigation), where that sign-out lives. Reviewing the connected Buzz identity (the mismatch prompt and Unpair identity) stays in Builderlab's communities view; moving it to Identity is a follow-up.ensureSignedInsettles when the native sign-in attempt finishes, so a sign-in that leaves the snapshot unchanged (unavailable before restore, or unconfigured) can't leave a caller waiting.abandon()).Review threads addressed
oauthTarget()and the auth/me subject are the same in both modes, so the stored tuple doesn't change.GET v1/auth/me, not the FI revision or email.Logincallsabandon(), which is a no-op natively.this.ctxis a new object on every access and the old cache never hit.Compose-ctrl
The Builderlab Apps agent tools are made native in the stacked draft #1958.
Validation
At
f4eaf7991:biome check,tsc --noEmitand the design typecheck are clean.vitest: 14,110 tests passed. New tests cover:cargo test -p buzzodz-plugins --libpassed 44 andcargo test --libinsrc-tauripassed 738 (2 ignored), including a native sign-out mid-backup that sends no later request.https://app.builderlabstaging.xyz: the same suites passed 44 and 738 (2 ignored).cargo clippy -p Buzz -p buzzodz-plugins --all-targets -D warningsis clean in the default build.Testing an FI build
Unset
BUZZ_BUILDERLAB_URL. The FI descriptor supplies the Builderlab authority, and the build fails when both are set ("BUZZ_BUILDERLAB_URL must be removed when FI is configured").FI build rollout
The release logs checked on October 30 (runs 41106665291 and 41121945380) have an empty
BUZZ_BUILD_FEDERATED_IDENTITY_CONFIG. Those builds keep legacy OAuth. Merging this PR does not enable FI.Before enabling the descriptor, deploy the Bearer support for account and community routes, Apps viewer exchange, and backup enroll/upload. Build a candidate containing this PR with the descriptor set and
BUZZ_BUILDERLAB_URLempty. Verify Organization sign-in appears, sign in, restart and confirm the saved session restores, then check account access, communities, Apps viewer and backup. Check sign-out/account changes and refused requests too. These live checks have not been run.Rollback requires a new build with
BUZZ_BUILD_FEDERATED_IDENTITY_CONFIGunset and the legacy Builderlab URL restored. Promote that build before removing server Bearer support. Existing installed binaries retain their compiled configuration; there is no runtime toggle.CI now builds the frontend and runs the native plugin and host-request grant tests with a public fixture descriptor, after the default native tests.
Generated with Codex