Onboarding: each tenant gets Myra and the core workflows - #708
Open
TheGreatAxios wants to merge 14 commits into
Open
Onboarding: each tenant gets Myra and the core workflows#708TheGreatAxios wants to merge 14 commits into
TheGreatAxios wants to merge 14 commits into
Conversation
The document is plain client-side data composed by reference over DEFAULT_WORKFLOWS, REQUIRED_SEED_TOOL_PACKAGES, and DEFAULT_SKILLS — no hub table and no migration. readTenantDesiredStateStatus reads a tenant's real workflow, tool-package, and skill state against it using native GETs only. Also adds fetchRegistryTarballSource and installRegistryTarball for the (tested but unpopulated) tarball-url source kind, and re-exports the defaults through @corbits/seeding.
Installs only absent pins, tools first, then skills, grants, and workflows together through seedTenant with confirmDeployments false. A converged tenant reconciles with reads only: seedTenant is never entered and the registry publish is gated on the seeded check. Sidecar-unavailable (502-class) pins report blocked without throwing; other failures report failed and are safe to re-run. Model resolution picks the tenant's top-priority resolved catalog offering, inherited included.
runOnce no longer sequences publish, fully-seeded check, and ensureSeeded itself; it delegates to the doc-driven reconcile. Row semantics are unchanged: a ready report clears the pending_seed row, a blocked report keeps it for the next pass, and a failed report keeps it and counts for backoff.
POST /api/onboarding/provision fires a fire-and-forget desired-state reconcile kick when the caller's tenant still has pending pins — this is how a joined member's bench converges. GET /api/onboarding/provisioning-status now carries the doc-labeled step list the onboarding page renders; the ready/provisioning gate stays on the workflow set.
An outer wrap beside the tenant-create guard watches the native POST /api/tenants route: a 201 fires one fire-and-forget desired-state reconcile for the new tenant under the creator's minted session, deduped per tenant in process. A tenant with no catalog offerings reports the workflow pins blocked in the log instead of throwing. The onboarding provision route's revisit kick shares this reconciler.
The onboarding page polls complete-setup while pins are pending, renders the hub's doc-labeled steps under the loader, and collapses the list and hands off to the app once the answer is ready.
The observer is hoisted so hub close can stop it and wait (bounded) for in-flight reconciles before the pool ends, and kicks replay the creator's cookies instead of minting a session. Fire-and-forget reconcile catches document why they report through pin status instead of the error sink.
Non-sidecar reconcile failures now reach reportError instead of dying as log lines; the blocked branch keeps already-present pins honest; the observer's shutdown contract is documented as what it actually is; debug residue and dead code from the first pass are gone.
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.
Linear: CL-7584
Summary
Onboarding is now a per-tenant desired-state install, driven by a client-side document — no hub table, no boot seeding, no per-user Myra.
TENANT_DESIRED_STATEinpackages/onboarding/src/desired-state.tspins this build's stack (Myra viaDEFAULT_WORKFLOWS, the required tool packages, the default skills) by reference to the existing single-source constants. Adding a core workflow is a data edit the reconciler honors per tenant.reconcileTenantDesiredStatecompares a tenant's native workflow assets/deployments, tool registry, and skills to the document and installs only what is missing (tools → skills/grants/workflows viaseedTenant, deploy gated on the tenant's resolved catalog offerings). A converged tenant gets a reads-only pass — proven by a zero-non-GET second-pass test. Sidecar-unavailable pins reportblocked(honest copy, retry later); real failures reportfailedand re-run safely.pending_seeddrain delegates to reconcile (row semantics unchanged). (2) A tenant-create observer fires a fire-and-forget reconcile onPOST /api/tenants201 (in-process dedupe; 403 fires none) — a second tenant gets its own Myra. (3) The provision probe kicks reconcile when pins are pending; joined members included.GET /api/onboarding/provisioning-statuscarries doc-derived steps; the onboarding page renders them and collapses when ready.A second user in a tenant joins as a member and deploys nothing — one Myra per tenant.
Test plan
packages/onboardingsuites (desired-state, reconcile idempotency, drain, routes) — greenapps/hub— signup-genesis 8/8, tenant-create-onboard green,boot-does-not-seedstill proves boot seeds nothingbun test scripts/e2e/local-rip.test.ts— fresh hub → signup → connect yields Myra without boot seed; second user, second tenant, and revisit legs greenbun run check— exit 0