Skip to content

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.

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.

Durable-work dependencies point from a consumer to its prerequisites. Create leaves first and the final root last:

Terminal window
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 14400000

The 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.

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
}
Terminal window
harn supervisor create --team ./team.json \
--mission ./mission.json --replanning ./replanning.json \
--id goal-release

The 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.

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
}
}
}
Terminal window
harn supervisor create work-root --team ./team.json \
--replanning ./replanning.json --id goal-release

Paths 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:

Terminal window
harn supervisor plan list goal-release
harn supervisor plan show goal-release plan-0001-a1b2c3d4
harn supervisor plan approve goal-release plan-0001-a1b2c3d4 \
--actor operator --reason "Scoped recovery graph"
# or
harn supervisor plan reject goal-release plan-0001-a1b2c3d4 \
--actor operator --reason "Needs a narrower migration"
# or, after the plan stops for human judgment
harn 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.

Terminal window
harn supervisor tick goal-release --subscription-only
harn supervisor run goal-release --subscription-only --policy ./policy.jsonc

tick 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 accepted complete proposal;
  • 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.

Enroll one or more existing goals in the repository’s optional detached service:

Terminal window
harn supervisor service start goal-release goal-docs \
--subscription-only --policy ./policy.jsonc
harn supervisor service status
harn supervisor service logs --lines 100
harn supervisor service stop

The 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 fails closed by default:

  • Passing proof stops in in_review. --accept-passing-proof authorizes the supervisor to append an explicit acceptance event as its own actor.
  • A resolved approval resumes the same attempt by default. Use --no-resume-approved to require a separate invocation.
  • Failed work stops blocked. --retry-blocked authorizes bounded retry, still constrained by work-level and goal-wide attempt ceilings. The new attempt receives a frozen synopsis of the preceding terminal evidence as ctx.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.

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.