# Elevasis Workspace Ship-Train

## Why this note exists

The Elevasis runtime (`external/elevasis/`) was promoted into the pnpm workspace as `packages/elevasis-{core,operations}/`. That migration exposed two latent SDK pipeline failures -- a rollup `.dts` resolver bug affecting transitive type-only peers (`openai`, `@supabase/*`, `@workos-inc/node`, etc.) and a deploy-validator crash on ESM-only `exports` maps -- both of which are now fixed in `@elevasis/sdk`. The same migration forced a formal subpath boundary contract for `@elevasis/sdk`: the default barrel is now browser-safe only, with `@elevasis/sdk/worker`, `@elevasis/sdk/node`, and `@elevasis/sdk/test-utils` as explicit runtime-gated subpaths, enforced by `no-restricted-imports` lint rules and a build-time bundle-leak test suite. Separately, workflow input/output schemas are now codified as the canonical SSOT through a three-layer pattern (operations contract owns schemas; CC imports from the workflow contract; `apps/api` stays envelope-only). The result is minor bumps to `@elevasis/core`, `@elevasis/ui`, and `@elevasis/sdk`, a `_template` dependency-baseline update, and new boundary rules that external SDK consumers must follow.

## Applies to

All template-derived projects that consume `@elevasis/sdk`, `@elevasis/core`, or `@elevasis/ui`. Specifically:

- `nirvana-marketing`
- `ZentaraHQ`
- Any future external SDK consumer derived from the `_template` baseline

`@elevasis/sdk` is now boundary-enforced. Any external project that previously imported Node-only modules from the default `@elevasis/sdk` barrel -- including `knowledge-codegen`, anything touching `node:fs`, or `worker_threads` -- must migrate those imports to `@elevasis/sdk/node`. Workflow handler code that uses `platform.call`, `acqDb`, or adapter factories should already be on `@elevasis/sdk/worker`; verify this is the case.

## Required actions

1. Pull template changes with `/git-sync` after this train publishes so the refreshed package baselines (`core/package.json`, `ui/package.json`, `operations/package.json`) reach the project.

2. After the baseline lands, update package versions in the project:

```bash
pnpm up @elevasis/core @elevasis/ui @elevasis/sdk --latest
```

Version baselines are written into the `_template` package files by the release train. Match the versions from `_template` after sync or run `--latest` to pull the published minors.

3. Run `pnpm install` from the project root after the dep bump to ensure the lockfile is updated.

4. **Audit `@elevasis/sdk` import subpaths.** In `operations/src/`, search for any import from `@elevasis/sdk` that touches `knowledge-codegen`, `node:fs`, `worker_threads`, or any other Node-only module. These must move to `@elevasis/sdk/node`. Workflow handler files that use `platform`, `acqDb`, or adapter factories belong on `@elevasis/sdk/worker` -- verify the subpath is explicit.

   ```ts
   // Before (incorrect for Node-only tooling)
   import { knowledgeCodegen } from '@elevasis/sdk'

   // After
   import { knowledgeCodegen } from '@elevasis/sdk/node'
   ```

5. **Audit for `@repo/elevasis-core` or `@repo/elevasis-operations` imports.** These package names are workspace-internal to the platform monorepo and are not published. External consumers must use the published packages (`@elevasis/sdk`, `@elevasis/core`, `@elevasis/ui`) exclusively. If a tenant project forked or copied an import path using the `@repo/elevasis-*` namespace, replace it with the appropriate published subpath.

6. **Audit workflow input/output schema usage in `ui/src/`.** Per the schema SSOT pattern, CC code should import schemas from the workflow's `contract.inputSchema` or `contract.outputSchema`, not from hand-duplicated local type declarations. If the project has hand-written copies of workflow input or output schemas in `ui/src/`, flag them for migration to direct imports from the workflow contract. If a workflow's main file imports Node-only code, use the browser-safe sibling-schema pattern (a separate `<workflow-name>-schema.ts` file, importing `node:*`-free schema definitions only) so CC can consume the schema without triggering Vite's `"fs" has been externalized` error.

7. **Rebuild and type-check:**

```bash
pnpm -C ui build
pnpm -C ui exec tsc --noEmit
pnpm -C operations exec tsc --noEmit
```

## Verification

After applying all actions above:

- `pnpm install` completes cleanly with no unresolved peer warnings.
- `pnpm check-types` passes across all project packages (`ui`, `operations`, `core`).
- `pnpm test` passes where test suites exist.
- `pnpm -C ui dev` starts the CC dev server. Navigating to any workflow detail route (e.g., a lead-gen list action form) produces no `Module "fs" has been externalized for browser compatibility` console errors. If those errors appeared before this upgrade, they should be gone.
- A workflow execution round-trips end-to-end in dev: trigger a workflow from the CC UI, confirm the execution record appears in the monitoring view.

## Not handled by /git-sync

`/git-sync` propagates template-authored files (package baselines, scaffold doc copies, sync-managed surfaces) but does NOT:

- Run `pnpm up @elevasis/core @elevasis/ui @elevasis/sdk --latest` -- dep bumps are manual after the baseline lands.
- Infer or apply subpath migrations for `@elevasis/sdk`. If any workflow in `operations/src/` was importing Node-only modules from the default `@elevasis/sdk` barrel, `/git-sync` will not rewrite those import paths to `@elevasis/sdk/node`. That migration is manual per project.
- Replace hand-duplicated workflow schemas in `ui/src/` with imports from workflow contracts. Tenant-side schema copies need manual migration to use `contract.inputSchema` / `contract.outputSchema`.
- Remove or update any `no-restricted-imports` lint rule overrides that the project may have added to disable `@elevasis/sdk` subpath enforcement. If the project disabled the rule, re-enable it after sync and resolve any violations it surfaces.
- Clear the Vite module-graph cache (`ui/node_modules/.vite`). After upgrading the SDK, clear this directory manually and restart the dev server before verifying that browser-safety errors are gone -- stale cache can make fixed boundary violations appear to persist.
