Skip to content

Review workflows

Review workflows connect Autopoetic's engine to your own agents: your service receives signed webhooks, your agents do the work and the reviewing, and the decision engine tracks how much the outcomes should be trusted.

The same mechanics drive plain external-agent orchestration (no review) and full peer review — the work_unit clause on each call decides.

The work_unit clause

Every call carries a work_unit (…) clause — the step's review configuration:

Key Meaning
minimum_reviews Reviews required before evaluation. 0 = ungated: the step's work is recorded and the run proceeds.
minimum_confidence Confidence (0–1) the decision engine must reach to resolve the work as trusted.
maximum_reviews Hard cap on review rounds; unresolved work halts when reached.
reviewer_competency_names Competencies reviewers should be good at, e.g. ["editorial"].
producer_competency_names Competencies the producing step's agent claims, e.g. ["writing"].
work_unit_name Optional explicit name for this unit of work.

With minimum_reviews > 0, each execution of the call runs one review round in a loop: invite a reviewer, wait for the answer, let the decision engine judge, repeat until it resolves or halts.

The passphrase

When you start a run, input.secret is your passphrase for that run. Use at least 32 bytes of entropy. Autopoetic stores only its fingerprint; both sides authenticate every webhook from the passphrase alone:

  • Outbound to your service: headers X-Autopoetic-Timestamp: <unix seconds> and X-Autopoetic-Signature: HMAC-SHA256(key=SHA256(passphrase), message=timestamp + "\n" + raw body). Verify the signature (with a 300-second tolerance on the timestamp) before trusting a request.
  • Inbound from your agents: your agents present the same two headers over their callback bodies, computed the same way.

If your service exposes a single review endpoint, verify the signature and reject anything that fails.

What your service receives

Each webhook_call POSTs to the URL you provide:

{
  "instance_uuid": "…",
  "project_uuid": "…",
  "template_name": "reviewed_publish",
  "step_id": "thens[0]",
  "callback_url": "https://app.autopoetic.ai/webhooks/projects/{p}/workflows/callback/{instance_uuid}",
  "payload": { …your authored static fields… }
}
  • Your service replies 2xx to acknowledge — the result travels by callback later, so your agent may take seconds or days.
  • A non-2xx fails the step (and the run records an exception).
  • The callback_url is provided per round; your agents never construct it.

What your agents send back

Your agents POST to the callback_url with a small, closed vocabulary:

{
  "answer": "yes",
  "agent_name_sha256": "<your chosen agent>",
  "work_unit_name": "draft-2026-10-18"
}
  • answer — a literal "yes" or "no". It is never derived from prose; a missing or invalid answer is a loud failure, not a default.
  • agent_name_sha256 — the SHA-256 hex of the agent's name, exactly as registered with the decision engine.
  • work_unit_name — for producers: the name of the completed work. The producer names its work — this name is the reviewers' lookup key into your systems; Autopoetic never generates one for you.

Everything else in the callback body is ignored. Your agents' work product never moves through Autopoetic — no documents, no code, no output are stored, relayed, or inspected; only identity references travel on the wire.

Who reviews: your choice

Which agent reviews a piece of work is your runtime decision — random, strongest-for-competency (query the decision engine first), or any policy you like. The invitation webhook carries the work unit's name and its requirements (competencies, thresholds); your service selects the agent and returns the choice as the callback's agent_name_sha256. Autopoetic never picks reviewers for you; it computes how much the outcome deserves to be trusted.

Round mechanics

  1. The producer step runs (e.g. webhook_call to your drafting service) and its callback names the work.
  2. The engine invites your reviewer service with the work unit's name and requirements.
  3. Your reviewer answers via callback (answer + chosen agent).
  4. The decision engine evaluates: resolve (confidence met), continue (not enough reviews yet), add review (another round), or halt (maximum reviews reached, unresolved).
  5. Steps repeat rounds until a verdict; what the run does with a no verdict or a halt is your template's policy — a branch you author.

Minimal end-to-end example

Template (yours to adapt):

new workflow "reviewed_publish" v1
  then call "webhook_call" (url_key="url") as "draft"
       work_unit (minimum_reviews=2, minimum_confidence=0.8,
                 maximum_reviews=5,
                 reviewer_competency_names=["editorial"],
                 producer_competency_names=["writing"])
       until state result_ready == true

Run input: {"url": "https://you.example/work", "reviewer_url": "https://you.example/review", "secret": "<32+ bytes>"}. Your work service POSTs back {"work_unit_name": "…"}; your review service POSTs back {"answer": "yes", "agent_name_sha256": "…"}. The run resolves when the decision engine's confidence passes 0.8.