Files
project-orchestrator/docs/bootstrap.md
mfowler 0456837444 feat(po): drop periodic fleet sweep — operator-driven, recover-if-dead only
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>
2026-06-14 15:04:08 +00:00

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 (stdlib tomllib), tmux — all provided by nix develop (see the README's Nix section).
  • The agent CLI the PO agent uses (claude) on PATH — external, not from Nix.
  • A git host for the PO repo (this PO lives at recipe-maintainers/project-orchestrator).

Steps (one time)

  1. Create the PO repo and clone it.

    git init -b main project-orchestrator && cd project-orchestrator
    
  2. 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
    
  3. Write the harness configagents.toml declaring the PO's own agent(s). A single kind = "persistent" project-orchestrator agent (backend claude) is enough to start; its startup prompt is prompts/orchestrator.md, with watch = "heal" (recover-if-dead) and no wake — the PO is operator-driven, not woken on a timer. (You can scaffold a starter with python3 engine/agents.py init . and then edit it, or copy this repo's agents.toml.)

  4. 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) and create/start/stop/update-project.sh.
    • docs/ — these runbooks.
  5. Add Nix + .gitignore (.ao-state/ is runtime state, never committed). Commit and push main with the submodule pinned.

  6. 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.