Skip to content

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 repo

fleet.yml

# <workspace>/fleet.yml
baseline:
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 } # monorepo

The seeding chain

fleet-bootstrap octopus setup enforce-*
─────────────── ───────────── ─────────
1. resolve profile + tier
2. compose .octopus.yml
3. diff vs current ─ preview
4. (--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 template
5. (--pr) branch + PR per repo

fleet-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 clean

The 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 ← fallback

So 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:

Terminal window
# dry-run: print the per-repo diff, write nothing
octopus fleet bootstrap
# apply: write the merged .octopus.yml + run octopus setup in each
octopus fleet bootstrap --apply

Promote a legacy repo a tier — edit fleet.yml (tier: T0T1), then:

Terminal window
octopus fleet bootstrap --apply # only the changed repo actually changes

Add a new repo — append it to repos: (profile auto-detected), then apply.

Guarded rollout via PRs (never pushes to main):

Terminal window
octopus fleet bootstrap --apply --pr

Remediate only what drifted — feed an audit-fleet report:

Terminal window
octopus fleet bootstrap --apply --from-audit fleet-report.md

See also