Manager Setup — codeword-triggered Manager mode + HARD delegation wall

sonnet hook project only user-invoked

Tip

What is Manager mode? You type a short codeword (++m, ++rr, ++r, or ++a) anywhere in your message and Claude instantly activates a discipline contract — just for that one message. ++m makes Claude a pure orchestrator that delegates all hands-on work — and when you are in plan mode it automatically adds a full task-graph planning pass. ++rr and ++r inject review discipline (anti-regression / two-phase double-check). ++a injects an architecture-first directive — design before code, reuse existing patterns, no over-engineering. No setup required. The codeword is stripped from your message; your actual text is preserved.

What actually happens

You type:

++m refactor the payment module

Claude actually receives (you never see this part — it is injected invisibly by a hook):

[ROLE: MANAGER]

You are a Manager, not an executor. Your only actions: think, plan, build the
TaskGraph, delegate, observe, integrate. You do not write/edit code, run
builds/tests, or hands-on debug. Catch yourself editing a file or running an
impl command -> STOP, spawn a subagent. "Faster to do it myself" is a symptom,
not an argument - delegate anyway.

Protocol, always:
1. Decompose the TASK into a full TaskGraph BEFORE any work (TaskCreate for all).
2. Dependencies via TaskUpdate addBlockedBy/addBlocks - real data-handoffs only.
   No dependency = independent = parallel.
3. Assign owner (TaskUpdate owner), then launch the agent.
4. Status honestly: pending -> in_progress (BEFORE start) -> completed (only truly
   done, green - never "partially").
5. Observe: read reports, validate, integrate. Agent failed -> file a follow-up
   task and re-delegate, never fix by hand.
6. ALL code written (not per-piece) -> file one recommended final task: simplify
   the whole written code, strip over-engineering. Delegate it like any other.

Sizing before spawning: one subagent = ONE bounded unit - one deliverable,
~<=5 files, ~<=10 steps. Bigger MUST be split into N tasks, fanned out in ONE
message. A big task handed to one agent = an agent gone for an hour: you cannot
observe it, cannot correct it, and it usually drifts off-target.

Widest fan-out: a dependency must be a REAL data handoff, else parallel. Size a
unit to ~<=20 min of agent work; longer -> split again.

Branch: work in the current branch; none chosen -> main. Unless the user says
branch/PR, stay on main and take over ALL workspace changes, incl. from other
sessions.

Every spawn prompt MUST carry, explicitly:
  GOAL     - the overall task and why it exists; the point beyond the file edit.
  ROLE     - what this agent owns; what it must NOT touch.
  SCOPE    - exact paths/commands in bounds + explicit out-of-bounds.
  CONTEXT  - what is already done, by whom, what runs in parallel. Adapt it per
             agent, trimmed to what THIS one needs; never dump everything.
  CONSUMER - who or what uses the result next, and the shape it must fit.
  DONE     - acceptance criteria + the exact report shape you want back.
A bare one-line task is never enough.
Every code/test brief MUST make the agent find the closest well-built counterpart
in the repo and follow its principles - IN ADDITION to conventions/rules/docs,
never instead.

Scan ALL available agents; summon only genuine experts - one best-match per task.
Autonomy: finish the job, don't stop halfway, don't ask where you can decide.
Minimize the critical path.
refactor the payment module

Your single line becomes: the full Manager contract (above) + your original request. The codeword ++m is consumed; your text reaches Claude unchanged. Curious how injection works? See Prompt Injection.

Two rules that do the heavy lifting

  1. Bounded units, not one giant agent

    One subagent = one deliverable, roughly 5 files and 10 steps. Anything bigger is split into N tasks fanned out in ONE message. A big task handed to one agent = an agent gone for an hour: you cannot observe it, cannot correct it, and it usually drifts off-target.

  2. Six-field brief on every spawn

    Each spawn prompt carries GOAL, ROLE, SCOPE, CONTEXT, CONSUMER, DONE. CONTEXT is trimmed per agent — never dump everything. A bare one-line task is never enough. Every code/test brief must also send the agent to find the closest well-built counterpart in the repo and follow its principles — additive to conventions/rules/docs, never instead.

  3. One simplification task at the end

    Once ALL code is written — not per piece — the Manager files one recommended final task: simplify the whole written code and strip over-engineering. It is delegated like any other task, never done by hand.

