Files
orchestra/deploy/config.example.jsonc
T
kami a221502356 Let Orchestra establish plan progress instead of the implementer asserting it
A detailed plan that nothing enforces is a document. This makes the phases
executable: the implementer may write exactly one status, and every other
status is a conclusion Orchestra reaches by running the plan's own commands.

    agent may request:  ready_for_verification
    agent may not assert: verified, awaiting_manual_verification, failed, skipped

The worker resolves commands from the coordinator, never from the request, so a
request cannot smuggle in a command the planner did not write. They run as argv
through exec with Dir set to the worktree, which is the quality gate's existing
envelope and not a weaker one. There is no shell, so a pipe is a literal
argument.

Project policy decides executable reach. registry.Project.Verification matches
argv positionally, and an absent policy refuses everything: a plan command is
agent-authored, so inheriting the operator-authored gate's reach by default
would be the wrong direction to fail in. A refused command is refused before
anything runs, and the refusal names the project and the command so the planner
learns its real reach.

Two bindings make the record mean something later. PlanRef, so progress earned
under plan A cannot survive into plan B. AtSHA, so "verified" does not outlive
the code that made it true: a record whose commit has moved is retained as
provenance and rendered as stale, never as a claim about the current tree.
Both are the same failure this codebase already fixed for reviews, which bind
to the commit they examined.

Manual steps hold a phase at awaiting_manual_verification. The sign-off is an
ordinary human decision whose subject carries the plan ref and the phase id, so
a later "looks good" on an unrelated thread cannot satisfy a gate nobody was
discussing.

A plan sealed before plan.md declares no executable unit, and says so: the
implement context states that phase progress is unavailable and the work
continues under the old semantics. Inventing phases it never had would be worse
than admitting it has none.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVbaKucEYBjMqVeUgJUsc1
2026-08-28 11:59:39 +04:00

114 lines
5.9 KiB
JSON

// Annotated reference for registry.Config (internal/registry/registry.go).
// This file is NOT valid JSON (it has comments) and is not loaded by orchestra —
// it exists purely to document fields. Copy it, strip the comments, and install
// the result as the deployed config.jsonc (bind-mounted into /etc/orchestra/ by
// compose.override.yaml). The plain config.example.json was deleted on
// 2026-07-31 as a duplicate of this file.
{
// Static project topology. One entry per project the fleet routes tasks for.
"projects": [
{
"id": "correx", // Project id; tasks/events are tagged with this.
"machine_affinity": ["mainframe"], // Machine ids (below) this project may run on.
// Required — a project with no affinity can't be routed.
"repo": "/var/lib/orchestra/repos/correx.git", // Optional per-project git repo path.
// Overrides the global ORCHESTRA_REPO default.
"worktree_root": "/var/lib/orchestra/worktrees/correx", // Optional per-project worktree dir.
// Overrides global ORCHESTRA_WORKTREE_ROOT.
"quality_gate": "go test ./... && go vet ./..." // Worker runs this before deterministic delivery.
,
// What a plan's automated verification may execute. A plan command is
// agent-authored, so it does not inherit the operator-authored quality
// gate's envelope: it runs as argv with no shell, and only if some
// pattern here matches it positionally. An absent policy refuses every
// plan command, and the planner is told so when it seals.
// "*" matches exactly one element, any value
// "x/..." matches a path argument under that prefix
// a trailing "*" matches the remaining elements, and is the only way
// a pattern authorises a longer command
"verification": {
"allowed": [
["go", "test", "./..."],
["go", "test", "./internal/..."],
["go", "vet", "./..."],
["go", "build", "./..."]
]
},
// Cognitive phase path. Omit for the default
// frame -> research -> plan -> implement -> review. A phase left out is
// skipped, which is how a trivial project runs frame/implement/review.
"work_phases": ["frame", "research", "plan", "implement", "review"],
// Phase transitions the human must confirm before work continues. The
// task blocks with block_reason "trajectory_gate" and the decision
// packet arrives on the usual notification surfaces. Any reply is
// recorded as a human decision and outranks the sealed plan.
"trajectory_gate": { "plan_to_implement": "required" },
// Per-task budget for bounded questions to the human. Default 6. Once
// spent, the task blocks with block_reason "operator_required" and a
// reply no longer resumes it, so a task cannot become an interview.
"human_decisions": { "max_requests_per_task": 6 }
},
{
"id": "maven",
"machine_affinity": ["mainframe", "satellite"] // Multiple affinities: routable to either machine.
// repo/worktree_root omitted here: falls back to the deployment's global default.
}
],
// Physical/logical machines in the fleet. herdrs.machine_id below must reference one of these.
"machines": [
{ "id": "mainframe", "address": "10.0.0.10:9145" }, // address: host:port this machine's orchestra API listens on.
{ "id": "satellite", "address": "10.0.0.11:9145" }
],
// Herdrs: individual harness worker slots that execute tasks.
"herdrs": [
{
"id": "mainframe-claude-1", // Unique herdr id.
"machine_id": "mainframe", // Which machine (above) this herdr runs on.
"backend": "herdr", // Pane backend: "herdr" (default) or "tmux" (Claude only).
// "address" omitted: falls back to the parent machine's address (used here since
// this herdr's harness listens on the machine's default port).
"harness": "claude", // Harness adapter to use: "claude" | "codex" | "opencode".
"protocol": "1", // Herdr wire protocol version. Falls back to
// ORCHESTRA_HERDR_PROTOCOL if omitted.
"capabilities": ["code", "review"], // Task capability tags this herdr can accept.
"concurrency": 2, // Max simultaneous sessions this herdr will run.
"quota_limit_5h": 50, // Rolling 5-hour usage quota (harness-specific units).
"quota_limit_weekly": 500 // Rolling weekly usage quota.
// "quota_limit" (deprecated): if set without quota_limit_5h, treated as weekly-only,
// to preserve old configs' historical meaning without inventing a 5h cap.
},
{
"id": "satellite-claude-1",
"machine_id": "satellite",
"backend": "tmux", // tmux entries are always worker-owned, including on the
// coordinator machine; the worker reports local health.
"harness": "claude",
"capabilities": ["code"],
"concurrency": 1,
"quota_limit_5h": 20,
"quota_limit_weekly": 200
},
{
"id": "mainframe-codex-1",
"machine_id": "mainframe",
"harness": "codex", // OpenAI Codex CLI harness adapter.
"protocol": "1",
"capabilities": ["code"],
"concurrency": 1,
"quota_limit_weekly": 300 // codex has no separate 5h window tracked here; weekly only.
},
{
"id": "satellite-opencode-1",
"machine_id": "satellite",
"address": "10.0.0.11:9345",
"harness": "opencode", // OpenCode CLI harness adapter.
"protocol": "1",
"capabilities": ["code", "review"],
"concurrency": 1,
"quota_limit_weekly": 300
}
]
}