Repository navigation
feat(hub-zero): T7 installer driver to client observer (CL-8131) - #753
Merged
Merged
Conversation
The stock member invite route only attaches a role when the caller passes roleId; without it an invited principal lands with zero grants and every subsequent read 403s. inviteMember now resolves the manifest's role name to the tenant's own role id over GET /api/tenants/:id/roles before inviting. Claude-Session: https://claude.ai/code/session_01RweuMUskU2nvcFhdckc7EG
…(CL-8131) The onboarding-page setup-pending phase now runs the portable client bootstrap directly: it mints the account's primary tenant over stock POST /api/tenants (no parentId, so the caller becomes owner — the 0->1 ruling's execution, never hub boot) and converges Myra onto it, landing on the shell once ready or showing the exact stock capability gap otherwise. The background bootstrap effect that used to run silently on every signed-in load in main.tsx is removed — the browser installer is now the only driver of the needs-list convergence. Claude-Session: https://claude.ai/code/session_01RweuMUskU2nvcFhdckc7EG
4 of 5 tasks
TheGreatAxios
added a commit
that referenced
this pull request
Sep 17, 2026
After T7 (#753), the onboarding page drove install over stock routes but never supplied myraDeploy, so every fresh hub stopped on the "Myra is absent" gap screen. This wires the converge loop the owner ruled on: authenticate, mint the primary tenant if needed, resolve whether it already has a usable model offering (inherited, or a previous run), and ask the operator for a provider credential only when it doesn't — never a multi-step wizard. myra-source.ts pins the deploy-source variant apps/web actually uses: neither `registry` (workflows/assistant is unpublished) nor a git-pushed `asset` "source" (the push helper shells out to a system git binary and node:fs, unavailable to a browser SPA) work today. The `asset` "tarball" variant does: PUT /api/tenants/:id/assets/:assetId/ tarballs/:filename takes raw bytes over plain fetch, no git protocol. myra-deploy.ts hand-builds the exact WorkflowDefinition JSON `buildAssistantWorkflow` would produce (from the browser-safe prompt data split out of workflows/assistant), packs it into an npm-shaped tarball with a hand-rolled USTAR writer plus the browser's own CompressionStream("gzip"), and PUTs it into a package-registry asset. provider-connect-step.tsx is the one prompt this flow asks for: three providers, each mapping to one canonical model, so connecting a provider mints exactly one offering and needs no separate "which model" pick. A tenant that already resolves a catalog offering skips this screen entirely. needs-converge.ts's HubTenant/TenantShape now carries the tenant's `domain` field the stock tenant route already returns — needed to derive Myra's trigger address, and no hub change since the field was already there. Deleted the old test asserting the pre-CL-8154 "surfaces the myra-deploy gap" behavior; replaced it with one asserting the new credential-connect landing. Claude-Session: https://claude.ai/code/session_01RweuMUskU2nvcFhdckc7EG
TheGreatAxios
added a commit
that referenced
this pull request
Sep 17, 2026
* feat(workflows/assistant): split Myra's prompt data into a browser-safe subpath Myra's system prompt, tool-package pins, and workflow/step ids now live in workflows/assistant/src/prompt.ts, which imports nothing but a type-only ToolPackagePin. index.ts re-exports the same names so no existing consumer needs to change. This is prep for CL-8154: apps/web needs these constants to hand-build Myra's deployable definition client-side, but importing the package's default entry point pulls in @intx/workflow/@intx/agent's Node-bound runtime (file locking, in particular) that a browser bundle cannot resolve. Claude-Session: https://claude.ai/code/session_01RweuMUskU2nvcFhdckc7EG * feat(web): onboarding supplies the Myra deploy input (CL-8154) After T7 (#753), the onboarding page drove install over stock routes but never supplied myraDeploy, so every fresh hub stopped on the "Myra is absent" gap screen. This wires the converge loop the owner ruled on: authenticate, mint the primary tenant if needed, resolve whether it already has a usable model offering (inherited, or a previous run), and ask the operator for a provider credential only when it doesn't — never a multi-step wizard. myra-source.ts pins the deploy-source variant apps/web actually uses: neither `registry` (workflows/assistant is unpublished) nor a git-pushed `asset` "source" (the push helper shells out to a system git binary and node:fs, unavailable to a browser SPA) work today. The `asset` "tarball" variant does: PUT /api/tenants/:id/assets/:assetId/ tarballs/:filename takes raw bytes over plain fetch, no git protocol. myra-deploy.ts hand-builds the exact WorkflowDefinition JSON `buildAssistantWorkflow` would produce (from the browser-safe prompt data split out of workflows/assistant), packs it into an npm-shaped tarball with a hand-rolled USTAR writer plus the browser's own CompressionStream("gzip"), and PUTs it into a package-registry asset. provider-connect-step.tsx is the one prompt this flow asks for: three providers, each mapping to one canonical model, so connecting a provider mints exactly one offering and needs no separate "which model" pick. A tenant that already resolves a catalog offering skips this screen entirely. needs-converge.ts's HubTenant/TenantShape now carries the tenant's `domain` field the stock tenant route already returns — needed to derive Myra's trigger address, and no hub change since the field was already there. Deleted the old test asserting the pre-CL-8154 "surfaces the myra-deploy gap" behavior; replaced it with one asserting the new credential-connect landing. Claude-Session: https://claude.ai/code/session_01RweuMUskU2nvcFhdckc7EG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
bootstrapClientSession/convergeNeedsList, previously dead code with zero callers) intoonboarding-page.tsx'ssetup-pendingphase: the browser installer now mints the account's primary tenant over stockPOST /api/tenants(noparentId— the caller becomes owner, executing the "0→1 is first signup, not hub boot" ruling), then converges Myra onto it, landing on/once ready or rendering the exact stock capability gap otherwise.inviteMembernow resolves the manifest role name to the tenant's own role id overGET /api/tenants/:id/rolesbefore inviting, so an invited member actually gets a grant instead of 403ing on every read.main.tsxthat used to fire on every signed-in load — the installer (onboarding page) is now the only driver of the needs-list convergence./api/setupstatus was already honest (derived from native tenant count) and hub-sideseedTenant/pending-seed/onboardingDepsblocks were already gone fromapps/hub/srcin earlier waves —rg "seedTenant|createBenchProvisioner|pending-seed" apps/hub/srcis empty.Gaps
myraDeploy(source/offering ids) or workbench member emails, so a fresh hub with no Myra deployed lands on the "stock capability gap" screen rather than fully completing setup end-to-end — that's the expected outcome until deploy config / invite UI exists.packages/onboarding(the old server-side seed/pending-seed/bench-provisioning package) still exists but has zero callers inapps/huborapps/web; deleting it is a separate ticket (CL-7586/CL-7585 wave), out of this ticket's scope.Verification
bun run typecheck— passbun run lint— pass (3 pre-existing unrelated errors inapps/hub/src/index.ts, untouched by this PR)bun run check:structural— passbun --cwd apps/web test ./src/needs-converge.test.ts ./src/needs-list.test.ts ./src/client-bootstrap.test.ts ./test/onboarding.test.tsx— 919 pass, 0 failhttps://claude.ai/code/session_01RweuMUskU2nvcFhdckc7EG