Shadow Agent

Launch an advisory companion agent that reads a running agent’s output, explains it, helps with prompts and plans, reviews the implementation, diagnoses failures, and spawns skill-learning sessions

When you have a coding agent working a task, it is not always easy to follow what it is doing — its output can be dense, a plan it produced may assume background you don’t have, or it may pause on a question whose context has scrolled away. The shadow agent is an advisory companion you launch beside the agent you are watching (the followed agent). It reads that agent’s terminal output and helps you reason about it, in plain terms, on demand.

The shadow is read-only and advisory by design. It explains and suggests; it never types into the followed agent’s pane. You remain the one who answers prompts and approves plans — the shadow just makes you a better-informed driver. For how a shadow is bound to the agent it follows, and what that contract does and does not guarantee, see the Shadow agent concept page.

Launching a shadow

You launch a shadow with e from either of two surfaces:

  • the minimonitor sidebar that sits next to each running agent — focus the agent’s card and press e;
  • ait monitor — select the agent in the pane list and press e. Launching from monitor keeps your focus in monitor, so the shadow preview column shows the new shadow instead of pulling you away to its window.

On both surfaces E opens a picker first so you can choose the code agent and model before the shadow starts.

By default the shadow opens as a new pane in the same tmux window as the followed agent, so the two sit side by side. (You can configure it to open in a separate window instead — see Configuration.)

The shadow is a companion pane, like minimonitor itself: it never appears in the agent list, and it closes automatically when the agent it shadows exits. Only one shadow runs per followed agent.

See How to Launch a Shadow Agent (minimonitor) or How to Launch a Shadow Agent (monitor) for the per-TUI keybinding details.

What happens once it is running

When the shadow starts, it greets you with a short summary of what it can do, then waits for you to tell it — in your own words — what you’d like. There is no mode to pick up front: you just describe what you want, and it routes to the right capability.

Two things are worth knowing:

  • It reads the followed agent’s current screen, and can re-read it any time. The agent keeps working after you launch the shadow, so its state changes. Ask the shadow to refetch whenever you want it to look at the latest output — or, in minimonitor, arm the auto-recheck loop with L and let it ask for the next review round each time the agent settles.
  • It offers help proactively. Each time it reads the screen, the shadow glances at what is visibly there and, if something obviously useful applies, it offers it without being asked — for example, if the agent is paused on a question, it offers to help you decide; if a plan is on screen awaiting approval, it offers to explain or pressure-test it. These are suggestions you can take or ignore; they never restrict what you can ask for.
  • Some actions are on request only. The shadow does not proactively diagnose errors, spawn learner agents, or summarise the task. Ask for those actions explicitly when you want them.
  • Every capability has a shortcode. The greeting lists them: >e explain the screen, >q help with the prompt on screen, >t the task in plain words, >px explain the plan, >pc challenge the plan, >ps socratic questions, >pa the plan’s assumptions, >i review the implementation (>i1–>i4 pick the tier), >r a new review round (>rpc, >ri, >rpa, >rd name which review), >d diagnose errors, >l learn a skill, >f refetch the screen, and >? to see the list again. The > is always required — a bare t is just a message. A code works anywhere in a sentence when you are asking for it (>i3 but only the callers), while merely talking about one (“what does >l do?”) gets an answer, not an action.

What the shadow can do

All of the following are served in a single flow — you reach them just by asking.

Explain what the agent is doing

Ask “what is this agent doing right now?” (or about a specific error or message) and the shadow reads the current screen and explains, in plain terms, what is happening, what the agent is waiting on, or what a message means.

Help you answer a prompt

When the followed agent is paused on a question — including one shown without the underlying task or plan visible — the shadow can fetch the relevant task and plan in the background, lay out what each option means and its trade-offs, and suggest an answer with its reasoning. You type the answer into the agent yourself; the shadow never does.

The task in plain words

Ask >t (or “what is this task about?”) and the shadow explains, in a few short paragraphs anyone can follow, what the followed agent is working on: what the task is trying to achieve and why, what will change for someone using it, and — when a plan can be found — how the agent means to get there and roughly how far along it is. It reads the task file and the plan; while the agent is still in plan mode the plan is only a draft, so the shadow reads it from the screen (and says so) rather than reporting that no plan exists. This is on request only — it never appears at startup or after a refetch — and it is a summary, not an interrogation: for a subject-by-subject walkthrough of the plan, use the explainer below.

Interrogate a plan

