Files
stack/docs/plans/CONDUCTOR.md
T
jason.woltje 527bc581ca refactor(layout): role contracts move to roles/ - root is bootstrap-only
Owner direction: the repository root holds first-class, bootstrap-required
configuration only. conductor-policy.json is a ROLE contract (the
conductor's authority), one of scores of future role contracts
(agent-policy, coder-policy, ...) - such files get a dedicated home.

- roles/conductor-policy.json (git mv)
- conductor-apply.sh + test-conductor.sh read the new path
- CONDUCTOR.md records the roles/ convention

Closes UX follow-up from owner layout review; no issue (convention change).
2026-09-03 10:56:07 -05:00

2.6 KiB

Conductor protocol — poor-man orchestration loop

How the stack orchestrates headless pi workers to do work on itself.

Role contracts

Role authority is declared in role contracts, one file per role, under roles/ (e.g. roles/conductor-policy.json). The repository root holds only first-class, bootstrap-required configuration; role contracts are tracked, versioned files whose changes arrive as reviewed commits.

Roles

Role Runs where Powers Never has
Conductor host (assistant or owner) git (clone/commit/push), task dispatch, review, verification suites, Gitea nothing new
Worker container (headless pi via scripts/run-task.sh) read/write/edit/bash inside its workspace; persistent session on request git credentials, docker socket, host filesystem

The loop

  1. Decompose: conductor turns a goal into worker tasks small enough to specify completely in one prompt (file paths, acceptance criteria, style constraints, verification the worker can run itself, e.g. node --check).
  2. Mirror: conductor maintains the repo clone at <dataRoot>/workspaces/stack-repo (host-side git; workers see it read-write through their workspace mount).
  3. Dispatch: scripts/run-task.sh run <worker-task.json> — worker edits the clone. Session name worker-<n> keeps continuity across refinement rounds.
  4. Extract: git -C <workspace> diff > patch — the worker's entire output is a reviewable diff. Run record (result.json, stderr.txt) is the receipt.
  5. Review: conductor reads the diff line by line. Bad output → refine the prompt, re-dispatch (same session: "your patch had these problems…").
  6. Integrate: conductor applies the patch to the real repo, runs the full suites, commits and pushes. Suites failing → revert apply, back to step 5.
  7. Record: update CURRENT.md, BUILD-LOG, close the Gitea issue.

Guardrails

  • Workers never receive credentials; they never run git; they never leave the workspace (container is the boundary; tools allowlist is the gate).
  • Every worker diff is reviewed by the conductor before integration. No auto-apply. (Auto-apply would be a capability-policy decision for later.)
  • Verification is mechanical: suites + node --check / bash -n gates.
  • Recursive decomposition = "fail → smaller task", never "hope."

Worker task template

{
  "taskVersion": 1,
  "id": "t-worker-<name>",
  "prompt": "<full spec: goal, files, constraints, acceptance, self-checks>",
  "workspace": "stack-repo",
  "capabilities": { "tools": ["read", "write", "edit", "bash"] },
  "session": "worker-1",
  "timeoutSeconds": 600
}