# Nest `projects` under `platform` (fleet-wide OM reparent)

## Why this note exists

The shared `@elevasis/ui` `deliveryManifest` now emits `systemId: 'platform.projects'` (it consumes the republished `@elevasis/core` constant `PROJECTS_SYSTEM_ID`, which flipped from `'projects'` to `'platform.projects'`). Any tenant Organization Model that still declares a **root-level** `projects` system will fail `validateManifests` on boot once it installs the new `@elevasis/ui`, because the delivery manifest references a `systemId` that does not exist in the tenant OM.

This is a fleet-wide convention change: `projects` is now a child of `platform` (canonical id `platform.projects`) everywhere — Elevasis, the template, and every derived tenant.

## Applies to

- Every tenant whose `core/config/organization-model/` declares a root `projects` system (work-item / checkpoint shape) and a root `platform` system to nest it under.
- Confirmed in this train: `ZentaraHQ`, `nirvana-marketing`. Run the verification below in any other derived project before installing the new `@elevasis/ui`.

## Required actions

Apply these in your own `core/config/organization-model/` (this is project-owned OM content — `/external sync` does NOT overwrite it; reparent it yourself via `/om`):

1. **Reparent the system.** In `systems.ts`, move the `projects` system block under the existing `platform` system. Set `id: 'platform.projects'` and add `parentSystemId: 'platform'`. Leave the object key, route `path`, and icon as-is.
2. **Rewrite ontology IDs.** Change every `projects:*` ontology id to `platform.projects:*` (objects, links, actions, catalogs, events, surfaces) — including all cross-references (`ownerSystemId`, `objectType`, `catalogType`, `from`/`to`).
3. **Navigation.** In `navigation.ts`, update any `targets: { systems: ['projects'] }` to `['platform.projects']`.
4. **Profile / roles.** In `profile.ts` (or `roles.ts`), update `deliveryFeatureId` / role `responsibleFor` references from `projects` to `platform.projects`.
5. **Tests.** Update `core/config/organization-model.test.ts`, `organization-model.contract.test.ts`, and `ui/src/routes/__tests__/__root.test.tsx` assertions that reference the `projects` system id, parent, or ontology ids.
6. **Install + reparent together.** Bump `@elevasis/core` and `@elevasis/ui` (see the dependency baseline written by `/external sync`), reparent the OM in the **same** change, then `pnpm -C core test` and `pnpm -C ui check-types` before booting the app. Do not install the new `@elevasis/ui` while the OM still has root `projects`.

Route file paths (`ui/src/routes/projects*.tsx`) stay at `/projects`; only OM ids and nav/profile targets change.

## Verification

```bash
# 1. Find any remaining root projects references
grep -rn "'projects'\|projects:" core/config/organization-model ui/src/routes

# 2. Template-family coherence
pnpm -C core test
pnpm -C ui check-types
pnpm -C ui test:contracts

# 3. Boot must not throw validateManifests (deliveryManifest systemId must resolve)
```

`platform.projects` must resolve as a child System of `platform`, and the delivery surface must render under it.

## Not handled by /git-sync

`/git-sync` and `/external sync` will deliver the new `@elevasis/core` + `@elevasis/ui` dependency baselines and this note, but they will **not** edit your `core/config/organization-model/` — tenant OM content is project-owned (`sync-preservation`). The reparent in steps 1-5 is manual per tenant. Installing the new `@elevasis/ui` without doing the reparent first will crash the app on boot.
