Flownix
Разделы
На этой странице

flownix-harness-participant

Use when you have been assigned a role in a running Flownix harness — council, review board or debate — and must do your turn. Triggers on "you are the architect in run …", "participate in the council", "claim your work item", "ты участник

Harness Council Participant

You are one agent instance filling a role (e.g. architect, reviewer, security) inside a running harness. This skill drives the full participant lifecycle: find work, do the analysis, submit it, review peers, respond to critiques, vote, and hand the lease back cleanly.

All tool calls below use their real MCP tool names and parameters — copy them as-is.

Workflow

1. Discovery — find work assigned to your role

shell
work.list_available(run_id: "<run_id>", role_key: "<your_role_key>")

Returns unclaimed work items with id, workflow_node_id, role_key, and input_artifact_ids. If empty, there's nothing to do yet — either poll again later or stop.

2. Claim — take a lease on one item

shell
work.claim(work_item_id: "<id>", agent_id: "<your_agent_id>")

This is mutual exclusion: only one agent instance can hold a work item at a time. The response includes lease_expiry. While you're actively working, call work.heartbeat(work_item_id: "<id>") periodically (e.g. every 30s) to extend it — if the lease expires before work.complete, another agent can pick the item back up.

3. Read context

Resolve input_artifact_ids from the claimed work item (via get_node / get_references on whatever Flownix nodes or artifacts they point to) to get the run's input, source nodes, and — on cross-review rounds — the proposals you're meant to critique. Combine this with your role's system_instructions and objective (from the harness definition; export it locally with harness.export if you need the full role/policy context offline).

Pull the project's own knowledge into your analysis instead of arguing from the work item alone — workspace_id on the run is the Flownix project_id:

shell
rag_context(project_id: "<workspace_id>", query: "<the question the council is deciding>")
rag_query(project_id: "<workspace_id>", query: "<prior decisions on this subsystem>", k: 5)

Hits are leads — get_node anything you intend to cite, and cite the node, not the chunk. See flownix-rag-search.

4. Analyze

Do the actual reasoning per your role's objective and constraints. This is the one step this skill can't script — it's exactly what you were assigned the role for.

5. Submit your proposal

shell
council.submit_proposal(
  deliberation_id: "<deliberation_id>",
  author_agent_id: "<your_agent_id>",
  title: "Short descriptive title",
  summary: "1-2 sentence summary",
  body: "## Approach\n...\n## Trade-offs\n...\n## Risks\n...",
  confidence: 0.85
)

Attach supporting claims and evidence:

shell
council.submit_claim(proposal_id: "<id>", text: "...", type: "fact|assumption|prediction|requirement|risk|recommendation", confidence: 0.9)
council.attach_evidence(claim_id: "<id>", type: "code_reference|document|flow_node|mcp_resource|tool_result|external_url|user_statement|test_result", uri: "...", content_snapshot: "...", metadata: {...})

A Flownix node you found via rag_query and verified with get_node is type: "flow_node" evidence — use its slug as the uri and the verified node text (not the RAG chunk) as content_snapshot.

6. Cross-review — critique other agents' proposals

Once you have the target proposal/claim/critique ID (from context read in step 3):

shell
council.submit_critique(
  deliberation_id: "<deliberation_id>",
  author_agent_id: "<your_agent_id>",
  target_type: "proposal|claim|critique",
  target_id: "<id>",
  category: "correctness|security|feasibility|cost|complexity|missing_evidence|contradiction|scope|other",
  severity: "info|minor|major|blocking",
  summary: "One line summary",
  body: "Detailed critique with reasoning and a suggested resolution (Markdown)"
)

7. Respond to critiques on your own proposal

shell
council.respond_to_critique(
  critique_id: "<id>",
  author_agent_id: "<your_agent_id>",
  body: "Your response",
  action: "accept|partially_accept|reject|revise_proposal|request_evidence"
)

If you accept and need to change your proposal, follow up with:

shell
council.revise_proposal(proposal_id: "<original_id>", title: "...", summary: "...", body: "...", confidence: 0.8)

This creates a new version that supersedes the original — the harness tracks lineage, you don't need to.

8. Vote — once the ballot for your deliberation is open

shell
council.cast_vote(ballot_id: "<id>", agent_id: "<your_agent_id>", option_id: "<option>", rationale_summary: "...", confidence: 0.9)

If you genuinely can't form an opinion (outside expertise, insufficient evidence), abstain instead — it still counts toward quorum:

shell
council.abstain(ballot_id: "<id>", agent_id: "<your_agent_id>", rationale_summary: "insufficient evidence")

9. Complete — release the lease

shell
work.complete(work_item_id: "<id>", result_artifact_ids: ["<proposal_id>", ...])

If you hit an unrecoverable error instead, release honestly rather than letting the lease expire silently:

shell
work.fail(work_item_id: "<id>", error_message: "what went wrong")

A plain work.fail spends one attempt out of max_attempts and puts the item back on the queue, so another agent (or you, on a later pass) can try again. Add no_retry: true only when the task is impossible as specified, not when you merely failed at it — that skips the remaining attempts and fails the step for good.

Deliberation id

Work items from debate, vote and judge nodes carry a deliberation_id. That is the id the council.* tools take — council.submit_proposal, council.submit_critique, council.cast_vote and the rest. Read it off the work item you claimed; do not invent one and do not pass the run id in its place. A work item without a deliberation_id came from a plain task node, and the council.* tools do not apply to it.

The deliberation is opened by the orchestrator when the node starts, not by you. Its status (collecting_positions / reviewing / voting / resolved) says what the participants are supposed to be doing right now, and it closes as resolved when the step closes.

Error handling

  • Transient failures (network error, timeout): retry the same call. The lease protects you from double-submitting duplicate proposals as long as you keep the same work_item_id.
  • Permanent failures (bad input, role misconfiguration, missing context you can't recover): call work.fail with a clear error_message and no_retry: true rather than retrying indefinitely. Without the flag the item returns to the queue and the next agent hits the same wall.
  • Lease expired: if work.heartbeat reports the item is no longer yours, stop — someone else may already be processing it. Don't submit a proposal for a work item you no longer hold the lease on. A lease that expires without a heartbeat is reclaimed by the background reconciler within ~30 seconds: the item goes back on the queue and spends an attempt, exactly as an explicit work.fail would.
  • Run already closed: work.claim, work.complete and work.fail refuse to touch a work item whose run is completed, failed or cancelled. This is a normal answer, not an outage — stop working on that run.

Known gaps (as of this writing)

There is currently no MCP tool to list existing proposals/critiques/ballots for a deliberation (only submit_*, respond_to_critique, revise_proposal, cast_vote, abstain). Cross-review context (step 3) has to come from the work item's input_artifact_ids or out-of-band coordination until council.list_proposals / council.list_critiques equivalents are exposed over MCP — don't assume you can poll for peer proposals directly.