---
{
  "n": 65,
  "title": "What reaches a subagent",
  "abstract": "Every line, guard, hold and typed line says in its own definition whether it reaches the main agent, its subagents or both, and each funnel honours that one word",
  "refs": [
    "message:11615",
    "message:11618",
    "message:11606",
    "todo:1951",
    "todo:1952"
  ],
  "seen": [
    "agent",
    "user"
  ],
  "data": {
    "buttons": [
      {
        "label": "Accept this design",
        "say": "I accept the subagent reach design",
        "choice": "answer"
      },
      {
        "label": "Change it first",
        "say": "I want changes to the subagent reach design first",
        "choice": "answer"
      }
    ],
    "environment": "main",
    "revisions": 1,
    "open_until": 1790398222.024816,
    "pressed": [
      "Accept this design"
    ]
  },
  "created": 1790396378.550873,
  "updated": 1790789531.464489,
  "deleted": 0.0,
  "completed": 0.0,
  "outcome": "",
  "type": "doc"
}
---


## Why
The journal reaches an agent by four routes, and each decides about subagents in its own place:

- **Lines** (nudges, whispers, typed lines) all pass one funnel, FeatureJournal.say, which asks the whole feature: runs_for_subagents.
- **Guards** (interceptors and cancelers that refuse or hold a tool call) pass hooks.serving, which asks the same feature switch.
- **The pause** is applied separately, in the hook's branch for subagents.
- **The terminal typist** typed into whatever view was open, so a finished board-filler was woken again and again.

A feature can only say yes or no for everything it owns. One feature cannot have a line for subagents and a guard that leaves them alone, and nothing makes a new line or guard think about subagents at all. That is how the board-filler got whispers, question gates and a command guard it never needed.

## The one word
Everything that reaches an agent declares its reach in its own definition, with one word from one small closed set, **Reach**:

- **MAIN**: only the main agent of a session. The default.
- **SUBAGENTS**: only subagents.
- **BOTH**: the main agent and its subagents.

It sits beside the thing itself:

- a Line: Line(name=..., title=..., reach=Reach.MAIN)
- a guard (ToolInterceptor or canceler): a class attribute, reach = Reach.MAIN
- a hold: the hold call carries the reach of the line it holds with
- a handler that speaks only through lines needs nothing: its lines carry the reach.

No feature-wide switch remains: the answer is where the thing is written, so reading a line or a guard tells you who gets it.

## Where it is honoured
One check in each funnel, and nowhere else:

- **FeatureJournal.say** (every nudge, whisper and typed line): a subagent row gets the line only when the line's reach is SUBAGENTS or BOTH; the main agent only when it is MAIN or BOTH.
- **hooks.serving** (every interceptor and canceler): a subagent's tool call is checked only by guards whose reach includes subagents.
- **The hold and the pause**: the hook's subagent branch asks the same reach before it applies a hold; the pause is the user's own stop button, see Defaults.
- **The terminal typist**: typed lines are MAIN by definition, and the typist never types while a subagent's view is on screen (shipped in 2.194.1).

Handlers still run for every agent row, because running is not reaching: whatever a handler wants to say goes through a line, and the line decides.

## What goes away
- **FeatureDetails.runs_for_subagents** and **Feature.mine()**: replaced by the reach of each line and guard. The worktrees feature, the only one that needs to act for subagents, only links a worktree's journal; it says nothing and guards nothing, so it needs no reach.
- **ToolInterceptor.for_subagents** and **policy.for_subagents**: replaced by reach.
- The subagent special case in hooks.serving from 2.194.1 becomes the general rule rather than an exception.

## Defaults
- **Every line: MAIN.** No nudge, whisper, rule or fact reminder reaches a subagent unless its definition says so. Today no line needs to.
- **Every guard: MAIN.** No refusal, gate or hold reaches a subagent. Today no guard needs to: the board-filler's command guard and the question gate for subagents were removed in 2.194.1.
- **The pause: BOTH.** Pausing is your own stop button, not a journal guard, so a paused session stops its subagents too. Say so if you want a pause to leave running subagents alone instead.
- **Dispatch lines** ("dispatch the board-filler now") are MAIN: they are for the main agent, which is the only one that can dispatch.

## How it stays true
- **Reach is required**, not optional: a Line or a guard without a reach fails when the feature loads, so a new one cannot quietly default the wrong way. The default of MAIN is written out by the Line class itself, and a guard class states its own.
- **One generated check**: the test that loops over every feature also loops over every line and guard, sends each to a main row and a subagent row, and checks that it arrives exactly where its reach says.
- **Visible in the viewer**: each feature's page in Settings lists its lines and guards with their reach, so you can see what a subagent is told without reading code.
- **The feature skill** says it in one sentence: which of its lines and guards reach subagents, if any.
