@navels/neal 0.1.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 (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +527 -0
  3. package/SECURITY.md +91 -0
  4. package/config.yml +104 -0
  5. package/dist/neal/activity-footer.js +177 -0
  6. package/dist/neal/activity-reporting.js +1 -0
  7. package/dist/neal/adjudicator/artifacts.js +58 -0
  8. package/dist/neal/adjudicator/blocked-adjudicator.js +223 -0
  9. package/dist/neal/adjudicator/contracts.js +139 -0
  10. package/dist/neal/adjudicator/execute.js +611 -0
  11. package/dist/neal/adjudicator/final-completion.js +104 -0
  12. package/dist/neal/adjudicator/planning.js +145 -0
  13. package/dist/neal/adjudicator/specs.js +453 -0
  14. package/dist/neal/agents/prompts.js +120 -0
  15. package/dist/neal/agents/rounds.js +706 -0
  16. package/dist/neal/agents/schemas.js +832 -0
  17. package/dist/neal/agents/structured-coder.js +82 -0
  18. package/dist/neal/agents/structured-json.js +528 -0
  19. package/dist/neal/agents.js +4 -0
  20. package/dist/neal/atomic-write.js +18 -0
  21. package/dist/neal/blocked-guidance.js +406 -0
  22. package/dist/neal/cli.js +471 -0
  23. package/dist/neal/commands/check.js +401 -0
  24. package/dist/neal/commands/compat.js +807 -0
  25. package/dist/neal/commands/interactive-activity.js +57 -0
  26. package/dist/neal/commands/new-run.js +79 -0
  27. package/dist/neal/commands/plan-and-execute.js +44 -0
  28. package/dist/neal/commands/recovery-guidance.js +217 -0
  29. package/dist/neal/commands/resume-run.js +395 -0
  30. package/dist/neal/commands/review.js +21 -0
  31. package/dist/neal/commands/runtime.js +557 -0
  32. package/dist/neal/commands/setup.js +596 -0
  33. package/dist/neal/commands/squash.js +113 -0
  34. package/dist/neal/commands/status.js +33 -0
  35. package/dist/neal/commands/writer-exit-codes.js +42 -0
  36. package/dist/neal/commit-message.js +17 -0
  37. package/dist/neal/config.js +432 -0
  38. package/dist/neal/context/artifacts.js +140 -0
  39. package/dist/neal/context/context.js +324 -0
  40. package/dist/neal/context/inline-review-context.js +131 -0
  41. package/dist/neal/context/reviewer-context.js +166 -0
  42. package/dist/neal/context/shared.js +117 -0
  43. package/dist/neal/context/types.js +1 -0
  44. package/dist/neal/diagnostic.js +208 -0
  45. package/dist/neal/execute-finalization.js +5 -0
  46. package/dist/neal/final-completion-review.js +188 -0
  47. package/dist/neal/final-completion.js +229 -0
  48. package/dist/neal/git.js +339 -0
  49. package/dist/neal/index.js +135 -0
  50. package/dist/neal/interactive-controls.js +85 -0
  51. package/dist/neal/logger.js +102 -0
  52. package/dist/neal/manual-gates.js +121 -0
  53. package/dist/neal/orchestrator/artifacts.js +70 -0
  54. package/dist/neal/orchestrator/completion.js +531 -0
  55. package/dist/neal/orchestrator/failures.js +31 -0
  56. package/dist/neal/orchestrator/notifications.js +175 -0
  57. package/dist/neal/orchestrator/phases/coder.js +516 -0
  58. package/dist/neal/orchestrator/phases/planning.js +540 -0
  59. package/dist/neal/orchestrator/phases/recovery.js +798 -0
  60. package/dist/neal/orchestrator/phases/review.js +136 -0
  61. package/dist/neal/orchestrator/phases/shared.js +279 -0
  62. package/dist/neal/orchestrator/run-loop.js +113 -0
  63. package/dist/neal/orchestrator/split-plan.js +235 -0
  64. package/dist/neal/orchestrator/transitions.js +309 -0
  65. package/dist/neal/orchestrator.js +215 -0
  66. package/dist/neal/phase-display.js +27 -0
  67. package/dist/neal/plan-doc.js +154 -0
  68. package/dist/neal/plan-queue.js +1092 -0
  69. package/dist/neal/plan-refinement.js +39 -0
  70. package/dist/neal/plan-validation.js +525 -0
  71. package/dist/neal/progress.js +237 -0
  72. package/dist/neal/prompts/assert-builder.js +13 -0
  73. package/dist/neal/prompts/execute.js +290 -0
  74. package/dist/neal/prompts/guidance.js +70 -0
  75. package/dist/neal/prompts/planning.js +313 -0
  76. package/dist/neal/prompts/review-doctrine.js +142 -0
  77. package/dist/neal/prompts/shared.js +101 -0
  78. package/dist/neal/prompts/specialized.js +212 -0
  79. package/dist/neal/prompts/specs.js +572 -0
  80. package/dist/neal/providers/anthropic-claude.js +1599 -0
  81. package/dist/neal/providers/detection.js +139 -0
  82. package/dist/neal/providers/generic-agentic-tools.js +586 -0
  83. package/dist/neal/providers/generic-agentic.js +1238 -0
  84. package/dist/neal/providers/liveness.js +151 -0
  85. package/dist/neal/providers/openai-codex.js +1014 -0
  86. package/dist/neal/providers/openai-compatible.js +654 -0
  87. package/dist/neal/providers/registry.js +389 -0
  88. package/dist/neal/providers/telemetry.js +208 -0
  89. package/dist/neal/providers/types.js +21 -0
  90. package/dist/neal/recovery-artifacts.js +50 -0
  91. package/dist/neal/resume-decision.js +220 -0
  92. package/dist/neal/resume-planner.js +265 -0
  93. package/dist/neal/retrospective.js +391 -0
  94. package/dist/neal/review-debt.js +18 -0
  95. package/dist/neal/review-findings/artifacts.js +173 -0
  96. package/dist/neal/review-findings/prompts.js +172 -0
  97. package/dist/neal/review-findings/provider.js +330 -0
  98. package/dist/neal/review-findings/run.js +373 -0
  99. package/dist/neal/review-findings/types.js +1 -0
  100. package/dist/neal/review-mode.js +67 -0
  101. package/dist/neal/review.js +137 -0
  102. package/dist/neal/run-lock.js +334 -0
  103. package/dist/neal/run-metrics.js +355 -0
  104. package/dist/neal/run-narrative-types.js +1 -0
  105. package/dist/neal/run-narrative.js +1374 -0
  106. package/dist/neal/run-registry.js +218 -0
  107. package/dist/neal/run-status.js +25 -0
  108. package/dist/neal/scopes.js +451 -0
  109. package/dist/neal/sensitive-text.js +8 -0
  110. package/dist/neal/squash-message.js +379 -0
  111. package/dist/neal/squash.js +591 -0
  112. package/dist/neal/state-invariants.js +496 -0
  113. package/dist/neal/state-views.js +344 -0
  114. package/dist/neal/state.js +887 -0
  115. package/dist/neal/status-footer.js +258 -0
  116. package/dist/neal/status.js +1260 -0
  117. package/dist/neal/storage-paths.js +57 -0
  118. package/dist/neal/support.js +58 -0
  119. package/dist/neal/terminal-narrator.js +435 -0
  120. package/dist/neal/types.js +1 -0
  121. package/dist/neal/verification-events.js +81 -0
  122. package/dist/neal/version.js +37 -0
  123. package/dist/neal/worktree-status.js +137 -0
  124. package/dist/notifier.js +44 -0
  125. package/docs/ADJUDICATOR_INVENTORY.md +310 -0
  126. package/docs/PROMPT_SPECS.md +266 -0
  127. package/docs/README.md +22 -0
  128. package/docs/architecture.md +113 -0
  129. package/docs/assets/neal-execution-flow.png +0 -0
  130. package/docs/automation.md +65 -0
  131. package/docs/comparison.md +105 -0
  132. package/docs/compat.md +269 -0
  133. package/docs/compatible-models.md +135 -0
  134. package/docs/demo.md +55 -0
  135. package/docs/maintenance.md +64 -0
  136. package/docs/plan-format.md +213 -0
  137. package/docs/providers.md +751 -0
  138. package/docs/release.md +147 -0
  139. package/docs/state-machine.md +266 -0
  140. package/docs/storage.md +207 -0
  141. package/docs/troubleshooting.md +152 -0
  142. package/examples/compat/add-edit-verify/PLAN.md +29 -0
  143. package/examples/compat/add-edit-verify/broken.diff +8 -0
  144. package/examples/compat/add-edit-verify/good.diff +8 -0
  145. package/examples/compat/add-edit-verify/package.json +5 -0
  146. package/examples/compat/add-edit-verify/src/add.js +2 -0
  147. package/examples/compat/add-edit-verify/test/add.test.js +9 -0
  148. package/examples/compat/is-even-add-test/PLAN.md +30 -0
  149. package/examples/compat/is-even-add-test/broken.diff +11 -0
  150. package/examples/compat/is-even-add-test/good.diff +11 -0
  151. package/examples/compat/is-even-add-test/package.json +5 -0
  152. package/examples/compat/is-even-add-test/src/is-even.js +3 -0
  153. package/examples/compat/is-even-add-test/test/is-even.test.js +9 -0
  154. package/examples/compat/manifest.json +60 -0
  155. package/examples/compat/plan-greeting/ISSUE.md +25 -0
  156. package/examples/compat/plan-greeting/package.json +5 -0
  157. package/examples/compat/plan-greeting/src/greet.js +2 -0
  158. package/examples/compat/plan-greeting/test/greet.test.js +8 -0
  159. package/examples/compat/reverse-grep-edit/PLAN.md +32 -0
  160. package/examples/compat/reverse-grep-edit/broken.diff +12 -0
  161. package/examples/compat/reverse-grep-edit/good.diff +12 -0
  162. package/examples/compat/reverse-grep-edit/package.json +5 -0
  163. package/examples/compat/reverse-grep-edit/src/strings.js +10 -0
  164. package/examples/compat/reverse-grep-edit/test/strings.test.js +15 -0
  165. package/examples/issue-triage-js/PLAN.md +83 -0
  166. package/examples/issue-triage-js/README.md +76 -0
  167. package/examples/issue-triage-js/package.json +9 -0
  168. package/examples/issue-triage-js/src/issue-triage.js +87 -0
  169. package/examples/issue-triage-js/test/issue-triage.test.js +107 -0
  170. package/package.json +70 -0
@@ -0,0 +1,266 @@
1
+ # Neal Prompt Specs Inventory
2
+
3
+ ## Scope
4
+
5
+ This document is the current prompt-spec inventory for Neal's recurring
6
+ engineering roles/tasks.
7
+
8
+ - The prompt-spec contract and registry live in
9
+ [src/neal/prompts/specs.ts](../src/neal/prompts/specs.ts).
10
+ - Concrete prompt builders live in `src/neal/prompts/planning.ts`,
11
+ `src/neal/prompts/execute.ts`, and `src/neal/prompts/specialized.ts`, with
12
+ shared plan-contract and marker lines in `src/neal/prompts/shared.ts`.
13
+ - The interactive blocked-recovery and blocked-adjudicator prompt builders live
14
+ in `src/neal/agents/prompts.ts` (which otherwise re-exports the
15
+ `src/neal/prompts/` builders).
16
+ - Schema builders, object validators, and retained compatibility parsers live
17
+ in `src/neal/agents/schemas.ts`.
18
+ - Round sequencing lives in `src/neal/agents/rounds.ts`.
19
+
20
+ Reviewer prompt surfaces share a doctrine helper in
21
+ [src/neal/prompts/review-doctrine.ts](../src/neal/prompts/review-doctrine.ts).
22
+ That helper owns adversarial posture, falsification, verification skepticism,
23
+ regression-preservation, the pre-existing-failure acceptance-surface contract,
24
+ finding-quality wording, and the three-way reviewer access mode
25
+ (`tool-access` / `read-only` / `no-read`). It does not own schemas, provider
26
+ selection, adjudication, or transition behavior. Its consumers are
27
+ execute-scope review, plan review, and final completion review; the read-only
28
+ `neal review` findings loop uses its own prompts in
29
+ `src/neal/review-findings/prompts.ts`.
30
+
31
+ ## Ownership Boundary
32
+
33
+ Prompt specs live under `src/neal/prompts/`.
34
+
35
+ That boundary is deliberate: the adjudicator owns loop mechanics, not prompt
36
+ ownership. Keeping prompt specs in `src/neal/prompts/` avoids baking them back
37
+ into `src/neal/agents/rounds.ts` and avoids putting prompt semantics inside the
38
+ adjudicator package.
39
+
40
+ Concrete split:
41
+
42
+ - prompt-spec library owns role/task prompt identity, required context, schema linkage, and provider-variant metadata
43
+ - adjudicator / round runner owns coder-reviewer sequencing, retries, convergence, and transition hooks
44
+ - transitions own finalization, adoption, blocked-recovery routing, and commit semantics
45
+
46
+ ## Inventory
47
+
48
+ ### Registered Prompt Specs
49
+
50
+ All schema targets are `structured_json` with provider surface
51
+ `neal_json_block_protocol` — the prompt-spec metadata name for the runtime
52
+ `neal-json-block-v1` JSON-block transport that providers validate locally.
53
+
54
+ | Prompt spec id | Current builder(s) | Current round entrypoints | Schema target | Notes |
55
+ | --- | --- | --- | --- | --- |
56
+ | `plan_author` | `buildPlanningPrompt`, `buildCoderPlanResponsePrompt` (`reviewMode=plan`, `reviewMode=derived-plan`) | `runCoderPlanRound`, `runCoderPlanResponseRound` | Primary planning: `buildCoderPlanSchema` / `validateCoderPlanPayload`; response rounds: `buildCoderPlanResponseSchema` / `validateCoderPlanResponsePayload` | Primary planning routes new/resumed structured sessions by persisted `plannerSessionProtocol`; legacy marker parsing is retained only for active `legacy_marker_v1` sessions. |
57
+ | `plan_reviewer` | `buildPlanReviewerPrompt` (`mode=plan`, `mode=derived-plan`) | `runPlanReviewerRound` | `buildPlanReviewerSchema` / `PlanReviewerPayload` | Execution-shape confirmation is part of the contract. Shares skeptical doctrine without becoming implementation diff review. |
58
+ | `scope_coder` | `buildScopePrompt`, `buildCoderResponsePrompt` | `runCoderScopeRound`, `runCoderResponseRound` | Primary execution: `buildCoderScopeSchema` / `validateCoderScopePayload`; response rounds: `buildCoderResponseSchema` / `validateCoderResponsePayload` | Primary execution routes new/resumed structured sessions by persisted `coderSessionProtocol`; legacy marker and progress-payload parsing is retained only for active `legacy_marker_v1` sessions. Also carries an `adjacent`-status blocked-recovery `response` variant (see below). |
59
+ | `scope_reviewer` | `buildReviewerPrompt` | `runReviewerRound` | `buildReviewerSchema` / `ReviewerPayload` | Execute-scope review only; `neal review` external ranges use the separate read-only review-findings loop. Meaningful-progress remains a capability variant of `scope_reviewer`, not a new top-level id. Reviewer prompts include a run-local `scratchDir` requirement for temporary verification artifacts. |
60
+ | `completion_coder` | `buildFinalCompletionSummaryPrompt` | `runCoderFinalCompletionSummaryRound` | `buildFinalCompletionSummarySchema` / `parseFinalCompletionSummaryPayload` | Structured advisor round, but still a coder-owned role/task. The completion packet includes aggregate review context when Neal can compute it. |
61
+ | `completion_reviewer` | `buildFinalCompletionReviewerPrompt` | `runReviewerFinalCompletionRound` | `buildFinalCompletionReviewerSchema` / `parseFinalCompletionReviewerPayload` | Whole-plan aggregate review remains distinct from ordinary scope review and keeps its final-completion verdict schema. Reviewer prompts include a run-local `scratchDir` requirement for temporary verification artifacts. |
62
+
63
+ ### Adjacent Current Prompt Surfaces
64
+
65
+ These prompts are real but are not separate top-level prompt-spec ids:
66
+
67
+ | Current builder | Registry status | Schema target | Why not a top-level id |
68
+ | --- | --- | --- | --- |
69
+ | `buildBlockedRecoveryCoderPrompt` (`src/neal/agents/prompts.ts`) | Registered as a `scope_coder` `response` variant with status `adjacent` | `buildCoderBlockedRecoveryDispositionSchema` / `validateCoderBlockedRecoveryDispositionPayload` | It is still the same execute-scope owner responding inside blocked recovery. |
70
+ | `buildBlockedAdjudicatorPrompt` (`src/neal/agents/prompts.ts`) | Not in the prompt-spec registry today; a future change may register it | `buildBlockedAdjudicatorSchema` / `validateBlockedAdjudicatorVerdictPayload` via `runBlockedAdjudicatorRound` | Single no-read-safe variant for the read-only blocked adjudicator; it judges entirely from Neal-inlined context and its static instructions pass the shared no-read guard. |
71
+ | `buildReviewFindingsDraftPrompt`, `buildReviewFindingsReviewPrompt` (`src/neal/review-findings/prompts.ts`) | Not in the prompt-spec registry | `ReviewFindingsDraft` / `ReviewFindingsReview` payloads | Read-only `neal review` findings loop with its own draft/review prompts and read-only rules. |
72
+
73
+ ## Contract Expectations
74
+
75
+ Each prompt spec in `src/neal/prompts/specs.ts` makes these fields explicit:
76
+
77
+ - `id`
78
+ - `role`
79
+ - `purpose`
80
+ - `requiredContext`
81
+ - `schemaTarget`
82
+ - `baseInstructions`
83
+ - `providerVariants`
84
+ - `evaluationNotes`
85
+ - `firstMigrationPriority`
86
+ - `currentHome`
87
+ - `ownershipNotes`
88
+ - `variants`
89
+
90
+ Three implementation details are intentionally concrete:
91
+
92
+ 1. `baseInstructions` names the current prompt-builder function and its explicit input shape.
93
+ 2. `requiredContext` lists the exact context keys the prompt assumes, including artifact and repository inputs that are not always passed as one raw function argument today.
94
+ 3. `schemaTarget` names the concrete schema builder plus validator/parser surface.
95
+
96
+ That keeps prompt specs reviewable as contracts rather than as scattered string literals.
97
+
98
+ ## Prompt-Spec Wiring
99
+
100
+ Prompt specs are not the whole execution loop. They are the prompt-facing contract layer that tells Neal which role/task is being performed, what context that role/task assumes, and which output contract the result must satisfy.
101
+
102
+ That wiring is intentionally split across a few modules:
103
+
104
+ - `src/neal/prompts/specs.ts` owns prompt-spec identity, required-context contracts, schema linkage metadata, and provider-variant policy.
105
+ - `src/neal/prompts/review-doctrine.ts` owns shared reviewer posture for execute-scope review, plan review, and final completion review.
106
+ - `src/neal/prompts/*.ts` owns the concrete prompt builders that render instructions for planning, execute-mode, and specialized flows.
107
+ - `src/neal/agents/schemas.ts` owns the actual schema builders plus validators or retained parsers named by each spec's `schemaTarget`.
108
+ - `src/neal/agents/rounds.ts` owns round execution and parsing against those schemas.
109
+ - `src/neal/adjudicator/*.ts` owns the adjudication specs that reference prompt surfaces by `(promptSpecId, variantKind, exportName)` (see [ADJUDICATOR_INVENTORY.md](ADJUDICATOR_INVENTORY.md)).
110
+ - `src/neal/orchestrator.ts` and `src/neal/orchestrator/*.ts` own phase transitions, adoption/finalization semantics, blocked-recovery routing, and commit consequences.
111
+
112
+ That split is deliberate. A prompt spec is incomplete without explicit schema linkage, but it also must not absorb sequencing or state-transition semantics that belong to the orchestrator.
113
+
114
+ ### Context Assembly Rules
115
+
116
+ `requiredContext` should be read as a contract for context assembly, not just documentation for a prompt author.
117
+
118
+ When adding or changing a prompt spec:
119
+
120
+ 1. Every required field in `requiredContext` should have one clear source such as a prompt argument, persisted run artifact, review history packet, repository-state query, orchestrator-state field, or operator input.
121
+ 2. The corresponding prompt builder in `src/neal/prompts/*.ts` should either accept that data directly or assemble it from a narrowly-scoped helper. Do not hide major context dependencies inside unrelated utilities.
122
+ 3. If a prompt needs new state, artifact, or repository-derived context, add that dependency at the owning layer first and then link it from the spec. Do not document impossible context.
123
+ 4. If a field is only used in a variant, keep that distinction explicit in the variant contract instead of pretending it is universally required.
124
+ 5. Variant `inputShape` keys must stay a subset of the spec's top-level `requiredContext` keys. Neal validates that contract at module load so prompt-spec drift fails fast in tests and at startup.
125
+
126
+ Final completion has one additional context assembly rule: `buildFinalCompletionPacket()` includes `aggregateReviewContext` for the whole implementation range from `initialBaseCommit` to the resolved final commit. When the range can be read, the packet carries commit subjects, diff stat, and changed files; when it cannot, it carries an explicit `unavailableReason` so the reviewer treats the missing aggregate range as evidence to consider instead of silently accepting completion.
127
+
128
+ Execute-scope and final-completion reviewer prompts also receive a deterministic run-local `scratchDir` under `.neal/runs/<run-id>/scratch/`. Reviewers are instructed to use it for temporary verification artifacts, copied tests, scratch builds, logs, and modified throwaway files, and not to create project-root scratch directories such as `build_review/` or leave project-tree scratch files behind.
129
+
130
+ The goal is for reviewers to be able to answer two questions quickly:
131
+
132
+ - "What does this prompt assume is available?"
133
+ - "Where does Neal actually get that data?"
134
+
135
+ ### Schema-Linkage Rules
136
+
137
+ `schemaTarget` exists so prompt changes remain coupled to the concrete validator or retained parser surface they must satisfy.
138
+
139
+ The `PromptSchemaTarget` type admits two kinds:
140
+
141
+ - `structured_json` means the prompt must remain aligned with a named schema builder and validator or retained object parser in `src/neal/agents/schemas.ts`, delivered through the `neal-json-block-v1` transport.
142
+ - `terminal_marker` means a legacy prompt is governed by a plain-text final-line protocol. It remains in the type, but no current spec or variant declares it — every current schema target is `structured_json`.
143
+
144
+ For coder-owned decisions, `structured_json` maps to
145
+ `CoderAdapter.runStructuredPrompt()` via the shared structured-coder helper.
146
+ `runPrompt(..., outputSchema)` is retained as raw provider compatibility
147
+ outside Neal product control paths; it is not the prompt-spec surface for
148
+ Neal-owned coder decisions. The retained terminal-marker and progress-payload
149
+ parsers exist only for active `legacy_marker_v1` primary sessions loaded from
150
+ older run state.
151
+
152
+ If a prompt change would force validator or retained parser behavior to change, treat that as a contract change and review the prompt spec, prompt builder, schema builder, and tests together.
153
+
154
+ ## Provider Variants
155
+
156
+ Provider-specific variants are allowed, but they are not the default escape hatch. Each spec declares `providerVariants` for `shared` (status `default`) plus `openai-codex` and `anthropic-claude` (status `reserved_for_justified_divergence`).
157
+
158
+ Use a provider-specific override only when at least one of these is true:
159
+
160
+ - deterministic fixture coverage shows shared wording is ambiguous or misleading for one provider
161
+ - the provider API exposes a materially different structured-output surface that the prompt must acknowledge
162
+ - the same shared wording repeatedly causes provider-specific failure modes that cannot be handled in adapter code alone
163
+
164
+ Do not add provider-specific variants merely because:
165
+
166
+ - one provider is stylistically different
167
+ - a wording preference is subjective
168
+ - a single anecdotal run felt better with custom phrasing
169
+
170
+ Before introducing divergence, prefer this order:
171
+
172
+ 1. tighten the shared prompt wording
173
+ 2. tighten schema or parser validation
174
+ 3. localize provider-surface differences in the provider adapters
175
+ 4. add a prompt-spec provider variant only if the role/task instructions genuinely need to differ
176
+
177
+ When a provider-specific variant is added, record why the shared wording was insufficient and which fixture or failure evidence justified the fork.
178
+
179
+ The `neal-json-block-v1` JSON-block transport is intentionally an adapter
180
+ concern, not a prompt-spec variant: the shared prompt builders own review
181
+ substance, schema linkage, and meaningful-progress semantics, while provider
182
+ adapters own the local control-block transport instructions so providers
183
+ return prose plus a final `neal-json` block that Neal validates locally.
184
+
185
+ ## Adjudicator Alignment
186
+
187
+ Adjudication specs in `src/neal/adjudicator/specs.ts` reference prompt surfaces by `(promptSpecId, variantKind, exportName)`, and that linkage is validated at import time against the prompt-spec registry. The relationship is:
188
+
189
+ - prompt specs define the coder/reviewer role/task contracts that adjudication specs reference
190
+ - adjudication specs define which coder prompt, reviewer prompt, schemas, artifact/context packet, and convergence rule belong to a loop
191
+ - the adjudicator helpers own loop mechanics such as round invocation and settled-vs-revise synthesis
192
+ - execute and plan transitions own operational meaning such as adoption, blocked recovery, replacement, and finalization
193
+
194
+ That means prompt specs stay separate from:
195
+
196
+ - phase transitions
197
+ - success/block routing
198
+ - commit/finalization semantics
199
+ - operator-adoption policy
200
+
201
+ Three current role/task boundaries matter especially:
202
+
203
+ - `scope_reviewer` keeps meaningful-progress as a capability variant, not a separate top-level prompt id
204
+ - `scope_reviewer` and `completion_reviewer` share adversarial doctrine, but they keep separate schemas and adjudication families
205
+ - `completion_reviewer` is plan-review-adjacent in the adjudicator family mapping, but its execute-mode completion transitions remain outside prompt ownership
206
+
207
+ ## Adding Or Extending Prompt Specs
208
+
209
+ Add prompt specs in a disciplined order:
210
+
211
+ 1. Confirm the feature is a recurring role/task surface rather than a one-off continuation inside an existing role. If it is only a bounded continuation, prefer a variant on an existing spec.
212
+ 2. Add or update the prompt spec in `src/neal/prompts/specs.ts` with explicit `requiredContext`, `schemaTarget`, `baseInstructions`, and ownership notes.
213
+ 3. Implement or update the concrete prompt builder in the relevant `src/neal/prompts/*.ts` module.
214
+ 4. Keep schema linkage explicit by adding or updating the corresponding schema builder and validator/parser surface in `src/neal/agents/schemas.ts` when structured control output is required.
215
+ 5. Add or update deterministic fixtures and prompt-render assertions under `test/fixtures/prompts/` and the prompt-spec regression tests.
216
+ 6. Only after the prompt contract is stable should adjudicator work decide whether the new surface deserves its own adjudication spec or reuses an existing loop family.
217
+
218
+ Use a new top-level `PromptSpecId` only when the role/task is genuinely distinct in at least one of these ways:
219
+
220
+ - it has its own durable artifact or output contract
221
+ - it has a materially different required-context packet
222
+ - it is expected to recur as an independently understandable Neal surface
223
+
224
+ Otherwise prefer a variant such as `response`, `derived_plan`, `meaningful_progress`, or `final_completion`.
225
+
226
+ ## Testing
227
+
228
+ Deterministic prompt regression coverage has three fixture layers:
229
+
230
+ - prompt-render assertions for required sections and invariants
231
+ - inventory assertions that every curated role/task still points at explicit builders and schema targets
232
+ - fixture inputs for known ambiguity cases such as execution-shape declaration and meaningful-progress review
233
+
234
+ Current coverage:
235
+
236
+ - planning prompts have dedicated JSON fixtures under `test/fixtures/prompts/planning/`
237
+ - execute and completion prompts have deterministic fixture coverage under `test/fixtures/prompts/execute/` and `test/fixtures/prompts/specialized/`
238
+ - completion fixtures and render assertions pin aggregate range review, cross-scope invariant review, happy-path reachability, mocked-risk skepticism, and concrete completion-blocking issue quality
239
+ - inventory assertions in `test/review.test.ts` pin module ownership, schema targets, and current-home metadata
240
+
241
+ The blocked-recovery prompt is covered by the same additive guidance model as its owning coder role; the blocked-adjudicator prompt takes no guidance injection (see below).
242
+
243
+ ## User Guidance Injection
244
+
245
+ Users can layer their own guidance onto Neal's built-in coder, reviewer, and planner prompts without forking the prompt source. The injection surface is deliberately additive: built-in sections still own structured coder envelopes, retained legacy terminal-marker compatibility, reviewer verdict JSON schemas, and the canonical plan contract.
246
+
247
+ Guidance files (all optional):
248
+
249
+ - `~/.neal/guidance/coder.md` — injected into scope coder (including the retained legacy variant), scope response, interactive blocked recovery, and final completion summary prompts
250
+ - `~/.neal/guidance/reviewer.md` — injected into scope reviewer, plan reviewer, and final completion reviewer prompts
251
+ - `~/.neal/guidance/planner.md` — injected into plan author (including the retained legacy variant) and plan response prompts
252
+
253
+ The blocked-adjudicator prompt and the `neal review` findings prompts take no guidance injection.
254
+
255
+ By default Neal reads those files from `~/.neal/guidance/`. For each role, a
256
+ missing or whitespace-only `~/.neal/guidance/<role>.md` file is a no-op. Set
257
+ `NEAL_GUIDANCE_DIR` to point at another directory with the same file names for
258
+ testing or profile experiments; that override wins over the default directory.
259
+
260
+ When present, the file contents are appended under a fixed `## User Guidance` section inside the built-in prompt; structured output contracts, completion markers, and the canonical plan contract survive injection.
261
+
262
+ Diagnostics: when a Neal writer run initializes or resumes, it logs which roles have guidance applied and the byte count to the run's `stderr.log` and as a `run.user_guidance_applied` / `run.user_guidance_scanned` event. That is enough to confirm a guidance file was picked up without dumping contents.
263
+
264
+ Non-goals: no repo-local `.neal/guidance/` override, no full-prompt replacement, no per-scope guidance variants, and no substitution of built-in sections.
265
+
266
+ The module lives in [src/neal/prompts/guidance.ts](../src/neal/prompts/guidance.ts). Tests in [test/user-guidance.test.ts](../test/user-guidance.test.ts) cover default-directory loading, the `NEAL_GUIDANCE_DIR` override, empty-file no-op, injection into coder/reviewer/planner and blocked-recovery prompts, additive injection (structured actions and the plan contract survive), and guidance diagnostics.
package/docs/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # Neal Docs
2
+
3
+ These docs are current product and implementation references, not an archive of
4
+ historical implementation plans.
5
+
6
+ - [architecture.md](architecture.md): one-page map of how neal is built — **start here**
7
+ - [providers.md](providers.md): built-in provider adapter contract and extension checklist
8
+ - [maintenance.md](maintenance.md): dependency-update and versioning policy
9
+ - [compat.md](compat.md): `neal compat` model-compatibility smoke test (PASS/FAIL per model/role)
10
+ - [compatible-models.md](compatible-models.md): dated whitelist of `neal compat`-verified models
11
+ - [plan-format.md](plan-format.md): executable plan shapes, normalization, and selected-plan Git behavior
12
+ - [storage.md](storage.md): project-local `.neal/` storage contract and artifact classes
13
+ - [release.md](release.md): manual release process, versioning, and SDK-update policy
14
+ - [demo.md](demo.md): safe `asciinema` terminal demo recording workflow
15
+ - [state-machine.md](state-machine.md): persisted run and queue state invariants
16
+ - [PROMPT_SPECS.md](PROMPT_SPECS.md): prompt-spec inventory and ownership boundaries
17
+ - [ADJUDICATOR_INVENTORY.md](ADJUDICATOR_INVENTORY.md): shared coder/reviewer loop inventory
18
+ - [../examples/issue-triage-js/README.md](../examples/issue-triage-js/README.md): dependency-free in-repo example
19
+ for local testing and an optional live Neal run
20
+
21
+ The public README carries the user-facing workflow. Keep docs here focused on
22
+ contracts that help maintain or extend Neal.
@@ -0,0 +1,113 @@
1
+ # Architecture
2
+
3
+ A one-page map of how neal is built. The deep contracts live in the linked docs;
4
+ this page is the synthesis — how the run loop, the persisted state, the provider
5
+ registry, and the prompt layer fit together.
6
+
7
+ ```
8
+ plan.md
9
+
10
+ ┌─────▼─────────────────────────────────────────────┐
11
+ │ Orchestrator (src/neal/orchestrator.ts + phases/) │
12
+ │ │
13
+ │ plan refinement ─▶ per-scope coder/reviewer loop │
14
+ │ │ │ │
15
+ │ │ ├─ split-plan (subdivide)
16
+ │ │ └─ blocked recovery (adjudicated)
17
+ │ ▼ ▼ │
18
+ │ final-completion review ─▶ squash │
19
+ └───────┬─────────────────────────┬───────────────────┘
20
+ │ │
21
+ roles ◀──────┤ ├──────▶ persisted state
22
+ Provider │ │ .neal/ ledgers
23
+ registry ▼ ▼ (run + queue)
24
+ (planner / coder / reviewer) prompt specs + structured rounds
25
+ ```
26
+
27
+ ## 1. The run loop (orchestrator)
28
+
29
+ `src/neal/orchestrator.ts` drives a deterministic state machine over a plan
30
+ document. The phases live in `src/neal/orchestrator/phases/`:
31
+
32
+ - **planning** — refines the authored plan into an executable shape
33
+ (`plan-refinement.ts`, `plan-validation.ts`; see
34
+ [plan-format.md](plan-format.md)) through its own planner/reviewer loop.
35
+ - **coder** — runs one scope with the coder role from a fresh context, then
36
+ commits.
37
+ - **review** — hands the committed diff to the read-only reviewer role; findings
38
+ route back to the coder until accepted.
39
+ - **recovery** — interactive/unattended blocked recovery is the single chokepoint
40
+ every block class funnels through, fronted by a bounded, read-only **blocked
41
+ adjudicator** (`adjudicator/blocked-adjudicator.ts`) that triages coder-blocked
42
+ signals, reviewer `review_stuck` deadlocks, and the split-plan invalid-payload
43
+ block. Under unattended runs it autonomously resolves a narrow recoverable class
44
+ (and escalates genuine walls); under attended runs it surfaces its verdict as
45
+ advice and yields.
46
+
47
+ After every scope is accepted, a **final-completion review**
48
+ (`final-completion-review.ts`) checks the whole plan, then neal squashes the run
49
+ into a clean commit range.
50
+
51
+ ## 2. State and persistence
52
+
53
+ Every run is **crash-safe and resumable** because all state is persisted under
54
+ the project-local `.neal/` directory ([storage.md](storage.md)) via atomic writes
55
+ (`atomic-write.ts`). Two ledgers:
56
+
57
+ - **Run state** (`RUN_STATE.json`) — the phase/status state machine for a single
58
+ run, with documented invariants ([state-machine.md](state-machine.md)).
59
+ - **Plan queue** (`plan-queue.ts`) — the ordered set of scopes and their
60
+ completion.
61
+
62
+ `neal resume` (`resume-decision.ts`, `resume-planner.ts`) reconstructs an
63
+ interrupted run from these ledgers — which is why a killed process never loses
64
+ committed work. A per-run lock (`run-lock.ts`) prevents concurrent runs from
65
+ colliding.
66
+
67
+ ## 3. Providers and roles
68
+
69
+ The three roles — planner, coder, reviewer — are bound to providers
70
+ independently, so you can run different vendors/models per role. The provider
71
+ **registry** (`src/neal/providers/registry.ts`) is where capabilities are
72
+ declared and **enforced**:
73
+
74
+ - **Native adapters:** `openai-codex` and `anthropic-claude` wrap the vendors'
75
+ agentic SDKs (which own their tool loop and sandbox).
76
+ - **`generic-agentic`:** a neal-owned agentic loop over any OpenAI-compatible /
77
+ OpenRouter model, with a jailed tool surface
78
+ (`providers/generic-agentic-tools.ts`).
79
+
80
+ The key invariant: **the reviewer role is read-only by construction.** Every
81
+ provider definition is checked at registration
82
+ (`assertStructuredAdvisorReadOnly`) to declare `write:false, shell:false` for its
83
+ structured-advisor (reviewer) capability — so a reviewer structurally cannot
84
+ mutate the repo, regardless of prompt. See [providers.md](providers.md) and
85
+ [SECURITY.md](../SECURITY.md) for the full trust model.
86
+
87
+ ## 4. Prompts and adjudication
88
+
89
+ Each role's behavior is defined by versioned **prompt specs**
90
+ (`src/neal/agents/`, [PROMPT_SPECS.md](PROMPT_SPECS.md)) and run through shared
91
+ **structured rounds** (`agents/rounds.ts`) that force schema-validated output
92
+ (`agents/schemas.ts`). The coder/reviewer adjudication loop is inventoried in
93
+ [ADJUDICATOR_INVENTORY.md](ADJUDICATOR_INVENTORY.md). Structured output is
94
+ schema-enforced (not loose JSON), which is also how `neal compat` attributes a
95
+ model's failures to the model rather than to transport noise.
96
+
97
+ ## 5. Model qualification (`neal compat`)
98
+
99
+ `neal compat` (`src/neal/commands/compat.ts`) is a self-contained harness that
100
+ drives a candidate model through the planner/coder/reviewer roles on trivial
101
+ bundled fixtures, classifies failures structurally (protocol vs structured-output
102
+ vs behavior), and emits a PASS/FAIL matrix. It's how the dated
103
+ [compatible-models.md](compatible-models.md) whitelist is produced, and it
104
+ doubles as the live CI smoke for dependency bumps (see
105
+ [maintenance.md](maintenance.md) and [compat.md](compat.md)).
106
+
107
+ ## Where to go next
108
+
109
+ - [plan-format.md](plan-format.md) — the executable plan contract
110
+ - [state-machine.md](state-machine.md) — run/queue state invariants
111
+ - [providers.md](providers.md) — provider adapter contract + extension checklist
112
+ - [PROMPT_SPECS.md](PROMPT_SPECS.md) — prompt-spec ownership boundaries
113
+ - [storage.md](storage.md) — the `.neal/` storage contract
@@ -0,0 +1,65 @@
1
+ # Automation Contract
2
+
3
+ This document is the machine-facing contract for driving neal from scripts,
4
+ CI, and benchmark harnesses.
5
+
6
+ Noninteractive harnesses should run `neal execute <plan.md>` for an already
7
+ accepted executable plan, or `neal run <plan.md>` when Neal should refine and
8
+ execute one or more plans as a serial queue. Use `neal resume --run <run-id>` to
9
+ continue an interrupted writer run; pass `--message` only when status says the
10
+ run is waiting for operator guidance. After each writer command, classify the
11
+ result from the process exit code plus `neal status --json --run <run-id>` when
12
+ a run id is known. Use `neal status --json --all` only for run discovery and
13
+ queue overview, not as a replacement for exact run-local status.
14
+
15
+ `neal execute`, `neal run`, and `neal resume` do not prompt for input. They run
16
+ with closed stdin and either complete, stop in a controlled state, or fail fast
17
+ when setup, configuration, CLI usage, Git state, or worktree preconditions are
18
+ invalid. Keyboard controls are available only when stdin is a TTY. `neal setup`
19
+ and public `neal squash` remain interactive setup and maintenance commands, not
20
+ the harness execution path.
21
+
22
+ The stable JSON classification fields are:
23
+
24
+ - `runId`, `status`, `effectiveStatus`, `publicStatus`, `phase`,
25
+ `publicPhase`, and `nextAction` for outcome and follow-up decisions.
26
+ - `waitingForOperatorGuidance`, `pendingOperatorGuidance`, `blocker`,
27
+ `manualGate`, `health`, and `lock.kind` for controlled incomplete states,
28
+ timeouts, and stale or live writer-lock evidence.
29
+ - `providerError` for the latest provider or phase failure. Provider failures
30
+ expose provider id, role, label, session handle, normalized kind, bounded
31
+ message, retryability, and timestamp without raw provider payloads.
32
+ - `commits`, `squash`, and `patch` for patch selection. `patch` includes the
33
+ default-submission decision, reason, base/head/range, source, commit count,
34
+ changed-file count, changed files, and unavailable reason.
35
+ - `build` for reproducibility: Neal package version, Neal source Git SHA when
36
+ available, Node version, whether the values came from run `meta.json` or live
37
+ fallback, and the persisted planner/coder/reviewer agent config.
38
+
39
+ Default public patch submission is conservative. Submit automatically only when
40
+ `patch.defaultSubmissionEligible` is true. Neal sets that only for clean
41
+ completed execute runs with a non-empty readable patch range. Successful squash
42
+ metadata is preferred (`squash.originalBaseCommit..squash.replacementCommit`);
43
+ otherwise completed unsquashed execute runs use
44
+ `commits.initialBaseCommit ?? commits.baseCommit` through `commits.finalCommit`.
45
+ Failed, blocked, paused, running, provider-error, waiting, timed-out,
46
+ malformed-squash, pending-squash, unreadable-range, and empty-patch runs can
47
+ still expose patch metadata for analysis, but are not default-submission
48
+ eligible.
49
+
50
+ For public traces, copy `neal status --json --run <run-id>` output and the
51
+ run-local `RUN_NARRATIVE.md` path reported at
52
+ `artifacts.runNarrativeMarkdownPath`. Do not publish raw run directories,
53
+ `RUN_NARRATIVE.json`, `events.ndjson`, `stderr.log`, `RUN_STATE.json`, full
54
+ diffs, prompts, provider responses, or provider payloads as benchmark traces.
55
+
56
+ Writer command exit codes (`0`, `1`, `2`, `3`) are defined in the README's
57
+ [Command Exit Codes](../README.md#command-exit-codes) section.
58
+
59
+ Harnesses own wall-clock timeouts. Launch Neal in a process group, terminate
60
+ that group on timeout, wait a short grace period, and force-kill the group if it
61
+ does not exit. When a run id is known, call `neal status --json --run <run-id>`
62
+ after termination and record the wrapper timeout as the primary classification.
63
+ Status JSON stays readable for interrupted runs and includes `lock.kind`, so a
64
+ wrapper can distinguish a cleaned-up timeout (`none`) from a still-active or
65
+ stale writer lock.
@@ -0,0 +1,105 @@
1
+ # Why neal instead of X?
2
+
3
+ neal is a harness, not an agent. It runs three independent roles — planner,
4
+ coder, reviewer — each bound to whatever provider and model you choose
5
+ ([providers.md](providers.md)), and drives them with a deterministic state
6
+ machine ([architecture.md](architecture.md)) rather than letting a model decide
7
+ the control flow. Verdicts are schema-validated structured output, not prose an
8
+ orchestrator model interprets. Every run is persisted under `.neal/` and
9
+ resumable after a crash ([storage.md](storage.md)). The reviewer is read-only by
10
+ construction: the provider registry rejects any reviewer capability that
11
+ declares write or shell access, so a reviewer structurally cannot mutate the
12
+ repo regardless of prompt. Most alternatives are agents; neal is the loop that
13
+ holds agents accountable to a plan.
14
+
15
+ ## Claude Code
16
+
17
+ What it's great at: interactive, conversational coding with a single very
18
+ capable agent. Its subagents delegate work, plan mode gates execution behind an
19
+ approved plan, and hooks let you inject your own checks into the tool loop.
20
+
21
+ The structural difference: Claude Code is a single-vendor agent product.
22
+ Its subagents are prompt-scoped delegates inside one product, sharing a vendor
23
+ and orchestrated by a model — the top-level agent decides when to delegate and
24
+ how to weigh what comes back. There is no cross-vendor adversarial review: the
25
+ judge and the judged are the same vendor, often the same model family. neal is
26
+ not a competitor to Claude Code; it is a consumer of it. The `anthropic-claude`
27
+ adapter drives Claude Code's SDK as a coder or reviewer, and the common
28
+ configuration is exactly the adversarial split Claude Code cannot express:
29
+ Codex codes, Claude reviews, and a deterministic orchestrator — not a model —
30
+ decides what happens with the verdict.
31
+
32
+ Pick Claude Code when the work is exploratory or conversational, when you want
33
+ a human in the loop turn by turn, or when you have no plan yet. neal wants a
34
+ plan document; Claude Code is a good place to figure one out.
35
+
36
+ ## Aider (architect/editor mode)
37
+
38
+ What it's great at: fast, terminal-native pair programming. Its
39
+ architect/editor mode was an early demonstration that splitting reasoning from
40
+ editing across two models improves results.
41
+
42
+ The structural difference: Aider's two models cooperate on one change — the
43
+ architect proposes, the editor applies — and the control flow between them is
44
+ mediated by the models within a chat session. There is no independent reviewer
45
+ producing a structured verdict that a state machine acts on, no scoped plan
46
+ queue where each scope starts the coder from a fresh context, and continuity is
47
+ conversation-shaped rather than a persisted run ledger. neal's roles are
48
+ adversarial rather than cooperative: the reviewer judges committed diffs it had
49
+ no hand in producing, findings route back to the coder until a schema-validated
50
+ accept, and `neal resume` reconstructs an interrupted run from the `.neal/`
51
+ ledgers rather than replaying a chat.
52
+
53
+ Pick Aider for tight interactive edits where you are the reviewer and the loop
54
+ is you. neal earns its overhead on multi-scope work where drift over a long
55
+ session is the failure mode.
56
+
57
+ ## OpenHands and autonomous agents
58
+
59
+ What they're great at: sandboxed, hands-off execution — hand an issue to an
60
+ agent in an isolated runtime and come back to a pull request. The sandbox makes
61
+ broad autonomy defensible.
62
+
63
+ The structural difference: these systems bet on maximizing agent autonomy and
64
+ containing it with a sandbox. neal bets the opposite way: local-first execution
65
+ in your checkout, a human-authored plan as the contract for what may happen,
66
+ and bounded autonomy with structural escalation — blocked states that wait for
67
+ `neal resume --message`, manual gates for work only a human can do, and a
68
+ bounded adjudicator that resolves a narrow recoverable class and escalates
69
+ genuine walls. Even `--unattended` mode only bounds how long neal persists
70
+ before failing cleanly; it never widens authorization.
71
+
72
+ Pick an autonomous agent when you want isolation and don't need to constrain
73
+ the path taken. Pick neal when the plan is the point — when you want to
74
+ specify the decomposition, the verification per scope, and the stop conditions,
75
+ and have the machine enforce them.
76
+
77
+ ## If you just want CI review
78
+
79
+ PR-review bots comment on diffs after they reach the forge. neal's review is
80
+ inside the loop: every scope's committed diff is judged before the run moves
81
+ on, and a final-completion review checks the whole plan before the squash — so
82
+ findings are fixed by the same coder in the same run, not triaged later.
83
+ `neal review` also works standalone against any committed range, role-symmetric
84
+ (the coder provider drafts findings, the read-only reviewer adjudicates them),
85
+ local, and provider-agnostic — no forge integration or CI required. The two are
86
+ complementary: neal reviews before you push, bots review after.
87
+
88
+ ## What neal does not do
89
+
90
+ - **No GUI.** neal is a CLI with narrative terminal output; state lives in
91
+ files under `.neal/`.
92
+ - **No sandbox of its own for the coder.** Writer providers run with broad
93
+ local permissions (Codex under `danger-full-access`, Claude under
94
+ `bypassPermissions`, the generic writer's `run` tool is unsandboxed shell).
95
+ Bring your own isolation — disposable checkout, container, or VM. See
96
+ [SECURITY.md](../SECURITY.md).
97
+ - **Serial scopes only, today.** Scopes execute one at a time, and `neal run`
98
+ queues run plans serially. There is no parallel scope execution.
99
+ - **It requires a plan document.** There is no "just fix it" mode — the
100
+ authored plan, with its mandatory `## Execution Shape` section
101
+ ([plan-format.md](plan-format.md)), is the product's opinion. If writing a
102
+ plan feels like overhead, neal is the wrong tool for that task.
103
+ - **No provider plugins yet.** Adapters are built-in (`openai-codex`,
104
+ `anthropic-claude`, `openai-compatible`, `generic-agentic`); external
105
+ provider plugins are future work.