# 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. ```bash 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): ```bash 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 config** — `agents.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: ```bash 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.