FieldWhat it must say
GOALThe overall task and why it exists; the point beyond the file edit
ROLEWhat this agent owns; what it must NOT touch
SCOPEExact paths/commands in bounds + explicit out-of-bounds
CONTEXTWhat is already done, by whom, what runs in parallel — trimmed to what THIS agent needs
CONSUMERWho or what uses the result next, and the shape it must fit
DONEAcceptance criteria + the exact report shape you want back

Codewords

CodewordMeansWhat it does
++mManagerManager + delegation for the current task — Claude orchestrates, never codes by hand; splits work into bounded units and briefs every spawn with GOAL / ROLE / SCOPE / CONTEXT / CONSUMER / DONE; every code/test brief also orders the agent to find the closest well-built counterpart in the repo and follow its principles — additive to conventions/rules/docs, never instead
++rrRegression ReviewRegression review with double-check — after each significant phase, run a review focused on no regression + project standard + correctness; before the review proper the code goes through a simplification pass (over-engineered? simpler?); two-phase (review → double-check → fix); mandatory final cross-review at task end
++rReviewReview with double-check — after each significant change, run a two-phase multi-agent review (review → double-check → fix), preceded by a simplification pass over the code; codeword-only, no ambient injection or wall state change
++aArchitectureArchitecture-first pass before coding — delegate a design that fits the existing project architecture, patterns and rules; robust, scalable, and simple (no over-engineering); find the closest well-built counterpart in the repo, take its principles, reuse its patterns/classes — additive to conventions/rules/docs, never instead; keep clean seams. Independent group, combines with ++m/++rr/++r; same block in normal and plan mode (in plan mode it is written into the plan).

Detection order: within the review group, ++rr is tested before ++r (longest-prefix first). ++m is matched as a standalone token; in plan mode it auto-adds the plan addon. ++a is its own independent group and can combine with either.

Put the codeword anywhere: start, middle, or end of your message. Everything else is passed through unchanged.

The same find-the-closest-counterpart rule is also injected into generated agents by /brewcode:teams-setup and /brewcode:agents, gated to agents whose domain writes code, scripts, SQL, schemas, or infra — see Teams and Agents.


Everyday commands

Canonical mode order, shared by every -setup skill: status | install | upgrade | enable | disable | uninstall | purge. No argument = status when the wall is installed, install when it is not.

CommandWhat it does
/brewtools:manager-setup statusShow what is currently on — codeword state, wall state, prompt source
/brewtools:manager-setup installInstall the guard into this project and arm the HARD wall — Claude physically cannot write/edit files here until you disable it
/brewtools:manager-setup disableDisarm the wall, leave the guard registered
/brewtools:manager-setup editOpen the Manager prompt text so you can customize it

Note

The old command words on, off and reset are gone. They still work as free text (on -> enable, off -> disable, reset -> purge), but the canonical verbs are the ones above.


The HARD wall

Caution

With the HARD wall ON, Claude in the main chat physically cannot edit files, write, or run mutating commands. It is forced to delegate every hands-on step to a subagent. Subagents have full freedom — they can write, edit, run tests, push commits, anything. Arm it with /brewtools:manager-setup install, drop it with /brewtools:manager-setup disable. It is opt-in and per-project — nothing changes until you install it.

The wall in action

The wall is ON. You ask:

fix the bug in payment.ts

Claude tries to edit the file directly — and is blocked:

Caution

Edit blocked — Manager HARD wall is ON. The main session cannot edit files, write, or run mutating commands. Delegate this to a subagent.

So Claude does the right thing — it spawns a subagent, which has full access:

  1. Main session: delegate

    Claude spawns a developer subagent with the task “fix the bug in payment.ts”.

  2. Subagent: do the work

    The subagent edits payment.ts, runs the tests — all tools allowed inside a subagent.

  3. Main session: integrate

    Claude reads the subagent’s result and reports back. It never touched the file itself.

What is allowed vs blocked (wall ON)