Before you approve a plan an agent has produced, the shadow can examine it for you in four distinct ways:

  • Explain it to a non-expert — beyond a plain-terms summary, it identifies the technical subjects the plan rests on and offers, for each one you choose, a short introduction and why the plan relies on it, then walks through the plan in plain language.
  • Challenge it — acting as a constructive adversary, it actively looks for where the plan could fail (regressions, missed edge cases, a wrong-shaped approach, blast radius, verification gaps, unstated dependencies) and gives you a prioritized list, separating problems that should block approval from improvements you could accept as follow-ups.
  • Question it (Socratic) — instead of telling you what’s wrong, it asks open-ended questions that lead you to examine the plan’s own reasoning and trade-offs, a few at a time.
  • Surface its assumptions — it enumerates what the plan quietly takes for granted (about the environment, the data, other code’s behavior, sequencing, and scope) and highlights the assumptions that are both load-bearing and unverified — the ones most likely to make a plan silently go wrong.

Ask for one of these specifically, or ask broadly (“review this plan”) and the shadow runs several and presents a combined result.

Review the implementation

Once an agent has implemented a task — not just planned it — the shadow can adversarially review the code that was actually written. This is the implementation-side companion to challenging a plan. It reads the task and plan (what was supposed to be built), discovers the real change — everything the task’s commits, the index, the working tree, and brand-new untracked files contain, taken together — and the plan’s own Final Implementation Notes if they exist yet, then reviews at one of four effort tiers:

  • Quick — a reduced, hunk-only scan of the diff: only correctness bugs visible from the changed lines themselves (plus obvious duplication and dead code), at most 4 findings, no verification pass. A fast sanity check; it runs only when you explicitly ask for it.
  • Default — one full-context adversarial pass over the diff, the plan, its risks, and the Final Implementation Notes, along three axes: implementation flaws (bugs, missed cases, incorrect logic, or regressions in the code as actually written); risks left unmitigated (risks the plan flagged that the landed code does not address — an already-handled risk is reported as informational rather than raised as a problem, never dropped); and unjustified deviations from the plan (divergences the Final Implementation Notes do not explain). No findings cap, and a candidate the shadow is merely unsure about is reported rather than discarded.
  • Advanced — the recommended systematic review. Ten targeted review angles run in sequence — a line-by-line diff scan, a removed-behavior audit (what invariant did each deleted line enforce, and where is it re-established?), caller/callee tracing across files, five cleanup angles (reuse, simplification, efficiency, altitude, project-convention violations), and the two plan axes above — followed by a verification pass that re-reads the code and grades every candidate finding CONFIRMED, PLAUSIBLE, or REFUTED; only the first two are reported. Tuned for precision: at most 8 findings, each one a maintainer would act on.
  • Deep — the widest net. Adds language-pitfall and wrapper/delegation-correctness angles, biases verification toward recall (realistic-but-unconfirmed triggers are kept, not dismissed), and finishes with a gap-sweep pass hunting only for defects the earlier angles missed. Up to 15 findings.

Every finding states the problem, why it bites, and an impact vector — which qualities addressing it would improve, which it would worsen, and what it would cost. The improve and worsen sides are drawn from one shared vocabulary of quality dimensions (goal, correctness, robustness, performance, verification, maintainability, simplicity), so instead of an unexplained “high” you see on which dimension a finding is high. The worsen side is mandatory — a finding that costs nothing still says so explicitly — because that is what makes the shadow price its own suggestion: a concern with no stated cost is a pure demand, and a review that accumulates those quietly over-engineers your change. Effort is quoted separately, since a cheap fix and a lasting improvement are different facts. The dimensions are the part to act on; the magnitudes only refine them. A finding’s severity is derived from its vector rather than judged twice, so the two can never disagree.

Each finding also carries a disposition decided from that vector: blocking, follow-up, or informational. A blocking finding’s improve side touches something this change is obliged to deliver, so it should be addressed before the change is accepted; a follow-up is real and net-positive but obliges nothing, making it sensible as a separate task; an informational finding is real, but the shadow believes it is already handled, explicitly accepted, or outside this change’s remit — shown with the reasoning that led to that judgement, so you can disagree. Findings are listed blocking-first, then follow-up, then informational, and in the Advanced and Deep tiers each finding also carries its verification verdict. A tier’s findings cap cuts informational findings first, then follow-up, and never drops a blocking finding.

The shadow never silently hides a finding. Anything left out — by a cap, by a focus you asked for, or by deduplication — is disclosed at the end of the list with a count. The only thing dropped without mention is a candidate the shadow can refute by quoting the line that disproves it; “probably not worth mentioning” is not a refutation, and such a finding is reported as informational for you to judge.

