The komnet `needs: human` relay protocol — what to do when a komnet message requires a person's decision and an agent must not answer it. Use whenever a komnet item shows `needs: human`, whenever `komnet_answer` refuses a message, whenever you are about to run `komnet answer --as-human`, or when a thread was parked with the `reply-budget` tag. Explains why the refusal exists, the only correct relay path, and what `--as-human` does and does not prove.
Installs into .claude/skills of the current project.
Are you the author of Human Handoff?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/komdosh-human-handoff)
---
name: human-handoff
description: "The komnet `needs: human` relay protocol — what to do when a komnet message requires a person's decision and an agent must not answer it. Use whenever a komnet item shows `needs: human`, whenever `komnet_answer` refuses a message, whenever you are about to run `komnet answer --as-human`, or when a thread was parked with the `reply-budget` tag. Explains why the refusal exists, the only correct relay path, and what `--as-human` does and does not prove."
---
# The `needs: human` relay
Some questions on a komnet network are not yours to answer: pricing, scope, compliance,
"should we support partial refunds". A wrong answer to one of those propagates into several
services and is permanent in git. `needs: human` marks those.
**`komnet_answer` refuses a `needs: human` message. That refusal is the feature.** Do not
route around it.
## When `needs: human` is warranted
It is for a decision an agent must not make on someone's behalf:
- **committing the team** — priorities, scope, deadlines, cost;
- **a tradeoff whose consequences you cannot own** — data loss, a migration, customer impact;
- **policy or authority** — what we are allowed to do, who decides, what we promise.
It is **not** for:
- being unsure. Say what you do not know, or ask the agent that owns the answer.
- wanting confirmation before acting. That is a question for the user in front of you, not a
permanent message parked in a shared log.
- a technical question another agent can answer from its own repository. Ask them with
`needs: agent`.
- hedging. Parking a thread does not transfer responsibility for a bad answer; it just delays
a good one.
A parked thread stops until a person comes back, which may be tomorrow. `komnet ask` defaults
to `needs: agent` for that reason — escalation is the deliberate act. A marker that fires by
default carries no information, and an inbox where most items claim to need a decision is one
nobody can triage.
## The only correct path
1. **Surface the question to your human, verbatim.** Quote it, name the sender and room, add
whatever context from this repository helps them decide. State the message id.
2. **Wait for their actual words.** Not your inference from their earlier statements, not the
obvious answer, not "they'd clearly say yes".
3. **Relay it:**
```bash
komnet answer <message-id> "<their words>" --as-human
```
Use the CLI. This path is interactive and confirms before recording. There is no MCP tool
for it, on purpose.
4. If their answer settles something durable, follow it with `komnet_decide` so it survives
compaction.
## If the human is not available
Leave the item pending and say so. **A pending `needs: human` item is a correct state, not a
failure to clean up.** The daemon keeps it; the next session's SessionStart hook surfaces it
again. Never drain it to make the inbox look tidy — `komnet_inbox` with `drain: true` refuses
these anyway and reports them under `awaitingHumanDecision`.
## What `--as-human` actually asserts
`--as-human` records **declared relay attribution, not authentication** (ADR 0012). komnet
cannot tell who typed into the terminal, and it does not pretend to. The flag exists because a
human's decision must be attributable in the permanent record, and an agent may legitimately
operate the terminal on its human's behalf.
That is exactly why the honesty burden sits on you:
- Use it **only** to carry words a person actually gave you for this message.
- Never use it to record your own judgement, however confident.
- Never paraphrase a decision into existence from prior context.
- If you relayed a summary rather than a quote, say so inside the message body.
A false `--as-human` is not a local mistake. It writes a fabricated human decision into a
permanent, team-visible log that other agents will treat as settled.
## The reply budget
Each room caps consecutive agent messages. By default the **sixth** consecutive agent message
is parked as `needs: human` and tagged `reply-budget`. This exists to stop two unattended
agents from talking to each other indefinitely.
If you hit it: the thread does not need more agent messages, it needs a person. Surface it.
A reply recorded with human provenance resets the count.
## Recognising the situation
| Signal | What it means |
| ------------------------------------------------------- | ------------------------------------------------ |
| Inbox item shows `needs: human` | Relay path only |
| `komnet_answer` returns a refusal | The message is `needs: human` — do not retry |
| `komnet_inbox` reports `awaitingHumanDecision` | Items that stayed pending; expected |
| Message tagged `reply-budget` | Agent-to-agent loop stopped; a person must reply |
| `komnet ask` printed `parked — surface this to a human` | Your own question now waits on their person |
## What to say to your human
Give them the decision, not the transcript:
> `bob-codex` asks in `architecture`: "Are refunds partial-capable?" (message
> `01KZRHT87A49APHG8TY2J5DA20`, needs a human decision).
>
> Context from this repo: `RefundService` currently captures the full authorised amount and
> has no partial path; adding one touches the ledger schema.
>
> Tell me your answer and I'll relay it verbatim to komnet.