Implements North Star goal H2: a declarative mapping from a system type to a persona roster + org topology, plus a loader/validator and a mosaic fleet profile CLI. Profiles are DATA (yaml seeded like roles), so an operator declares a system type and gets the matching roster from the baseline library with no code change (NS-9 / AC-NS-6).
Profile yaml schema
id: kebab system-type id (== filename stem)
title: human name
description: one paragraph
lead: persona class that coordinates the roster (the orchestrating seat)
floor: [persona class] # persistent minimum that stays staffed
roster: # full default roster
- class: <persona class> # MUST resolve to a real role's class
reports_to: <persona class> # optional; omit for lead; encodes topology
multiplicity: <int, default 1>
notes: optional
The full schema lives commented in software-delivery.yaml.
5 baseline profiles
id
lead
roster size (seats, w/ multiplicity)
software-delivery
planner
14
personal-assistant
personal-assistant
5
research
lead-researcher
8
business (company-in-a-box)
ceo
10
marketing
marketing-lead
8
Loader / validator
packages/mosaic/src/commands/fleet-profiles.ts — loadProfiles / loadProfile / parseProfile / validateProfile. Resolves <mosaicHome>/fleet/profiles/*.yaml via the same MOSAIC_HOME helper as the rest of fleet code (tests use a dir-override param). listPersonaClasses() derives the set of valid classes from the role library by unioning three signals: inline `class: X` markers (handles the newline-wrapped support-agent marker), LIBRARY.md index rows, and role filenames — so marker-less engineering personas (planner, decomposition) resolve. Validation rejects unknown lead/floor/roster.class/reports_to, duplicate ids, and a reports_to not present in the roster.
CLI
mosaic fleet profile list [--json] and mosaic fleet profile show <id> [--json]. Invalid profiles / unknown ids exit non-zero with a readable message.
Library-drift validation test
fleet-profiles.spec.ts includes the key guard: every class referenced by every baseline profile resolves against the real committed role library — so roster/library drift fails CI. Also covers parse defaults, list/show shape, and unknown-class / unknown-reports_to rejection via a temp dir.
Deviation
The task spec asked for lead: orchestrator on software-delivery, but orchestrator has no role file or class: marker — roles/planner.md states "the planner role IS the existing orchestrator class". To keep every referenced class resolvable (the hard validation requirement), software-delivery uses planner as lead and [planner, enhancer] as floor. Documented inline in the yaml.
## H2 — System-type profiles (declarative roster + topology)
Implements North Star goal **H2**: a declarative mapping from a *system type* to a persona roster + org topology, plus a loader/validator and a `mosaic fleet profile` CLI. Profiles are **DATA** (yaml seeded like roles), so an operator declares a system type and gets the matching roster from the baseline library with **no code change** (NS-9 / AC-NS-6).
### Profile yaml schema
```
id: kebab system-type id (== filename stem)
title: human name
description: one paragraph
lead: persona class that coordinates the roster (the orchestrating seat)
floor: [persona class] # persistent minimum that stays staffed
roster: # full default roster
- class: <persona class> # MUST resolve to a real role's class
reports_to: <persona class> # optional; omit for lead; encodes topology
multiplicity: <int, default 1>
notes: optional
```
The full schema lives commented in `software-delivery.yaml`.
### 5 baseline profiles
| id | lead | roster size (seats, w/ multiplicity) |
|---|---|---|
| software-delivery | planner | 14 |
| personal-assistant | personal-assistant | 5 |
| research | lead-researcher | 8 |
| business (company-in-a-box) | ceo | 10 |
| marketing | marketing-lead | 8 |
### Loader / validator
`packages/mosaic/src/commands/fleet-profiles.ts` — `loadProfiles` / `loadProfile` / `parseProfile` / `validateProfile`. Resolves `<mosaicHome>/fleet/profiles/*.yaml` via the same MOSAIC_HOME helper as the rest of fleet code (tests use a dir-override param). `listPersonaClasses()` derives the set of valid classes from the role library by **unioning** three signals: inline `` `class: X` `` markers (handles the newline-wrapped `support-agent` marker), `LIBRARY.md` index rows, and role filenames — so marker-less engineering personas (`planner`, `decomposition`) resolve. Validation rejects unknown `lead`/`floor`/`roster.class`/`reports_to`, duplicate ids, and a `reports_to` not present in the roster.
### CLI
`mosaic fleet profile list [--json]` and `mosaic fleet profile show <id> [--json]`. Invalid profiles / unknown ids exit non-zero with a readable message.
### Library-drift validation test
`fleet-profiles.spec.ts` includes the key guard: **every class referenced by every baseline profile resolves against the real committed role library** — so roster/library drift fails CI. Also covers parse defaults, list/show shape, and unknown-class / unknown-reports_to rejection via a temp dir.
### Deviation
The task spec asked for `lead: orchestrator` on software-delivery, but `orchestrator` has no role file or `class:` marker — `roles/planner.md` states "the planner role IS the existing orchestrator class". To keep every referenced class resolvable (the hard validation requirement), software-delivery uses **`planner`** as lead and `[planner, enhancer]` as floor. Documented inline in the yaml.
### Gates
typecheck ✓ · lint ✓ · prettier ✓ · vitest **585 passed** (incl. 16 new profile tests) ✓ · CLI smoke-tested from `dist/cli.js`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add declarative system-type profiles: framework/fleet/profiles/*.yaml map a
system type to a persona roster + org topology (reports_to, multiplicity).
Profiles are DATA, seeded like roles, so an operator declares a system type and
gets the matching roster from the baseline library with no code change
(NS-9 / AC-NS-6).
- 5 baseline profiles: software-delivery, personal-assistant, research,
business (company-in-a-box), marketing.
- fleet-profiles.ts: loadProfiles/loadProfile/parseProfile/validateProfile +
listPersonaClasses (extracts valid classes from the role library by unioning
inline `class:` markers, LIBRARY.md rows, and role filenames so marker-less
personas like planner/decomposition resolve).
- CLI: `mosaic fleet profile list|show [--json]`; invalid profiles exit non-zero.
- Spec covers parse/validate, the library-drift guard (every referenced class
resolves against the real role library), and unknown-class/reports_to rejection.
- install.sh: profiles seed via the existing rsync (comment clarified; the
preserved top-level `fleet/*.yaml` glob does not shadow fleet/profiles/*.yaml).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
H2 — System-type profiles (declarative roster + topology)
Implements North Star goal H2: a declarative mapping from a system type to a persona roster + org topology, plus a loader/validator and a
mosaic fleet profileCLI. Profiles are DATA (yaml seeded like roles), so an operator declares a system type and gets the matching roster from the baseline library with no code change (NS-9 / AC-NS-6).Profile yaml schema
The full schema lives commented in
software-delivery.yaml.5 baseline profiles
Loader / validator
packages/mosaic/src/commands/fleet-profiles.ts—loadProfiles/loadProfile/parseProfile/validateProfile. Resolves<mosaicHome>/fleet/profiles/*.yamlvia the same MOSAIC_HOME helper as the rest of fleet code (tests use a dir-override param).listPersonaClasses()derives the set of valid classes from the role library by unioning three signals: inline`class: X`markers (handles the newline-wrappedsupport-agentmarker),LIBRARY.mdindex rows, and role filenames — so marker-less engineering personas (planner,decomposition) resolve. Validation rejects unknownlead/floor/roster.class/reports_to, duplicate ids, and areports_tonot present in the roster.CLI
mosaic fleet profile list [--json]andmosaic fleet profile show <id> [--json]. Invalid profiles / unknown ids exit non-zero with a readable message.Library-drift validation test
fleet-profiles.spec.tsincludes the key guard: every class referenced by every baseline profile resolves against the real committed role library — so roster/library drift fails CI. Also covers parse defaults, list/show shape, and unknown-class / unknown-reports_to rejection via a temp dir.Deviation
The task spec asked for
lead: orchestratoron software-delivery, butorchestratorhas no role file orclass:marker —roles/planner.mdstates "the planner role IS the existing orchestrator class". To keep every referenced class resolvable (the hard validation requirement), software-delivery usesplanneras lead and[planner, enhancer]as floor. Documented inline in the yaml.Gates
typecheck ✓ · lint ✓ · prettier ✓ · vitest 585 passed (incl. 16 new profile tests) ✓ · CLI smoke-tested from
dist/cli.js.🤖 Generated with Claude Code