Autonomous auto-refine loop
For templates configured autonomous (instead of operator-in-loop), the platform runs the refine loop itself — no operator step on first block.
How it runs
Send fires → validator → verdict
├─ clean → send
└─ blocked → auto-refine loop:
attempt 1: refine + re-validate → clean? send. blocked? continue
attempt 2: refine + re-validate → clean? send. blocked? continue
...
attempt 5: re-validate → clean? send. blocked? notify operator (WA + in-app)
Cap = 5 attempts (gh#879). After 5 the loop stops + escalates to the operator.
What gets fed back
Each refine attempt feeds the LLM:
- The original draft
- The validator's findings (severity, slug, plain-English reason)
- The thread history (so the refined draft stays consistent with prior context)
- The template's outbound language (per Languages)
The validator runs against the refined draft; if any finding remains above the blocking threshold, the loop continues.
Operator visibility
While the loop runs, the task surface shows:
- A
auto-refining (attempt N/5)chip on the task card. - The current validator finding.
- A CANCEL button — operator can stop the loop + take over manually.
After the loop ends (success or escalation):
- Success — task settles
done; audit row capturesautoRefineAttempts=N + verdict=clean. - Escalation — task stays open; WA + in-app notification fires (see WA block alerts); operator gets the 3-button surface to decide.
Retry-rolls-validator anti-pattern guard (gh#854)
Before gh#854, an auto-resolve that re-tried every 6 minutes could re-roll the non-deterministic validator until a blocked send happened to PASS — defeating the validator's purpose. A blocked check-in reminder reached a guest (Patrik) this way.
Fix in gh#854: validator verdicts are cached for the same draft body + context for N minutes. Re-rolls within the cache window return the same verdict. The retry can't randomly pass.
When to use autonomous vs operator-in-loop
- autonomous — high-volume low-stakes templates (Pre-checkout reminder, Thank-you message). Operator doesn't want to babysit every send.
- operator-in-loop — high-stakes templates (Send Check-in with access code, dispute response, partial-refund message). Operator confirms every send.
Per-template configuration lives in the Task Templates editor → Auto-refine behavior field — see also Auto-refine drafts.
Implements: gh#879 (autonomous loop cap 5 + notify), gh#854 (validator-verdict cache guard).