Name a tier in your ask — “quick review of the implementation”, “advanced review”, “deep review” — or type it as a digit: >i1 Quick, >i2 Default, >i3 Advanced, >i4 Deep. An unqualified “adversarial review” runs the Default tier, and the shadow says so up front and points you at Advanced, so you always know which review you got. A generic “review the implementation” — or a bare >i — with no tier wording is where the shadow_impl_review_tier profile setting applies: with it set, the shadow runs that tier straight away and announces which profile chose it; without it, the shadow asks which tier you want, recommending Advanced. A tier you name yourself, by word or by digit, always wins over the profile setting, with no prompt and no “inferred tier” line. You can also narrow the focus in free text (“just check the callers”, “only plan deviations”) at any tier.

Before it starts, the shadow tells you what it is about to review. It resolves the change as the union of four sources — the task’s commits, staged changes, unstaged changes, and brand-new untracked files — rather than stopping at the first one that has content, because an earlier commit plus newer uncommitted edits is a normal shape and the newest work is usually what you most want reviewed. It lists the files it picked up, grouped by source. Uncommitted and untracked changes carry no task id, so if your working tree holds another task’s work too, the shadow flags any file the plan does not mention as possibly unrelated, and you can narrow it in free text (“only the monitor files”).

Reviewing before the agent has committed is the normal case, not a mistake: the Final Implementation Notes are written after the Step 8 review prompt, so at the moment you are being asked to review, they do not exist yet. The shadow does not warn you or ask for confirmation about this — it simply says the notes are not written yet and audits deviations against the plan directly. A real deviation it finds in that state is reported as pending narration (informational — real, but the agent has not written its explanation yet) unless the deviation is wrong on its own merits. The one thing that stops a review is having genuinely nothing to review: no commits, nothing staged, nothing unstaged, and no untracked files.

Diagnose skill or helper errors

When the followed agent appears stuck on tool-call errors, tracebacks, shell errors, or repeated retries, ask the shadow to diagnose what is going wrong. It reads the captured screen, decides whether the visible signals are genuine failures rather than benign error-shaped text, and attributes each error cluster to the likely workflow skill or aitask_*.sh helper.

For real issues, the shadow presents candidate concerns and emits the same structured concern block used by plan review. You choose which concerns are worth acting on. For selected concerns, the shadow can offer to launch /aitask-explore with a seed prompt that names the likely file and includes the captured error excerpt, so the bug becomes its own scoped fix-task. It never auto-launches that follow-up and never types into the followed pane.

Learn a skill from the followed workflow

When the followed agent has just performed a workflow you want to reuse, ask the shadow to learn a skill from it. The shadow does not run the learning flow itself, because that would occupy the companion you are using for advice. Instead, it confirms the action and opens a dedicated learner agent in a new tmux window running /aitask-learn-skill:

/aitask-learn-skill <followed_pane_id>

The learner captures the followed pane read-only, walks you through selecting which part of the workflow to learn, asks how to generalize concrete details, and writes a static skill. The learner appears as a normal agent-learn* window in ait monitor; you close it when the learning session is done. The shadow remains available in its own pane.

Follow where the review is heading

You do not have to read the plan, or the concerns in full, to follow what the review rounds are doing to it. Every finding the shadow reports — in a plan review, an implementation review, or an error diagnosis — ends with an In plain words line: a one- or two-sentence restatement for a non-expert, derived from the full concern the shadow forwards, so the two never say different things. And from the second recheck round on (a manual “recheck” — >r for a new round of whichever review ran last, or >rpc / >ri / >rpa / >rd to name the review, with >ri3 picking the tier — or the auto-loop’s next round), the shadow opens with Where this is heading before its findings: what changed since the last round; what has changed since the original plan, and which earlier concern asked for each change (or that nobody did); whether it still does what was asked — with an explicit list of what it will no longer do and what it will now also do; how much bigger it got; whether each change was worth it (needed / nice to have / not worth it / nobody asked, with a count); and a bottom line of on track, drifting, or getting over-built, decided by a fixed rule rather than a fresh judgement, followed by which incorporations the shadow would undo and move into follow-up tasks. The whole preamble is written for someone who will not open the plan: it names outcomes and behaviours, not files or functions.

