Prompt Injection

hook

Tip

Type a short codeword — ++m, ++rr, ++r, or ++a — anywhere in your message. A UserPromptSubmit hook intercepts the message before the model sees it and appends the matching operating contract as a hidden system-reminder. You see only what you typed; the model receives your text plus the full contract for that one turn.

The injection point

+---------------------------+
| You type:                 |
| "++m fix the login bug"   |
+---------------------------+
            |
            v
+----------------------------------+
| UserPromptSubmit hook fires      |
| (manager-prompt.mjs)             |
| - detects "++m" codeword         |
| - resolves prompt text           |
| - emits additionalContext        |
+----------------------------------+
            |
            v
+---------------------------------------------+
| Model receives:                             |
| [system-reminder header line]               |
| [full Manager operating contract]           |
| [your original text: fix the login bug]     |
+---------------------------------------------+

What you type vs what the model receives

++m fix the login bug
>> system-reminder (additionalContext) <<

User typed ++m -- Manager mode is active for this turn:

[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.

fix the login bug

The injected block is a system-reminder — invisible in the user’s transcript but fully part of the model’s context for that turn.

How it works

  1. You include a codeword anywhere in your message

    The codeword can appear at the start, middle, or end. Your surrounding text is preserved unchanged. No special formatting is required.

  2. The UserPromptSubmit hook fires before the model

    manager-prompt.mjs runs on every user message. It matches ++m as a standalone token, and tests the review group longest-prefix first: ++rr++r. When ++m is used in plan mode (permission_mode === ‘plan’) it also injects the Plan Mode addon. The review codewords (++rr, ++r) are codeword-only — there is no ambient HARD-wall equivalent for review mode. ++a is a third, independent group detected alongside manager and review, injected in the order manager -> architect -> review when combined. If no codeword is found (and the HARD wall is off), the hook exits immediately — zero file I/O, zero overhead.

  3. The hook resolves the prompt text

    Three-level fallback: project override (.claude/brewtools/manager/prompts/<mode>.md) -> global override (~/.claude/manager/prompts/<mode>.md) -> plugin default (references/<mode>.md). Project and global overrides survive plugin updates because they live outside the plugin cache.

  4. The resolved text is emitted via additionalContext

    The model receives a system-reminder containing a header line plus the full prompt block, followed by your original message. The contract applies for that turn only — the next message starts clean unless you type a codeword again.

Codewords and injected prompts

TriggerMeansWhen it firesWhat gets injected
++mManagerany message containing itfull Manager block — delegate-everything orchestrator contract, bounded-unit sizing (one deliverable, ~5 files, ~10 steps), one final delegated task to simplify all written code, the six-field spawn brief GOAL / ROLE / SCOPE / CONTEXT / CONSUMER / DONE, and a rule that every code/test brief must send the agent to find the closest well-built counterpart in the repo and follow its principles (additive to conventions/rules/docs, never instead); in plan mode also injects the Plan Mode addon (TaskGraph in English, parallel indicators)
++rrRegression Reviewany message containing it (checked after ++m)anti-regression review discipline — review each significant phase for NO regression + project standard + correctness; simplification pass before the review proper; two-phase review->double-check->fix; final cross-review at task end
++rReviewany message containing it (checked last; ++rr tested first)two-phase review discipline — simplification pass first, then multi-agent review after each significant change, review->double-check->fix; codeword-only, no ambient
++aArchitectureany message containing itfull [DIRECTIVE: ARCHITECTURE-FIRST] block — fits the existing project architecture/patterns/rules, finds the closest well-built existing counterpart in the repo and reuses its patterns/classes (additive to conventions/rules/docs, never instead), adds a new pattern only when nothing fits; independent third group, combinable with ++m and the review group (++rr/++r); same block in normal and plan mode
HARD wall ON(state)every turn, no codeword requiredfull Manager block (ambient injection alongside any codeword)

Not the only injection on the turn

If brewcode is installed too, its forced-eval.mjs (UserPromptSubmit) adds three short lines to every prompt, independently of any codeword:

[ROLE] Manager: scan agents (project .claude/agents/ first) - expert for this domain exists -> delegate regardless of size; no expert or trivial one-off -> self.
[SPLIT] One agent for an hour = drift you cannot observe: split into bounded units (1 deliverable, ~5 files, ~20 min), fan out in ONE message; a dependency must be a REAL data handoff, else parallel; every spawn prompt carries goal + scope + what is already done + who consumes the result + acceptance.
[BRANCH] Stay on the current branch; none chosen -> main. No explicit branch/PR instruction -> work on main and take over ALL workspace changes, incl. from other sessions.

That reminder fires on slash commands as well, and is skipped only for empty prompts and meta-replies (yes, ok, a bare number, a single letter). It only fires on a prompt, so an auto-compaction mid-turn skips it — brewcode covers that gap with a separate SessionStart pair that re-anchors the same role plus the plan and task graph. See Brewcode hooks for detail.

The prompt text is editable and update-proof. Use /brewtools:manager-setup edit to copy the plugin default into a writable project or global override, and /brewtools:manager-setup purge to drop the override and revert to the plugin default.

Where this is used

The /brewtools:manager-setup skill is the control plane for the entire mechanism. It lets you inspect the current effective prompt source (status), customize the Manager text (edit/purge), install and arm the HARD delegation wall (install/enable/disable/uninstall), and run one-shot manager tasks (inline-run, hard-one-shot, manager-run).

The codeword hook itself (manager-prompt.mjs) is always on — it cannot be toggled by the skill, and renaming the skill to manager-setup did not change that. The four codewords fire regardless of whether the wall is installed. The skill manages text and state; the hook fires unconditionally on every turn.

Subagents can no longer ask a question mid-task

Note

As of Claude Code 2.1.233, AskUserQuestion is removed from every subagent — only the main session keeps it. A subagent a ++m Manager delegates work to can no longer pause and ask for approval partway through; if it used to, it now has nothing to call. The affected brewtools agents (ssh-admin, deploy-admin) were rewritten to emit an ## APPROVAL REQUIRED envelope in their final return and stop there instead, leaving the decision with whoever reads the result — the main session, or you. This is unrelated to the codeword injection mechanism on this page, but it changes what a delegated subagent can do once it starts running.

Note

The hook and helper filenames stayed as they are through the v5.0.0 rename: manager-prompt.mjs, hardmode-guard.mjs, lib/manager-state.mjs, lib/manager-prompts.mjs. The guard’s self-exemption requires the script node actually executes to match (.claude/brewtools/manager|hooks/lib)/manager-state.mjs$, so renaming or relocating that helper would silently break the wall’s off-switch.

The closest-counterpart rule injected by ++m and ++a is not unique to this hook — /brewcode:teams-setup and /brewcode:agents inject the same rule into generated agents whose domain writes code, scripts, SQL, schemas, or infra. See Teams and Agents.

⚙️

Manager Setup

The control plane for these prompts — customize text, install and arm the HARD wall, check status, and run manager-mode tasks.

📄

Brewtools overview

All brewtools skills and agents in one place.

🔗

Hook source

The UserPromptSubmit hook that performs the injection on every turn.

Updating plugins

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