harn supervisor
harn supervisor create [root-work-id] --team <file> [--id <goal-id>] [--title <text>] [--max-cycles <n>] [--max-runtime-ms <n>] [--max-parallel-work <n>] [--max-total-attempts <n>] [--max-agents-per-work <n>] [--agent-concurrency <n>] [--accept-passing-proof] [--no-resume-approved] [--retry-blocked] [--replanning <file>] [--mission <file>] [--json]harn supervisor list [--json]harn supervisor show <goal-id> [--json]harn supervisor plan list <goal-id> [--json]harn supervisor plan show <goal-id> <plan-id> [--json]harn supervisor plan approve <goal-id> <plan-id> [--actor <name>] [--reason <text>] [--json]harn supervisor plan reject <goal-id> <plan-id> --reason <text> [--actor <name>] [--json]harn supervisor plan retry <goal-id> <plan-id> --reason <text> [--actor <name>] [--json]harn supervisor tick <goal-id> [workflow host options] [--json]harn supervisor run <goal-id> [workflow host options] [--json]harn supervisor service start [goal-id...] [service options] [--json]harn supervisor service run [goal-id...] [service options] [--json]harn supervisor service status [--json]harn supervisor service stop [--json]harn supervisor service logs [--lines <n>]A supervisor is a bounded host above
harn work. It reconstructs a root work item’s immutable dependency
closure, selects legal progress actions, dispatches bounded workflow attempts,
and reconstructs the graph from journals and proof before every new cycle.
It does not change reconciliation. Running harn work reconcile remains
observational. Foreground supervisor tick / supervisor run and the optional
explicitly enrolled service are the only hosts that can execute the automation
policy frozen at goal creation.
Define a specialist team
Section titled “Define a specialist team”The team file is a JSON object keyed by role ID:
{ "architect": { "instructions": "Own system boundaries, contracts, and decomposition.", "harness": "codex", "effort": "high", "maxTurns": 20, "timeoutMs": 900000 }, "implementer": { "instructions": "Implement the assigned slice and attach concrete verification.", "harness": "claude-code", "maxTurns": 30 }, "reviewer": { "instructions": "Review independently. Report defects with file and evidence references.", "harness": "codex", "effort": "high" }}A workflow selects a frozen profile:
export default async ({ agent, evidence }) => { const result = await agent("Implement the scoped change", { specialist: "implementer", }); const review = await agent(`Review this result:\n${result}`, { specialist: "reviewer", }); evidence({ kind: "review", status: "passed", label: "Independent review complete", acceptanceIds: ["review"], }); return { result, review };};Instructions and defaults are copied into the private supervisor intent. Each workflow run freezes that same map in its run manifest, so a parked run resumes under exactly the team contract it started with. The original team file may be moved or edited without changing existing goals.
Create the graph and goal
Section titled “Create the graph and goal”Durable-work dependencies point from a consumer to its prerequisites. Create leaves first and the final root last:
harn work create "Implement" ./workflows/implement.mjs \ --objective "Produce the scoped implementation" --id work-implement
harn work create "Verify" ./workflows/verify.mjs \ --objective "Verify the implementation" \ --depends-on work-implement --id work-verify
harn supervisor create work-verify --team ./team.json \ --id goal-release --max-runtime-ms 14400000The supervisor intent is private and immutable. It freezes the root, the full team, automation decisions, and these defaults:
| Limit | Default | Meaning |
|---|---|---|
max_cycles |
50 | Scheduling/reconciliation cycles per run invocation |
max_runtime_ms |
14,400,000 | Four-hour foreground wall-time ceiling |
max_parallel_work |
1 | Work workflows running at once |
max_total_attempts |
100 | Attempt budget across the complete graph |
max_agents_per_work |
20 | Child-agent ceiling inside one work workflow |
agent_concurrency |
4 | Child concurrency inside one work workflow |
The maximum simultaneous children is max_parallel_work × agent_concurrency.
Work items retain their own stricter attempt limits.
Start from a mission
Section titled “Start from a mission”To let the planner create the first bounded graph, omit the root work ID and provide a mission file alongside replanning authority:
{ "objective": "Ship the verified release without weakening compatibility", "acceptance": [ "The requested behavior is available through the public package", "Regression, package, and runtime verification pass" ], "max_milestones": 4}harn supervisor create --team ./team.json \ --mission ./mission.json --replanning ./replanning.json \ --id goal-releaseThe mission, team, planner, templates, policy, and limits are normalized into
private immutable intent before the first planner runs. Harnery creates no
placeholder work item. The initial projection is ready/plan_initial; one
ordinary tick or run produces an initial plan request.
Mission plans materialize one milestone at a time. An apply proposal includes
the milestone sequence, title, objective, acceptance, and its immutable work
graph. When that graph’s root is explicitly accepted, the goal becomes
ready/plan_milestone and the planner reassesses structured proof and remaining
bounds. It may propose another milestone, return attention, or propose
complete. Completion follows the same explicit-review default as work plans;
only a durable plan.completed event succeeds the mission.
Reject a plan with a narrow reason to redirect the next bounded proposal. The
rejected proposal remains unchanged and its planner call still consumes budget.
Mission, recovery, and completion requests all share max_replans; for an
objective-first mission that bound must be greater than max_milestones so a
final boundary decision remains possible.
Bounded dynamic replanning
Section titled “Bounded dynamic replanning”Replanning is opt-in at goal creation. Pass a JSON policy that names one frozen specialist as the planner and exposes a bounded catalog of workflows the planner is allowed to select:
{ "planner_specialist": "architect", "auto_apply": false, "max_replans": 5, "max_work_items_per_plan": 8, "max_total_work_items": 25, "review": { "reviewer_specialists": ["reviewer"], "max_revision_rounds": 1 }, "templates": { "implementation": { "workflow": "./workflows/implement.mjs", "max_attempts": 3, "root": true }, "verification": { "workflow": "./workflows/verify.mjs", "max_attempts": 2, "root": true } }}harn supervisor create work-root --team ./team.json \ --replanning ./replanning.json --id goal-releasePaths are resolved relative to the replanning file. Harnery freezes each workflow’s absolute path, SHA-256 digest, attempt ceiling, and root capability inside goal intent. A later file edit is detected before planner-created work is materialized.
review is optional. When present, it freezes an ordered panel of specialists
from the same team file and a hard revision bound. Reviewers must be distinct
from the planner. A panel contains one to five reviewers and
max_revision_rounds may be zero to three. The supervisor rejects a review
policy whose worst-case planner, reviewer, and revision calls would exceed
max_agents_per_work.
Without a mission, the planner runs only after the active graph has no legal progress action. It does not replace review, approval, cancellation, retry policy, or an exhausted goal-wide work-attempt budget. One schema-gated planner child receives the active graph, remaining bounds, and frozen template catalog. Its result is one of:
apply: a replacement graph with a new root;attention: a bounded explanation that operator judgment is required.
Every proposed dependency must name an active work ID or an earlier key in the
same proposal. Every proposed item must be reachable from the proposed root,
and the root must use a template explicitly marked root: true. The planner
cannot introduce a script path, mutate an existing work intent, or remove
history.
Proposals are private under
.harnery/supervisors/<goal-id>/plans/<plan-id>/. Review and resolve them with:
harn supervisor plan list goal-releaseharn supervisor plan show goal-release plan-0001-a1b2c3d4harn supervisor plan approve goal-release plan-0001-a1b2c3d4 \ --actor operator --reason "Scoped recovery graph"# orharn supervisor plan reject goal-release plan-0001-a1b2c3d4 \ --actor operator --reason "Needs a narrower migration"# or, after the plan stops for human judgmentharn supervisor plan retry goal-release plan-0001-a1b2c3d4 \ --actor operator --reason "Keep the migration local and preserve the old API"Approval creates new immutable work items with planner provenance, then appends
a plan.applied event that advances the goal’s active root. The prior graph is
not edited or deleted. All attempts across original and superseded generations
continue to count against max_total_attempts, so replanning cannot reset the
execution budget.
Rejecting a proposal records the reason as planner feedback and makes the goal
eligible for another bounded planner attempt, if its replan budget remains.
An attention decision stays quiescent because the planner itself has declared
that another model pass cannot safely resolve the missing judgment. When an
operator supplies that judgment, plan retry appends one addressed
plan.retry_requested event to the latest attention plan. It requires an
unchanged active graph and a remaining replan slot, then creates a distinct
planner workflow on the next tick. The original request, proposal, review
receipt, attention event, frozen team, templates, and cumulative limits remain
unchanged. Repeating the accepted retry is idempotent.
With independent plan review enabled, a planner candidate is reviewed before it
can become a pending proposal. Each reviewer returns structured findings and a
verdict. Any attention, revise, or blocking finding fails the round. If
revision budget remains, the planner must return a complete replacement
candidate, which receives a new full review. Exhaustion, reviewer failure, or a
no-change revision parks the plan for human attention.
Passing review writes a bounded receipt and a plan.reviewed event, then
continues through ordinary plan authority. It does not approve execution by
itself. harn supervisor plan show renders receipt status, round count, and
finding totals; --json includes the complete plan record for tooling.
auto_apply defaults to false. Setting it to true is immutable authority
for valid proposals to advance the active root without human review. Schema,
template, dependency, reachability, workflow-digest, per-plan, cumulative-work,
replan, cycle, wall-time, and work-attempt bounds still apply.
Tick and run
Section titled “Tick and run”harn supervisor tick goal-release --subscription-onlyharn supervisor run goal-release --subscription-only --policy ./policy.jsonctick performs at most one cycle. It is useful for schedulers, tests, and
stepwise inspection. run repeats in the foreground until one of these stop
conditions is reconstructed:
- a non-mission root reaches explicitly accepted
succeeded, or a mission receives an acceptedcompleteproposal; - work needs an unresolved approval or explicit review;
- blocked work is not authorized for retry, or its attempt limit is exhausted;
- the graph-wide attempt, cycle, or wall-time limit is exhausted;
- a cycle produces no durable state change;
- no legal progress action remains.
Process loss does not erase the goal. Restart supervisor run; work attempt
receipts, workflow journals, approvals, proofs, and accepted dependencies
determine where it continues. A private exclusive lease prevents two
supervisors from driving the same goal concurrently.
Standard workflow host options remain available: --harness, --cwd,
--subscription-only, --allow-api-billing, --policy, --isolation, and
--approval-to.
Background service
Section titled “Background service”Enroll one or more existing goals in the repository’s optional detached service:
harn supervisor service start goal-release goal-docs \ --subscription-only --policy ./policy.jsoncharn supervisor service statusharn supervisor service logs --lines 100harn supervisor service stopThe service is one process per coordination root. It runs one supervisor tick
for each ready goal, then polls compact durable state without making model calls
while goals are unchanged. A review, unresolved approval, terminal state, or
blocked goal becomes awaiting_change. A replanning-enabled terminal graph is
instead ready for one bounded planner tick. A pending proposal then becomes
awaiting_change; approving it changes the active-root fingerprint and wakes
the service without model churn while it waits.
Service configuration is private and frozen at start under
.harnery/supervisor-service/config.json. It includes the exact enrolled goal
IDs, runtime options, and normalized host-policy content. The policy file may be
moved or edited without changing a running or restarted service. Stop the
service before changing its enrollment or authority.
| Service bound | Default | Meaning |
|---|---|---|
--wake-interval-ms |
5,000 | Poll interval for durable goal changes |
--heartbeat-interval-ms |
2,000 | Independent liveness update, including during long ticks |
--error-backoff-base-ms |
2,000 | First delay after a service-level error |
--error-backoff-max-ms |
300,000 | Maximum exponential service-error delay |
Backoff applies only to service failures, such as a temporarily unavailable harness. It does not authorize a failed work retry or consume a work attempt. Any durable goal change bypasses stale backoff.
The service writes private status, recoverable per-goal wake state, an audit
ledger, and a bounded-summary log beneath .harnery/supervisor-service/. The
dashboard’s Goals page shows heartbeat, enrollment, active goal, last tick
result, and backoff state through a read-only package boundary.
service stop is graceful: an active bounded tick finishes before the daemon
exits, avoiding orphaned child processes. After a process or host restart, run
harn supervisor service start with no goal IDs to reuse the existing frozen
configuration and wake state. For automatic operating-system restart, use
harn supervisor service run as the foreground command owned by the host’s
process manager.
Automation policy
Section titled “Automation policy”Automation fails closed by default:
- Passing proof stops in
in_review.--accept-passing-proofauthorizes the supervisor to append an explicit acceptance event as its own actor. - A resolved approval resumes the same attempt by default. Use
--no-resume-approvedto require a separate invocation. - Failed work stops blocked.
--retry-blockedauthorizes bounded retry, still constrained by work-level and goal-wide attempt ceilings. The new attempt receives a frozen synopsis of the preceding terminal evidence asctx.attempt.prior; the workflow decides how to use it.
These choices are immutable goal intent, not runtime convenience flags. Create a new supervisor when the automation authority must change.
Current boundary
Section titled “Current boundary”Replanning advances between immutable graph generations. It is not a mutable
kanban board: a planner cannot edit work in place, change frozen authority,
silently discard attempt cost, or choose arbitrary workflows. Harnery still
does not create worktrees and sandboxes; --isolation declares a boundary the
host already created. Mission planning adds bounded foresight without weakening
this append-only contract.