docs(fleet): add operator configuration guide
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
42
docs/fleet/concepts/desired-vs-observed-state.md
Normal file
42
docs/fleet/concepts/desired-vs-observed-state.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Desired, Derived, and Observed Fleet State
|
||||
|
||||
## One writable authority
|
||||
|
||||
The canonical local v2 roster at `<MOSAIC_HOME>/fleet/roster.yaml` is desired state. Membership, stable identity, class, runtime/provider/model selection, launch policy, enablement, and persisted `running`/`stopped` intent are written only through generation-guarded roster mutations.
|
||||
|
||||
Derived projections are reproducible consequences of that authority:
|
||||
|
||||
- `<name>.env.generated`;
|
||||
- exact roster-named tmux sessions on the configured socket after reconciliation;
|
||||
- systemd service targets managed by installation/reconciliation.
|
||||
|
||||
Current systemd unit enablement is not yet lifecycle-conformant at boot: installation can enable every
|
||||
agent unit, and the launcher projection does not carry `enabled` or `desired_state`. Therefore reboot
|
||||
preservation for stopped/disabled agents remains an FCM-M3-002 acceptance hold, not a guaranteed
|
||||
projection behavior.
|
||||
|
||||
Observed evidence available to current roster-v2 status commands includes systemd active state, tmux
|
||||
presence, holder ownership, and unmanaged sessions. Heartbeat files are observational in the wider fleet,
|
||||
but roster-v2 `status`, `doctor`, and `verify` do not currently read them. Observation never writes back
|
||||
to the roster.
|
||||
|
||||
## Generation and ownership
|
||||
|
||||
`generation` is a positive integer concurrency fence. A mutating request must provide the current value. Successful changed CRUD increments it exactly once; stale or concurrent writers fail before mutation. Apply/reconcile rereads the canonical roster under a private exclusive lock and uses only that generation and content for effects.
|
||||
|
||||
Ownership is exact, never fuzzy. Reconciliation is limited to roster names, the configured socket, the exact holder session, a private installation identity, and private managed paths. An ownership mismatch, unmanaged session, unsafe path, stale generation, or ambiguous lock fails closed.
|
||||
|
||||
## Drift decisions
|
||||
|
||||
| Observation | Interpretation | Safe response |
|
||||
| ---------------------------------------- | ------------------------ | ---------------------------------------------------------------------- |
|
||||
| Generated file differs or is missing | Derived projection drift | Review `apply --dry-run`; regenerate from the roster. |
|
||||
| Desired `running`, exact session missing | `missing-session` | Diagnose ownership/runtime, then reconcile if safe. |
|
||||
| Desired `stopped`, exact session present | `unexpected-session` | Inspect; reconciliation may stop only the proven roster target. |
|
||||
| Disabled agent running | `disabled-running` | Inspect; disabled state wins during explicit safe reconciliation. |
|
||||
| Unknown session on the configured socket | Unmanaged state | Report only. Do not adopt, rename, or kill it. |
|
||||
| Heartbeat stale in the wider fleet | Liveness evidence | Diagnose separately; current roster-v2 status does not read heartbeat. |
|
||||
|
||||
`status` and `doctor` classify. `verify` is also observational but exits non-zero when ownership, drift, or unmanaged-state checks fail. `plan`/`apply --dry-run` validates proposed projection and lifecycle work without mutation. `apply` and `reconcile` converge only after all preconditions pass.
|
||||
|
||||
A partial projection failure does not roll the roster back. Treat the committed roster as authority and regenerate. A lifecycle failure after projection completion preserves both roster and projections for inspection. Sensitive legacy values are never printed; diagnostics are bounded to stable codes, key names where applicable, and hashes.
|
||||
23
docs/fleet/concepts/generated-env-launch-chain.md
Normal file
23
docs/fleet/concepts/generated-env-launch-chain.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Generated Environment Launch Chain
|
||||
|
||||
The launcher consumes validated data, not shell configuration.
|
||||
|
||||
1. Read and validate the canonical roster.
|
||||
2. Render deterministic `<name>.env.generated` data from that roster.
|
||||
3. Parse optional `<name>.env.local` through a strict allowlist.
|
||||
4. Reject generated-key shadowing, unknown or sensitive-looking keys, unsafe paths/values, duplicates, malformed lines, shell syntax, and command overrides.
|
||||
5. Derive the runtime command from validated runtime/model/reasoning data.
|
||||
6. Target only the exact configured tmux socket and roster session after ownership checks.
|
||||
|
||||
## File precedence and ownership
|
||||
|
||||
| File | Owner | Use |
|
||||
| ----------------- | ------------------------ | --------------------------------------------------------------------------- |
|
||||
| `.env.generated` | Mosaic projection writer | Complete deterministic roster projection. Rebuild; do not edit. |
|
||||
| `.env.local` | Operator | Optional, private, strict machine-local data. Cannot shadow generated keys. |
|
||||
| `.env` | Legacy input | One-time migration input only; never launch authority. |
|
||||
| `.env.quarantine` | Private quarantine | Retained unsafe legacy evidence; never loaded by the launcher. |
|
||||
|
||||
Neither systemd nor the launcher sources these files. No `eval`, shell expansion, arbitrary `MOSAIC_AGENT_COMMAND`, channel, or secret-reference compatibility path exists. Safe legacy generated keys are regenerated, allowed local keys are relocated, and unsafe material is quarantined.
|
||||
|
||||
Diagnostics never expose the rejected value, credential material, or command text. They are bounded to stable rule code, key name where safe, and SHA-256 content identity. See [generated environment reference](../reference/generated-env-boundary.md) and [quarantine operations](../operations/env-quarantine.md).
|
||||
20
docs/fleet/concepts/identity-class-runtime.md
Normal file
20
docs/fleet/concepts/identity-class-runtime.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Fleet Identity, Class, and Runtime
|
||||
|
||||
Each roster field has one job. Do not use names or model strings as authority shortcuts.
|
||||
|
||||
| Concern | Field | Contract |
|
||||
| ----------------------- | ------------------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| Stable machine identity | `agents[].name` | Unique, immutable mutation target and exact service/session name. |
|
||||
| Display identity | `agents[].alias` | Human-facing label only; may be changed and grants no authority. |
|
||||
| Behavioral contract | `agents[].class` | Resolves through the shared baseline plus `roles.local` persona library. |
|
||||
| Tool boundary | `agents[].tool_policy` | Must match protected canonical classes; cannot independently grant authority. |
|
||||
| Harness | `agents[].runtime` | One of `claude`, `codex`, `opencode`, or `pi`, declared in `runtimes`. |
|
||||
| Backend selection | `agents[].provider` and `model` | Explicit non-empty data; capability validity is not inferred from the display name or class. |
|
||||
| Effort | `agents[].reasoning` | `low`, `medium`, or `high`. |
|
||||
| Local placement | `working_directory` | Explicit safe local work path; not remote placement authority. |
|
||||
|
||||
Tess and Ultron are conventional instance/display names only. They are not products, required machine identities, role aliases, or authority-bearing classes. A configurable interaction instance uses `class: interaction`; a configurable validation instance uses `class: validator`. Any stable name and alias satisfying the structural contract may be used.
|
||||
|
||||
Class aliases are deliberately narrow: `implementer → code`, `reviewer → review`, and `operator-interaction → interaction`. No runtime, provider, model, persona prose, or instance name changes this mapping. See [role classes](../reference/role-classes.md) and the [validated generic example](../examples/roster-v2.yaml).
|
||||
|
||||
Roster v2 is local-only. It contains no host/SSH placement, connector, channel, secret-reference, arbitrary-command, per-agent socket, or gateway mapping fields. Those concerns require separate requirements and threat models.
|
||||
22
docs/fleet/concepts/role-authority-and-leases.md
Normal file
22
docs/fleet/concepts/role-authority-and-leases.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Fleet Role Authority and Leases
|
||||
|
||||
Role content describes behavior; protected authority is immutable code metadata derived only from the canonical class.
|
||||
|
||||
## Required workstream classes
|
||||
|
||||
`code`, `review`, `validator`, `orchestrator`, `team-leader`, `enhancer`, and `interaction` are required FCM classes. `merge-gate` is additionally protected because it remains the sole approve-to-land and merge authority.
|
||||
|
||||
| Class | Authority | Boundary |
|
||||
| -------------------------------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
||||
| `merge-gate` | Approve-to-land and merge | Sole merge authority. |
|
||||
| `validator` | Issue independent validation evidence/certificate | Never approves landing or merges. |
|
||||
| `orchestrator` | Orchestrate topology and issue bounded leases | Does not gain merge authority. |
|
||||
| `team-leader` | Use explicitly leased capacity | Cannot issue leases or mutate roster, credentials, topology authority, or merge state. |
|
||||
| `interaction` | Receive requests and report status | Cannot orchestrate, issue leases, mutate configuration, or merge. |
|
||||
| `code`, `review`, `enhancer`, custom classes | No protected authority by default | Persona prose cannot grant protected powers. |
|
||||
|
||||
A lease is capacity authorization from an orchestrator, not ownership. It must identify a bounded task or period and does not alter the leased agent's roster identity, role contract, credentials, authority, or persisted lifecycle. Expiry/revocation returns capacity; it does not rewrite the roster.
|
||||
|
||||
Semantic validation rejects protected class/tool-policy mismatch in either direction. An instance named Ultron with `class: validator` remains validation-only. An instance named Tess with `class: interaction` remains request/status-only. Renaming either instance changes no authority.
|
||||
|
||||
For resolver layering and safe customization, see [role classes](../reference/role-classes.md) and [customize roles](../how-to/customize-roles.md).
|
||||
Reference in New Issue
Block a user