| name | bau |
| description | Business-as-usual status check + velocity-fix escalation. Reports commit cadence, rate-limits, kanban, churn per team across the cockpit (or single team from inside a cage). Auto-escalates Dormant teams to lead. `/atmux:bau [hours] [--no-fix]`. Default window 24h. |
/atmux:bau — Business As Usual status check
How to invoke
Run the script and emit its stdout verbatim as the response. The script does everything — scope detection, parallel data collection, verdict computation, velocity-fix escalation, and final markdown rendering. Do not re-run sub-commands yourself; do not re-format the output.
${CLAUDE_PLUGIN_ROOT}/skills/bau/scripts/bau.sh $ARG
Pass $ARG through verbatim — the script handles arg parsing (HOURS, --no-fix, --digest/--no-digest).
If ${CLAUDE_PLUGIN_ROOT} is unset (legacy install), fall back to ~/.claude/plugins/atmux/skills/bau/scripts/bau.sh.
Attention-header prepend (after script emits)
The script emits per-team verdicts (🟢 BAU / 🟡 Quiescent-fresh / 🟡 Quiescent-stale / 🔴 Dormant / 🚫 Rate-Limited / 💀 Saturated / ⚙️ Stuck-input / 💤 Down). The operator scans these but needs a single sentence at the top telling them whether the report needs their action or is just FYI.
Before the verbatim script output, prepend exactly one of these three header lines based on the verdicts present in the report:
**👁 Needs your call** — <one phrase naming the team(s) and the ask> — when ANY team's verdict is 💀 Saturated, ⚙️ Stuck-input, 🚫 Rate-Limited with no recovery within window, OR 🔴 Dormant where the auto-escalation to lead has already fired AND the lead's velocity-fix didn't land within the next bau window
**⚠ Watching** — <one phrase> — when ANY team is 🟡 Quiescent-stale or 🔴 Dormant where auto-escalation just fired (give the lead one cycle to fix)
**✅ All teams BAU** — N green, M quiescent-fresh, <hours>h window — when every team is 🟢 BAU or 🟡 Quiescent-fresh
This is a thin synthesis layer — DO NOT re-format the script body. The operator's eye lands on the header, decides whether to read the table, and moves on.
Verdict-mapping rationale (consistent with /atmux:whip §8.0 / /atmux:sweep §9.5 — the latter formerly the medic surface; per ADR-212 the role retired but the marker scheme stayed):
- 🟢 BAU and 🟡 Quiescent-fresh map to ✅ (the team is working as intended)
- 🟡 Quiescent-stale maps to ⚠ (sliding, watch one cycle)
- 🚫 Rate-Limited / 💤 Down / 💀 Saturated / ⚙️ Stuck-input / 🔴 Dormant map to 👁 + 🔴 unless the auto-fix is in-flight (then ⚠ for one cycle)
If the script's escalation step (Step 5) already wrote a velocity-fix to the team's driver-inbox, name that team and "auto-fix dispatched, watching next cycle" in the ⚠ header — the operator doesn't need to act unless the lead also fails.
Arguments
<hours>: integer, default 24. Time window for commit-cadence + task-completion checks.
--no-fix: disables Step-6 velocity-fix escalation, keeps the read-only diagnostic.
--digest / --no-digest: forces the shipped-features digest on/off. Default is auto — on for HOURS ≥ 24, off below.
What it does (1-line summary per step)
- Detects scope from the tmux socket (cockpit-wide vs single-team cage).
- Loads the team roster from
~/.atmux/cockpit.json.
- Fans out per-team data collection in parallel (git root + submodules,
atmux task list, atmux complaints list, per-window tmux capture-pane).
- Computes per-team verdict: 🟢 BAU · 🟡 Quiescent-fresh · 🟡 Quiescent-stale · 🔴 Dormant · 🚫 Rate-Limited · 💀 Saturated · ⚙️ Stuck-input · 💤 Down.
- If verdict trigger fires (last ship age ≥
BAU_STALE_THRESHOLD_HOURS, default 4h) and the lead can act, writes a velocity-fix directive to that team's .atmux/driver-inbox.md via atmux tell-lead. Skipped on Rate-Limited / Saturated / Down / Stuck-input.
- Emits the final markdown report on stdout.
Filename note: a rename proposed under the original ADR-198 slot was REVERTED before landing on trunk; .atmux/driver-inbox.md is and remains the canonical helper path (driverInboxPath). ADR-198 was then re-assigned to the medic host-pressure playbook.
Key invariants (so the model knows what it's reading)
- Timezone-aware timestamps. All HH:MM tags render in the user's configured
COORDINATION_TZ (plugin userConfig, default UTC) with the COORDINATION_TZ_SUFFIX appended (default UTC). Override at the shell with COORDINATION_TZ=… COORDINATION_TZ_SUFFIX=….
- Durations:
<60min → Nmin, ≥60min → HhMm. Never day units.
- State source is SQLite via atmux verbs (post-ADR-076). Never grep
.atmux/kanban.json — that file is gone. atmux task list --json, atmux complaints list --status open --json are the truth source.
- Lead is always window 2 per ADR-044 + CLAUDE.md "Team Roles". The script doesn't
jq into team.json to find it.
Working is defined by commit-cadence, not pane liveness (CLAUDE.md L191).
- Cage socket resolution tries
/tmp/atmux-<team>/sock (legacy) then <team-root>/.atmux/tmux/tmux-0/default (current).
- Stuck-input is cross-checked against whip-velocity-gate.log (per t-0a4fc7f6). When pane-snapshot reports
queued_n>=3, the script reads the team's last 3 entries from $HOME/.atmux/logs/whip-velocity-gate.log — if ANY show velocity=OK, the team is demonstrably shipping (commits-30min >= 1) and the verdict falls through to the normal BAU ladder instead of ⚙️ Stuck-input. Stuck-input fires only when BOTH signals (pane-snapshot AND velocity-gate) agree teams are idle. The cross-check function lives at scripts/lib-velocity-gate.sh with bats tests at tests/velocity-gate.bats.
When the script fails or surprises
- If
~/.atmux/cockpit.json is missing → script exits 1 with a one-line error.
- If a team has no cage socket → verdict is
💤 Down (correct surface).
- If the operator passes a scope that doesn't match the cockpit roster (e.g. from inside an unregistered cage), the script falls back to all-teams and prepends a
> note: line explaining.
The script is the source-of-truth for behaviour. If the output looks wrong, read scripts/bau.sh — verdict ordering, escalation gating, and digest bucketing all live there with comments. Do NOT re-implement the procedure in this skill prompt.
Performance
Single bash invocation; all probes fanned out in parallel. Wall-clock typically 0.5-2s for a 3-team cockpit. The prior multi-step LLM procedure took 30-60s.
Examples
/atmux:bau # cockpit-wide (or single-team if invoked from a cage), 24h + auto-escalate
/atmux:bau 48 # 48h window
/atmux:bau 1 # last hour
/atmux:bau 168 # last week — long-horizon churn + cadence review
/atmux:bau 24 --no-fix # read-only — no lead pings
/atmux:bau 1 --no-digest # skip shipped-features digest