Files
stack/docs/fleet/how-to/customize-roles.md
T
veronica f0d2dd9920 docs(W4): stamp kind and status front matter on 104 live documents
Applies the document contract from
docs/plans/2026-08-20_stack-docs-flatten-and-alignment.md section 3, partially:
`kind` and `status` only. `parent` is deliberately held until the flatten in
section 4 lands, so that 127 documents do not have to be re-pointed by hand
when docs/fleet/NORTH_STAR.yaml moves to docs/NORTH_STAR.yaml.

Scope, measured on origin/next at 63069149:

  127 live docs   = all *.md under docs/ minus docs/archive/ minus docs/_old_structure/
  104 stamped     here
   19 held        operator judgement (plan section 9), worklist in the same PR
    3 held        the SUPERSEDED TASKS.md stamps, which cite the moving path
    1 untouched   docs/fleet/FLEET-DOCTRINE.md, already stamped in W1

Kinds applied: 54 guide, 34 record, 9 spec, 6 tracking, 1 projection.
Every row carries a confidence and a one-line rationale in the worklist.

Two collisions with the existing state, both flagged rather than resolved:

1. docs/README.md:150-160 already documents a front-matter convention
   (title/type/audience/status/source_of_truth) with its own allowed values.
   It is applied to 4 of 127 files. Its `status` vocabulary is
   current|draft|deprecated|historical; the new contract's is active|superseded-by.
   The key collides. This commit lets the new contract win and rewrites
   `status: current` to `status: active` on those 4 files, keeping their other
   legacy keys untouched. No code reads any of them: `git grep source_of_truth`
   outside docs/ returns nothing. docs/README.md still prescribes the old
   convention and is an operator row, so it is not edited here.

2. Two of the plan's 20 operator rows are YAML files, not markdown
   (docs/fleet/examples/roster-v2.yaml, docs/openapi-tess.yaml), and the
   contract's front-matter form has no defined meaning for a .yaml document.
   That gap also applies to docs/fleet/NORTH_STAR.yaml, the source of truth
   itself. Raised in the worklist.

A third row from the plan, docs/fleet/north-star.md, no longer exists: W1
renamed it to docs/fleet/FLEET-DOCTRINE.md.

Verification: 104/104 parse with the expected kind and status in front matter;
the check was shown to reject a wrong kind before it was trusted. The diff
removes 4 lines total, all of them `status: current`.
2026-08-20 19:30:25 -05:00

60 lines
2.3 KiB
Markdown

---
kind: guide
status: active
---
# Customize Fleet Roles
Mosaic resolves persona contracts through two layers:
1. fleet/roles/<canonical-class>.md — seeded baseline contract.
2. fleet/roles.local/<canonical-class>.md — operator override or custom role; this layer wins.
The same shared resolver is used by profile validation, provisioning, roster-v2 semantic validation,
and launch-time persona injection.
## Override a baseline role
Create a readable Markdown contract under `roles.local` with the canonical filename and class marker:
```markdown
# Code — local role definition
The local code role (`class: code`) follows the operator's repository conventions.
```
Save it as `fleet/roles.local/code.md`. Do not edit generated or seeded baseline assets when the goal
is a durable local customization.
Legacy aliases canonicalize before lookup. Therefore `roles.local/implementer.md` does not override
`code`; use `roles.local/code.md`. See [Legacy Fleet Class Aliases](../migration/legacy-class-aliases.md).
## Add a custom class
A custom class remains supported when a readable contract exists for the exact identifier:
```markdown
# Release notes — local role definition
The release-notes role (`class: release-notes`) prepares operator-reviewed release copy.
```
Save it as `fleet/roles.local/release-notes.md`, then reference class: release-notes and a matching
tool_policy: release-notes in roster v2. Adding only a `LIBRARY.md` row is insufficient.
Names such as `worker`, `analyst`, and `canary` are not built-in aliases; they need genuine custom
contracts. agents[].alias, Tess, and Ultron are display names and cannot select a class.
## Validation and authority boundaries
Semantic validation reads the winning contract and rejects missing, unreadable, or empty files.
Protected authority is derived from canonical class metadata in code, never from role prose. A custom
contract cannot claim merge, validation-certificate, orchestration, lease, or interaction authority.
Roster v2 also fails closed when a protected class and tool policy do not match after canonicalization,
or when an unprotected class claims a protected tool policy. The legacy `operator-interaction` policy
canonicalizes to `interaction`.
Role customization does not issue leases, store validation certificates, mutate credentials, or
change lifecycle state.