To compare against what earlier rounds read, the shadow keeps a per-round copy of the plan (or, for implementation reviews, of the change it reviewed) alongside its rejection store; these are local, never committed, and cleaned up when the task is archived. When a copy could only be taken from a terminal capture that might be incomplete, the shadow says so rather than presenting the comparison as complete.

Forward concerns to the followed agent

When the shadow interrogates a plan, reviews an implementation, or diagnoses genuine skill/helper errors, alongside its human-readable findings it can emit a structured, machine-parseable concern block — a fenced list (===AITASK-CONCERNS=== … ===END-CONCERNS===) of - [priority | region] body items, where priority is high, medium, or low and region names the plan area, skill, or helper the concern targets. Every concern ends its body with its impact vector — what it improves, what it worsens (always stated, even when the answer is nothing), and the effort it would take — followed by its disposition, and in the Advanced and Deep tiers the verification verdict. Plan reviews carry the same trailer as implementation reviews: a plan concern is classified too, so the ones that merely inform no longer sit alongside the ones that need a decision. Concerns are ordered blocking-first. The picker reads that trailer to group the concerns, and forwards it to the agent unchanged. The block is additive: the shadow still prints its normal prose; the block is an extra copy meant for pick-and-forward.

From either minimonitor or ait monitor you can then selectively forward these concerns to the followed agent without retyping them. Press c to open a checklist of the shadow’s concerns, tick the ones you want, and the TUI copies them — with a short preamble — to your clipboard for you to paste into the agent. Concerns the shadow marked informational — real, but not a request for action — are grouped in their own dimmed section, so what actually needs attention is what you see first. Each row that priced itself also carries its impact vector in compact form — see Read the trade profile. Every row is set individually and the four dispositions are mutually exclusive: Space marks a concern to forward (✓), r rejects it (✗), t spins it off into its own draft task (»), and an untouched row stays unmarked (□). When a fresh concern block appears, both TUIs also proactively hint that the shadow raised concerns. This keeps the advisory-only contract intact: the concerns land on your clipboard, and you decide what to paste. See How to pick shadow concerns (minimonitor) or How to Pick Shadow Concerns (monitor).

Read the trade profile

Where a concern priced itself, the picker renders that impact vector as a compact trade profile, so what the concern would buy and what it would cost are visible on the row itself:

▲robus ▼simpl E:lo

▲ is the improve side, ▼ the worsen side, and E: the effort it would take — E:lo, E:md, E:hi, or E:? when the effort was not stated. The labels are short forms of the quality dimensions named under Review the implementation.

Three things the row encodes without spending characters on them:

  • Magnitude is carried by the arrow’s colour, not by extra text: red for high, yellow for medium, grey for low, and a muted blue when the magnitude was never stated. The colour is a scale of how much, not of good-versus-bad — direction is already the glyph’s job, so a high improve and a high worsen are the same colour on purpose. A ? after a label also marks an unstated magnitude, and it is never quietly read as low; at the narrowest widths that ? is the first thing dropped, which is why “unstated” has a colour of its own rather than sharing one. The dimensions are what to act on; the magnitudes only refine them.
  • ▲– or ▼– means that side was priced and the price is nothing. A side the shadow never priced renders no token at all. “Priced as nothing” and “never priced” are different facts, and keeping them apart is the entire point of making the worsen side mandatory.
  • +N counts entries that did not fit. What is dropped as space runs short is ordered so the first improve entry, the first worsen entry and the effort always survive — a row can never show you an improvement without its price.

In a wide picker the profile sits between the region and the body on one line. In a narrow companion pane the row grows to three lines: region, body, then the profile on its own. A concern that priced nothing on any axis has no trade profile and renders exactly as it always has — pricing only a cost, or only an effort, is still pricing.

See the whole impact vector

The row cannot show all of it. As space runs short the trade profile degrades to one improve entry, one worsen entry and the effort — with five-character labels — so a concern that priced four dimensions shows two of them, abbreviated.

Where the dialog has the rows to spare, a detail panel below the list spells out the focused concern’s vector: one line per entry, with the full dimension name and, where the width allows, the magnitude as a word.

▲correctness (high)
▲verification (medium)
▼simplicity (low)
▼performance (unspecified)

The panel follows the selection — move with ↑/↓ and it re-fills for whichever concern is focused — and it is populated as soon as the picker opens, before you press anything. There is no key to press: it appears wherever there is room and steps aside where there is not, taking only as many rows as it has entries to draw. In a short pane (a 40x20 companion, for instance) it does not appear at all, and the row’s compact profile remains the data.