In the MAIN chat (wall ON)Allowed?
Read, search, plan, delegate (Task)Yes
Edit / Write filesNo — delegate
Run mutating commandsNo — delegate (read-only Bash allowed on the default level)
Anything inside a subagentYes — full freedom

This is what “delegate everything” means in practice — the wall makes it physically true, not just a suggestion. As of v6.0.0 the guard is a strict allowlist (not a denylist) with per-binary flag vetting, and it fails closed on a broken or unparseable state — see the technical spoiler below for exactly which binaries and flags are vetted.


When to use

SituationWhat to type
Delegate one complex task as Manager, just this turndo X ++m
Start a full parallel plan with task breakdown (in plan mode)plan Y ++m
Enforce the delegation rule for a whole project session/brewtools:manager-setup install
Run one task under the wall then auto-revertrefactor payment service in hard mode
Run task as Manager without changing any wall statebuild release plan as manager
Check current state/brewtools:manager-setup status
Pick the guard up after a plugin update/brewtools:manager-setup upgrade
Wall installed before v5.0.0 — get the off-switch CLI into the project/brewtools:manager-setup upgrade

Technical: how the HARD wall works (tool buckets, strict vs balanced, agent_id linchpin)

The HARD wall is an optional, project-scoped guard that physically blocks the main Claude session from writing or editing files. Subagents always stay fully free — delegation is never blocked.

Install-once + state-gate

/brewtools:manager-setup install copies hardmode-guard.mjs from the plugin cache into <cwd>/.claude/brewtools/manager/hardmode-guard.mjs and registers a PreToolUse * entry in <cwd>/.claude/settings.local.json (personal, gitignored). The guard is registered once; a later upgrade re-copies it from the current plugin version (so plugin updates propagate) without adding duplicates and without touching the arm state. A /reload or session restart is required after first install.

install also copies lib/manager-state.mjs to <cwd>/.claude/brewtools/manager/manager-state.mjs. That copy is the wall’s off-switch CLI (get / set hard=<bool> level=<strict|balanced> [--cwd DIR]); it lives at a fixed project path because resolving the plugin root would need shell operators the armed wall denies.

The guard reads <cwd>/.claude/brewtools/manager/state.json on every PreToolUse call. When hard !== true, the guard exits immediately — no denial. disable flips state.hard=false without touching settings.local.json; the guard stays registered but becomes a no-op. This split exists because editing settings while the wall is armed would be blocked — the state flip goes through the one self-exempt Bash shape instead. uninstall is therefore two Bash calls: the bare disarm first, then the deregistration block, which is only allowed because the first call disarmed the wall.

agent_id linchpin — main session blocked, subagents free

The PreToolUse payload carries agent_id / agent_type only for subagent-internal tool calls. Main-session calls have no agent_id. The guard denies mutations only when agent_id is absent. Subagents pass through freely — delegation itself is never blocked.

Re-verified on CC 2.1.195 (2026-06-27) — the discriminator still holds. agent_id / agent_type presence is an undocumented field; re-verify on each major CC upgrade.

Tool buckets

BucketToolsMain session while wall ON
ALWAYS-ALLOW · readRead, Grep, Glob, NotebookReadAllowed — inspect only
ALWAYS-ALLOW · delegateTask, Agent, Skill, SlashCommand, ListAgents, SendMessage, MonitorAllowed — they only hand work to a subagent
ALWAYS-ALLOW · plan modeEnterPlanMode, ExitPlanModeAllowed — without ExitPlanMode an armed wall traps a plan-mode session, and manager-prompt.mjs actively steers you into plan mode
ALWAYS-ALLOW · discoveryToolSearchAllowed — under ENABLE_TOOL_SEARCH=true the Task* tools are deferred, so denying it would make the tracking bucket unreachable
ALWAYS-ALLOW · trackTaskCreate, TaskUpdate, TaskList, TaskGet, TodoWrite, ReportFindingsAllowed — no filesystem side effects
ALWAYS-ALLOW · shellsBashOutput, KillShell, KillBashAllowed — read or stop a shell started before arming; neither writes
ALWAYS-ALLOW · MCP metaListMcpResourcesTool, ReadMcpResourceToolAllowed — read-only by protocol
ALWAYS-ALLOW · humanAskUserQuestionAllowed
ALWAYS-BLOCKWrite, Edit, NotebookEdit, WebFetchDenied — hands-on mutation / fetch
Default-denyArtifact and every unlisted tool, plus MCP-write verbsDenied — Artifact publishes a page, so it stays out
LEVEL-gatedBash, WebSearch, MCP-read toolsDecided by level (see below)

