Back to Stories

You're always in control

Most AI tools have one gear: go. They take your prompt, pick a direction, and start making changes. Files get written. Shell commands fire. Code gets committed. By the time something goes wrong, there's already a diff to untangle.

Contenox was built differently. The agent works autonomously — but only as far as you let it. At exactly the moments you care about, it stops and asks.

This is Human-in-the-Loop (HITL): configurable approval gates that sit between the agent and the actions it wants to take.

What it looks like in practice

You kick off a task. The agent plans it out, breaks it into phases, and starts working through them. At some point it reaches a step that your policy says requires approval — maybe it's about to write to production files, or run a shell command, or apply a patch it generated.

It stops. The thread shows you where it is, what phase it's in, and what it's waiting on.

Plan phases visible as the agent pauses — "Awaiting approval" before proceedingPlan phases visible as the agent pauses — "Awaiting approval" before proceeding

This isn't a vague "are you sure?" It shows you the actual artifact: the diff it wants to apply, the command it wants to run, the file it wants to write. You're looking at the real thing, not a summary.

The agent surfaces the full diff before applying it — you see exactly what changes and approve or rejectThe agent surfaces the full diff before applying it — you see exactly what changes and approve or reject

You review. You approve. The agent picks up exactly where it left off, finishes the remaining phases, and surfaces the result.

Full execution thread after approval — the Remote Connector phase completes without further interruptionFull execution thread after approval — the Remote Connector phase completes without further interruption

No re-running from scratch. No lost context. The agent was waiting, not stopped.

HITL policies

The approval behavior isn't hardcoded. It's driven by a policy file you define — a list of rules that say exactly which operations require human sign-off and what happens if no one responds.

default_action: allow
rules:
  - hook: local_shell
    tool: "*"
    action: approve
    timeout_s: 120
    on_timeout: deny

  - hook: local_fs
    tool: write_file
    when:
      - key: path
        op: glob
        value: "**/*.go"
    action: approve
    timeout_s: 0

Walking through this:

default_action: allow — everything is permitted unless a rule matches. File reads, network lookups, plan generation: all flow through uninterrupted.

First rule — any local shell tool (tool: "*") requires approval. The agent will wait up to 120 seconds; if no one responds, the action is denied. This covers bash, sed, git commit, anything touching the real shell.

Second rulewrite_file calls that target a .go file require approval regardless of timeout. timeout_s: 0 means it waits indefinitely. A .md or .json file write would pass through (no matching rule, falls back to default_action: allow).

Rules are evaluated in order. First match wins. The policy file can have as many rules as your workflow needs — route by tool, by file path glob, by argument value.

Why it matters

The problem with autonomous agents isn't that they're slow to act. It's that they act at the wrong moment, on the wrong thing, with no checkpoint between "the model decided" and "the change landed."

HITL policies let you draw that line exactly where it belongs for your codebase and your risk tolerance. Read operations run freely. Writes pause. Destructive operations block. The agent does the work; you keep the control.

It's not a safety checkbox. It's a configurable gate you own.

See the HITL policy reference for the full schema, available hooks, and examples for common approval patterns.