It shows the vector and nothing else — no body, no region, no disposition. Those are already on the row directly above it, and repeating them there reads as duplication rather than detail.

Two things it will not do. It never cuts a dimension name in half: where the magnitude word does not fit it drops the word and keeps the name, and below the width where the name itself fits, the panel steps aside entirely. And it never drops an entry silently — anything that did not fit is counted with a +N. If the focused concern priced nothing, the panel says so rather than leaving the previous concern’s vector on screen.

The priority badge. For a concern that priced itself, the badge shows a priority derived from its improve side rather than the one the shadow typed. Where the two disagree a ≠ appears beside the badge: both facts stay visible, because the picker is where you decide and quietly reconciling them would hide the disagreement. A concern that priced nothing keeps its stated priority and never shows a ≠.

Deciding from the profile. Forward a concern when its improve side touches something this change is obliged to deliver, or when it is a pure win at low effort. Spin it off when it is real and net-positive but obliges nothing, or when it costs medium effort or more. Reject it when the worsen side is at least as large as the improve side — a well-argued suggestion can still be a bad trade, and this is what lets you say so. A picker with room for it (roughly 80 columns and 24 rows) prints that rule as a one-line reminder above the list; in a companion pane the key hints take that space and the per-row profile is the data.

Reject a concern so it does not come back

Every review round re-derives the shadow’s findings from scratch, so a concern you have looked at and decided against would otherwise reappear each time. Rejecting it tells the shadow to stop raising it for this task.

Rounds are numbered, and each concern block records the round and the time the review was done. That is what makes the rounds individually identifiable: it lets the TUIs tell you which round you are looking at, and lets a repeat round re-raise concerns you have already seen rather than being mistaken for a stale copy of the previous one. The round number alone is not an identity — a restarted shadow counts from 1 again — so it is always paired with the review time.

In the picker, r marks the focused concern rejected (✗) rather than forwarding it. The four dispositions are mutually exclusive per row — Space forwards, r rejects, t spins off, and pressing the same key again clears the mark.

Press R to see what is already rejected for this task. In that list, Space marks an entry to bring back and Enter hands your marks to the picker; q or Esc closes it. R does not always open a list: if nothing has been rejected for this task yet it tells you the store is empty, and if the pane has no task to attach rejections to it warns that the rejection store is unavailable — which is your signal, before you confirm, that rejections made here cannot be kept.

Nothing is written until you confirm the picker. Rejections and un-rejections are staged as you work: confirming the picker with Enter or OK is what saves them, and cancelling with Esc discards both. If the pane has no resolvable task, the TUI tells you the rejections were not persisted rather than dropping them silently.

Confirmed rejections are kept per task in a local, git-ignored store that is removed when the task is archived. On its next review round the shadow consults that store and drops any fresh concern that is substantively the same as one you rejected — even when it has been reworded — then reports Suppressed N previously-rejected concern(s). in the prose before its block. Suppression is never silent and never over-eager: when the shadow cannot tell whether a fresh concern matches a rejected one it keeps the concern and says why, and if it cannot resolve the task or read the store it emits everything and states that suppression was skipped. An error is never read as “nothing was rejected”.

Advisory only

The shadow is read-only with respect to the followed agent. It never sends keystrokes or answers into the agent’s pane — not even an answer it just suggested. Everything it produces goes to you, and you decide what to do with it. This is the core contract of the shadow: it informs your decisions without ever making them for you.

Configuration

Three settings control the shadow, all editable in ait settings:

  • Placement — tmux.shadow_same_window (Tmux tab). true (the default) splits the shadow into the followed agent’s window; false opens it in its own window.

  • Agent and model — the shadow row on the Agent Defaults tab selects which coding agent and model the shadow runs as. You can run the shadow as a lighter, faster model than the agent it watches.

  • Default implementation-review tier — shadow_impl_review_tier in an execution profile (Profiles tab, “Shadow Review” group). Set it to quick, default, advanced, or deep to skip the tier prompt for a generic “review the implementation”; leave it unset to keep being asked.

    The shadow picks its profile the same way every other skill does, so this key only takes effect once you have pointed the shadow skill at that profile. Setting the tier alone changes nothing. In aitasks/metadata/userconfig.yaml (just you) or aitasks/metadata/project_config.yaml (the whole team):

    default_profiles:
      shadow: fast
    

    The shipped fast profile already sets shadow_impl_review_tier: advanced, so the two lines above are all it takes to get advanced reviews without a prompt.


Next: Explain — use code evolution history to rebuild understanding of why code exists.