Human-in-the-Loop

Human-in-the-loop (HITL) checkpoints give you control over where and when agents require human oversight before acting. You decide the balance between autonomy and governance.

How it works

  1. A pipeline reaches a HITL checkpoint node
  2. Execution pauses and the system creates a review request
  3. A reviewer claims the request (15-minute claim window by default)
  4. The reviewer inspects the artifact and context
  5. The reviewer approves (pipeline continues) or rejects (pipeline stops). Rejections create structured Feedback Records that can trigger correction runs.

Claim workflow

Each HITL gate sets claim_expiry_minutes (default 15, maximum 1440). Once claimed, other reviewers see it as claimed and cannot take it. The claim expires automatically if the reviewer does not act within the window.

POST /api/v1/runs/{run_id}/hitl/{review_id}/claim    # Claim a HITL gate
POST /api/v1/runs/{run_id}/hitl/{review_id}/approve  # Approve
POST /api/v1/runs/{run_id}/hitl/{review_id}/reject   # Reject

Review UI

The review interface shows:

  • The artifact produced by the agent (diff, text, JSON, file)
  • The prompt that generated it
  • The full run context and upstream agent outputs
  • Previous review history for this pipeline
  • An approval checklist (configurable per pipeline)

Notification webhooks

Farna Control sends a webhook to each configured endpoint when a HITL event fires:

Notification webhooks
Event Fires when
hitl_awaiting A pipeline reaches a HITL checkpoint and a gate opens for review
hitl_overdue A gate passes its review deadline
hitl_deadline_warning An unclaimed gate approaches its deadline; it is auto-terminalized if nobody reviews it in time
claim_expired A reviewer’s claim lapses before they act, returning the gate to the queue

The payload carries the run and gate identity, for example:

Pipeline config
{
  "event": "hitl_awaiting",
  "pipeline_id": "...",
  "run_id": "...",
  "agent_name": "draft-email",
  "url": "https://<your-control-host>/runs/..."
}

The url is your instance’s public URL (MODULO_PUBLIC_URL) with the run’s detail path appended.

Run-level events share the same channel: run_failed, run_stalled, budget_exceeded, and circuit_breaker_tripped. Failed deliveries retry with a backoff.

Rejection handling

When a reviewer rejects an artifact, the rejection is recorded as a structured Feedback Record. The pipeline’s feedback handler determines the next step: manual review, automatic AI correction, or AI correction with human review. See Feedback System for the full routing strategy.

Who can decide a human-only gate

A gate can be marked human-only where oversight must come from a person rather than an automated step. A browser session can decide one, and so can a credential linked to a human account: a consent-derived OAuth 2.0 access token issued to a member of your organization. Deciding one from Model Context Protocol (MCP) requires that human-linked credential. An MCP API key, including a per-user key, and any service-account credential are refused, so an unattended agent cannot approve a human-only gate.

A human-linked token carries that person’s authority into the audit record, not the agent’s or Farna Control’s. It does not prove the person was present when the decision was made, because a token can be copied. Keep one in a client you drive yourself, on your own machine, and use an organization or machine credential for anything that runs unattended. Manually delivering a gate’s output remains browser-only. See MCP for the credential rules and their limits.

Governance tiers

A pipeline has a default autonomy level, an optional maximum ceiling, and an earned level. The value used at a gate is the lowest of those, and a human-only gate overrides all of them.

Governance tiers
Autonomy level HITL policy
manual_approval Every gate interrupts and waits for a human decision
notify_on_complete Gates that opt out of human-only auto-approve and notify you when the step completes
fully_autonomous Gates that opt out of human-only are skipped

A gate with human_only: true (the default) interrupts at every level. Only an explicit human_only: false lets the pipeline’s autonomy level decide it.

  • Pipelines: the directed-graph execution model
  • Feedback System: rejection routing and correction runs
  • Agents: the atomic units that make up a pipeline
  • Evals: automated quality checks that run before HITL gates
  • MCP: claiming and deciding gates from an MCP client