Fleet setup flow
This page explains how a manager standardizes Octopus across 6+ repos at
once — the end-to-end seeding flow behind fleet-bootstrap
. It assumes a multi-stack fleet with legacy code, because that is the
case that shapes the design.
The model in one picture
┌─────────────────────── workspace repo ───────────────────────┐ │ rules/common/*.local.md (shared rules, symlinked) │ manager ──► │ fleet.yml (baseline + profiles + tiers + │ edits one │ repos map) │ file │ templates/{ide,precommit,ci}/<stack>.* (optional standard) │ └───────────────┬───────────────────────────────────────────────┘ │ fleet-bootstrap reads it ▼ for each repo: compose .octopus.yml = baseline ∪ profile(s) ∪ tier │ ▼ `octopus setup` ──► seeds the repo (rules, hooks, agent config, .editorconfig, .husky)The manager edits one fleet.yml; every repo receives a composed
.octopus.yml and is seeded by octopus setup. The repos never contain
fleet.yml — only the composed result.
The layered standard
There is no single canonical .octopus.yml on a multi-stack fleet. The
standard is composed per repo:
baseline stack profile adoption tier (every repo) (detected or pinned) (per repo) ───────────── ───────────────────── ────────────── agents dotnet → backend+dotnet T0 hooks:false workflow node → backend T1 hooks:true + enforce-ide workspace: frontend→ frontend T2 + enforce-precommit + CI quality, docs python → backend mentor, architect, security └──────────────────┬───────────────────────────┘ ▼ composed .octopus.yml for the repofleet.yml
# <workspace>/fleet.ymlbaseline: agents: [claude, opencode] workflow: true workspace: git@github.com:acme/octopus-workspace.git bundles: [quality, docs] # tech-lead is the manager's install, not baseline roles: [mentor, architect, security]
profiles: dotnet: { detect: ["*.sln", "*.csproj"], bundles: [backend], skills: [dotnet] } node-backend: { detect: ["package.json + (express|nestjs)"], bundles: [backend] } frontend: { detect: ["package.json + (react|next)"], bundles: [frontend] } python: { detect: ["pyproject.toml", "requirements.txt"], bundles: [backend] }
tiers: T0: { hooks: false, precommit: false, qualityWorkflow: false } T1: { hooks: true, precommit: false, qualityWorkflow: false } T2: { hooks: true, precommit: true, qualityWorkflow: true }
repos: - { path: ../billing-api, profile: dotnet, tier: T0 } # legacy - { path: ../checkout-web, tier: T1 } # auto-detected - { path: ../payments-svc, profile: node-backend, tier: T2 } - { path: ../legacy-erp, profile: [dotnet, frontend], tier: T0 } # monorepoThe seeding chain
fleet-bootstrap octopus setup enforce-*─────────────── ───────────── ─────────1. resolve profile + tier2. compose .octopus.yml3. diff vs current ─ preview4. (--apply) write manifest └──────────────────────► expand bundles deliver rules (workspace symlinked) deliver skills / roles / knowledge if T1+: ───────────────────────────► .editorconfig (per stack) if T2+: ───────────────────────────► .husky / pre-commit (per stack) if T2: qualityWorkflow CI template5. (--pr) branch + PR per repofleet-bootstrap writes only the .octopus.yml. Everything else is
octopus setup’s job — identical to a single-repo install. Stack-specific
.editorconfig / .husky are generated by detecting each repo’s stack (a
monorepo gets both), idempotent and merge-respecting.
The tier ratchet (legacy adoption)
T0 ───────────────► T1 ───────────────► T2 capabilities loop-level full ─────────── ────────── ──── hooks: false hooks: true + enforce-precommit (.husky) no .editorconfig + enforce-ide + qualityWorkflow (CI) no .husky (.editorconfig) no CI no commit/CI gate blocking floor on every commit/PR
safe on any legacy catches new only when the repo immediately assistant drift is cleanThe key insight: loop-level hooks only act on what the agent edits going
forward — they do not retroactively fail legacy code. What breaks legacy is
the git-level pre-commit and CI, so those live in T2. A legacy repo starts at
T0/T1; the manager edits tier: in fleet.yml and re-runs to promote it.
Config-template precedence
When enforce-ide / enforce-precommit write .editorconfig / .husky, the
source is resolved highest-wins:
1. project-local the repo's own file / *.local.md ← always wins 2. workspace template <workspace>/templates/{ide,precommit}/<stack>.* 3. generated default Octopus stack-inferred generation ← fallbackSo a fleet manager curates one editor/git standard in the workspace, and it overrides the generic generated default — while a repo’s intentional local choice still wins, and generation fills the gaps. This is the workspace config-template precedence.
The merge policy
A repo that already has an .octopus.yml is merged per key, never clobbered:
converge baseline + tier values (add missing; set hooks/CI) keep local additions matching the profile (justified — e.g. backend-developer) flag local additions matching neither (⚠ conflict — keep or drop?) flag any tier de-escalation (⚠ reducing enforcement) survive *.local.md rule overrides (project layer always wins)Nothing is removed silently; de-escalations and arbitrary keeps are surfaced for a human — this is the non-destructive fleet merge policy.
Usage examples
First bootstrap — preview, then apply:
# dry-run: print the per-repo diff, write nothingoctopus fleet bootstrap# apply: write the merged .octopus.yml + run octopus setup in eachoctopus fleet bootstrap --applyPromote a legacy repo a tier — edit fleet.yml (tier: T0 → T1), then:
octopus fleet bootstrap --apply # only the changed repo actually changesAdd a new repo — append it to repos: (profile auto-detected), then apply.
Guarded rollout via PRs (never pushes to main):
octopus fleet bootstrap --apply --prRemediate only what drifted — feed an audit-fleet report:
octopus fleet bootstrap --apply --from-audit fleet-report.mdSee also
fleet-bootstrapskill- Bundle composition — how bundles expand
audit-fleet— the detect half of detect → remediate