@navels/neal 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +206 -209
  2. package/SECURITY.md +16 -19
  3. package/dist/neal/adjudicator/{blocked-adjudicator.js → consultant.js} +21 -21
  4. package/dist/neal/adjudicator/execute.js +33 -33
  5. package/dist/neal/adjudicator/final-completion.js +2 -31
  6. package/dist/neal/adjudicator/planning.js +264 -24
  7. package/dist/neal/agents/prompts.js +7 -15
  8. package/dist/neal/agents/rounds.js +51 -73
  9. package/dist/neal/agents/schemas.js +615 -502
  10. package/dist/neal/agents/structured-json.js +36 -0
  11. package/dist/neal/blocked-guidance.js +16 -9
  12. package/dist/neal/cli.js +2 -2
  13. package/dist/neal/commands/check.js +2 -2
  14. package/dist/neal/commands/compat.js +100 -36
  15. package/dist/neal/commands/interactive-activity.js +2 -2
  16. package/dist/neal/commands/recovery-guidance.js +20 -8
  17. package/dist/neal/commands/runtime.js +4 -2
  18. package/dist/neal/config.js +40 -7
  19. package/dist/neal/context/inline-review-context.js +13 -28
  20. package/dist/neal/context/reviewer-context.js +19 -14
  21. package/dist/neal/eval/reviewer-eval-manifest.js +86 -0
  22. package/dist/neal/eval/reviewer-eval.js +155 -0
  23. package/dist/neal/git.js +9 -3
  24. package/dist/neal/interactive-controls.js +5 -0
  25. package/dist/neal/orchestrator/completion.js +215 -113
  26. package/dist/neal/orchestrator/failures.js +7 -0
  27. package/dist/neal/orchestrator/notifications.js +9 -9
  28. package/dist/neal/orchestrator/phases/planning.js +124 -112
  29. package/dist/neal/orchestrator/phases/recovery.js +151 -115
  30. package/dist/neal/orchestrator/phases/review.js +28 -1
  31. package/dist/neal/orchestrator/split-plan.js +12 -11
  32. package/dist/neal/orchestrator/transitions.js +36 -71
  33. package/dist/neal/orchestrator.js +3 -0
  34. package/dist/neal/plan-doc.js +24 -1
  35. package/dist/neal/plan-queue.js +29 -1
  36. package/dist/neal/prompts/assert-builder.js +8 -1
  37. package/dist/neal/prompts/execute.js +11 -19
  38. package/dist/neal/prompts/planning.js +64 -55
  39. package/dist/neal/prompts/review-doctrine.js +13 -50
  40. package/dist/neal/prompts/specialized.js +28 -22
  41. package/dist/neal/prompts/specs.js +223 -17
  42. package/dist/neal/providers/agent-settings-isolation.js +35 -0
  43. package/dist/neal/providers/anthropic-claude.js +309 -248
  44. package/dist/neal/providers/detection.js +3 -7
  45. package/dist/neal/providers/git-config-isolation.js +83 -0
  46. package/dist/neal/providers/openai-codex.js +102 -204
  47. package/dist/neal/providers/{generic-agentic-tools.js → openai-compatible-tools.js} +11 -5
  48. package/dist/neal/providers/openai-compatible.js +1079 -403
  49. package/dist/neal/providers/openrouter-routing.js +68 -0
  50. package/dist/neal/providers/pricing.js +124 -0
  51. package/dist/neal/providers/rate-card.js +2275 -0
  52. package/dist/neal/providers/registry.js +6 -17
  53. package/dist/neal/providers/telemetry.js +4 -0
  54. package/dist/neal/providers/types.js +12 -0
  55. package/dist/neal/resume-decision.js +7 -6
  56. package/dist/neal/resume-planner.js +9 -0
  57. package/dist/neal/retrospective.js +36 -7
  58. package/dist/neal/review-debt.js +30 -0
  59. package/dist/neal/review-findings/provider.js +17 -29
  60. package/dist/neal/review.js +17 -1
  61. package/dist/neal/run-metrics.js +74 -9
  62. package/dist/neal/state-invariants.js +11 -3
  63. package/dist/neal/state-views.js +27 -5
  64. package/dist/neal/state.js +59 -15
  65. package/dist/neal/status.js +28 -1
  66. package/dist/neal/support.js +3 -3
  67. package/docs/README.md +22 -18
  68. package/docs/{ADJUDICATOR_INVENTORY.md → adjudicator-inventory.md} +58 -57
  69. package/docs/architecture.md +79 -83
  70. package/docs/automation.md +11 -11
  71. package/docs/compat.md +91 -61
  72. package/docs/compatible-models.md +145 -110
  73. package/docs/demo.md +15 -5
  74. package/docs/maintenance.md +74 -32
  75. package/docs/plan-format.md +61 -33
  76. package/docs/prompt-evals.md +96 -0
  77. package/docs/{PROMPT_SPECS.md → prompt-specs.md} +52 -48
  78. package/docs/providers.md +330 -283
  79. package/docs/release.md +43 -40
  80. package/docs/review-convergence.md +246 -0
  81. package/docs/state-machine.md +61 -59
  82. package/docs/storage.md +40 -31
  83. package/docs/troubleshooting.md +32 -29
  84. package/examples/compat/add-edit-verify/PLAN.md +2 -0
  85. package/examples/compat/add-edit-verify/broken.diff +2 -2
  86. package/examples/compat/add-edit-verify/good.diff +2 -2
  87. package/examples/compat/add-edit-verify/src/add.js +1 -1
  88. package/examples/compat/manifest.json +25 -29
  89. package/examples/compat/sum-grep-edit/PLAN.md +33 -0
  90. package/examples/compat/sum-grep-edit/broken.diff +12 -0
  91. package/examples/compat/sum-grep-edit/good.diff +12 -0
  92. package/examples/compat/sum-grep-edit/package.json +5 -0
  93. package/examples/compat/sum-grep-edit/src/numbers.js +9 -0
  94. package/examples/compat/sum-grep-edit/test/numbers.test.js +15 -0
  95. package/examples/issue-triage-js/README.md +0 -15
  96. package/examples/reviewer-eval/clean-doc/base/src/clamp.ts +3 -0
  97. package/examples/reviewer-eval/clean-doc/change.diff +9 -0
  98. package/examples/reviewer-eval/clean-extract/base/src/greet.ts +3 -0
  99. package/examples/reviewer-eval/clean-extract/change.diff +13 -0
  100. package/examples/reviewer-eval/dropped-error/base/src/load.ts +4 -0
  101. package/examples/reviewer-eval/dropped-error/change.diff +15 -0
  102. package/examples/reviewer-eval/manifest.json +45 -0
  103. package/examples/reviewer-eval/off-by-one/base/src/paginate.ts +5 -0
  104. package/examples/reviewer-eval/off-by-one/change.diff +11 -0
  105. package/{config.yml → neal.yml} +1 -1
  106. package/package.json +20 -15
  107. package/dist/neal/providers/generic-agentic.js +0 -1238
  108. package/docs/comparison.md +0 -105
  109. package/examples/compat/is-even-add-test/PLAN.md +0 -30
  110. package/examples/compat/is-even-add-test/broken.diff +0 -11
  111. package/examples/compat/is-even-add-test/good.diff +0 -11
  112. package/examples/compat/is-even-add-test/package.json +0 -5
  113. package/examples/compat/is-even-add-test/src/is-even.js +0 -3
  114. package/examples/compat/is-even-add-test/test/is-even.test.js +0 -9
  115. package/examples/compat/reverse-grep-edit/PLAN.md +0 -32
  116. package/examples/compat/reverse-grep-edit/broken.diff +0 -12
  117. package/examples/compat/reverse-grep-edit/good.diff +0 -12
  118. package/examples/compat/reverse-grep-edit/package.json +0 -5
  119. package/examples/compat/reverse-grep-edit/src/strings.js +0 -10
  120. package/examples/compat/reverse-grep-edit/test/strings.test.js +0 -15
