Refusals

Part of team approve — what refuses a write: a seat or the wrong delegate, a change that needs the owner, --confirm's answer, and a line waiting on the terminal.

Every refusal

MessageExit
team approve: unexpected "x" (with the usage)2
team approve: line <n>: <message> / team approve: <message>2
team approve: the approval store <store> is inside <folder>, where seats work1
team approve: only the owner approves a team file, from a terminal outside herdr; this call is <caller> (no delegates section)1
team approve: only the owner or the approved delegate approves a team file; this call is <caller>1
team approve: this change needs the owner: <what changed> (an owner section that is not rules)1
team approve: --file is the owner's; the approved delegate cannot use it1
team approve: delegation needs a verified approval: <what is not in force> / delegation needs a readable approved copy: run \team approve`/delegation cannot verify its placement or seats: /the approved delegate must be an external non-seat pane/the approved delegate may not run `approve`; its approved commands are `1
team approve: input was waiting on the terminal: run \team approve` on its own line`1
team approve: the terminal this call runs on could not be read to check for input waiting on it; nothing was written1
team approve: not approved; nothing was written (--confirm)1

A file that loads with warnings prints them on stderr as team approve: warning, line <n>: <message> and goes on. The last refusal is what --confirm's answer gets when it is not the number of seats: a blank answer, a wrong one, and a closed terminal are all the same answer.

The two input refusals are the default path's. The check reads the terminal this call's own standard input is attached to — never /dev/tty, which is not that terminal when the command runs without a controlling one. It reads once, up to 4096 bytes: a terminal with nothing queued answers EAGAIN and the run goes on; a complete line waiting there is taken as a pasted block's remainder and refuses the call, and the read consumes that line — which is why the refusal says to run the command by itself. Cooked mode, the default, makes only complete lines (Enter included) visible, so a partial line typed without Enter is not seen; raw mode makes every byte already typed visible, and the read takes up to 4096 of them. A terminal that cannot be found or read at all refuses with the second message rather than approving blind. Either way the check looks at one moment: input that arrives after the check and before the write is not seen.

The exit codes these refusals carry are on the team approve page.

A new seat, and the write gate

A new seat needs one too — a seat already approved may be taken out without bothering the owner. Parking or stopping one needs an approval, unless remove --keep or add wrote the mark and recorded the digest. A seat the file never had is not approved:

.agents/team.yaml
format: 1
project: beacon
coordinator: claude-keeper
operator: claude-keeper

trust:
  - ~/.config/team/lobby
  - ~/Code/beacon
  - ~/Code/worktrees/beacon

workspace:
  mode: shared

seats:
  - role: coordinator
    name: claude-keeper
    label: coordinator
    cli: claude-code
    vendor: anthropic
    model: Claude Opus
    version: "5.5"
    launch: claude --model claude-opus-5-5
  - role: implementer
    name: claude-beacon
    label: implementer
    cli: claude-code
    vendor: anthropic
    model: Claude Opus
    version: "5.5"
    launch: claude --model claude-opus-5-5

--confirm asks, and a wrong answer writes nothing:

Terminal
 team approve --confirm ; echo "exit $?"
team approve: warning, line 3: `coordinator:` is now `leads: true` on the lead's seat, and is still read
./.agents/team.yaml: against the copy approved on 2026-10-04T09:00:00.000Z:

  + 9:   - ~/Code/worktrees/beacon
  + 23:   - role: implementer
  + 24:     name: claude-beacon
  + 25:     label: implementer
  + 26:     cli: claude-code
  + 27:     vendor: anthropic
  + 28:     model: Claude Opus
  + 29:     version: "5.5"
  + 30:     launch: claude --model claude-opus-5-5

Needs a new approval: `trust` changed; `limits` changed; seat claude-beacon is not in the approved file.
Ceilings approved: 3 seats at most, 2 temporary.
Ceilings this approval fixes: 4 seats at most, 2 temporary.
Seats: 2 (claude-keeper, claude-beacon).
approval #2 for this project; the last one was on 2026-10-04; key fe21ef6293de.

Type the number of seats (2) to approve this file, and its commands and rules, to run: 1
team approve: not approved; nothing was written
exit 1

