handback · git:20260819.ab724a3 · 2026-08-19 · sha256 f324deef114b4aba
handback git:20260819.ab724a3A
Immutable. This exact content is served forever at /api/v1/blob/f324deef114b4aba.
---
name: handback
category: orchestration
description: |
Terminal-message contract for an autonomous arc that has run out of
agent-executable work and genuinely needs a human. Produces a WORK ORDER —
asks first, each one an imperative addressed to the reader, carrying a default
so silence is never fatal (the exception is narrow and must be named:
irreversible, externally visible, or spends money) — followed by the unchanged
nine-item receipt. Distinct from `handoff` (same arc, different reader: `handoff`
writes `docs/handoffs/` for the NEXT AGENT; `handback` writes the chat
message for the HUMAN AS DECISION-MAKER).
Asking is the last resort, not the interface: no ask may exist until the
seven-rung autonomy ladder has been climbed and recorded.
Use when: (1) an autonomous arc is stopping and at least one ask is open,
(2) the user asks "what do you need from me" / "what's blocking",
(3) a lane has parked on a human dependency and the arc is notifying,
(4) writing any message whose purpose is to obtain a decision.
Triggers on "handback", "hand back", "what do you need from me", "what is
blocking", "blocked on you", "what should I decide", "unblock", "your call".
---
# handback — end an arc with a work order, not a lab notebook
**Spec:** `broomva/workspace` → `docs/specs/2026-08-18-agent-handback-contract.html` (BRO-2179).
## Why this skill exists
Measured over 994 Claude Code transcripts (analysis set: 100 sessions of ≥6h
wall-clock and ≥150 assistant turns):
| | |
|---|---|
| Long arcs whose final message mentions a blocker at all | 31 / 100 |
| Long arcs **halting on a human** (terminal-stance phrasing) | **18 / 100** |
| …of those 18, containing a conforming ask block | **0 / 18** |
| …containing an imperative anywhere in the message | 3 / 18 |
| …containing any `?` at all | 13% |
| …with the question next to the blocker it describes | 6% |
| Stating a default if the human stays silent | 5% of all 100 |
| Ever emitting a push notification | **0 / 100** |
| Blockers knowable before the arc started | **81%** |
The two blocker rows differ on purpose. The broad count (31) includes messages
that merely *mention* being blocked — "the pre-commit hook blocked it", "#381
remains blocked by the hang". The narrow count (18) is the defensible one: a
terminal message that stops the arc **on a person**. The enforcement gate keys on
the narrow definition, because refusing a healthy receipt that happens to contain
the word "blocked" would fight the operator.
The ask usually exists. It is placed last, written in the indicative ("Not
merged — auto-merge correctly blocked"), and carries no default, so the arc
dies on it — median 2.4h of stalled arc-time behind such a message, 25 of them
overnight-length.
## Rule zero — asking is the last resort, not the interface
**No ask may exist until every rung below has been tried and recorded.** A row
with an empty `exhausted` list is a defect, not a question.
| Rung | Try this | |
|---|---|---|
| 1 · Read | Is the answer already on disk — ticket history, prior conversations, the knowledge graph, the handoff doc, the code? | Most "decisions" are recoverable, not new |
| 2 · Standing grant | Has this exact question been answered before? Check `.control/preauth.yaml` | Re-asking a settled question is the cheapest failure to eliminate |
| 3 · Delegate | Can a fresh agent resolve it — a reader, a researcher, an adversarial reviewer with different context? | Chain agents instead of chaining to the human |
| 4 · Reroute | Can another lane, worktree, fan-out, or approach go around it? | The blocker is often a path, not a wall |
| 5 · Loop | Can iteration resolve it — retry under a changed assumption, let a persist loop converge? | Slow beats blocked when nobody is awake |
| 6 · Default | Is the choice reversible? **Take it, log it, tell the human afterwards. Do not ask.** | Reversible decisions are not the human's to make in real time |
| 7 · Ask | Only now. Record which rungs were tried and why each failed. | |
**Rung 6 is where most asks should die.** A choice that can be undone with one
commit does not warrant stopping an arc; it warrants a line in the receipt.
Only actions that are **irreversible**, **externally visible**, or **spend
money** may reach rung 7 without a default — and the ask must say which.
## Rule minus-one — never stop the arc while an unblocked lane remains
Blocked is a **lane** state, not an **arc** state. When an ask fires: park the
lanes it gates, emit the ask (push it if outside the waking window), and
continue on the next unblocked lane. Run `handback` only when the unblocked set
is empty. An arc that halts with runnable work left is the failure this skill
exists to prevent.
## The shape — five blocks, always in this order
```
## ⛔ Blocked on you — N items, ~M min
table: # | ask (imperative, addressed to "you") | unblocks | if you say nothing
a decision row lists options A/B/C, one marked suggested, each with its cost
plain language only; hard cap 7 rows, ranked by what each unblocks
## ▶ Running meanwhile
what is still executing, or what ran with zero input from you
## ✅ Shipped
PR table. One line each. No narrative.
## 📋 Receipt — the nine items, unchanged
1 dep chain · 2 plan vs done · 3 parallel streams · 4 files changed · 5 PRs
6 deploys · 7 validation · 8 merge result · 9 follow-ups
## 📎 Detail → docs/handoffs/<arc>.md
the NARRATIVE lives there: what happened and why, the review sagas, the
corrections. That prose is what this contract displaces.
```
## The nine rules
Each is derived from a measured failure, not a style preference.
1. **The ask block is first.** Not a "Your call" section at 80% depth.
*Measured: the ask lands around p80 of the message.*
2. **Every row is an imperative addressed to "you"** — a command to run, a link
to click, a value to paste, or a one-line answer to a closed question.
*Measured: 0 of the 18 halting messages contained a conforming ask block.*
3. **A decision row offers options, not an open question.** Two or three
concrete choices, each with its consequence in one line, one marked as the
recommendation. Never "what should we do about X?" — always "A, B, or C; I
suggest B because …".
4. **Plain language, no internal vocabulary.** No primitive numbers, no gate
names, no acronyms, no ticket ID standing in for the question. If a term
needs the spec to understand, it does not belong in an ask.
5. **Every row carries a default.** "If you say nothing, I do X." A row with no
safe default must say so explicitly and name what it costs.
*Measured: 5% stated a default. Silence is otherwise fatal.*
6. **Every row is self-contained.** Answerable without opening a ticket. The
ticket ID is a reference for later, never the carrier of the question.
*Measured: 58% used a ticket as the carrier; median 1 ticket, up to 13.*
7. **Rows are ranked by what they unblock**, stated in the row — "unblocks 9 of
18 rows", "unblocks 1 lane". A tired person answering one thing should be
answering the right one.
8. **Hard cap: 7 rows.** More than seven means the arc should have asked
earlier. Overflow goes to the ledger, with the total stated in the header
("3 of 11 shown").
9. **The nine-item receipt stays, underneath the asks.** It is structured and
proves the work. What this contract displaces is the **free-form narrative**
— that moves to `docs/handoffs/`.
## Anti-patterns
| Rationalization | Why it fails |
|---|---|
| "I'll describe the blocker; they'll know what to do" | A statement about the world transfers no obligation. Zero of 31 measured messages contained a request addressed to a person. |
| "The ticket explains it" | The reader has no context loaded and may be on a phone. The ticket was written by an agent for an agent. |
| "It's a big decision, I shouldn't presume a default" | Defaults are for **reversible** choices, and most are. Reserve no-default for irreversible / externally visible / money-spending. |
| "I'll list everything so they have full context" | Seven rows maximum. More means the ladder was not climbed or the hour-zero batch was skipped. |
| "I'll ask now and keep working after they answer" | Wrong order. Park the gated lanes and keep working *now*; the answer arrives whenever it arrives. |
| "Asking is safer than assuming" | Asking is expensive — median 2.4h of stalled arc-time, 25 overnight stalls in the measured corpus. Rung 6 exists for this. |
| "I'll write the narrative first so they understand the ask" | That ordering is the measured defect. Narrative goes to the handoff doc; the ask goes first. |
## Composition
- **`handoff`** — same arc, different reader. `handoff` writes
`docs/handoffs/YYYY-MM-DD-<arc>.md` for the next *agent*; `handback` writes
the chat message for the *human*. A stopping arc usually produces both, and
the handback's Detail block links to the handoff.
- **`autonomous`** — supplies the nine-item receipt that block 4 renders, and
owns the pre-flight that builds the ask ledger.
- **`persist` / `governed-autonomy-loop`** — a parked lane is a lane the next
iteration's `PROMPT.md` omits; `handback` fires only when none remain.
## References
- `references/template.md` — copy-paste skeleton with a worked example.