Boss Mode — the agent that works your HITL queue
Boss mode is a time-boxed run you start from the dashboard (Run BOSS) or ask an agent to start. While it is active, HITL interactions your agents raise are mirrored to a coordinating agent that can answer them for you, so a queue does not pile up while you are away from the phone.
It is off until you start it, one run at a time, and it always expires.
The ops
Boss mode is three engine ops — the same for the dashboard and for an agent’s tools:
| Tool | Capability | Does |
|---|---|---|
boss_status | boss:read (safe) | The active run — its config (expireAt, hitl.forwardingDelayMs, hitl.allowedKinds, initialCaps, approvableCaps), the boss’s agentId, who started it and when — or null; and defaults, the MANIFEST boss: values a new run opens with. A run past its expireAt is ended on this read. |
boss_start | boss:execute (restricted, HITL) | Start a run on a full config (the keys above; dryRun: true checks it and starts nothing). Refused while one is active. |
boss_stop | boss:execute | End the run now: its grant is revoked, the boss stops, whatever it has not answered stays for a person. |
boss:execute is granted to no role: an agent starting Boss mode hands an
agent a person’s authority over the queue, so when an agent calls
boss_start, a person approves it first. A role meant to run Boss mode
for you adds boss:read / boss:execute to its capabilities:.
Two things are yours to tune, and they do not overlap:
| You want to change | Where |
|---|---|
| How the boss decides — judgement, tone, what it refuses to touch | constitution/Agents/system/role-boss.md |
| How much reach a run opens with — window, delay, kinds, capabilities | constitution/MANIFEST.yaml § boss: |
1. The prompt — constitution/Agents/system/role-boss.md
Put a file at that exact path in your brain and it becomes the boss’s
system prompt. There is no registration step and no config key: the
engine ships its own role-boss.md and looks in your constitution/
first, so yours wins on name alone. Delete the file and the engine
default is back.
The override is wholesale, not a merge. Your file replaces the engine’s body and its frontmatter — there is no layer where the two combine. Whatever the engine’s copy said about the workflow, say it yourself or accept that the boss will not know it.
Start from the engine’s copy rather than a blank file. It is in your
brain’s docs/ sibling tree after an upgrade, and a worked example ships
in brain-example/constitution/Agents/system/role-boss.md.
The same mechanism covers every constitution/Agents/system/role-*.md
— boss is not special here, only better documented.
Frontmatter
Optional, and the same block every role file takes:
---
modelRef: smartest # which model works the queue
memory: {} # the boss remembers — omit the block and it has no memory
skills: ['*'] # every skill — omit it and the boss sees no skills catalog
---
Do not put a capabilities: list here. It would not do what it
looks like it does. The boss is created holding ['*'] and every
restricted tool is gated at call time by the run’s grant, so a list in
this file can only widen the union — never narrow it. The lever that
actually narrows is boss.initialCaps below.
What the boss can see
Your prose can refer to the run’s terms because the engine puts them in every wake-up, above your instructions:
## This run
bossRunId=<id>
Hard stop: 2026-08-19T18:30:00.000Z — past it every wake-up is dropped unanswered.
Mirrored to you: question, grant_request (other kinds reach the human only).
Your own restricted capabilities: hitl:write
You may approve these for other agents: none
The split is worth internalising: the engine supplies the facts, your file supplies the judgement. Do not restate the capability lists in your prompt — they change per run, and a stale copy in the prompt is worse than no copy. Write “the approvable list in your wake-up” and let the engine fill it in.
2. The run defaults — constitution/MANIFEST.yaml § boss:
boss_status answers these as defaults.
boss:
ttlMinutes: 60
hitl:
forwardingDelayMs: 60000 # head-start the human gets before the boss acts
allowedKinds: [question] # kinds mirrored to the boss; the rest stay human-only
initialCaps: ['hitl:write']
approvableCaps: []
Everything here is optional; omit the section and you get the engine defaults shown above. It is G-set, so an edit applies on the next content-watcher tick — no restart, no rebuild.
| Key | Means |
|---|---|
ttlMinutes | How long the run lasts. At the hard stop the run ends, its grant is revoked, and pending wake-ups are dropped. |
hitl.forwardingDelayMs | How long the boss waits before touching a new interaction. This is your head start: respond inside the window and the boss finds nothing left to do. 0 means it races you. |
hitl.allowedKinds | Which kinds are mirrored at all. A kind left out never reaches the boss, whatever its capabilities say. |
initialCaps | Gated capabilities (hitl: true) the boss holds itself, as one grant for the run’s length. |
approvableCaps | Gated capabilities the boss may approve for other agents answering a grant_request. |
Both capability keys are gated-only — the gate is hitl: true, not the
risk tier (drive:delete is dangerous and gated; hitl:read is safe and
open). An ungated capability listed here is one the start form’s picker cannot
offer back once removed, and it mints a grant for authority the boss already
had. Check a capability’s gate on the dashboard’s Permissions page (/permissions) before listing it —
hitl:read needs no human, so the boss can call hitl_list without appearing
here at all. Admin-only capabilities (loop:auto_accept) are refused
for a boss run by GrantService.issue and are not offered either.
These are a seed, not a ceiling
The values open the start form (and are what boss_status answers as
defaults). Whoever starts the run still sends every field — boss_start
takes a full config — and can change any of them before starting. So lowering a value
here narrows what a distracted person accepts by default — it does not
cap what a deliberate one can pick.
That makes this section a good place for “what we normally want” and a bad place for “what must never happen”. If a capability must never be auto-approved, keep it out of the capability set or mark it so it always needs a human — do not rely on this list being short.
Omitting a capability list is not the same as emptying it
initialCaps and approvableCaps are the two keys where absence has a
surprising meaning:
- Key omitted → the form preselects every restricted capability. That is how boss mode has always started, and it is the widest either field goes.
[]written out → the picker opens empty.
They are different answers and the engine treats them differently. If
you have an opinion about either list — and approvableCaps is the one
worth having an opinion about, since it is what the boss can hand to
other agents — write it out. Inheriting the fallback is a choice too,
just an invisible one.
The security model, stated plainly
Your prompt is not the boundary. An instruction in role-boss.md
saying “never approve db:write” is documentation. The thing that
actually stops it is the runtime check on approvableCaps: a capability
outside that list is refused [unauthorized_responder], the card stays
pending for you and no grant is minted, whatever the prompt says and
whatever the model decided. The boss is the only agent that may approve a
grant at all — every other agent, whatever it holds, is refused, so a
grant always traces back to a person or to the list you signed here.
Three more guardrails you get for free, none of which is prompt-level:
- Loop guard — the boss can never answer or cancel an interaction it raised itself. If it asks for a capability it lacks, that request goes to you.
- A person’s cards stay a person’s — a card the loop keeps
for a person (its decide and retry cards, a rating card) refuses the
boss’s
hitl_respondandhitl_cancelwith[unauthorized_responder]and stays pending for you (self-evolving.md). - Hard stop — every wake-up past
expireAtis dropped before any model runs. An expired run costs nothing and cannot act.
Write the prompt as if the model will occasionally ignore it, because the guards are what make that survivable.
Failure modes worth knowing
- The boss answers before you do.
forwardingDelayMsis too low for how fast you actually read notifications. Raise it; a minute is a starting point, not a recommendation. - The boss cancels everything. Usually the prompt sets a bar the
available context cannot clear. Check what
hitl_list(orhitl_getfor one request) actually carries for that kind before asking the boss to reason about it — each row says which verdicts itallows. - Grant requests all fail.
approvableCapsdoes not contain what agents are asking for. That is the guard working; widen the list deliberately or leave the requests for a human. - A prompt edit seems to do nothing. The role body is read per run.
Check the file is at exactly
constitution/Agents/system/role-boss.md— a typo’d path is silently the engine default, not an error. - Your
modelRefseems ignored. It is read from the role file; if you also see an unexpected model, confirm nothing else in your brain declares one forsystem:boss.
Related: human-input.md for how interactions get raised in the first place, and contract.md § 9 for the full list of values you own.