Skip to Content
ConfigurationReply Modes

Reply Modes (reply_modes)

Per-person switches that change how Navigator’s replies read, each one flipped by saying so. Every mode is one row in a table (hooks/nav_hook_lib/reply_modes.py, mirrored in hooks/mod/lib/reply_modes.ts) and one op, prompt_modes, serves them all. While a mode is on, its rule block rides every prompt as hook context. While it is off, the block exists nowhere in the context.

ModeSayLayerSince
ADHDadhd mode onthe reply: order, list caps, closing actionv7.9.0
STEste mode on, use stethe sentence: one idea, 20 words, activev8.3.0

The switch is yours, not the project’s: it lives in your home directory, follows you into every repository, and takes effect on your next prompt without a restart.

Say the word

adhd mode on ste mode on

That is the whole setup. The hook runtime answers the phrase itself, with no model turn, and writes ~/.config/navigator/<key>-mode.json. From the next prompt on, that mode’s rule block is attached to every prompt as hook context. The reply you get is shaped by it.

adhd mode off ste mode off

Same channel, same speed. The block stops arriving and the context contains no trace of it. <key> mode on its own reports the current state and where it came from.

The phrase table is generated from the mode’s key, so every mode answers the same forms:

  • On: <key> mode on, <key> on, enable <key> mode, start <key> mode, turn on <key> mode
  • Off: <key> mode off, <key> off, disable <key> mode, stop <key> mode, turn off <key> mode
  • Status: <key> mode, <key> mode?, <key> status

STE adds two short forms: use ste and stop ste. Matching is exact and case-insensitive, trailing punctuation ignored, and only prompts of 32 characters or fewer are considered. A prompt that merely mentions a mode, or embeds the phrase in a longer sentence, is never a toggle.

Claude Code renders these answers as “operation blocked by hook” followed by the message. That is the standard rendering of a zero-model-turn answer, the same one Tier-1 uses; nothing is wrong.

Where the switch lives

A mode is a trait of the person, so each switch is per person and global:

~/.config/navigator/adhd-mode.json {"on": true, "updated": "2026-10-01T12:34:50+00:00"} ~/.config/navigator/ste-mode.json {"on": true, "updated": "2026-10-05T09:12:00+00:00"}

NAVIGATOR_CONFIG_HOME overrides the directory (XDG_CONFIG_HOME/navigator is honoured). The file is written by the phrase, by “enable adhd_mode” / “enable ste_mode” (nav-features), or by hand.

A repository can pin a mode regardless of the person, with <key>_mode.on in .agent/.nav-config.json (shared) or .agent/.nav-config.local.json (personal, per checkout):

<key>_mode.onEffect
null (default)Defer to the person’s switch
trueOn for everyone in this repo
falseOff in this repo, even if your switch is on

Resolution order, per mode: repo pin, then personal switch, then off. Saying adhd mode on inside a pinned repo still writes your switch and tells you the pin wins here.

Config block

{ "reply_modes": { "enabled": true }, "adhd_mode": { "enabled": true, "on": null }, "ste_mode": { "enabled": true, "on": null } }
  • reply_modes.enabled (default true): the op runs at all. false silences every mode in this repo: no phrase answers, nothing is injected.
  • <key>_mode.enabled (default true): that one mode is available. false hides it: its toggle phrase answers “disabled in this repo”, nothing is written or injected.
  • <key>_mode.on (default null): repo pin. true/false overrides every personal switch; null defers to the person.

None of these inject anything on their own. Nothing is injected for anyone until they say <key> mode on.

ADHD mode

A switch that changes the shape of a reply for a reader with ADHD. On: every reply opens with the one next action, time-critical items come first with the deadline in bold, lists stay short, steps are numbered, and there is no preamble. Off: nothing.

New in v7.9.0.

What changes in a reply

The block states facts about the reader and the reply shape that works, in this order:

  1. First line: the ONE next action. Time-critical items first, the deadline in bold.
  2. Bullets over prose. Lists hold at most five items; longer ones split into now and later.
  3. Multi-step work is numbered, one bounded action per step, with “step k of n” restated each turn.
  4. Several things pending: the single most important one is named, not a flat list.
  5. Errors: cause and fix in a flat tone. Wins stated plainly. No preamble, no recap, no pleasantries. The reply ends with one action under two minutes.

Four things are never shortened, mode or no mode: error output, test results, anything you asked to have explained, and every warning before a destructive action. The rules apply to replies only, not to files, reports, task docs or commit messages Navigator writes.

The rule set builds on the user-tested rules from i-have-adhd (lead with action, number steps, restate state, cap lists, flat errors, no preamble, sub-two-minute closer) plus two it lacked: time-critical first with a bold deadline, and naming the single most important pending item.

STE mode

A switch that changes the sentences of a reply to ASD-STE100 Simplified Technical English (Issue 9, January 2025), Part 1 only. The block is a subset of the writing rules:

  • One idea per sentence. Instructions have 20 words or fewer, descriptions 25 or fewer.
  • Instructions use the imperative. Descriptions use the active voice and the present tense.
  • One instruction per sentence. A paragraph has one topic and six sentences or fewer.
  • No gerunds, no noun clusters over three words, no synonyms for one meaning.
  • Full sentences with articles, not labels. Technical names stay as written in the code.

Error output, test results and quoted text stay verbatim. The rules apply to replies only.

The controlled dictionary (Part 2, about 900 approved words) is deliberately not applied: it cannot describe a hook runtime, and full STE would delete the answer.

Since v8.3.0.

Stacking order

When both modes are on, the blocks join in table order: shape first, sentences inside it. The STE block ends with “inside any reply-shape rules above”, so the ADHD rules decide what a reply contains and in what order, and the STE rules decide how each sentence in it reads. ADHD-only output is byte-identical to v8.2.8.

What it costs

The ADHD block is 823 characters, about 206 tokens, attached to each prompt while the mode is on. Each copy stays in the transcript, so a 50-prompt session carries roughly 10k tokens of rule text, mostly as cached input. The STE block is shorter, and a test asserts that the sum of every block stays under 1,600 characters, so a new mode cannot quietly double the per-prompt cost. Replies get shorter in exchange, and output tokens cost several times what input does. Measure your own split with nav stats.

What it does not touch

Subagents never see the blocks: the research, planner and deep-research agents keep their own formats. The Pilot executor never sees them either (PILOT_EXECUTOR silences the op, as it does every interactive behaviour). Intent briefs, deep-research reports and the WORKFLOW CHECK block keep their layouts.

Under the hood

One op, prompt_modes, on UserPromptSubmit, listed right after prompt_tier1. An exact phrase of any mode returns a decision: block answer (the channel verified in the v7 spikes, never exit-2) and writes that mode’s personal file; any other prompt returns the blocks of every enabled mode that resolves on as additional_context, joined with a blank line in table order. Session start prints one line per mode that someone switched explicitly, such as ADHD mode: on (personal switch, …).

Adding a mode

  1. Append a Mode(...) row to MODES in hooks/nav_hook_lib/reply_modes.py and the same row in hooks/mod/lib/reply_modes.ts. Keep the block declarative, under 900 characters, starting with <LABEL> MODE: on (personal setting; "<key> mode off" ends it).
  2. Add "<key>_mode": {"enabled": true, "on": null} to config.DEFAULTS, the migrator version block, .agent/.nav-config.json, and a FEATURES entry with personal: True.
  3. Run python3 scripts/gen_mod_data.py and add a phrase/block test to test_reply_modes.py.

The toggle phrases come from the key, so a new row needs no phrase list.