package/README.md CHANGED
@@ -1,39 +1,45 @@
1
1
  # neal
2
2
 
3
+ **neal** — from *anneal*: repeated, controlled adjustment toward a more
4
+ stable result.
5
+
3
6
  [![CI](https://github.com/navels/neal/actions/workflows/ci.yml/badge.svg)](https://github.com/navels/neal/actions/workflows/ci.yml)
4
7
  [![npm version](https://img.shields.io/npm/v/@navels/neal.svg)](https://www.npmjs.com/package/@navels/neal)
5
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
9
 
7
- > **A source-first, multi-agent coding loop.** Separate **planner**, **coder**, and **reviewer** roles each on the provider and model you choose — drive scoped, reviewed, crash-safe changes to your repository.
10
+ > **A plan-driven, multi-agent coding loop.** Separate **planner**, **coder**, and **reviewer** roles, each on the provider and model you choose, work together to implement your plan.
11
+
12
+ ![neal execution flow](docs/assets/neal-execution-flow.png)
13
+
14
+ neal is a local planner/coder/reviewer loop for your repo. You write a plan, and neal's planner/reviewer loop turns it into a human-reviewable execution plan with an execution shape, manageable scopes, and high-level implementation detail grounded in the current repository. neal then runs each scope with your configured coder and reviewer roles. After every scope is accepted, a final review pass checks the total set of changes against the entire plan. Run artifacts are recorded under `.neal/` so interrupted work can resume.
8
15
 
9
- ![neal driving a planner/coder/reviewer run](https://raw.githubusercontent.com/navels/neal/main/assets/neal-demo.gif)
16
+ Two choices explain the design:
10
17
 
11
- neal is a source-first local planner/coder/reviewer loop for your repo. You write a plan; neal refines it with your configured planner role, runs each scope with your configured coder role, commits the result, and hands the diff to your configured reviewer role before moving on. When every scope is accepted, a final review pass checks the whole plan, and run artifacts stay under `.neal/` so interrupted work can resume.
18
+ - **The coder and reviewer run on different vendors.** The review is genuinely adversarial: a second model with its own blind spots checks the first, instead of one model grading its own work.
19
+ - **Each scope starts the coder from a fresh context.** A long plan doesn't drift the way a single agent does as its context fills up.
12
20
 
13
21
  ### What makes it interesting
14
22
 
15
- - **Roles, not one monolithic agent.** Planner, coder, and reviewer are independent, separately configurable roles mix vendors and models per role (e.g. Codex codes, Claude reviews).
16
- - **The reviewer is read-only** declared at provider registration and enforced mechanically in each adapter (OS sandbox for Codex, SDK tool allowlist for Claude, a neal-owned jailed toolset for OpenRouter models), pinned by a conformance test — never just prompt-deep. See [SECURITY.md](SECURITY.md) and [docs/providers.md](docs/providers.md).
17
- - **`neal compat`** a built-in harness that qualifies any OpenAI-compatible / OpenRouter model across all three roles and emits a dated PASS/FAIL whitelist. See [docs/compatible-models.md](docs/compatible-models.md).
18
- - **Crash-safe and resumable** every run's state and artifacts live under `.neal/`; `neal resume` continues an interrupted run.
19
- - **Bounded autonomous recovery** neal resolves a class of reviewer/coder deadlocks itself, and escalates genuine blockers.
23
+ - **Roles, not one monolithic agent.** Planner, coder, and reviewer are independent, separately configurable roles. Mix vendors and models per role (e.g. Codex codes, Claude reviews).
24
+ - **The reviewer is read-only.** Declared at provider registration and enforced mechanically in each adapter (OS sandbox for Codex, SDK tool allowlist for Claude, a neal-owned jailed toolset for OpenRouter models). See [SECURITY.md](SECURITY.md) and [docs/providers.md](docs/providers.md).
25
+ - **`neal compat`.** A built-in harness that qualifies any OpenAI-compatible / OpenRouter model across all three roles and emits a dated PASS/FAIL whitelist. See [docs/compatible-models.md](docs/compatible-models.md).
26
+ - **Crash-safe and resumable.** Every run's state and artifacts live under `.neal/`. `neal resume` continues an interrupted run.
27
+ - **Bounded autonomous recovery.** neal resolves a class of reviewer/coder deadlocks itself, and escalates genuine blockers.
28
+ - **Scopes can split themselves.** When a scope turns out bigger than expected, the coder splits it into a derived sub-plan instead of forcing a bad implementation into one commit. See [docs/plan-format.md](docs/plan-format.md).
20
29
 
21
30
  For how the pieces fit together, see the [architecture overview](docs/architecture.md).
22
- Wondering how this differs from Claude Code, Aider, or OpenHands? See
23
- [docs/comparison.md](docs/comparison.md).
24
31
 
25
32
  **Contents:** [Quickstart](#quickstart) ·
26
33
  [Why neal exists](#why-neal-exists) ·
27
- [neal is built with neal](#neal-is-built-with-neal) ·
28
34
  [Installation](#installation) ·
29
- [Provider Setup](#provider-setup) ·
30
- [Command Tour](#command-tour) ·
35
+ [Provider setup](#provider-setup) ·
36
+ [Command tour](#command-tour) ·
31
37
  [Commands](#commands) ·
32
- [Exit Codes](#command-exit-codes) ·
38
+ [Exit codes](#command-exit-codes) ·
33
39
  [Configuration](#configuration) ·
34
40
  [Artifacts](#artifacts-and-storage) ·
35
- [Plan Shape](#plan-shape) ·
36
- [Safety Notes](#safety-notes)
41
+ [Plan shape](#plan-shape) ·
42
+ [Safety notes](#safety-notes)
37
43
 
38
44
  ## Quickstart
39
45
 
@@ -43,85 +49,57 @@ neal setup # pick providers for the coder and reviewer roles
43
49
  neal check # verify config and provider readiness
44
50
  ```
45
51
 
46
- The cheapest way to try neal is a single OpenRouter API key — no Codex or
47
- Claude subscription required: run `neal setup --provider generic-agentic
48
- --all-roles`, set `OPENAI_COMPATIBLE_API_KEY`, and pick a model from the
49
- [qualified-model whitelist](docs/compatible-models.md). The flagship
50
- configuration — Codex writes, Claude reviews — uses those two locally
51
- authenticated CLIs instead; see [Provider Setup](#provider-setup).
52
+ No Claude or Codex subscription? Pick a qualified model slug from the
53
+ [compatibility whitelist](docs/compatible-models.md) and use the OpenRouter
54
+ provider (see [Provider setup](#provider-setup)).
52
55
 
53
- From a Git repository with at least one commit, write a minimal plan and run
54
- it:
56
+ Describe a real feature in plain language and write it to a file (e.g., `PLAN.md`):
55
57
 
56
58
  ```md
57
- # Add a project description
59
+ Add a "Sign in with Google" option to the login page using OAuth 2.0.
60
+ Store the resulting session the same way the existing email/password login does.
61
+ ```
58
62
 
59
- ## Execution Shape
63
+ Then run neal from your repository root:
60
64
 
61
- executionShape: one_shot
65
+ ```bash
66
+ neal run <path-to-PLAN.md>
67
+ ```
62
68
 
63
- ## Objective
69
+ Note: I usually keep plan docs in a .gitignore-ed directory in my repo but ymmv.
64
70
 
65
- Add a one-line project description to the top of README.md and keep the
66
- existing content unchanged.
67
- ```
71
+ Want to read the refined plan before neal executes it? Run the two steps
72
+ separately instead:
68
73
 
69
74
  ```bash
70
- neal run PLAN.md
75
+ neal plan <path-to-PLAN.md>
76
+ # review/update the refined plan, then:
77
+ neal execute <path-to-PLAN.md>
71
78
  ```
72
79
 
73
- neal refines the plan through the planner/reviewer loop, executes each scope
74
- with a fresh-context coder, has the reviewer judge every diff before moving
75
- on, and persists run state under `.neal/` — interrupt it any time and
76
- `neal resume` continues where it stopped. Plan shapes, queues, and loops:
77
- [docs/plan-format.md](docs/plan-format.md). If something misbehaves:
78
- [docs/troubleshooting.md](docs/troubleshooting.md).
79
-
80
80
  ## Why neal exists
81
81
 
82
- neal grew out of a large frontend upgrade (Ember 3.28 to Ember 5) where the agent would drift over time from its initial instructions, which led to me wanting to break up the work into smaller chunks and reset the agent context before each chunk. I also wanted to incorporate my typical manual workflow of having Claude review Codex's work, copy/pasting findings and responses until both agents were satisfied with the result, before reviewing myself. I settled on this flow for neal:
82
+ neal grew out of a large frontend upgrade (Ember 3.28 to Ember 5) where the agent would drift over time from its initial instructions, which led to me wanting to break up the work into smaller chunks and reset the agent context before each chunk. I also wanted to incorporate my manual workflow of having Claude review Codex's work, copy/pasting findings and responses until both agents were satisfied with the result, before reviewing myself. I settled on this flow for neal:
83
83
 
84
84
  - start with a plan of what work needs to be done and how to do it
85
- - neal sends this through the planner/reviewer loop to ensure it is broken into manageable chunks (aka scopes) and formatted for execution by neal
86
- - each scope is run through the coder/reviewer loop with the coder starting with a fresh context
85
+ - neal sends this through the planner/reviewer loop to give it an execution shape, define manageable scopes, and flesh out the implementation approach
86
+ - each scope is run through the coder/reviewer loop with the coder starting with a fresh context and the reviewer keeping its context from scope to scope
87
87
  - when the reviewer is satisfied, neal moves on to the next scope with the previous scope committed
88
88
  - after all scopes are complete, the entire set of changes is run through the coder/reviewer loop a final time
89
89
  - if a scope is found to be too large, the coder can split it into a sub-plan
90
- - if the coder is blocked on something, it can consult the reviewer for assistance
90
+ - if the coder is blocked on something, it can consult the reviewer model for assistance
91
91
  - if neal exits for any reason, `neal resume` will attempt to continue, prompting for direction if the coder was blocked
92
92
  - run artifacts and state are recorded in `.neal/`
93
93
 
94
- ![neal execution flow](docs/assets/neal-execution-flow.png)
95
-
96
- The name comes from `anneal`: repeated controlled adjustment toward a more stable result.
97
-
98
- ## neal is built with neal
99
-
100
- neal's development is its own primary proof. The blocked-handling redesign in
101
- this release — replacing an ad-hoc support loop with the unified, budgeted
102
- blocked adjudicator — was planned, implemented, and reviewed by neal driving
103
- itself: Codex wrote each scope from a fresh context, Claude reviewed every
104
- diff, and the run artifacts under `.neal/` were the working record. Much of
105
- the code and documentation in this repository was written by coding agents
106
- under human direction; the architecture, the judgment calls, and the final
107
- review are human.
108
-
109
- The public repository begins at a single squashed commit because the
110
- pre-release history carried private working context; it is preserved
111
- privately. From v0.1.0 forward, development happens in the open — including
112
- runs where neal maintains neal.
113
-
114
94
  ## Installation
115
95
 
116
96
  ```bash
117
97
  npm install -g @navels/neal
118
98
  ```
119
99
 
120
- neal requires Node.js >= 22.13 and drives your configured provider CLIs/SDKs
121
- (OpenAI Codex, Anthropic Claude, or any OpenAI-compatible / OpenRouter model)
122
- see [Provider Setup](#provider-setup). On Windows, run neal from WSL2 with the
123
- target repository on the Linux filesystem; direct PowerShell or cmd.exe
124
- operation is not a supported launch path.
100
+ neal requires Node.js >= 24.18.0 and drives your configured provider CLIs/SDKs
101
+ (OpenAI Codex, Anthropic Claude, or any OpenAI-compatible / OpenRouter model).
102
+ See [Provider setup](#provider-setup).
125
103
 
126
104
  ### Run from source / contribute
127
105
 
@@ -132,44 +110,94 @@ corepack enable && pnpm install && pnpm start -- help
132
110
  See [CONTRIBUTING.md](CONTRIBUTING.md) for contributor setup, the development
133
111
  link, verification commands, CI gates, and canonical doc references.
134
112
 
135
- ## Provider Setup
113
+ ## Provider setup
136
114
 
137
- neal delegates planning, coding, and reviewing to provider-owned local runtimes, selected by provider id in the `agent.coder.provider` and `agent.reviewer.provider` config keys. The planner inherits the coder provider/model unless `agent.planner` is configured explicitly. Each provider still owns its credentials, account state, model availability, permissions, quotas, and rate limits.
115
+ neal uses separate providers for the planner, coder, and reviewer roles. `neal
116
+ setup` writes explicit coder and reviewer defaults to `~/.neal/config.yml`.
138
117
 
139
- | Provider id | Roles it serves | What you need | Docs |
140
- | --- | --- | --- | --- |
141
- | `openai-codex` | planner, coder, reviewer | Local OpenAI Codex runtime, authenticated through its own provider-owned setup | [docs/providers.md](docs/providers.md) |
142
- | `anthropic-claude` | planner, coder, reviewer | Local Anthropic Claude runtime, authenticated through its own provider-owned setup | [docs/providers.md](docs/providers.md) |
143
- | `openai-compatible` | reviewer only (API-only: no repository tools — neal inlines diff/artifact context — no session resume, no `effort`) | Any OpenAI-compatible Chat Completions endpoint (DeepSeek, OpenRouter, vLLM, and similar) via the `providers.openai_compatible` config block; env fallbacks `OPENAI_COMPATIBLE_BASE_URL`, `OPENAI_COMPATIBLE_API_KEY`, `OPENAI_COMPATIBLE_MODEL` | [docs/providers.md](docs/providers.md#openai-compatible-endpoints) |
144
- | `generic-agentic` | coder (and the inherited planner); reviewer through a read-only toolset | The same `providers.openai_compatible` block plus a strong tool-calling model | [docs/providers.md](docs/providers.md#generic-agentic-writer), [docs/compat.md](docs/compat.md) |
118
+ A typical config uses Codex for coding and Claude for review:
145
119
 
146
- For `generic-agentic`, neal owns the agentic loop and supplies its own file/search/shell tools, so the endpoint only needs reliable tool calling; its reviewer inspects the repository directly through read-only tools instead of judging inlined context — prefer it over `openai-compatible` for reviewer duty when the model calls tools reliably. It never persists provider sessions (`neal resume` restarts the interrupted scope from scratch in a fresh session) and runs with the same trust level as the other writer providers — its coder-role `run` tool is unsandboxed shell. Use paid tool-calling model slugs for coder duty; `:free` pools are reviewer-only. Before trusting a generic-agentic model with real work, qualify it with `neal compat` (see [docs/compat.md](docs/compat.md)) to confirm it can drive the full loop.
120
+ ```yaml
121
+ agent:
122
+ coder:
123
+ provider: openai-codex
124
+ model: null
125
+ reviewer:
126
+ provider: anthropic-claude
127
+ model: null
128
+ ```
129
+
130
+ `model: null` lets the provider choose its default model. The planner can also be configured
131
+ but otherwise inherits from the coder config.
132
+
133
+ | Provider id | Setup |
134
+ | --- | --- |
135
+ | `openai-codex` | Complete the normal Codex local setup/login, or use your `OPENAI_API_KEY`. |
136
+ | `anthropic-claude` | Complete the normal Claude local setup/login, or use your `ANTHROPIC_API_KEY`. |
137
+ | `openai-compatible` | Connect an OpenAI-compatible Chat Completions API such as OpenRouter, DeepSeek, Ollama, or vLLM. |
147
138
 
148
- Run setup once before first writer-run use:
139
+ ### OpenRouter and other OpenAI-compatible APIs
140
+
141
+ Use `openai-compatible` to run models through OpenRouter or another API that
142
+ implements OpenAI-compatible Chat Completions. It's separate from
143
+ `openai-codex` and doesn't use the Codex CLI or login.
144
+
145
+ For OpenRouter, export your API key:
146
+
147
+ ```bash
148
+ export OPENROUTER_API_KEY=...
149
+ ```
150
+
151
+ Then add the endpoint to `~/.neal/config.yml`:
152
+
153
+ ```yaml
154
+ providers:
155
+ openai_compatible:
156
+ base_url: https://openrouter.ai/api/v1
157
+ api_key_env: OPENROUTER_API_KEY
158
+ ```
159
+
160
+ For another compatible API, change the URL and key variable. See
161
+ [docs/providers.md](docs/providers.md) for environment-only configuration and
162
+ local endpoints.
163
+
164
+ Run setup once:
149
165
 
150
166
  ```bash
151
167
  neal setup
152
168
  ```
153
169
 
154
- `neal setup` detects local runtime availability for built-in providers without making live provider calls, asks for coder and reviewer defaults, and writes explicit `agent.coder` and `agent.reviewer` provider/model settings to `~/.neal/config.yml`. The planner inherits coder by default; interactive setup asks before writing an explicit planner override. To script the same provider for every role:
170
+ `neal setup` detects local runtimes and configured OpenAI-compatible settings,
171
+ but it doesn't authenticate or send prompts. Choose `openai-compatible` for
172
+ each role you want to run through OpenRouter, then enter an OpenRouter model
173
+ slug such as `deepseek/deepseek-v3.2`.
174
+
175
+ To script the same provider for every role:
155
176
 
156
177
  ```bash
157
178
  neal setup --provider anthropic-claude --all-roles
158
179
  ```
159
180
 
160
- When a model is omitted, setup writes `model: null` so the provider chooses its default model. Existing effective provider settings are not overwritten unless you confirm interactively or pass `--force`.
161
-
162
- Authenticate or configure each provider through its normal provider-owned local setup before running provider-backed workflows such as `neal plan`, `neal execute`, `neal run`, or `neal resume`. Neal does not collect or store provider credentials. Provider contract details are in [docs/providers.md](docs/providers.md). External provider adapters are future work.
181
+ Existing effective provider settings are not overwritten unless you confirm
182
+ interactively or pass `--force`.
163
183
 
164
- After setup, verify local config and provider readiness:
184
+ Then verify the config and live provider access:
165
185
 
166
186
  ```bash
167
187
  neal check
168
188
  ```
169
189
 
170
- After the config passes, `neal check` prints the effective planner/coder/reviewer roles and prompts before sending one small prompt to each configured role for live connectivity verification. In non-interactive shells, it validates config and reports that live provider verification was skipped. Common setup and auth failures, with their exact messages and fixes, are collected in [docs/troubleshooting.md](docs/troubleshooting.md).
190
+ `neal check` prints the effective planner/coder/reviewer choices, then prompts
191
+ before sending one small live request to each configured role. In non-interactive
192
+ shells, it only validates config and reports that live verification was skipped.
171
193
 
172
- ## Command Tour
194
+ Before using an `openai-compatible` model for real work, run `neal compat` (see
195
+ [docs/compat.md](docs/compat.md)). Free or heavily rate-limited model pools
196
+ usually fail as coders and are unreliable reviewers. Provider details are in
197
+ [docs/providers.md](docs/providers.md), and common setup/auth failures are in
198
+ [docs/troubleshooting.md](docs/troubleshooting.md).
199
+
200
+ ## Command tour
173
201
 
174
202
  Writer commands require a Git repository with an existing `HEAD` commit before
175
203
  provider execution. Create and commit the repository's initial baseline before
@@ -199,13 +227,7 @@ neal execute PLAN.md --unattended
199
227
  neal run --unattended tmp/A.md tmp/B.md
200
228
  ```
201
229
 
202
- Try the dependency-free in-repo example without provider calls:
203
-
204
- ```bash
205
- pnpm --dir examples/issue-triage-js test
206
- ```
207
-
208
- To run the same example through Neal after configuring providers:
230
+ To run an example through neal after configuring providers:
209
231
 
210
232
  ```bash
211
233
  neal setup
@@ -231,7 +253,9 @@ Give guidance only when `neal status` or `neal resume` says the selected run is
231
253
  neal resume --run <run-id> --message "Keep the change bounded to the failing test and rerun the required validation gate."
232
254
  ```
233
255
 
234
- Review already-committed work:
256
+ `neal review` is a separate, plan-free workflow for already-committed work. The
257
+ coder proposes findings, the reviewer judges them, and neal rejects any
258
+ worktree changes made during the review:
235
259
 
236
260
  ```bash
237
261
  neal review --last 3
@@ -248,73 +272,91 @@ neal status --all
248
272
  neal status --json --all
249
273
  ```
250
274
 
251
- ## Automation Contract
275
+ ## Automation contract
252
276
 
253
277
  neal keeps a stable machine-facing contract for driving it from scripts, CI, and benchmark harnesses: writer exit codes, the `neal status --json` classification schema, patch-submission eligibility, and harness timeout and trace-publishing guidance. See [docs/automation.md](docs/automation.md).
254
278
 
255
279
  ## Commands
256
280
 
257
281
  ```bash
282
+ # Setup
258
283
  neal setup
284
+ neal check
285
+ neal compat [--model <slug>] [--role coder|reviewer|planner|all] [--reference openai-codex|anthropic-claude|openai-compatible:<slug>] [--json]
286
+
287
+ # Plan execution
288
+ neal run [--no-squash] [--unattended] <plan.md> [more-plans...]
259
289
  neal plan <plan.md> [--unattended]
260
290
  neal execute <plan.md> [--no-squash] [--unattended]
261
- neal run [--no-squash] [--unattended] <plan.md> [more-plans...]
262
291
  neal resume [--run <run-id>] [--message "..."]
292
+
293
+ # Plan-free review
263
294
  neal review [message] (--last <n> | --since <base>)
264
- neal squash [plan.md]
265
- neal check
266
- neal compat [--model <slug>] [--role coder|reviewer|planner|all] [--reference openai-codex|anthropic-claude|generic-agentic:<slug>] [--json]
295
+
296
+ # Inspection and maintenance
267
297
  neal status [--json] [--run <run-id>]
268
298
  neal status [--json] --all
299
+ neal squash [plan.md]
300
+
301
+ # CLI information
269
302
  neal version
270
303
  neal help
271
304
  neal --help
272
305
  neal -h
273
306
  ```
274
307
 
275
- `neal plan` revises the target plan file in place and stores the original-plan backup at `.neal/runs/<run-id>/PLAN_ORIGINAL.md`.
308
+ ### Setup
276
309
 
277
- `neal execute` runs an already-ready plan. It requires a Git repository with at least one commit and no dirty work outside the selected plan document, and can edit files and create commits. When the selected plan document is repo-local, nonignored, and changed, neal may include it in the run's final tree through ordinary Git staging. Ignored, missing, non-file, or outside-repository plan documents are recorded as metadata only and are not force-added. Completed execute runs squash run-owned commits by default without confirmation; pass `--no-squash` to leave the individual commits in place.
310
+ `neal setup` detects available providers and writes coder, reviewer, and optional
311
+ planner choices to `~/.neal/config.yml`. `neal check` validates that config and
312
+ can make a small live request to each configured role.
278
313
 
279
- `neal run` refines each plan through the planning loop, then executes the accepted plan. It requires a Git repository with at least one commit and uses the same clean-worktree admission as `neal execute`: dirty work outside the selected plan document blocks writer-run start and queue continuation. Queue items run serially. The queue stops at the first blocked, failed, paused, or operator-attention run. Execution children use the same selected-plan-document handling as `neal execute`: eligible repo-local nonignored plan documents may land in the final run tree, while ignored or outside-repository plans remain metadata-only. Execution children squash completed run-owned commits by default; pass `--no-squash` to preserve per-scope commits.
314
+ `neal compat` is a full-loop smoke test for an `openai-compatible` model, not a
315
+ skill benchmark. See [docs/compat.md](docs/compat.md) for the test contract and
316
+ [docs/compatible-models.md](docs/compatible-models.md) for the current results.
280
317
 
281
- `neal resume` continues the selected writer run when it is mechanically resumable, including ordinary failed, paused, and stale-running states. With no `--run`, neal uses the current local run pointer. If the run is waiting for operator guidance, `neal resume` and `neal status` explain the blocker and print the exact `neal resume --run <run-id> --message "..."` command. `--message` is reserved for that waiting-guidance state.
318
+ ### Plan execution
282
319
 
283
- If a coder scope reaches expected human work that Neal cannot perform itself, the run can wait in `waiting_for_manual_gate`. `neal status` shows the gate title, reason, run-local `GATE-<id>.md` instructions file, last failed check if any, and the resume command. `neal resume --run <run-id>` runs the gate's configured noninteractive command checks before provider execution; failed checks keep the gate open, and passing checks clear the gate and resume the same coder scope. Manual gates do not use `neal resume --message`.
320
+ `neal run` is the normal workflow. It refines each plan, executes it, and runs
321
+ multiple plan arguments in order. Use `neal plan` and `neal execute` separately
322
+ when you want to inspect or edit the refined plan before execution.
284
323
 
285
- ### Unattended Mode
324
+ Writer commands require a Git repository with an existing commit. `neal execute`
325
+ and `neal run` can edit files and create commits, then squash their completed
326
+ work by default. Pass `--no-squash` to keep the per-scope commits.
286
327
 
287
- `--unattended` (on `neal plan`, `neal execute`, and `neal run`) runs Neal
288
- headlessly CI, cron, or a benchmark harness when no operator is available:
289
- eligible blocks auto-resume for a small bounded number of turns with a fixed
290
- conservative guidance message, and the operator review gates fail cleanly and
291
- terminally (exit code `3`, produced artifacts left unsubmitted) instead of
292
- waiting for `neal resume --message`; verification, authorization, and the
293
- squash/grading paths are never weakened. The resolved value is persisted on run
294
- state, so a later `neal resume` and the `neal run` plan→execute hand-off keep
295
- the same behavior without re-passing the flag. The squash preference
296
- (`--no-squash`) is likewise persisted on run state across resume. See
297
- [config.yml](config.yml) for the `agent.unattended` config key (default
298
- `false`; the flag overrides it) and [docs/state-machine.md](docs/state-machine.md)
299
- for the operator-block and gate states.
328
+ `neal resume` continues the current run or a run selected with `--run`. If neal
329
+ needs guidance or manual work, `neal resume` and `neal status` explain what is
330
+ needed and print the command to continue.
300
331
 
301
- `neal review` never mutates your repository: candidate findings are drafted on the coder provider and judged by the read-only reviewer, and neal verifies after every provider call that the worktree and neal's own run state are byte-unchanged, failing the review otherwise. It uses neal's built-in adversarial review posture by default; the optional positional message is additive context. The selector is resolved when the command starts, and neal reviews commits ending at the current checkout `HEAD` for `--last` or `--since`. Dirty worktrees are allowed because the selected committed range is the review target. Accepted findings are printed to the terminal and written under `.neal/reviews/<review-id>/`.
332
+ `--unattended` runs `neal plan`, `neal execute`, or `neal run` without waiting
333
+ for an operator. See [docs/state-machine.md](docs/state-machine.md) for unattended
334
+ blocks, manual gates, and resume behavior, and [docs/plan-format.md](docs/plan-format.md)
335
+ for execution shapes and selected-plan handling.
302
336
 
303
- `neal squash` squashes run-owned commits for a completed plan. With no argument, it selects the latest completed execute-mode run with readable run-local state and uses that run's recorded plan doc. With a plan argument, it selects the latest completed execute-mode run for that plan. It preserves later commits added after the selected neal run by replaying them on top of the replacement squash commit. It previews the selected run, commit range, later commits to preserve, plan-document disposition, commit-message source, and generated semantic commit message, then requires interactive TTY confirmation before rewriting history. The replacement commit is signed when Git signing is configured for commits. Squash result artifacts keep Neal provenance separately from the Git commit message, including the run id, selected and normalized plan paths, plan-document disposition, replacement-tree inclusion, commit-message source, and commit-message subject.
337
+ ### Plan-free review
304
338
 
305
- `neal setup` configures explicit coder and reviewer provider defaults for fresh writer runs, with an optional planner override. It reports local runtime availability, writes `~/.neal/config.yml` by default, preserves unrelated user config, and recommends provider-owned authentication followed by `neal check` after writing.
339
+ `neal review` has the coder propose findings and the reviewer judge them against
340
+ already-committed work. Use `--last` or `--since` to choose the commit range and
341
+ an optional message to focus the review. The drafting coder still has coder
342
+ privileges, so neal checks the worktree after every provider call and fails if
343
+ anything changed outside the review artifacts. This is useful for a coordinated
344
+ multi-model review of a PR.
306
345
 
307
- `neal check` validates the effective config, reports the effective planner, coder, and reviewer provider/model choices, then prompts before making live provider connectivity calls. When the resolved **coder or reviewer** role uses a non-native (generic-agentic / openai-compatible) provider, it prints a one-line pointer to `neal compat`; native adapters (`openai-codex`/`anthropic-claude`) do not. (The planner inherits the coder provider by default, so the coder check already covers the common case; an explicitly configured non-native planner alongside native coder/reviewer is not separately flagged.)
346
+ ### Inspection and maintenance
308
347
 
309
- `neal compat` is a **compatibility smoke test, not a skill benchmark**: it answers whether an OpenAI-compatible model can drive neal's loop at all as a coder, reviewer, or planner. It reuses `neal check`'s structured pre-filter, then drives the candidate through complete neal runs against bundled trivial fixtures (`examples/compat/`) in throwaway git copies (it never mutates a committed fixture), and emits a binary PASS/FAIL matrix per (model, role) with a structural failure mode for each FAIL. `--model <slug>` runs the slug on the `generic-agentic` provider in the candidate role, and `--reference <id>` names a native provider (`openai-codex` default, or `anthropic-claude`) for the non-candidate roles so a FAIL is attributable to the candidate; `--role` defaults to `all`; `--json` prints a stable machine-readable matrix. It is fully self-contained — the only prerequisites are the neal repo and an API key — forces unattended mode so a model is never penalized for a resumable halt, and exits non-zero on an overall FAIL. See [docs/compat.md](docs/compat.md) for the PASS definition, failure-mode taxonomy, and `--json` schema, and [docs/compatible-models.md](docs/compatible-models.md) for the verified-model whitelist.
348
+ `neal status` shows the current run, or all runs with `--all`. Its `--json`
349
+ forms are the stable automation interface.
310
350
 
311
- `neal status` prints a human-readable summary by default. `neal status --all` lists writer runs from `.neal/runs/*/RUN_STATE.json`. `neal status --json` and `neal status --json --all` are the stable automation contracts. Runs waiting on manual gates report `effectiveStatus: "waiting_for_manual_gate"` and include a nullable `manualGate` summary with the gate instructions path and resume command.
351
+ `neal squash` rewrites a completed run into one commit. It previews the change
352
+ and requires interactive confirmation before rewriting history.
312
353
 
313
- `neal version` prints the package version.
354
+ ### CLI information
314
355
 
315
- `neal help`, `neal --help`, and `neal -h` print the supported usage surface, including the package version.
356
+ `neal version` prints the package version. `neal help`, `neal --help`, and
357
+ `neal -h` print the supported command surface.
316
358
 
317
- ## Command Exit Codes
359
+ ## Command exit codes
318
360
 
319
361
  The writer commands `neal plan`, `neal execute`, `neal run`, and `neal resume`
320
362
  use this shell contract:
@@ -322,27 +364,27 @@ use this shell contract:
322
364
  - `0`: completed writer run, completed `neal run` queue, or resume selection
323
365
  that was already done.
324
366
  - `1`: invalid CLI usage, missing setup or configuration, pre-run Git/worktree
325
- precondition failure, or another thrown error before Neal has a writer result.
367
+ precondition failure, or another thrown error before neal has a writer result.
326
368
  - `2`: controlled incomplete state: blocked, waiting for operator guidance,
327
369
  waiting for a manual gate, paused, already running under a live lock, or
328
370
  manual-gate resume checks still failing.
329
- - `3`: failed writer run or failed `neal run` queue after Neal has run
371
+ - `3`: failed writer run or failed `neal run` queue after neal has run
330
372
  state/result evidence.
331
373
 
332
374
  Use `neal status --json` for the stable detailed automation interface. `neal
333
375
  status` exits `0` when it successfully reports status, even if the reported run
334
376
  is blocked, paused, waiting for guidance, waiting for a manual gate, or failed.
335
377
 
336
- ## Terminal Output
378
+ ## Terminal output
337
379
 
338
380
  neal prints narrative-focused progress by default. The default stream says what the loop is doing at a human level, while raw provider detail, command output, session handles, and reviewer context are kept out of the normal terminal view.
339
381
 
340
382
  Interactive TTY writer runs accept live keys:
341
383
 
342
- - `q`: stop after the current scope
343
384
  - `v`: switch between narrative and low-level detail views
385
+ - `q`: stop after the current scope during execution (`neal execute` or the execution portion of `neal run`)
344
386
 
345
- The read-only long-running `neal review` command also supports the `v` detail toggle. Toggling views is process-local terminal state only; provider prompts, run state, resume behavior, artifacts, and command semantics stay unchanged.
387
+ The read-only long-running `neal review` command also supports the `v` detail toggle. Toggling views is process-local terminal state only. Provider prompts, run state, resume behavior, artifacts, and command semantics stay unchanged.
346
388
 
347
389
  Low-level detail is still persisted for debugging. Inspect `.neal/runs/<run-id>/stderr.log` and `.neal/runs/<run-id>/events.ndjson` for writer runs, or the corresponding review artifact directory for read-only review loops.
348
390
 
@@ -350,65 +392,15 @@ Low-level detail is still persisted for debugging. Inspect `.neal/runs/<run-id>/
350
392
 
351
393
  Config precedence is:
352
394
 
353
- 1. repo `config.yml`
395
+ 1. repo `neal.yml`
354
396
  2. `~/.neal/config.yml`
355
397
  3. built-in defaults
356
398
 
357
- Fresh writer-run commands require explicit `agent.coder.provider` and `agent.reviewer.provider` settings from either user or repo config. The built-in defaults remain for compatibility paths, but they are not enough to start new plan, execute, run, or check workflows. If either role is missing, neal reports the missing config key. Use `neal setup` for first-time provider/model defaults; edit YAML manually only when you need precise control.
399
+ Fresh writer-run commands require explicit `agent.coder.provider` and `agent.reviewer.provider` settings from either user or repo config. If either role is missing, neal reports the missing config key. Use `neal setup` for first-time provider/model defaults. Edit YAML manually when you need precise control.
358
400
 
359
- The checked-in [config.yml](config.yml) is a commented template. Machine-local overrides usually belong in `~/.neal/config.yml`.
360
-
361
- Manual writer-provider config shape:
362
-
363
- ```yaml
364
- agent:
365
- coder:
366
- provider: openai-codex
367
- model: null
368
- reviewer:
369
- provider: anthropic-claude
370
- model: null
371
- ```
401
+ This repository has a commented template [neal.yml](neal.yml).
372
402
 
373
- In that simple config, the effective planner role inherits the coder provider
374
- and model:
375
-
376
- ```yaml
377
- agent:
378
- planner:
379
- provider: openai-codex
380
- model: null
381
- coder:
382
- provider: openai-codex
383
- model: null
384
- reviewer:
385
- provider: anthropic-claude
386
- model: null
387
- ```
388
-
389
- `model: null` means "let the provider choose its default model." You can keep other settings, such as `neal.notify_bin`, in the same file. neal currently ships built-in writer-run adapters for OpenAI Codex and Anthropic Claude, plus two adapters for OpenAI-compatible Chat Completions endpoints: the reviewer-only `openai-compatible` adapter and the `generic-agentic` writer adapter, which runs the coder role through a neal-owned agentic loop and tool set and the reviewer role through a read-only subset of those tools. See [docs/providers.md](docs/providers.md) for the provider contract, capability checks, telemetry/error mapping, and testing checklist.
390
-
391
- The reviewer role can target an OpenAI-compatible endpoint with a `providers.openai_compatible` block (DeepSeek shown; config first, environment fallbacks `OPENAI_COMPATIBLE_BASE_URL`, `OPENAI_COMPATIBLE_API_KEY`, and `OPENAI_COMPATIBLE_MODEL`):
392
-
393
- ```yaml
394
- providers:
395
- openai_compatible:
396
- base_url: https://api.deepseek.com
397
- api_key_env: DEEPSEEK_API_KEY
398
- default_model: deepseek-chat
399
-
400
- agent:
401
- coder:
402
- provider: openai-codex
403
- model: null
404
- reviewer:
405
- provider: openai-compatible
406
- model: deepseek-chat
407
- ```
408
-
409
- `openai-compatible` is reviewer/structured-advisor only: coder or planner selection fails the capability check, it has no repository tool access (neal inlines diff and artifact context into reviewer prompts, so the reviewer cannot independently run verification), no session resume, and no `effort` support. Behavior, model quality, and rate limits vary by upstream provider.
410
-
411
- Advanced configs can override the planner independently:
403
+ You can configure the planner independently:
412
404
 
413
405
  ```yaml
414
406
  agent:
@@ -426,13 +418,11 @@ agent:
426
418
  Each role also accepts an optional `effort` reasoning-depth override. Omitting it
427
419
  or setting `effort: null` keeps the provider default. Supported values are
428
420
  `minimal, low, medium, high, xhigh` for `openai-codex` and
429
- `low, medium, high, xhigh, max` for `anthropic-claude`; an unsupported value is
430
- rejected before a run starts. Planner effort inheritance mirrors planner model
431
- inheritance: the planner inherits the coder effort only when
432
- `agent.planner.provider` is not configured explicitly and `agent.planner.effort`
433
- is omitted. When `agent.planner.provider` is set explicitly, an omitted
434
- `agent.planner.effort` resolves to the provider default (`null`), so set
435
- `agent.planner.effort` explicitly to override it.
421
+ `low, medium, high, xhigh, max` for `anthropic-claude`. An unsupported value is
422
+ rejected before a run starts. `openai-compatible` doesn't currently support an
423
+ effort override. Some compatible endpoints expose reasoning controls, but the
424
+ accepted values and behavior vary by endpoint and model, so neal leaves them at
425
+ the upstream default.
436
426
 
437
427
  ```yaml
438
428
  agent:
@@ -446,7 +436,7 @@ agent:
446
436
  effort: xhigh
447
437
  ```
448
438
 
449
- ### Custom Guidance
439
+ ### Custom guidance
450
440
 
451
441
  neal supports additive guidance files for local preferences alongside the built-in protocol prompts:
452
442
 
@@ -454,13 +444,17 @@ neal supports additive guidance files for local preferences alongside the built-
454
444
  - `~/.neal/guidance/reviewer.md`
455
445
  - `~/.neal/guidance/planner.md`
456
446
 
457
- Set `NEAL_GUIDANCE_DIR=/path/to/guidance` to load those same `coder.md`, `reviewer.md`, and `planner.md` files from another directory. neal records applied guidance roles, selected paths, and byte counts in run artifacts; guidance contents stay out of terminal output.
447
+ Set `NEAL_GUIDANCE_DIR=/path/to/guidance` to load those same `coder.md`, `reviewer.md`, and `planner.md` files from another directory. neal records applied guidance roles, selected paths, and byte counts in run artifacts. Guidance contents stay out of terminal output.
458
448
 
459
- ## Artifacts And Storage
449
+ ## Artifacts and storage
460
450
 
461
451
  Writer run artifacts live under `.neal/runs/<run-id>/`, including the original-plan backup at `.neal/runs/<run-id>/PLAN_ORIGINAL.md` and reviewer scratch space under `.neal/runs/<run-id>/scratch/`. Queue artifacts live under `.neal/queues/<queue-id>/`. Review findings artifacts live under `.neal/reviews/<review-id>/`.
462
452
 
463
- Reviewer scratch is for temporary verification artifacts, copied tests, scratch builds, logs, and modified throwaway files. Root-level scratch directories such as `build_review/` are still ordinary project-tree dirtiness and must be cleaned up by the operator or committed through the normal accepted-scope flow.
453
+ The run-local scratch directory is reserved for reviewer verification artifacts.
454
+ Current built-in reviewer prompts are read-only and do not use it. Root-level
455
+ scratch directories such as `build_review/` are still ordinary project-tree
456
+ dirtiness and must be cleaned up by the operator or committed through the normal
457
+ accepted-scope flow.
464
458
 
465
459
  Project-local `.neal/` is the source of truth for runs, queues, reviews, progress, and audit history. Keep `.neal/` ignored by Git. It may contain prompts, diffs, command output, local paths, provider responses, reviewer scratch files, copied tests, build logs, and project-specific context. Use `neal status --all` to discover run IDs, and use `--run <run-id>` to select a run for `resume` or `status`.
466
460
 
@@ -468,17 +462,16 @@ For what may (and may not) be published from a run as public automation or bench
468
462
 
469
463
  The storage layout, artifact classifications, run pointers, and retention guidance are documented in [docs/storage.md](docs/storage.md). Persisted run and queue state boundaries are documented in [docs/state-machine.md](docs/state-machine.md).
470
464
 
471
- ## Known Limitations
465
+ ## Known limitations
472
466
 
473
- - Writer providers currently run with broad local permissions. See [docs/providers.md](docs/providers.md) and Safety Notes for the current provider permission boundaries.
474
- - neal stores project-local artifacts under `.neal/`. Those artifacts may contain prompts, diffs, command output, paths, provider responses, and local context; see [docs/storage.md](docs/storage.md) for artifact retention and privacy details.
475
- - External provider plugins are future work.
476
- - Provider accounts and authentication come from local provider SDK/CLI sessions.
467
+ - Writer providers currently run with broad local permissions. See [docs/providers.md](docs/providers.md) and Safety notes for the current provider permission boundaries.
468
+ - neal stores project-local artifacts under `.neal/`. Those artifacts may contain prompts, diffs, command output, paths, provider responses, and local context. See [docs/storage.md](docs/storage.md) for artifact retention and privacy details.
477
469
 
478
- ## Plan Shape
470
+ ## Plan shape
479
471
 
480
472
  Every executable neal plan must declare exactly one execution shape in a literal `## Execution Shape` section.
481
- The full executable-plan format reference is [docs/plan-format.md](docs/plan-format.md).
473
+ The full executable-plan format reference is [docs/plan-format.md](docs/plan-format.md). In practice you can just
474
+ let neal format your plan into this shape.
482
475
 
483
476
  Use `executionShape: one_shot` when the full task can be implemented, reviewed, and verified as one bounded scope:
484
477
 
@@ -510,18 +503,22 @@ executionShape: multi_scope
510
503
 
511
504
  Use `executionShape: multi_scope_unknown` when the work repeats one bounded recurring slice at a time, but the total number of slices is intentionally unknown until a stop rule becomes true.
512
505
 
513
- ## Safety Notes
506
+ ## Safety notes
514
507
 
515
508
  Writer commands can edit files and create commits in the target repository. Run neal in a disposable checkout, branch, worktree, container, or VM when the repository or provider credentials are sensitive.
516
509
 
517
- Current writer providers run with broad local permissions. The OpenAI Codex provider is configured with `approvalPolicy: never` and `sandboxMode: danger-full-access`; the Claude provider uses `permissionMode: bypassPermissions`. Treat planner and coder providers as capable of modifying the checkout unless you have added external sandboxing. The reviewer role is read-only OS-sandboxed for the Codex reviewer, and enforced at the SDK/tool-wiring level for the others, so outside Codex the guarantee is only as strong as the adapter. Reviewers can also read files outside the repository unless the adapter jails reads (only `generic-agentic` does); see [SECURITY.md](SECURITY.md).
510
+ Current writer providers run with broad local permissions. The OpenAI Codex provider is configured with `approvalPolicy: never` and `sandboxMode: danger-full-access`. The Claude provider uses `permissionMode: bypassPermissions`. Treat planner and coder providers as capable of modifying the checkout unless you have added external sandboxing. The reviewer role is read-only: OS-sandboxed for the Codex reviewer, and enforced at the SDK/tool-wiring level for the others, so outside Codex the guarantee is only as strong as the adapter. Reviewers can also read files outside the repository unless the adapter jails reads (only `openai-compatible` does). See [SECURITY.md](SECURITY.md).
518
511
 
519
- `neal execute` and `neal run` can create commits and rewrite run-owned commits into a final squash commit by default. Squashed commit messages are semantic summaries of the implemented project change; plan provenance is kept in Neal artifacts instead of commit subjects, bullets, or trailers. Repo-local nonignored selected plan documents may be included in the run's final tree when they changed. Ignored, missing, non-file, or outside-repository plan documents are metadata-only and are not force-added. `neal squash` rewrites history for plan-owned commits after printing a preview and receiving interactive confirmation. Neal rejects finalization and squash attempts that would include files matching `.gitignore` rules, even if those files were force-added.
512
+ `neal execute` and `neal run` can create commits and rewrite run-owned commits into a final squash commit by default. Squashed commit messages are semantic summaries of the implemented project change. Plan provenance is kept in neal artifacts instead of commit subjects, bullets, or trailers. Repo-local nonignored selected plan documents may be included in the run's final tree when they changed. Ignored, missing, non-file, or outside-repository plan documents are metadata-only and are not force-added. `neal squash` rewrites history for plan-owned commits after printing a preview and receiving interactive confirmation. neal rejects finalization and squash attempts that would include files matching `.gitignore` rules, even if those files were force-added.
520
513
 
521
- Read-only commands are intentionally narrower: `neal status` and `neal review` skip the writer lock. `neal review` writes only review artifacts under `.neal/reviews/`.
514
+ Read-only commands are intentionally narrower: `neal status` and `neal review` skip the writer lock. `neal review` owns only the review artifacts under `.neal/reviews/` and fails if a provider changes anything else. It does not clean up a provider's worktree changes.
522
515
 
523
- Roles carry very different privilege: the coder role (and the inherited planner) executes shell commands and writes files with your privileges in the working directory, while the reviewer role is structurally read-only, enforced per provider adapter. Running an unknown or untrusted model in the coder role for example via `neal compat` against an arbitrary OpenAI-compatible / OpenRouter slug grants that model coder-level shell access, so run untrusted models inside a container or disposable sandbox. See [SECURITY.md](SECURITY.md) for the full trust model and how to report a suspected vulnerability.
516
+ Roles carry very different privilege: the coder role (and the inherited planner) executes shell commands and writes files with your privileges in the working directory, while the reviewer role is structurally read-only, enforced per provider adapter. Running an unknown or untrusted model in the coder role (for example via `neal compat` against an arbitrary OpenAI-compatible / OpenRouter slug) grants that model coder-level shell access, so run untrusted models inside a container or disposable sandbox. See [SECURITY.md](SECURITY.md) for the full trust model and how to report a suspected vulnerability.
524
517
 
525
518
  ## Notifications
526
519
 
527
- Notifications are opt-in. If `neal.notify_bin` is configured, neal runs that command with the notification text for `blocked`, `complete`, `done`, and `retry`. With no configured path, notifications stay disabled.
520
+ Notifications are opt-in. If `neal.notify_bin` is configured, neal runs that command with one notification-text argument for `blocked`, `complete`, `done`, and `retry`. Messages start with `[neal] <planName>:` followed by the reason or status. Blocked and interactive-recovery retry messages append `| consultant advice (read-only): triage <category>; suggested directive: <directive>` when consultant advice is available.
521
+
522
+ `NEAL_NOTIFY_BIN` overrides the configured command. Set it to another path to use that command, or set it to an empty value to disable notifications for the process. Notification command failures never fail or change the result of a run.
523
+
524
+ `neal check` reports the resolved notification command and, in an interactive terminal, can send a test notification after confirmation.