@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.
- package/LICENSE +21 -0
- package/README.md +527 -0
- package/SECURITY.md +91 -0
- package/config.yml +104 -0
- package/dist/neal/activity-footer.js +177 -0
- package/dist/neal/activity-reporting.js +1 -0
- package/dist/neal/adjudicator/artifacts.js +58 -0
- package/dist/neal/adjudicator/blocked-adjudicator.js +223 -0
- package/dist/neal/adjudicator/contracts.js +139 -0
- package/dist/neal/adjudicator/execute.js +611 -0
- package/dist/neal/adjudicator/final-completion.js +104 -0
- package/dist/neal/adjudicator/planning.js +145 -0
- package/dist/neal/adjudicator/specs.js +453 -0
- package/dist/neal/agents/prompts.js +120 -0
- package/dist/neal/agents/rounds.js +706 -0
- package/dist/neal/agents/schemas.js +832 -0
- package/dist/neal/agents/structured-coder.js +82 -0
- package/dist/neal/agents/structured-json.js +528 -0
- package/dist/neal/agents.js +4 -0
- package/dist/neal/atomic-write.js +18 -0
- package/dist/neal/blocked-guidance.js +406 -0
- package/dist/neal/cli.js +471 -0
- package/dist/neal/commands/check.js +401 -0
- package/dist/neal/commands/compat.js +807 -0
- package/dist/neal/commands/interactive-activity.js +57 -0
- package/dist/neal/commands/new-run.js +79 -0
- package/dist/neal/commands/plan-and-execute.js +44 -0
- package/dist/neal/commands/recovery-guidance.js +217 -0
- package/dist/neal/commands/resume-run.js +395 -0
- package/dist/neal/commands/review.js +21 -0
- package/dist/neal/commands/runtime.js +557 -0
- package/dist/neal/commands/setup.js +596 -0
- package/dist/neal/commands/squash.js +113 -0
- package/dist/neal/commands/status.js +33 -0
- package/dist/neal/commands/writer-exit-codes.js +42 -0
- package/dist/neal/commit-message.js +17 -0
- package/dist/neal/config.js +432 -0
- package/dist/neal/context/artifacts.js +140 -0
- package/dist/neal/context/context.js +324 -0
- package/dist/neal/context/inline-review-context.js +131 -0
- package/dist/neal/context/reviewer-context.js +166 -0
- package/dist/neal/context/shared.js +117 -0
- package/dist/neal/context/types.js +1 -0
- package/dist/neal/diagnostic.js +208 -0
- package/dist/neal/execute-finalization.js +5 -0
- package/dist/neal/final-completion-review.js +188 -0
- package/dist/neal/final-completion.js +229 -0
- package/dist/neal/git.js +339 -0
- package/dist/neal/index.js +135 -0
- package/dist/neal/interactive-controls.js +85 -0
- package/dist/neal/logger.js +102 -0
- package/dist/neal/manual-gates.js +121 -0
- package/dist/neal/orchestrator/artifacts.js +70 -0
- package/dist/neal/orchestrator/completion.js +531 -0
- package/dist/neal/orchestrator/failures.js +31 -0
- package/dist/neal/orchestrator/notifications.js +175 -0
- package/dist/neal/orchestrator/phases/coder.js +516 -0
- package/dist/neal/orchestrator/phases/planning.js +540 -0
- package/dist/neal/orchestrator/phases/recovery.js +798 -0
- package/dist/neal/orchestrator/phases/review.js +136 -0
- package/dist/neal/orchestrator/phases/shared.js +279 -0
- package/dist/neal/orchestrator/run-loop.js +113 -0
- package/dist/neal/orchestrator/split-plan.js +235 -0
- package/dist/neal/orchestrator/transitions.js +309 -0
- package/dist/neal/orchestrator.js +215 -0
- package/dist/neal/phase-display.js +27 -0
- package/dist/neal/plan-doc.js +154 -0
- package/dist/neal/plan-queue.js +1092 -0
- package/dist/neal/plan-refinement.js +39 -0
- package/dist/neal/plan-validation.js +525 -0
- package/dist/neal/progress.js +237 -0
- package/dist/neal/prompts/assert-builder.js +13 -0
- package/dist/neal/prompts/execute.js +290 -0
- package/dist/neal/prompts/guidance.js +70 -0
- package/dist/neal/prompts/planning.js +313 -0
- package/dist/neal/prompts/review-doctrine.js +142 -0
- package/dist/neal/prompts/shared.js +101 -0
- package/dist/neal/prompts/specialized.js +212 -0
- package/dist/neal/prompts/specs.js +572 -0
- package/dist/neal/providers/anthropic-claude.js +1599 -0
- package/dist/neal/providers/detection.js +139 -0
- package/dist/neal/providers/generic-agentic-tools.js +586 -0
- package/dist/neal/providers/generic-agentic.js +1238 -0
- package/dist/neal/providers/liveness.js +151 -0
- package/dist/neal/providers/openai-codex.js +1014 -0
- package/dist/neal/providers/openai-compatible.js +654 -0
- package/dist/neal/providers/registry.js +389 -0
- package/dist/neal/providers/telemetry.js +208 -0
- package/dist/neal/providers/types.js +21 -0
- package/dist/neal/recovery-artifacts.js +50 -0
- package/dist/neal/resume-decision.js +220 -0
- package/dist/neal/resume-planner.js +265 -0
- package/dist/neal/retrospective.js +391 -0
- package/dist/neal/review-debt.js +18 -0
- package/dist/neal/review-findings/artifacts.js +173 -0
- package/dist/neal/review-findings/prompts.js +172 -0
- package/dist/neal/review-findings/provider.js +330 -0
- package/dist/neal/review-findings/run.js +373 -0
- package/dist/neal/review-findings/types.js +1 -0
- package/dist/neal/review-mode.js +67 -0
- package/dist/neal/review.js +137 -0
- package/dist/neal/run-lock.js +334 -0
- package/dist/neal/run-metrics.js +355 -0
- package/dist/neal/run-narrative-types.js +1 -0
- package/dist/neal/run-narrative.js +1374 -0
- package/dist/neal/run-registry.js +218 -0
- package/dist/neal/run-status.js +25 -0
- package/dist/neal/scopes.js +451 -0
- package/dist/neal/sensitive-text.js +8 -0
- package/dist/neal/squash-message.js +379 -0
- package/dist/neal/squash.js +591 -0
- package/dist/neal/state-invariants.js +496 -0
- package/dist/neal/state-views.js +344 -0
- package/dist/neal/state.js +887 -0
- package/dist/neal/status-footer.js +258 -0
- package/dist/neal/status.js +1260 -0
- package/dist/neal/storage-paths.js +57 -0
- package/dist/neal/support.js +58 -0
- package/dist/neal/terminal-narrator.js +435 -0
- package/dist/neal/types.js +1 -0
- package/dist/neal/verification-events.js +81 -0
- package/dist/neal/version.js +37 -0
- package/dist/neal/worktree-status.js +137 -0
- package/dist/notifier.js +44 -0
- package/docs/ADJUDICATOR_INVENTORY.md +310 -0
- package/docs/PROMPT_SPECS.md +266 -0
- package/docs/README.md +22 -0
- package/docs/architecture.md +113 -0
- package/docs/assets/neal-execution-flow.png +0 -0
- package/docs/automation.md +65 -0
- package/docs/comparison.md +105 -0
- package/docs/compat.md +269 -0
- package/docs/compatible-models.md +135 -0
- package/docs/demo.md +55 -0
- package/docs/maintenance.md +64 -0
- package/docs/plan-format.md +213 -0
- package/docs/providers.md +751 -0
- package/docs/release.md +147 -0
- package/docs/state-machine.md +266 -0
- package/docs/storage.md +207 -0
- package/docs/troubleshooting.md +152 -0
- package/examples/compat/add-edit-verify/PLAN.md +29 -0
- package/examples/compat/add-edit-verify/broken.diff +8 -0
- package/examples/compat/add-edit-verify/good.diff +8 -0
- package/examples/compat/add-edit-verify/package.json +5 -0
- package/examples/compat/add-edit-verify/src/add.js +2 -0
- package/examples/compat/add-edit-verify/test/add.test.js +9 -0
- package/examples/compat/is-even-add-test/PLAN.md +30 -0
- package/examples/compat/is-even-add-test/broken.diff +11 -0
- package/examples/compat/is-even-add-test/good.diff +11 -0
- package/examples/compat/is-even-add-test/package.json +5 -0
- package/examples/compat/is-even-add-test/src/is-even.js +3 -0
- package/examples/compat/is-even-add-test/test/is-even.test.js +9 -0
- package/examples/compat/manifest.json +60 -0
- package/examples/compat/plan-greeting/ISSUE.md +25 -0
- package/examples/compat/plan-greeting/package.json +5 -0
- package/examples/compat/plan-greeting/src/greet.js +2 -0
- package/examples/compat/plan-greeting/test/greet.test.js +8 -0
- package/examples/compat/reverse-grep-edit/PLAN.md +32 -0
- package/examples/compat/reverse-grep-edit/broken.diff +12 -0
- package/examples/compat/reverse-grep-edit/good.diff +12 -0
- package/examples/compat/reverse-grep-edit/package.json +5 -0
- package/examples/compat/reverse-grep-edit/src/strings.js +10 -0
- package/examples/compat/reverse-grep-edit/test/strings.test.js +15 -0
- package/examples/issue-triage-js/PLAN.md +83 -0
- package/examples/issue-triage-js/README.md +76 -0
- package/examples/issue-triage-js/package.json +9 -0
- package/examples/issue-triage-js/src/issue-triage.js +87 -0
- package/examples/issue-triage-js/test/issue-triage.test.js +107 -0
- 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
|
|
Binary file
|
|
@@ -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.
|