The plan-mode and discovery rows were self-defeating omissions before v5.0.0: a denied ExitPlanMode left a plan-mode session with no way out, and a denied ToolSearch hid the very task-tracking tools the Manager contract requires.

Fail-closed (v6.0.0)

Before v6.0.0 three failure paths let a mutation through undenied: a PreToolUse payload the guard could not parse, an installed manager directory whose state.json was missing or corrupt, and an uncaught internal error. All three now DENY the main session instead of passing through:

FailureNew behaviour
Unparseable stdin (malformed JSON)Denied — “the guard could not parse its PreToolUse payload and denies by default”
Manager directory present, state.json missing or not valid JSONDenied — “manager state at <path> is missing or unreadable, so the guard denies by default”
Uncaught error inside the guard itselfDenied, except the subagent discriminator — checked first, so a genuine subagent call never sees a false deny

Only two pass-throughs remain, both by design: the manager was never installed in this project at all (no manager directory at any candidate root — a no-op, not a security decision), and a genuine subagent call (agent_id present in the payload). Recovery from a broken state.json is still available because the self-exempt off-switch CLI is checked BEFORE the broken-state deny: node <ABS root>/.claude/brewtools/manager/manager-state.mjs set hard=false runs and rewrites the file even while state.json is corrupt.

Strict vs balanced

Caution

v6.0.0: the balanced Bash classifier changed shape, not just its contents. It used to be a denylist — anything not explicitly forbidden passed through, so a new dangerous flag on an already-listed binary opened a silent hole. It is now a strict allowlist: exactly the binaries below run at all, several with per-binary flag vetting on top. An unlisted binary, or a listed one used with a disallowed flag, is denied by default — not because someone remembered to forbid it.

