.nav-config.json Schema
The canonical configuration file for Navigator. It controls the v7 hook runtime (dispatcher + ops), the ToM features, loop and task modes, the knowledge graph, code simplification, auto-update, PM/chat integration, and Tier-1 instant answers.
Location: .agent/.nav-config.json (project root, relative to the repo).
Created by: nav-init writes the initial file when you initialize Navigator in a project.
Edited by: nav-features (toggle blocks interactively) or by editing the JSON directly. After changing it, the new values apply on the next session start; some hook changes require a Claude Code restart to take effect.
All keys below are taken from the live, authoritative file. Defaults shown are the values Navigator ships with.
v7: hook runtime, not prose mandates
As of v7.0.0, Navigator’s workflow is enforced by the hook runtime — a single dispatcher routing op modules — instead of prose mandates in CLAUDE.md. The v6 WORKFLOW CHECK block requirement is retired; every enforced behavior now maps to an op with a config off-switch:
| Behavior | Op | Off-switch |
|---|---|---|
| Workflow gating | prompt_gate | workflow_enforcer_hook.enabled, .strict_block |
| Intent briefs on ambiguous prompts | prompt_brief | brief_hook.enabled |
| Typed judge behind the prompt scorers | judge (library, used by prompt_gate + prompt_brief) | judge.enabled |
| Repeated-Read guard | read_guard | read_guard_hook.enabled, .strict_block |
| Session context injection | session_start | session_start_hook.enabled |
| Workflow/loop state recording | stop_state | workflow_state_hook.enabled |
| Completion gate (forced continuation) | stop_completion | stop_completion.continue_enabled |
| Reject log: one JSON line per refusal (v8.2.0) | runtime, after every blocking op result | reject_log.enabled |
| Tier-1 instant answers | prompt_tier1 | tier1.enabled, per rule via tier1.rules |
| Reply modes toggle + rule blocks (ADHD, STE) | prompt_modes | reply_modes.enabled; per mode adhd_mode.enabled, ste_mode.enabled; switch via <key> mode on/off or <key>_mode.on |
| Context markers around compaction | compact_marker | compact_hook.enabled |
New blocking features ship off: tier1.enabled and stop_completion.continue_enabled both default to false — you opt in explicitly. Setting the PILOT_EXECUTOR environment variable disables all interactive/blocking hook behavior regardless of config.
Layering: shared file plus personal override (v7.8.0)
Two files are read, in order, over DEFAULTS:
.agent/.nav-config.json— committed, shared with the team..agent/.nav-config.local.json— gitignored, personal; merged last, so any key set here wins.
Dicts merge key-wise; scalars and lists replace. A missing or unparsable local file changes
nothing (the config_guard op warns when either file fails to parse). nav-features enable|disable <feature> --local writes to the local file; show marks locally decided rows with L.
Defaults-safe and additive migration
- Defaults-safe: any block missing from your file falls back to safe defaults via
nav_hook_lib.config.DEFAULTS. A partial config is always valid. - Additive migration from v6: on first run, the config migrator preserves your existing v6 blocks and adds the new v7 blocks (
dispatcher,tier1,stop_completion,brief_hook). Nothing is removed or rewritten.
Annotated example
{
"version": "8.3.5",
"project_management": "none",
"task_prefix": "TASK",
"task_id_source": "local",
"team_chat": "none",
"auto_load_navigator": true,
"compact_strategy": "conservative",
"dispatcher": { "enabled": true },
"tier1": { "enabled": false, "rules": {} },
"stop_completion": {
"enabled": false,
"continue_enabled": false,
"max_continues": 2
},
"reject_log": {
"enabled": true
},
"deep_research": {
"enabled": false,
"max_sources": 30,
"min_sources": 8,
"fetchers": 4,
"max_full_reads": 10,
"critic_enabled": true,
"models": { "fetcher": "sonnet", "writer": "opus", "critic": "opus", "patcher": "opus" }
},
"judge": {
"enabled": false,
"provider": "typesafe",
"endpoint": "https://api.typesafe.ai/v1/systemone",
"model": "jev-latest",
"timeout_ms": 1500,
"min_confidence": 0.4,
"noul_low": 0.4,
"noul_high": 0.6,
"api_key_env": "TYPESAFE_API_KEY",
"api_key_file": "~/.config/typesafe/api_key",
"max_state_chars": 4000
},
"task_mode": {
"enabled": true,
"auto_detect": true,
"defer_to_skills": true,
"complexity_threshold": 0.5,
"show_phase_indicator": true
},
"tom_features": {
"verification_checkpoints": true,
"confirmation_threshold": "high-stakes",
"profile_enabled": true,
"diagnose_enabled": true,
"belief_anchors": false
},
"loop_mode": {
"enabled": false,
"max_iterations": 5,
"stagnation_threshold": 3,
"exit_requires_explicit_signal": true,
"show_status_block": true,
"iteration_approval": "none",
"periodic_interval": 3,
"never_pause_on_stagnation": false,
"stagnation_diversify_strategy": "combine"
},
"simplification": {
"enabled": true,
"trigger": "post-implementation",
"scope": "modified",
"model": "opus",
"skip_patterns": ["*.test.*", "*.spec.*", "*.md", "*.json", "*.yaml"],
"max_file_size": 50000,
"auto_apply": false,
"preserve_comments": true,
"rules": {
"avoid_nested_ternary": true,
"max_nesting_depth": 3,
"max_function_length": 50,
"prefer_explicit_returns": true,
"consolidate_imports": true
}
},
"auto_update": {
"enabled": true,
"check_interval_hours": 1,
"curl_fallback": false,
"last_check": "2026-06-08T16:11:33.109699"
},
"pilot": {
"enabled": true,
"label": "pilot",
"repo": null
},
"knowledge_graph": {
"enabled": true,
"auto_capture_corrections": true,
"auto_capture_decisions": true,
"auto_surface_relevant": true,
"max_session_memories": 5,
"confidence_decay_rate": 0.01,
"staleness_threshold_days": 90,
"git_tracked": true
},
"reply_modes": {
"enabled": true
},
"adhd_mode": {
"enabled": true,
"on": null
},
"ste_mode": {
"enabled": true,
"on": null
},
"session_start_hook": {
"enabled": true,
"include_sections": ["navigator", "marker", "config", "graph", "profile", "tasks", "auto_update"],
"char_budget": 9500
},
"compact_hook": {
"enabled": true,
"include_transcript_summary": true,
"include_git_state": true,
"char_budget": 8000,
"append_post_compact_summary": true
},
"brief_hook": { "enabled": true },
"task_graph_sync_hook": { "enabled": true },
"workflow_state_hook": { "enabled": true },
"profile_sync_hook": { "enabled": true },
"workflow_enforcer_hook": { "enabled": true, "strict_block": true },
"read_guard_hook": {
"enabled": true,
"warn_threshold": 3,
"escalate_threshold": 5,
"strict_block": true,
"allowlist": ["DEVELOPMENT-README.md", ".nav-config.json", ".user-profile.json", "knowledge/graph.json"]
}
}Top-level
| Key | Type | Default | Description |
|---|---|---|---|
version | string | "8.3.5" | Navigator version the config was written for. Used to detect drift and prompt sync. |
project_management | string | "none" | PM integration: "none", "linear", "github", "jira", or "gitlab". |
task_prefix | string | "TASK" | Prefix for task IDs and doc filenames (e.g. TASK-55). |
task_id_source | string | "local" | Where nav-task gets a new ID (v7.8.0). "local": next sequential {task_prefix}-NN from .agent/tasks/. "github": create the GitHub issue first via gh issue create and name the doc GH-<n>-<slug>.md — GitHub allocates the number, so two contributors can never mint the same ID. A failing gh is an error, never a silent local number. |
team_chat | string | "none" | Team chat integration for completion notices: "none", "slack", etc. |
auto_load_navigator | boolean | true | Load DEVELOPMENT-README.md automatically on session start. |
compact_strategy | string | "conservative" | How aggressively to suggest compaction. "conservative" waits for clear sub-task boundaries. |
dispatcher
The v7 hook runtime: a single dispatcher (hooks/nav_dispatch.py) routes every hook event to op modules in hooks/ops/.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Master switch for the hook runtime. When false, no ops run — Navigator behaviors fall back to documentation-only. |
tier1
Tier-1 instant answers: a narrow, exact-match command set answered deterministically with zero model invocation. New in v7; ships off. See the Tier-1 tuning page.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Master switch. When true, the prompt_tier1 op intercepts the five exact-match commands (nav stats, show features, list markers, graph health, nav version) and renders a terminal card without invoking the model. |
rules | object | {} | Per-rule toggles keyed by rule name. A rule set to false falls through to the model even when tier1.enabled is true; omitted rules follow the master switch. |
stop_completion
The completion gate: derives completion indicators from observable turn evidence and can force one continuation when a codebase-mutating turn ends with unfinished work. New in v7; forced continuation ships off. See the completion gate tuning page.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Evaluate the 6 completion indicators on Stop (git tree, test runs, docs/marker paths, ticket, simplification). |
continue_enabled | boolean | false | Allow the forced continuation when indicators are unmet and no exit signal is present. This is the blocking behavior — it ships off, and is always off under PILOT_EXECUTOR. |
max_continues | number | 2 | Hard cap on forced continuations. |
deep_research
Web deep research via the nav-deep-research skill. New in v7.3.0; ships off because a run fetches dozens of third-party pages and spends several opus subagent calls.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Master switch. The skill stops at step 0 and tells you how to enable it when this is false. |
max_sources | number | 30 | Target upper bound for the sweep’s URL queue. |
min_sources | number | 8 | Ship gate minimum: fewer cited sources block the report. |
fetchers | number | 4 | Parallel deep-research-fetcher agents per wave. |
max_full_reads | number | 10 | Source notes the writer may read in full; the rest are used from digests. |
critic_enabled | boolean | true | Run the critic and patcher steps. |
models | object | fetcher sonnet, writer/critic/patcher opus | Per-role model for the four agents. |
judge
Typed prompt judge — see Typed Prompt Judge. New in v7.7.0; ships off because the prompt text is sent to the TypeSafe API when enabled. Every axis falls back to the keyword heuristic when the judge is undecided, times out, has no key, or errors.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Master switch. |
provider | string | typesafe | Provider name (only typesafe today). |
endpoint | string | https://api.typesafe.ai/v1/systemone | API endpoint. |
model | string | jev-latest | Model alias; pin jev-1.13.0 for stable answers. |
timeout_ms | number | 1500 | Request fuse; prompt_gate is deadline-exempt so this is the only protection inside the 5 s UserPromptSubmit budget. |
min_confidence | number | 0.4 | Score axes (complexity, ambiguity) count at or above this confidence. |
noul_low | number | 0.4 | Yes/no axes count as “no” at or below. |
noul_high | number | 0.6 | Yes/no axes count as “yes” at or above; between the two the heuristic answers. |
api_key_env | string | TYPESAFE_API_KEY | Environment variable read first. |
api_key_file | string | ~/.config/typesafe/api_key | Fallback key file (mode 600). The key never goes in this config file. |
max_state_chars | number | 4000 | Head cap on the prompt before sending. |
reply_modes
The op behind every per-person reply mode (prompt_modes); see
Reply Modes. Ships in v8.3.0, where it replaces prompt_adhd.
Each mode keeps its own <key>_mode block below.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | The op runs at all. false silences every mode in this repo: no phrase answers, nothing is injected. |
adhd_mode
Per-person reply-shape switch; see Reply Modes. New in
v7.9.0. The block makes the mode available; the switch itself is the person’s
(~/.config/navigator/adhd-mode.json, written by saying adhd mode on). Resolution: repo
pin, then personal switch, then off.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Mode available: toggle phrases answer, the rule block can be injected. Injects nothing on its own. |
on | boolean or null | null | Repo pin. true/false overrides every personal switch for this repo (shared or .local file); null defers to the person. |
ste_mode
Per-person Simplified Technical English switch (ASD-STE100 Part 1 subset, dictionary not
applied); see Reply Modes. Ships in v8.3.0. Same shape
and resolution as adhd_mode; the personal file is ~/.config/navigator/ste-mode.json,
written by saying ste mode on or use ste.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Mode available: toggle phrases answer, the rule block can be injected. Injects nothing on its own. |
on | boolean or null | null | Repo pin. true/false overrides every personal switch for this repo (shared or .local file); null defers to the person. |
task_mode
Unified workflow orchestration. Auto-detects substantial work and either defers to a matching skill or runs phased execution. Activation scoring runs at prompt-submit time via the prompt_gate op.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable Task Mode orchestration. |
auto_detect | boolean | true | Detect complexity automatically rather than requiring a trigger. |
defer_to_skills | boolean | true | When a skill clearly matches, let the skill run its own workflow instead of Task Mode phases. |
complexity_threshold | number | 0.5 | Minimum complexity score (0–1) to activate Task Mode. |
show_phase_indicator | boolean | true | Show the PHASE: X → Y visual feedback on transitions. |
tom_features
Theory of Mind features for collaborative alignment.
| Key | Type | Default | Description |
|---|---|---|---|
verification_checkpoints | boolean | true | Show understanding before generating on high-stakes skills. |
confirmation_threshold | string | "high-stakes" | When to require confirmation: "high-stakes", "always", or "never". |
profile_enabled | boolean | true | Enable bilateral modeling via nav-profile (learns your preferences across sessions). |
diagnose_enabled | boolean | true | Enable nav-diagnose quality-drop detection and re-anchoring. |
belief_anchors | boolean | false | Emit explicit known/assumed/unknown assumption declarations before generation. |
loop_mode
Structured “run until done” iteration with explicit exit gating. In v7, exit evaluation runs on Stop via the stop_state and stop_completion ops.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable Loop Mode (also activatable via natural-language triggers). |
max_iterations | number | 5 | Maximum iterations before forced stop. |
stagnation_threshold | number | 3 | Same-state iterations before the stagnation circuit breaker fires. |
exit_requires_explicit_signal | boolean | true | Require EXIT_SIGNAL: true alongside heuristics to exit. |
show_status_block | boolean | true | Print the NAVIGATOR_STATUS block each iteration. |
iteration_approval | string | "none" | When to prompt between iterations: "none", "strict", or "periodic". |
periodic_interval | number | 3 | Iterations between prompts when iteration_approval is "periodic". |
never_pause_on_stagnation | boolean | false | When true, stagnation auto-diversifies instead of pausing for user input. |
stagnation_diversify_strategy | string | "combine" | Recovery strategy on stagnation: "combine", "radical", or "reread". |
simplification
Automatic code clarity pass before commit. Functionality is preserved; only form changes.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable the simplification pass. |
trigger | string | "post-implementation" | When it runs (after implementation, before commit). |
scope | string | "modified" | Files to consider: "modified" limits to changed files. |
model | string | "opus" | Model used for the simplification subagent. |
skip_patterns | string[] | ["*.test.*", "*.spec.*", "*.md", "*.json", "*.yaml"] | Glob patterns excluded from simplification. |
max_file_size | number | 50000 | Skip files larger than this many bytes. |
auto_apply | boolean | false | Apply changes automatically vs. propose them for review. |
preserve_comments | boolean | true | Keep meaningful (“why”) comments intact. |
rules.avoid_nested_ternary | boolean | true | Flatten nested ternaries to if-else/switch. |
rules.max_nesting_depth | number | 3 | Extract or use early returns beyond this depth. |
rules.max_function_length | number | 50 | Suggest splitting functions longer than this many lines. |
rules.prefer_explicit_returns | boolean | true | Favor early/explicit returns over deep branching. |
rules.consolidate_imports | boolean | true | Merge duplicate/fragmented import statements. |
auto_update
Session-start notice when a newer release exists. Navigator never updates itself from a hook; the notice carries the command (claude plugin update navigator@navigator-marketplace), and nav-start Step 1.5 applies it.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Check the latest GitHub release at session start and show the notice. false: no check, no notice. |
check_interval_hours | number | 1 | Minimum hours between release checks. The mod keeps its last answer in Claude Code’s plugin store, not in this file. |
curl_fallback | boolean | false | v8.3.4+. When Claude Code refuses the plugin fetch (CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC), repeat the same GET through curl. Ships off; usually set in .nav-config.local.json. |
last_check | string (ISO 8601) | — | Written by nav-start Step 1.5 (auto_updater.py) after it applies an update; not set by hand. |
pilot
Navigator → Pilot dispatch settings (one-way handoff of a task doc to a labeled GitHub issue).
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Allow nav-pilot dispatch. |
label | string | "pilot" | GitHub issue label applied to dispatched tasks. |
repo | string | null | null | Target repo (owner/name). null uses the current repo. |
knowledge_graph
Unified search and experiential memory across .agent/.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable the knowledge graph. |
auto_capture_corrections | boolean | true | Turn session corrections into memories. |
auto_capture_decisions | boolean | true | Capture task decisions as memories. |
auto_surface_relevant | boolean | true | Surface relevant memories on session start. |
max_session_memories | number | 5 | Cap on memories surfaced per session (token budget). |
confidence_decay_rate | number | 0.01 | Per-period confidence decay applied to memories. |
staleness_threshold_days | number | 90 | Age after which a memory is considered stale. |
git_tracked | boolean | true | Keep knowledge/graph.json under version control. |
Hook toggle blocks
Each block is the off-switch for one op in the hook runtime (see the behavior → op table above). Changing a hook’s enabled flag generally requires a Claude Code restart to take effect.
session_start_hook
Off-switch for the session_start op — injects Navigator context on session start.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Run the op on session start. |
include_sections | string[] | ["navigator", "marker", "config", "graph", "profile", "tasks", "auto_update"] | Sections to inject, in order. |
char_budget | number | 9500 | Maximum characters the op may inject. |
compact_hook
Off-switch for the compact_marker op — captures context markers around compaction.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Run the op around compaction. |
include_transcript_summary | boolean | true | Include a transcript summary. |
include_git_state | boolean | true | Include current git state. |
char_budget | number | 8000 | Maximum characters the op may inject. |
append_post_compact_summary | boolean | true | Append a summary after compaction completes. |
brief_hook
Off-switch for the prompt_brief op — injects a NAV-BRIEF prompt (plus relevant knowledge-graph memories) on ambiguous task-shaped prompts, asking for a one-screen intent brief before files change.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable intent-brief injection on UserPromptSubmit. |
ambiguity_threshold | number | 0.5 | Ambiguity score at or above which the brief fires. |
memory_budget_chars | number | 1200 | Cap on the injected relevant-memories text. |
contradiction_field | boolean | true | v7.1.0. Show the Contradict (TRIZ) row; false restores the v7.0.0 six-field line. |
task_graph_sync_hook
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Sync task docs into the knowledge graph. |
workflow_state_hook
Off-switch for the stop_state op — records workflow/loop state and completion indicators on Stop.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Persist workflow/phase/loop state across turns. |
profile_sync_hook
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Sync learned preferences into the user profile. |
workflow_enforcer_hook
Off-switch for the prompt_gate op — workflow gating at prompt-submit time. Task-shaped prompts are scored for loop triggers and complexity (>= 0.5 → Task Mode; below → direct execution). This replaces the v6 WORKFLOW CHECK prose mandate, which is retired in v7.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable workflow gating on UserPromptSubmit. |
strict_block | boolean | true | Hard-block instead of warn when gating fires. |
read_guard_hook
Off-switch for the read_guard op — guards against fan-out manual Reads that should be Task agents (upfront-loading anti-pattern).
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable the read guard on PreToolUse. |
warn_threshold | number | 3 | Warn after this many guarded reads. |
escalate_threshold | number | 5 | Escalate after this many guarded reads. |
strict_block | boolean | true | Block further reads past the escalation threshold. |
allowlist | string[] | ["DEVELOPMENT-README.md", ".nav-config.json", ".user-profile.json", "knowledge/graph.json"] | Files always allowed without counting against the guard. Entries ending in / match by directory prefix; research/ (nav-deep-research workspaces) is in the default list since v7.3.0. |