The PO's job is to manage projects on request, not watch them live. Remove the hourly wake/sweep entirely: - agents.toml: watch="heal" (recover-if-dead), no `wake` field - prompts/supervise.md: deleted - prompts/orchestrator.md, README.md, docs/bootstrap.md, docs/manage-projects.md: drop sweep/wake references; document operator-driven, no periodic sweep Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.3 KiB
Bootstrap — how the first project-orchestrator is hand-scaffolded
The PO creates projects — but nothing creates the first PO. It is hand-scaffolded once. Thereafter the PO can create projects, and can even re-scaffold itself. This doc records that one-time setup so a fresh PO can be stood up from scratch (it is exactly how this repo was made).
What a PO is
A PO is just a project that uses the agent-orchestrator harness, plus two things no ordinary
project has: a fleet registry (fleet.toml) and fleet-management agents/runbooks
(prompts/, scripts/, docs/). Its architecture is identical to any project; only its job
differs. So bootstrapping a PO = scaffolding a normal agent-orchestrator project, then adding the
fleet pieces.
Prerequisites
git(with submodule support),python3 >= 3.11(stdlibtomllib),tmux— all provided bynix develop(see the README's Nix section).- The agent CLI the PO agent uses (
claude) onPATH— external, not from Nix. - A git host for the PO repo (this PO lives at
recipe-maintainers/project-orchestrator).
Steps (one time)
-
Create the PO repo and clone it.
git init -b main project-orchestrator && cd project-orchestrator -
Vendor the harness as
engine/, pinned at a release tag (the submodule pin IS the engine version):git submodule add https://git.autonomic.zone/recipe-maintainers/agent-orchestrator.git engine git -C engine fetch --tags && git -C engine checkout v0.1.0 git add .gitmodules engine -
Write the harness config —
agents.tomldeclaring the PO's own agent(s). A singlekind = "persistent"project-orchestratoragent (backendclaude) is enough to start; its startup prompt isprompts/orchestrator.md, withwatch = "heal"(recover-if-dead) and nowake— the PO is operator-driven, not woken on a timer. (You can scaffold a starter withpython3 engine/agents.py init .and then edit it, or copy this repo'sagents.toml.) -
Add the fleet pieces (what makes this project a PO):
fleet.toml— the registry (schema:docs/fleet-registry.md), starting empty or with a sample.prompts/orchestrator.md— the PO agent's role / startup prompt.scripts/—fleet.py(read/validate the registry) andcreate/start/stop/update-project.sh.docs/— these runbooks.
-
Add Nix +
.gitignore(.ao-state/is runtime state, never committed). Commit and pushmainwith the submodule pinned. -
Bring the PO up — exactly like any project:
nix develop -c python3 engine/agents.py status # sanity: config parses, agent listed nix develop -c python3 engine/agents.py up # start the PO agent + its watchdog
That's it — the PO is live. From here it manages the fleet via the runbooks in
docs/manage-projects.md, and can scaffold further projects (including a replacement PO) with
scripts/create-project.sh.
Re-scaffolding the PO later
Because a PO is just a project, an existing PO can create a new PO by running the create-a-project flow with this repo's URL as the engine consumer and then adding the fleet pieces — or, more simply, by cloning this repo recursively. The bootstrap above is only needed when there is no PO at all.