Aspectstrictbalanced (default)
BashFully OFF — every command deniedAllowlist classifier — allow inspection, deny everything else
Allowed binaries (balanced)ls cat pwd which head tail wc date whoami basename dirname realpath test [ jq echo grep rg find git gh node — bare names only, so /bin/ls, VAR=x ls, env ls never match
WebSearchOFFON
MCP-readExplicit-allow list onlyHeuristic allow (read-shaped tool names)
MCP-writeDeniedDenied

The allowlist is a single table, one binary per row, so a binary and its flag vetter cannot drift apart into “added to one, forgotten in the other.” env is deliberately absent — it looks like an inspection tool but is a universal exec wrapper (env node evil.js would launder any command through it). Any >, < redirection, $(...), or a backtick anywhere in the command denies the WHOLE command, on any binary.

Per-binary flag vetting

BinaryVetted how
gitstatus/log/diff/show/rev-parse/describe bare; remote only with -v; tag only with -l; stash only with list; branch bare or every argument a listing flag (--list, -l, --show-current, -a/-r/--all/--remotes, -v/-vv, --contains, --merged, --no-merged, --format=...). Any of -c, --config-env, --exec-path, --upload-pack, --receive-pack, --ext-diff, -C, --output, --textconv denies the command outright, on any subcommand
ghRead verbs are POSITIONAL only — gh <group> <verb> or gh <verb> where the verb is list/view/status. A matching word elsewhere in the argument list does not count
grep / rgDenied on --pre, --pre-glob, --hostname-bin, --search-zip, -z
findDenied on any exec-class action: -exec, -execdir, -ok, -okdir, -delete, -fprint, -fprint0, -fprintf, -fls
nodeOnly node --check <file> — every other invocation counts as execution
everything else on the listNo flags vetted — ls, cat, pwd, which, head, tail, wc, date, whoami, basename, dirname, realpath, test/[, jq, echo cannot exec by design

Four bypasses closed in v6.0.0 — each one used to slip past the old denylist looking read-only, and each is now covered by a dedicated case in tests/suite.mjs:

CommandBeforeNowWhy it was a hole
git diff --output=/tmp/pwned HEAD~1AllowedDenied--output turns a read subcommand into a file write
git branch -D mainAllowedDeniedbranch deletes/renames; only listing flags are read-shaped
gh issue comment 1 --body listAllowedDeniedthe read-verb word list showed up as a flag VALUE, not the actual verb — position-blind matching let it launder a write
find . -fprint0 /tmp/pwnedAllowedDeniedGNU find writes a file through a search action that reads as inspection

Off-switch safety

Exactly ONE Bash shape survives an armed wall, at every level:

node <ABS project root>/.claude/brewtools/manager/manager-state.mjs set hard=false

/brewtools:manager-setup disable issues precisely that, as a single Bash call with nothing appended — no BT_ROOT= prelude, no && echo, no || echo. Skill is in ALWAYS-ALLOW, so the skill can always start. The exemption check runs only for tool_name === 'Bash', after every other tool has already been classified — no other tool can inherit it.

The exemption is narrow on purpose. The guard lets the command through only when ALL of these hold:

#Condition
1The command starts with node — no env prefix, no other binary — and it is the ONLY segment: no &&, ||, ;, |, &, or newline chaining
2No forbidden metacharacter anywhere, quoted or not — $(, a backtick, >, or < denies the whole command outright, before any of the rules below run
3No $ anywhere in the raw command — no variable or command expansion beyond what rule 2 already blocks
4No evaluator flag on the node invocation: -e, --eval, -p, --print, --input-type, --require/-r, --import, --loader, --experimental-loader
5The path node actually executes, resolved with realpath, must equal a helper file this project or the plugin genuinely shipped — <cwd>/.claude/brewtools/manager/manager-state.mjs or the plugin’s own hooks/lib/manager-state.mjs next to the guard. A file merely named manager-state.mjs elsewhere on disk, or a path that does not resolve at all, is NOT exempt
6The remaining tokens are the helper’s own CLI: get, or set with hard=<true|false> / level=<strict|balanced> and an optional --cwd DIR

Conditions 3-6 were introduced in v5.0.0 to close an arbitrary-code-execution hole: the original exemption matched the bare token manager-state.mjs anywhere on the line and skipped quoted text, so a crafted node invocation could run an arbitrary payload in a guarded main session at level strict. Condition 5 was tightened again for v6.0.0: it used to match a tail regex against the command string ((.claude/brewtools/manager|hooks/lib)/manager-state.mjs$), so a file merely planted at a matching path — e.g. /tmp/evil/hooks/lib/manager-state.mjs — passed too. The anchor is now the resolved absolute path of the file actually installed, checked with realpath, never a string pattern. Do not relax either fix back to tolerate && or a path-suffix match.

GuaranteeMechanism
/brewtools:manager-setup disable can always startSkill is ALWAYS-ALLOW
Its one Bash call is allowed even at level strictThe command above satisfies the six conditions — but only in that exact shape
Anything the main session cannot runDelegate it: Task/Agent are always allowed and subagents bypass the wall entirely
Every denied tool call shows the exit commandThe deny reason carries it verbatim

Caution

Installed the wall before v5.0.0? Run /brewtools:manager-setup upgrade once. The disarm command runs a project-local manager-state.mjs, and only install/upgrade copy it there. An older project has no such file, so the command fails with Cannot find module and the wall has no working off-switch. upgrade backfills it and leaves hard/level untouched. If the wall is already armed, delegate the upgrade to a subagent — resolving the plugin root in the main session needs shell operators the wall denies.

Version and ownership

Every write to state.json stamps three keys: version (the plugin version that wrote it), generated_by ("brewtools:manager-setup"), and last_updated. last_updated is the LOCAL calendar date — fixed from an earlier UTC stamp that dated the file wrong (yesterday’s date) anywhere west of UTC after roughly 17:00 local time. upgrade now restamps this trio unconditionally, even when the guard file content did not change; before the fix upgrade left state.json untouched and status kept reporting stale forever after a plugin update.

hardmode-guard.mjs, the copied guard, carries the same trio as a // brewcode-meta: version=X.Y.Z generated_by=brewtools:manager-setup comment on line 2. /brewcode:setup-status reads state.json’s version key first; only when that key is absent does it fall back to the guard’s brewcode-meta line.

One documented exception: pluginVersion() in manager-state.mjs returns null — and writeState then DELETES the version key from state.json and warns on stderr — when the plugin version cannot be resolved at all, instead of aborting like every other stamped-artifact writer in this repo. state.json is the HARD wall’s own off-switch (set hard=false); a writer that aborted here would leave the user locked behind an armed wall with no way out. It is the sole licensed exception to “abort when the version can’t be resolved.”

Technical: prompt resolution + scopes (where the Manager text comes from)

How the codeword injection works

On every user message, manager-prompt.mjs scans the prompt text. It matches ++m as a standalone token, and tests the review group longest-prefix first (++rr before ++r) so ++rr is never mis-matched as ++r. If no codeword is present (and the wall is not armed), the hook exits immediately — no file I/O, zero overhead.

The hook resolves the prompt text for the detected mode (full or planmode) via three-level fallback:

  1. Project override: .claude/brewtools/manager/prompts/<mode>.md
  2. Global override: ~/.claude/manager/prompts/<mode>.md
  3. Plugin default: plugin references/<mode>.md

Project and global overrides survive plugin updates because they live outside the plugin cache.

When the HARD wall is armed, the Manager (full) block is also ambient-injected every turn with no codeword needed — codewords and wall injection are independent channels. On top of that, brewtools’ session-start.mjs reports the armed wall at session start and repeats the same two rules: delegate in bounded units (one deliverable, ~5 files), and brief every agent with goal + scope + what is already done + who consumes the result + acceptance.

Scope table

ThingScopeFiles
Wall flags {"{"}hard, level{"}"}PROJECT ONLY<cwd>/.claude/brewtools/manager/state.json
Wall registration (guard)PROJECT ONLY<cwd>/.claude/settings.local.json + <cwd>/.claude/brewtools/manager/hardmode-guard.mjs
Soft mode field (informational)project statesame state.json
Prompt-text overrides (edit/purge)project or globalproject: <cwd>/.claude/brewtools/manager/prompts/<mode>.md — global: ~/.claude/manager/prompts/<mode>.md

The wall flags (hard/level) are resolved project-only. Passing --scope global to install/enable/disable/level is silently ignored (wall has no global scope); the flag only applies to prompt-text override scope in edit/purge.

Prompt resolution chain

PriorityState sourcePrompt override source
1 (highest).claude/brewtools/manager/state.json.claude/brewtools/manager/prompts/<mode>.md
2~/.claude/manager/state.json~/.claude/manager/prompts/<mode>.md
3 (lowest)Hardcoded {"{"}enabled:true, mode:"full"{"}"}Plugin references/<mode>.md

Global paths (~/.claude/*) are protected from direct Write/Edit tool access (Claude Code v3.4.70+). The skill writes them via bundled Node helpers using atomic lock+tmp+rename.

Plan Mode addon (auto in plan mode)

When ++m is used while the session is in plan mode (permission_mode === 'plan'), the hook injects both the full Manager block and the Plan Mode addon. The addon instructs the model to: write the full TaskGraph in English into the plan before starting; mark tasks with parallel / critical-path indicators; output all task and plan text in English regardless of user prompt language.

Full command and intent reference (all actions, hard-one-shot vs manager-run)

The skill also understands natural-language Russian (e.g. on/off, hard mode, status). The complete RU+EN trigger list lives in the skill’s SKILL.md.

Actions

ActionCommand / natural languageEffect
status/brewtools:manager-setup statusFull explainer: codewords + wall state + effective prompt sources. Default with no argument
install/brewtools:manager-setup installINSTALL guard + ARM the HARD wall (project). /reload on first install only
upgrade/brewtools:manager-setup upgradeRe-copy the guard and the off-switch CLI + re-register from the current plugin version; hard/level preserved; restamps state.json’s version/generated_by/last_updated trio unconditionally. Backfills manager-state.mjs into projects installed before it existed. Aborts if nothing is installed
enable/brewtools:manager-setup enableARM an already-installed wall (state flip only). Never installed -> routed to install
disable/brewtools:manager-setup disableDISARM the wall (state flip only — registration kept, guard no-ops)
uninstall/brewtools:manager-setup uninstallTwo Bash calls: the bare disarm first, then DEREGISTER guard from settings.local.json + delete the copied guard. Then /reload. State and prompt overrides kept
purge/brewtools:manager-setup purgeuninstall + delete state.json and the prompt-text overrides — back to the plugin default
level strict/brewtools:manager-setup level strictWall strictness = strict (Bash fully off)
level balanced/brewtools:manager-setup level balancedWall strictness = balanced (read-only Bash allowed)
edit/brewtools:manager-setup editCopy plugin default into project override for editing
hard-one-shot<task> in hard modeWall ON — run task as Manager — auto-revert wall OFF when done (reverts even on failure or abort)
manager-run<task> as managerRun task as Manager with wall UNTOUCHED (discipline via injected prompt only — no wall toggle)
inline-run/brewtools:manager-setup <task>Prepend Manager block, execute — no state change

Expected status output (wall off)

# Manager -- status

## Codewords (ALWAYS active -- hook-driven, independent of this skill)
Type `++m` anywhere   -> injects the Manager (full) block for that one turn.
Type `++m` while in plan mode -> injects the Manager + Plan Mode block for that one turn.
Type `++rr` anywhere  -> injects the Regression Review contract for that one turn.
Type `++r` anywhere   -> injects the Review contract for that one turn.
Type `++a` anywhere   -> injects the Architecture-first contract for that one turn.

--- injected by ++m (full) ---
<full Manager block text>

--- injected by ++m (planmode -- auto when permission_mode === 'plan') ---
<planmode block text>

## HARD wall (this project) -- registered=no  armed=OFF  level=balanced  (state source: default)
State version: <none>  plugin: <X.Y.Z>  (no version key until install/upgrade writes one)
Install:   /brewtools:manager-setup install    (install+arm; /reload only on FIRST install)
Upgrade:   /brewtools:manager-setup upgrade    (re-copy the guard; arm state preserved; restamps version/generated_by/last_updated)
Enable:    /brewtools:manager-setup enable     (arm an already-installed wall)
Disable:   /brewtools:manager-setup disable    (disarm only -- registration kept, guard no-ops)
Uninstall: /brewtools:manager-setup uninstall  (deregister from settings.local.json, then /reload)
Purge:     /brewtools:manager-setup purge      (uninstall + delete state and prompt overrides)
Level:     /brewtools:manager-setup level strict | /brewtools:manager-setup level balanced
Exit:      node <ABS project root>/.claude/brewtools/manager/manager-state.mjs set hard=false

disable always has a way out: Skill is ALWAYS-ALLOW, and the one Bash call it makes is the exempt command above — allowed at level strict too, but only in that exact shape. Copy it verbatim; a BT_ROOT= prelude or an appended && echo makes the guard deny it. For anything else, delegate — subagents bypass the wall.

hard-one-shot vs manager-run

hard-one-shot (<task> in hard mode) actually toggles the guard: wall ON — task runs — wall auto-reverts OFF when done, even on failure or abort. The guard never silently persists.

manager-run (<task> as manager) does NOT touch the wall state at all. Manager discipline is enforced via the injected prompt only. Use this when you want Manager behavior without arming or changing the guard.

⚙️

Think Short

Companion output-control skill — inject brevity directives via SessionStart and per-agent PreToolUse rather than per-prompt codewords.

Prompt Injection

How the ++m / ++rr / ++r / ++a codewords inject the Manager / review / architecture contract into the model — the full mechanism explained.

📋

Setup Status

Read-only dashboard across every -setup skill — installed, stale or missing, with the hand-run command for each.

📄

Brewtools overview

All brewtools skills and agents in one place.

🔗

GitHub source

Source code — skill, manager-prompt.mjs hook, hardmode-guard.mjs, prompt references, and state helpers.

Updating plugins

Use /brewtools:plugin-update to check and update the brewcode plugin suite in one command. See the FAQ for details.