Files
stack/docs/plans/HARVEST.md
T

52 lines
4.3 KiB
Markdown

# HARVEST — patterns from mosaicstack/stack + the live fleet runtime
Sources surveyed 2026-09-03 (owner-authorized):
- `~/src/mosaic-stack` (drifted) and fresh clone at
`~/src/mosaic-stack-worktrees/v2-harvest` (branch `next` @ 0db2d19a,
"mosaic doctor structure-anchor provisioning check (T51 WP0b)")
- `~/.mosaic/fleet/` — live fleet runtime: `bin/`, `roles/` (+`-ng`),
`agents/<seat>/`, `auth/`, `roster.yaml`, `SEAT-CUTOVER.md`
Rule honored: nothing pulled whole-cloth. This file is the pattern ledger;
each adoption lands through its own milestone with tests.
## Pattern ledger
| # | Pattern (source) | Verdict | Destination |
|---|---|---|---|
| 1 | **Channel dispatcher**`fleet/bin/mosaic`: shipped npm CLI is default; dev worktree opt-in via `MOSAIC_CLI_WORKTREE` health-checked with `--version`; `MOSAIC_FLEET_CLI_OFF` forces pass-through; launcher never writes to user dirs | **steal** | M20 unified `mosaic` CLI |
| 2 | **Single canonical launcher + per-seat env**`bin/launch-seat.sh` is the only launcher; per-seat variation lives in `launch.env` ("per-seat copies drift") | **steal** | M20 CLI + agent.sh stays thin |
| 3 | **Refuse-rather-than-guess provisioning**`bin/new-seat.sh`: seat classes, `--adopt` never overwrites real identity files, `--mint` fails closed (unminted = git writes fail closed), `--dry-run` | **steal** | seat instantiation (M15 evolution) |
| 4 | **Role manifest schema v3**`roles/code-ng/mosaic-core.manifest.json`: capability bindings (id/effect/binding/status), `tools[]`, `forbiddenTools[]`, `shell.mode: denied`, `credentials` policy, `evidence` journaling, `digestRules` postcondition (`active-set-exact`, sha256 over manifest) | **adapt progressively** | M18 seat-role restriction |
| 5 | **Per-seat git identity**`MOSAIC_GIT_IDENTITY=<seat>` + `GIT_AUTHOR_NAME/EMAIL`; incident 2026-08-19: seven seats committed as the wrong identity via directory git config | **steal** | M18/M20 (we have no per-seat git writes yet — adopt before we do) |
| 6 | **Auth slots + symlink shares**`fleet/auth/<provider>/<account>/` credential dirs; seat `.pi/agent/` symlinks `auth.json settings.json models-store.json bin skills` | **adapt** | M19 auth tooling |
| 7 | **Launch-time pre-flight probes** — every consumed path checked before start; pi's `existsSync` silently appends literal path strings as prompt text (documented trap) | **steal** | M19 launch check + our existing refusal style |
| 8 | **Prompt ordering doctrine** — estate context first, seat SOUL/AGENTS last ("closest to the task wins") | **matches ours** | document in adapters/README |
| 9 | **`--check` mode** on launchers (verify provisioning without launching) | **steal** | agent.sh / release ensure |
| 10 | **ENTITY.md per seat** — identity record incl. git identity, explicitly secret-free | **steal** | seat records (extend seat.json or add ENTITY.md) |
| 11 | **`mosaic doctor`** — structure-anchor provisioning check (T51) | **adapt** | M20 `mosaic --check` |
| 12 | packages/ anatomy on `next`: `mosaic` (CLI), `auth`, `agent`, `config`, `forge`, `quality-rails`, `comms`, `macp` | reference map | M18/M19/M20 deep reads |
## Skips (for now)
- tmux comms watchers, lanes/, board/, memory/, journal/ — L5/L6 fleet
territory; our conductor loop is deliberately not a resident service.
- openbao/swarm/coolify compose stacks — deployment, far future.
- roster.yaml + roster.schema.json — superseded by our agents/ definitions
for now; revisit when fleet registration returns.
## Owner-corrected design points (2026-09-03)
- M17 revised: skills must reach **non-conductor seats as role-scoped
subsets** — agents invent tooling when the right tool isn't supplied.
Role contracts will declare skill sets; the runner loads them explicitly
(mock-verified `--skill` + `--no-skills` coexistence pending).
- M19 revised (owner's own diagnosis): auth selection was symlinks from
`agents/<seat>/.pi` into `fleet/auth`, and a missing symlink silently
fell back to defaults. Our design: the launcher reads the seat's declared
account, **ensures** the symlink/auth selection before TUI launch, and
refuses loudly on mismatch — check + fix, never silent default.
- Unified `mosaic` CLI is directional (`mosaic tui`, `mosaic yolo
<harness>`, `mosaic --check`): tracked as M20, harvested from pattern #1
and stack `packages/mosaic`.