Manager Setup — codeword-triggered Manager mode + HARD delegation wall
sonnet hook project only user-invokedTip
Type a standalone codeword (++m, ++rr, ++r, or ++a) in your message to add its discipline contract for that turn. Manager delegates hands-on work; review checks changes; architecture designs before implementation. In Plan mode, +++ independently adds task anti-drift cron planning. The plugin hook supplies these instructions without installing the optional hard wall. It adds context while preserving your original prompt, including the codeword.
What's new in 6.2.0
The prompt contracts are compact, and +++ now adds an anti-drift timer execution step only in verified Plan mode. See Codewords and Plan-only anti-drift cron.
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]
Manager not executor: think/plan/TaskGraph/delegate/observe/integrate; never
code/build/test/hand-debug - catch yourself -> STOP, spawn a subagent.
Protocol: 1) TaskCreate the FULL graph before any work. 2) TaskUpdate
addBlockedBy/addBlocks for real data-handoffs only, else parallel. 3)
TaskUpdate owner, then launch. 4) pending -> in_progress (before start) ->
completed (only truly done, never "partially"). 5) Read reports, validate,
integrate; failure -> follow-up task + re-delegate, never fix by hand. 6) all
code written -> one final task: simplify, strip over-engineering.
No TaskCreate/TaskUpdate (need env CLAUDE_CODE_ENABLE_TODO_TOOLS=1)? Same graph
as a numbered checklist in the plan or .claude/features/<task>.md, updated
wherever this protocol names those tools.
Sizing: one subagent = 1 deliverable, ~<=5 files, ~<=10 steps, ~<=20 min -
bigger splits into N tasks fanned out in ONE message; one agent for an hour =
drift you cannot observe or correct.
Branch: current, none chosen -> main; no branch/PR instruction -> stay on
main, take over ALL workspace changes incl. other sessions.
State in every spawn prompt: GOAL (task + why, beyond this edit), ROLE
(owns / must-NOT-touch), SCOPE (paths/commands in + out of bounds), CONTEXT
(done-so-far, by whom, parallel work - trimmed per agent), CONSUMER (who/what
uses the result + shape), DONE (acceptance + exact report shape wanted back).
One-liners are never enough. Every brief also sends the agent to the closest
well-built repo counterpart to extend - ADDITIVE to conventions/rules/docs,
never instead.
Scan ALL agents, summon genuine experts only, 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
The hook adds the selected Manager contract as context alongside your original prompt; it does not strip the codeword or rewrite your request. The block above illustrates the delegation contract. See Prompt Injection for the mechanism.
Two rules that do the heavy lifting
- 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.
- 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.
- 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.
| Field | What it must say |
|---|---|
| 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 — trimmed to what THIS agent needs |
| CONSUMER | Who or what uses the result next, and the shape it must fit |
| DONE | Acceptance criteria + the exact report shape you want back |
Codewords
| Codeword | Means | What it does |
|---|---|---|
++m | Manager | Manager + 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 |
++rr | Regression Review | Regression 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 |
++r | Review | Review 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 |
++a | Architecture | Architecture-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). |
+++ | Anti-drift cron plan | Only when the hook payload confirms Plan mode: include a task-specific session timer as a future execution step. Independent of ++m; does not schedule during planning |
Alphabetic codewords are case-insensitive standalone tokens. Within the review group, ++rr wins over ++r. ++m is plan-aware, and ++a is independent. A standalone +++ is also independent; it requires the hook payload’s permission_mode to equal plan. When combined, cron planning context comes first, followed by manager, architecture, and the selected review block. Embedded words and longer plus sequences do not activate these tokens.
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.
Plan-only anti-drift cron
While already in Plan mode, write:
+++ plan the API upgrade and its task tracking
The hook adds a read-only planning requirement without needing ++m or an armed wall. It asks
the plan to include one unique session timer per active top-level task through task-board,
hourly by default or at your requested cadence. The future execution step records the complete
task-specific prompt, timezone, schedule id, tick count, and stop rule in the task record.
Each planned tick rereads the goal, methodology, anti-drift controls, and user corrections; collects concise active-agent evidence; reconciles statuses, dependencies, and remaining work; and rebuilds the task graph. It retains every unfinished node and the latest ten completed nodes, preserving older completion evidence outside the active graph. It checks progress against acceptance criteria, corrects drift within scope, and identifies the next authorized action.
The report uses at most five short lines: local time/timezone, tick number and elapsed time; 🟢 achievements; 🔵 remaining work and next action; 🔴 present problems/blockers/questions; ⚪ drift verdict. Empty lines are omitted; detailed evidence stays in task records.
Planning creates no timers and writes no task files. During execution, the main session’s
task-board flow owns timer creation and verifies stopping on completion or cancellation.
If native scheduling tools are unavailable, it reports the gap instead of claiming a timer
exists. Timers belong to the session; approximate scheduling does not guarantee exact receipt
or continued delivery after the session ends. Outside verified Plan mode, +++ adds no cron
instruction, though other codewords or an armed wall can still add their own context.
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.
| Command | What it does |
|---|---|
/brewtools:manager-setup status | Show what is currently on — codeword state, wall state, prompt source |
/brewtools:manager-setup install | Install the guard into this project and arm the HARD wall — Claude physically cannot write/edit files here until you disable it |
/brewtools:manager-setup disable | Disarm the wall, leave the guard registered |
/brewtools:manager-setup edit | Open 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:
- Main session: delegate
Claude spawns a developer subagent with the task “fix the bug in payment.ts”.
- Subagent: do the work
The subagent edits
payment.ts, runs the tests — all tools allowed inside a subagent. - 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 files | No — delegate |
| Run mutating commands | No — delegate (read-only Bash allowed on the default level) |
| Anything inside a subagent | Yes — 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
| Situation | What to type |
|---|---|
| Delegate one complex task as Manager, just this turn | do X ++m |
| Start a full parallel plan with task breakdown (in plan mode) | plan Y ++m |
| Include session anti-drift scheduling in an execution plan (in Plan mode) | plan Y +++ |
| Enforce the delegation rule for a whole project session | /brewtools:manager-setup install |
| Run one task under the wall then auto-revert | refactor payment service in hard mode |
| Run task as Manager without changing any wall state | build 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
| Bucket | Tools | Main session while wall ON |
|---|---|---|
| ALWAYS-ALLOW · read | Read, Grep, Glob, NotebookRead | Allowed — inspect only |
| ALWAYS-ALLOW · delegate | Task, Agent, Skill, SlashCommand, ListAgents, SendMessage, Monitor | Allowed — they only hand work to a subagent |
| ALWAYS-ALLOW · plan mode | EnterPlanMode, ExitPlanMode | Allowed — without ExitPlanMode an armed wall traps a plan-mode session, and manager-prompt.mjs actively steers you into plan mode |
| ALWAYS-ALLOW · discovery | ToolSearch | Allowed — under ENABLE_TOOL_SEARCH=true the Task* tools are deferred, so denying it would make the tracking bucket unreachable |
| ALWAYS-ALLOW · track | TaskCreate, TaskUpdate, TaskList, TaskGet, TodoWrite, ReportFindings | Allowed — no filesystem side effects |
| ALWAYS-ALLOW · shells | BashOutput, KillShell, KillBash | Allowed — read or stop a shell started before arming; neither writes |
| ALWAYS-ALLOW · MCP meta | ListMcpResourcesTool, ReadMcpResourceTool | Allowed — read-only by protocol |
| ALWAYS-ALLOW · human | AskUserQuestion | Allowed |
| ALWAYS-BLOCK | Write, Edit, NotebookEdit, WebFetch | Denied — hands-on mutation / fetch |
| Default-deny | Artifact and every unlisted tool, plus MCP-write verbs | Denied — Artifact publishes a page, so it stays out |
| LEVEL-gated | Bash, WebSearch, MCP-read tools | Decided 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:
| Failure | New 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 JSON | Denied — “manager state at <path> is missing or unreadable, so the guard denies by default” |
| Uncaught error inside the guard itself | Denied, 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.
| Aspect | strict | balanced (default) |
|---|---|---|
Bash | Fully OFF — every command denied | Allowlist 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 |
WebSearch | OFF | ON |
| MCP-read | Explicit-allow list only | Heuristic allow (read-shaped tool names) |
| MCP-write | Denied | Denied |
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
| Binary | Vetted how |
|---|---|
git | status/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 |
gh | Read 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 / rg | Denied on --pre, --pre-glob, --hostname-bin, --search-zip, -z |
find | Denied on any exec-class action: -exec, -execdir, -ok, -okdir, -delete, -fprint, -fprint0, -fprintf, -fls |
node | Only node --check <file> — every other invocation counts as execution |
| everything else on the list | No 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:
| Command | Before | Now | Why it was a hole |
|---|---|---|---|
git diff --output=/tmp/pwned HEAD~1 | Allowed | Denied | --output turns a read subcommand into a file write |
git branch -D main | Allowed | Denied | branch deletes/renames; only listing flags are read-shaped |
gh issue comment 1 --body list | Allowed | Denied | the 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/pwned | Allowed | Denied | GNU 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 |
|---|---|
| 1 | The command starts with node — no env prefix, no other binary — and it is the ONLY segment: no &&, ||, ;, |, &, or newline chaining |
| 2 | No forbidden metacharacter anywhere, quoted or not — $(, a backtick, >, or < denies the whole command outright, before any of the rules below run |
| 3 | No $ anywhere in the raw command — no variable or command expansion beyond what rule 2 already blocks |
| 4 | No evaluator flag on the node invocation: -e, --eval, -p, --print, --input-type, --require/-r, --import, --loader, --experimental-loader |
| 5 | The 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 |
| 6 | The 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.
| Guarantee | Mechanism |
|---|---|
/brewtools:manager-setup disable can always start | Skill is ALWAYS-ALLOW |
Its one Bash call is allowed even at level strict | The command above satisfies the six conditions — but only in that exact shape |
| Anything the main session cannot run | Delegate it: Task/Agent are always allowed and subagents bypass the wall entirely |
| Every denied tool call shows the exit command | The 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
Writes to state.json stamp version, content_version, generated_by
("brewtools:manager-setup") and last_updated when their sources resolve. Version records
release provenance; content_version records the writer’s content revision. The date uses the
local calendar. Upgrade refreshes metadata while preserving hard and level.
The copied guard’s line-2 stamp carries version, content_version and generated_by;
byte-copied assets omit last_updated. Setup-status reads state.json’s content_version
first, with release-version fallback for older metadata and the guard stamp as the documented
companion fallback. Release provenance alone does not prove content drift.
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 for standalone codewords and checks the payload’s permission mode. Review detection gives ++rr precedence over ++r; cron planning requires standalone +++ and permission_mode === 'plan'. Without an active codeword, the hook checks wall state and injects the Manager contract only when armed.
The hook resolves each selected block (full, planmode, cron-plan, architect, review-regression, or review-double) via three-level fallback:
- Project override:
.claude/brewtools/manager/prompts/<mode>.md - Global override:
~/.claude/manager/prompts/<mode>.md - Plugin default: plugin
references/<mode>.md
Project and global overrides survive plugin updates because they live outside the plugin cache.
When no active codeword selects a block, an armed wall supplies the ambient Manager full
block. An active codeword branch returns after its selected blocks; it does not also add the
ambient wall block. Session-start separately reports the armed wall and reminds the session
to delegate bounded units with complete briefs.
Scope table
| Thing | Scope | Files |
|---|---|---|
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 state | same state.json |
Prompt-text overrides (edit/purge) | project or global | project: <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.
State defaults are hard: false, level: "balanced", mode: "full"; there is no
default enabled: true field. Wall enforcement reads project state only. The informational
mode can fall back to global state, independently of the prompt-file order above. Bundled
helpers manage state and override writes; current permissions still apply.
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
| Action | Command / natural language | Effect |
|---|---|---|
status | /brewtools:manager-setup status | Full explainer: codewords + wall state + effective prompt sources. Default with no argument |
install | /brewtools:manager-setup install | INSTALL guard + ARM the HARD wall (project). /reload on first install only |
upgrade | /brewtools:manager-setup upgrade | Re-copy the guard and off-switch CLI, re-register, preserve hard/level, and refresh version/content-version provenance. Backfills a missing CLI; aborts if nothing is installed |
enable | /brewtools:manager-setup enable | ARM an already-installed wall (state flip only). Never installed -> routed to install |
disable | /brewtools:manager-setup disable | DISARM the wall (state flip only — registration kept, guard no-ops) |
uninstall | /brewtools:manager-setup uninstall | Two 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 purge | uninstall + delete state.json and the prompt-text overrides — back to the plugin default |
level strict | /brewtools:manager-setup level strict | Wall strictness = strict (Bash fully off) |
level balanced | /brewtools:manager-setup level balanced | Wall strictness = balanced (read-only Bash allowed) |
edit | /brewtools:manager-setup edit | Copy plugin default into project override for editing |
hard-one-shot | <task> in hard mode | Wall ON — run task as Manager — auto-revert wall OFF when done (reverts even on failure or abort) |
manager-run | <task> as manager | Run 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.
Type `+++` in verified Plan mode -> injects anti-drift cron planning; scheduling waits for execution.
--- 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 guard/CLI; arm state preserved; refresh content-version provenance)
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=falsedisable 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.
Task Board Setup
Domain methodology, task-specific work plans, graph reconciliation, and session anti-drift timers.
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
/brewtools:plugin-update to check and update the brewcode plugin suite in one command.
See the FAQ for details.