Use before writing to the human owner, escalating, or composing a thrum send or reply with prose - 'notify the owner', 'escalate', 'a notification just arrived', 'before restarting on a context reading'.
Installs into .claude/skills of the current project.
Are you the author of Coordinator Interacting With The Owner?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/thrum-team-coordinator-interacting-with-the-owner)
---
name: coordinator-interacting-with-the-owner
description: "Use before writing to the human owner, escalating, or composing a thrum send or reply with prose - 'notify the owner', 'escalate', 'a notification just arrived', 'before restarting on a context reading'."
---
# Coordinator: Interacting with the Owner
## The measured problem
Coordinators consume **40-50% of this box's total tokens** (owner's figure).
The dominant cause is narrating agent traffic to the pane for a human who is
not there — a stream of notification turns, each answered with a
multi-paragraph pane report, spending about half a coordinator session
talking to nobody.
🔴 **The cost is quadratic, not linear, and that is the point that must not
get lost in the fix.** A narration joins the transcript, so every later turn
re-reads every earlier one. N narrated messages means turn *k* carries all
*k−1* of them. Shortening a narration only changes the constant; not writing
it changes the growth curve.
Coordinator context scales with subordinate count and message volume, not
with work completed or discipline; a coordinator with no subordinates
talking to it produces no narration regardless of care taken.
## 1. A thrum notification is not the human
`New message from <agent> — run 'thrum inbox --unread' to read` arrives in
your input looking like a user turn. It is a system notification, generated by
the daemon, about a fact already recorded in the thrum message store.
**The complete list of times you write to the pane:**
1. The human asked you something — answer it.
2. You need a decision only the human can make — ask it, in one or two lines.
A decision only the human can make goes to the owner by `thrum send`; a pane line is optional and never the
delivery. Resolve the owner from CONFIG, never hardcode a name:
```bash
OWNER=$(jq -r '.permission_supervisors[] | select(startswith("@user:"))' .thrum/config.json | sed 's/^@//' | head -1)
thrum send --to "$OWNER" --stdin <<'EOF'
[ESCALATION] <what needs a decision>: <why>. Action needed: <what>.
EOF
```
- Never write the question only into your own pane.
- A watcher's escalation that needs the human is forwarded to the owner the same way.
- A watcher whose own `roster` edit was blocked sends the request to its coordinator, who edits `roster` in the
watcher's `watch_params.json`; the watcher confirms on its next read.
- Verify delivery (`thrum sent --unread`) before assuming it was seen. Send it at most three times in total: the
first send when you find the condition, then a later send only on a later tick while the same condition is still
open and unanswered, at most once per tick and never three in one tick. Then stop: never raise the same condition
more than three times.
- Agent-to-agent status rules are unchanged.
There is no third case. Never narrate what you did, what an agent said, what
you decided, what you are about to do, or what you are waiting on. The thrum
message store is already the audit trail — a human who wants to know can read
it; you do not need to re-render it to a pane nobody is watching.
⚠️ **The failure is not ignoring this rule — it is judging each case an
exception.** "This ruling might get overridden." "This is a method worth
passing on." "This is a self-correction, they'd want to see it." Each of
those passes *is this load-bearing?* asked in isolation; none of them passes
*did they ask, and do they need it now?* The feeling of exception IS the
failure mode — treat the impulse to narrate "just this once" as the trigger
for this section, not as a genuine edge case it didn't anticipate.
## 2. Prose into a command: heredoc or file, no third option
Every command that stores prose you compose — `thrum send`, `thrum reply`,
`thrum memory create`, `bd create`, `bd update`, `bd comments add` — must
carry that prose via **`--stdin <<'EOF'` (quoted delimiter) or a file**
(`--body-file`, or a file you `cat`). Never a double-quoted inline argument.
A double-quoted argument runs command substitution on backtick and `$( )`,
and parameter expansion on `${ }` / `$VAR`, **in your own shell, before
anything is stored.** The matched text is replaced by that subcommand's
output — usually nothing — and you get a success receipt with the content
already gone. The tool reports done; the content it stored is not what you
wrote.
The quoted delimiter is the mechanism: `<<'EOF'` suppresses expansion inside
the heredoc body; an unquoted `<<EOF` still expands and gives you nothing.
Not every flag has a file/stdin form — `bd update --notes` and `--append-notes`
are string-only (only `--description` gets `--body-file`/`--stdin`, and
`bd comments add` gets `-f`/`--file`). When the flag you need is string-only,
capture the prose into a shell variable via a quoted heredoc first, then pass
`"$var"` as the argument — a variable's stored value is inserted verbatim on
expansion and is never re-parsed for backticks or `$( )`, so this is safe even
though the flag itself takes a literal string.
⚠️ **The single-line form is the one that comes to mind first — that is the
failure.** This pollutes beads, messages, and memory writes until an agent
re-learns the heredoc habit in-session — and loses it again at the next
restart, because the lesson lived in a transcript, not in a rule.
## 3. Restart on a measurement, never a feeling
Read context **by position**, in the same command block that emits your
footer, every single time you're about to decide whether to restart.
**A number you measured earlier and have been mentally incrementing since is
a memory, not a measurement — and it feels measured because it once was.**
The drift always runs toward **false urgency, never
complacency**: an inflated number reads as caution, so nobody challenges it,
and it is exactly the direction that makes a bad restart look prudent instead
of wasteful. (Do not state a threshold percentage here — the existing
coordinator context-monitoring guidance already carries it; this section is
about how you read the number, not what the number should be.)
🔴 **The snapshot trap is how work actually gets lost, and it is a distinct
failure from the fabricated reading above:** you near the threshold, write a
snapshot, re-measure, find you have room, keep working — and the snapshot is
now stale and never gets updated. You hit the real threshold, think "no time
to rewrite it," and restart on the old one. Everything done in between is
gone, and it is the most recent and most load-bearing work in the session.
**⇒ A snapshot is the last thing you do, not a checkpoint you bank in
advance.** Never restart on a snapshot you did not write in the same turn as
the restart. Budget the remaining context to write it fresh, every time.
## 4. Escalate for authority, never for willingness
Escalate to the human when the decision is genuinely his to make: a ruling
only he can give, a change to a standing grant, a product-behavior call with
no correct answer derivable from what you already know.
**Do not escalate because you are unsure whether to do work you are already
empowered to do.** That is not an authority gap — it is hesitation, and
routing it through the human just relocates the decision without improving
it.
When you do escalate: ask in one or two lines, naming the decision and the
options with their costs. Never a TUI/dialog widget — a coordinator blocked
on a dialog cannot even signal that it is waiting, which is worse than the
thing the dialog was trying to prevent. Plain text or `thrum send`.
**Do not re-list pending items every turn.** State a pending decision once;
the human remembers it. Repeating it back is narration wearing the shape of
diligence, and it is exactly what section 1 already forbids.
## 5. Worked examples
The point of this section: **an example gets copied far more faithfully than
a rule gets obeyed.** Same situation, both ways.
**An agent reports a completed review.** ❌ *"<orchestrator> just finished reviewing <implementer>'s branch. The review
found two minor issues: an unused import in redact.go and a missing test case for the empty-string path. Both were fixed
and the branch is now clean. I'm going to merge it into the shared integration branch now and then check on the next
epic..."* ✅ Nothing to the pane. If the agent needs an ack, `thrum reply <msg_id> --stdin <<'EOF'` with
`merged, see <merge-target>` as the body — the pane stays silent.
**An agent surfaces a decision that genuinely needs the owner.**
❌ 300 words of background, the options considered, the tradeoffs, and a
recommendation, before finally landing on the question.
✅ *"<owner> — release/v0.10.6 soak found a schema-migration regression.
Options: (a) patch and re-soak 48h, (b) ship without the fix and hotfix
after. Your call."*
**A correction to something you already told the owner.** This DOES warrant
pane output — keep it short.
✅ *"Correction: the migration regression above is NOT in 0.10.6 — it's
already fixed on release/v0.10.6, my mistake. No action needed."*
**A `bd update` with a backtick in the note.**
❌ `bd update thrum-abc --notes "fixed by checking \`cfg.Model\` before dispatch"`
— the backtick runs a subshell in your own shell before `bd` ever sees it.
✅ `--notes` is string-only, so capture first, then pass the variable:
```bash
notes=$(cat <<'EOF'
Fixed by checking `cfg.Model` before dispatch.
EOF
)
bd update thrum-abc --notes "$notes"
```
## Project-specific rules (already loaded)
Load the /thrum:project-rules-protocol skill and follow it.
If you accumulate a new rule mid-session (the user corrects you), capture it
via the Memory section of your role preamble — it references the
`thrum-memory` skill for the canonical `thrum memory create`
shape.