Sections
On this page

run-harness

Use when the user wants an existing Flownix harness to work on something — "run-harness AF-HRNS-1 design the CSV export", "run the council on AF-FEAT-12", "прогони AF-HRNS-2 по этой фиче", "запусти харнесс", "запусти совет". Finds the harne

Run a Harness by Slug

run-harness <HARNESS-SLUG> <prompt> — for example run-harness AF-HRNS-1 спроектируй экспорт отчётов в CSV. You are the orchestrator of the run: you start it, hand its work to participants, watch it, and report back. You do not play the roles yourself unless the client cannot start sub-agents (see step 5).

Prerequisite: flownix-basics. Building a new harness is harness-blueprint, not this skill.

1. Parse the arguments

  • The first token is the harness slug: <KEY>-HRNS-<n> (e.g. AF-HRNS-1; case does not matter).
  • Everything after it, verbatim, is the prompt.
  • No slug, or no prompt → ask the user what to run / what the harness should do. Do not start a run on a guess.

2. Find the harness in the current project

shell
cat .flownix 2>/dev/null || cat .ai-flow        # project_id; none → flownix-init
harness.get(workspace_id: "<project_id>", harness_slug: "AF-HRNS-1")

A slug is looked up only inside this project. NotFound → tell the user the slug is not in this project and show what is:

shell
harness.list(workspace_id: "<project_id>")      # each item has slug, name, status, current_version

List them as AF-HRNS-1 — <name> (v<current_version> | not published) and stop.

3. Refuse drafts

harness.get returns current_version_id — empty when the harness was never published (harness.list shows no current_version). A run starts only from a published version, so: do not call harness.start_run; tell the user the harness has to be published first (in the web editor, or harness.validate + harness.publish) and stop.

4. Start the run

Collect node slugs mentioned in the prompt (<KEY>-(EPIC|FEAT|PLAN|TASK|DOC)-<n>), resolve each with get_node(slug: …, project_id: …) and keep the ids that exist. Name the ones that do not exist to the user — they do not go into the run.

shell
harness.start_run(
  workspace_id: "<project_id>",
  harness_slug: "AF-HRNS-1",
  title: "<the prompt, first ~80 characters>",
  input: { "prompt": "<the prompt, verbatim>" },
  source_node_ids: ["<resolved node ids>"]            # omit when none
)

The prompt goes into input.prompt verbatim — every participant reads it from work.get_context → run.input. Remember the returned run_id.

If you started it from a Flownix node, leave [progress] harness run <run_id> started (AF-HRNS-1) on that node — source_node_ids is not a join table, the comment is how people find the run.

5. Drive the run

Repeat until the run leaves the active states:

shell
harness.get_run(run_id: "<run_id>")                  # run.status, steps with node_type
work.list_available(run_id: "<run_id>")              # unclaimed work, every role
run.statusWhat you do
completed, failed, cancelledStop driving — go to step 7.
waiting_for_userA human gate is open — go to step 6.
queued, running, waiting_for_agentHand out the available work (below), wait for it, poll again.

Hand out the work. For each available work item, start one sub-agent and give it:

  • the skill: flownix-harness-moderator when the item's step is a judge node (find the step by workflow_node_id in harness.get_run → steps[].node_type), otherwise flownix-harness-participant;
  • run_id, the item's role_key and its work_item_id — it claims exactly that item instead of discovering its own, so two agents never race for one;
  • a distinct agent_id (e.g. run-harness:<role_key>:<n>) — it uses it for the claim and for every council call;
  • the user's prompt, for orientation (the authoritative input is still work.get_context).

Items of different roles, and the several instances of one debate/vote role, MAY run in parallel when the client can start sub-agents concurrently. One item — one agent. A client that cannot start sub-agents plays the items itself, one at a time, following the same skills.

When nothing is available but the run is still active, the next step is being produced by someone else (a peer's lease, the orchestrator advancing the graph). Poll again after a short pause. If the run stays active with no available work and no sub-agent of yours still working for three polls in a row, stop and report the run as stuck — status, the last completed step, and the run page — instead of waiting forever.

A sub-agent that fails leaves its item to the runtime (the lease expires, the item returns to the queue and spends an attempt) — hand it out again on the next poll; do not complete it yourself.

6. Human gate — stop and hand it over

shell
harness.list_pending_approvals(run_id: "<run_id>")

Tell the user which approval is waiting (its step and what it asks), and that it is answered in the web app on the run page /projects/<project_id>/harness/runs/<run_id>. You never answer it yourself — there is no tool for it on purpose. Stop here; the user reruns you (or asks you to continue driving run_id) after deciding.

7. Report

From harness.get_run(run_id):

  • the final status;
  • the decision: the output of the last judge / vote step (winner, rationale) — or, when the run failed, the failed step and its error;
  • nodes the run created: run.result_node_ids (create_flow_nodes) → get_node each and list their slugs and titles;
  • the run page /projects/<project_id>/harness/runs/<run_id>.

Keep it short: what was asked, what the council decided, what now exists in Flownix.

Don'ts

  • Don't start a run for a draft, for a slug of another project, or without a prompt.
  • Don't answer a human gate, approve a doc delta or pick a winner on the council's behalf.
  • Don't let two agents work one item, and don't work.complete an item you did not claim.
  • Don't poll without an exit: terminal status, human gate, or "stuck" after three idle polls.