The same protection without --confirm: a line already waiting on the terminal — the rest of a pasted block — makes the run refuse before anything is written:

Terminal
 team approve ; echo "exit $?"
team approve: warning, line 3: `coordinator:` is now `leads: true` on the lead's seat, and is still read
./.agents/team.yaml: against the copy approved on 2026-10-04T09:00:00.000Z:

  + 9:   - ~/Code/worktrees/beacon
  + 23:   - role: implementer
  + 24:     name: claude-beacon
  + 25:     label: implementer
  + 26:     cli: claude-code
  + 27:     vendor: anthropic
  + 28:     model: Claude Opus
  + 29:     version: "5.5"
  + 30:     launch: claude --model claude-opus-5-5

Needs a new approval: `trust` changed; `limits` changed; seat claude-beacon is not in the approved file.
Ceilings approved: 3 seats at most, 2 temporary.
Ceilings this approval fixes: 4 seats at most, 2 temporary.
Seats: 2 (claude-keeper, claude-beacon).
approval #2 for this project; the last one was on 2026-10-04; key fe21ef6293de.
team approve: input was waiting on the terminal: run `team approve` on its own line
exit 1

A terminal the check cannot read refuses as well, saying which failure it was, and writes nothing:

Terminal
 team approve ; echo "exit $?"
team approve: warning, line 3: `coordinator:` is now `leads: true` on the lead's seat, and is still read
./.agents/team.yaml: against the copy approved on 2026-10-04T09:00:00.000Z:

  + 9:   - ~/Code/worktrees/beacon
  + 23:   - role: implementer
  + 24:     name: claude-beacon
  + 25:     label: implementer
  + 26:     cli: claude-code
  + 27:     vendor: anthropic
  + 28:     model: Claude Opus
  + 29:     version: "5.5"
  + 30:     launch: claude --model claude-opus-5-5

Needs a new approval: `trust` changed; `limits` changed; seat claude-beacon is not in the approved file.
Ceilings approved: 3 seats at most, 2 temporary.
Ceilings this approval fixes: 4 seats at most, 2 temporary.
Seats: 2 (claude-keeper, claude-beacon).
approval #2 for this project; the last one was on 2026-10-04; key fe21ef6293de.
team approve: the terminal this call runs on could not be read to check for input waiting on it; nothing was written
exit 1

With --confirm, the answer is the number of seats, and nothing else — here, two:

Terminal
 team approve --confirm
team approve: warning, line 3: `coordinator:` is now `leads: true` on the lead's seat, and is still read
./.agents/team.yaml: against the copy approved on 2026-10-04T09:00:00.000Z:

  + 9:   - ~/Code/worktrees/beacon
  + 23:   - role: implementer
  + 24:     name: claude-beacon
  + 25:     label: implementer
  + 26:     cli: claude-code
  + 27:     vendor: anthropic
  + 28:     model: Claude Opus
  + 29:     version: "5.5"
  + 30:     launch: claude --model claude-opus-5-5

Needs a new approval: `trust` changed; `limits` changed; seat claude-beacon is not in the approved file.
Ceilings approved: 3 seats at most, 2 temporary.
Ceilings this approval fixes: 4 seats at most, 2 temporary.
Seats: 2 (claude-keeper, claude-beacon).
approval #2 for this project; the last one was on 2026-10-04; key fe21ef6293de.

Type the number of seats (2) to approve this file, and its commands and rules, to run: 2
Approved. The record is in ~/.config/team/beacon-<hash>; signed with key fe21ef6293de; check the rest with `team doctor`.

The same file again is the same text as the approved copy, and the approval stands:

Terminal
 team approve --show ; echo "exit $?"
team approve: warning, line 3: `coordinator:` is now `leads: true` on the lead's seat, and is still read
./.agents/team.yaml: the same text as the copy approved on 2026-10-04T09:00:00.000Z.

Nothing in it needs a new approval.
Ceilings this approval fixes: 4 seats at most, 2 temporary.
Seats: 2 (claude-keeper, claude-beacon).
approval #3 for this project; the last one was on 2026-10-04; key fe21ef6293de.
exit 0