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).
2.6 KiB
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
- 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). - Mirror: conductor maintains the repo clone at
<dataRoot>/workspaces/stack-repo(host-side git; workers see it read-write through their workspace mount). - Dispatch:
scripts/run-task.sh run <worker-task.json>— worker edits the clone. Session nameworker-<n>keeps continuity across refinement rounds. - Extract:
git -C <workspace> diff > patch— the worker's entire output is a reviewable diff. Run record (result.json, stderr.txt) is the receipt. - Review: conductor reads the diff line by line. Bad output → refine the prompt, re-dispatch (same session: "your patch had these problems…").
- Integrate: conductor applies the patch to the real repo, runs the full suites, commits and pushes. Suites failing → revert apply, back to step 5.
- 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 -ngates. - 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
}