@navels/neal 0.2.0 → 0.3.1
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/README.md +206 -209
- package/SECURITY.md +16 -19
- package/dist/neal/adjudicator/{blocked-adjudicator.js → consultant.js} +21 -21
- package/dist/neal/adjudicator/execute.js +33 -33
- package/dist/neal/adjudicator/final-completion.js +2 -31
- package/dist/neal/adjudicator/planning.js +230 -38
- package/dist/neal/agents/prompts.js +6 -17
- package/dist/neal/agents/rounds.js +43 -73
- package/dist/neal/agents/schemas.js +47 -13
- package/dist/neal/blocked-guidance.js +16 -9
- package/dist/neal/cli.js +2 -2
- package/dist/neal/commands/check.js +2 -2
- package/dist/neal/commands/compat.js +100 -36
- package/dist/neal/commands/interactive-activity.js +2 -2
- package/dist/neal/commands/recovery-guidance.js +20 -8
- package/dist/neal/commands/runtime.js +4 -2
- package/dist/neal/config.js +16 -7
- package/dist/neal/context/inline-review-context.js +13 -28
- package/dist/neal/context/reviewer-context.js +19 -14
- package/dist/neal/eval/reviewer-eval-manifest.js +86 -0
- package/dist/neal/eval/reviewer-eval.js +155 -0
- package/dist/neal/interactive-controls.js +5 -0
- package/dist/neal/orchestrator/completion.js +49 -2
- package/dist/neal/orchestrator/failures.js +7 -0
- package/dist/neal/orchestrator/notifications.js +9 -9
- package/dist/neal/orchestrator/phases/planning.js +117 -80
- package/dist/neal/orchestrator/phases/recovery.js +151 -115
- package/dist/neal/orchestrator/phases/review.js +28 -1
- package/dist/neal/orchestrator/transitions.js +7 -1
- package/dist/neal/orchestrator.js +3 -0
- package/dist/neal/plan-queue.js +29 -1
- package/dist/neal/prompts/execute.js +7 -19
- package/dist/neal/prompts/planning.js +64 -55
- package/dist/neal/prompts/review-doctrine.js +13 -50
- package/dist/neal/prompts/specialized.js +7 -17
- package/dist/neal/prompts/specs.js +180 -32
- package/dist/neal/providers/agent-settings-isolation.js +35 -0
- package/dist/neal/providers/anthropic-claude.js +18 -1
- package/dist/neal/providers/detection.js +3 -7
- package/dist/neal/providers/git-config-isolation.js +83 -0
- package/dist/neal/providers/openai-codex.js +25 -3
- package/dist/neal/providers/{generic-agentic-tools.js → openai-compatible-tools.js} +11 -5
- package/dist/neal/providers/openai-compatible.js +1078 -430
- package/dist/neal/providers/openrouter-routing.js +68 -0
- package/dist/neal/providers/pricing.js +1 -1
- package/dist/neal/providers/rate-card.js +6 -32
- package/dist/neal/providers/registry.js +6 -17
- package/dist/neal/providers/types.js +12 -0
- package/dist/neal/resume-decision.js +7 -6
- package/dist/neal/resume-planner.js +9 -0
- package/dist/neal/retrospective.js +3 -3
- package/dist/neal/review-debt.js +30 -0
- package/dist/neal/review-findings/provider.js +17 -29
- package/dist/neal/review.js +17 -1
- package/dist/neal/state-invariants.js +11 -3
- package/dist/neal/state-views.js +27 -5
- package/dist/neal/state.js +59 -15
- package/dist/neal/status.js +28 -1
- package/dist/neal/support.js +3 -3
- package/docs/README.md +22 -18
- package/docs/{ADJUDICATOR_INVENTORY.md → adjudicator-inventory.md} +58 -57
- package/docs/architecture.md +79 -83
- package/docs/automation.md +11 -11
- package/docs/compat.md +91 -61
- package/docs/compatible-models.md +145 -121
- package/docs/demo.md +15 -5
- package/docs/maintenance.md +65 -34
- package/docs/plan-format.md +61 -33
- package/docs/prompt-evals.md +96 -0
- package/docs/{PROMPT_SPECS.md → prompt-specs.md} +52 -48
- package/docs/providers.md +279 -349
- package/docs/release.md +63 -81
- package/docs/review-convergence.md +246 -0
- package/docs/state-machine.md +61 -59
- package/docs/storage.md +40 -31
- package/docs/troubleshooting.md +32 -29
- package/examples/compat/add-edit-verify/PLAN.md +2 -0
- package/examples/compat/add-edit-verify/broken.diff +2 -2
- package/examples/compat/add-edit-verify/good.diff +2 -2
- package/examples/compat/add-edit-verify/src/add.js +1 -1
- package/examples/compat/manifest.json +25 -29
- package/examples/compat/sum-grep-edit/PLAN.md +33 -0
- package/examples/compat/sum-grep-edit/broken.diff +12 -0
- package/examples/compat/sum-grep-edit/good.diff +12 -0
- package/examples/compat/sum-grep-edit/package.json +5 -0
- package/examples/compat/sum-grep-edit/src/numbers.js +9 -0
- package/examples/compat/sum-grep-edit/test/numbers.test.js +15 -0
- package/examples/issue-triage-js/README.md +0 -15
- package/examples/reviewer-eval/clean-doc/base/src/clamp.ts +3 -0
- package/examples/reviewer-eval/clean-doc/change.diff +9 -0
- package/examples/reviewer-eval/clean-extract/base/src/greet.ts +3 -0
- package/examples/reviewer-eval/clean-extract/change.diff +13 -0
- package/examples/reviewer-eval/dropped-error/base/src/load.ts +4 -0
- package/examples/reviewer-eval/dropped-error/change.diff +15 -0
- package/examples/reviewer-eval/manifest.json +45 -0
- package/examples/reviewer-eval/off-by-one/base/src/paginate.ts +5 -0
- package/examples/reviewer-eval/off-by-one/change.diff +11 -0
- package/{config.yml → neal.yml} +1 -1
- package/package.json +15 -14
- package/dist/neal/providers/generic-agentic.js +0 -1256
- package/docs/comparison.md +0 -105
- package/docs/issue-pipeline.md +0 -124
- package/examples/compat/is-even-add-test/PLAN.md +0 -30
- package/examples/compat/is-even-add-test/broken.diff +0 -11
- package/examples/compat/is-even-add-test/good.diff +0 -11
- package/examples/compat/is-even-add-test/package.json +0 -5
- package/examples/compat/is-even-add-test/src/is-even.js +0 -3
- package/examples/compat/is-even-add-test/test/is-even.test.js +0 -9
- package/examples/compat/reverse-grep-edit/PLAN.md +0 -32
- package/examples/compat/reverse-grep-edit/broken.diff +0 -12
- package/examples/compat/reverse-grep-edit/good.diff +0 -12
- package/examples/compat/reverse-grep-edit/package.json +0 -5
- package/examples/compat/reverse-grep-edit/src/strings.js +0 -10
- package/examples/compat/reverse-grep-edit/test/strings.test.js +0 -15
package/docs/state-machine.md
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
#
|
|
1
|
+
# State machine
|
|
2
2
|
|
|
3
3
|
The product-level storage layout, artifact classifications, run pointers,
|
|
4
4
|
retention guidance, and no-global-index decision are documented in
|
|
5
|
-
[storage.md](storage.md).
|
|
6
|
-
state invariants
|
|
5
|
+
[storage.md](storage.md). What follows covers the persisted ledgers and the
|
|
6
|
+
state invariants neal enforces when reading and writing them.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
neal keeps two persisted ledgers:
|
|
9
9
|
|
|
10
10
|
- `OrchestrationState` is the child-run ledger. It lives in each run directory as `RUN_STATE.json` and records one plan or execute writer run.
|
|
11
11
|
- `PlanAndExecuteQueueState` is the parent queue ledger. It lives under `.neal/queues/<queue-id>/QUEUE_STATE.json` and tracks serial `neal run` children, their active stage, child run ids, and queue-level stop status.
|
|
12
12
|
|
|
13
|
-
These ledgers are related but separate. A queue item points at child run state paths
|
|
13
|
+
These ledgers are related but separate. A queue item points at child run state paths. Child runs do not own the queue's status, item ordering, or current queue pointer.
|
|
14
14
|
|
|
15
|
-
## Hydration
|
|
15
|
+
## Hydration and validation
|
|
16
16
|
|
|
17
|
-
`src/neal/state.ts` owns v1 child-run hydration. It reads JSON, checks the basic shape, requires the current v1 fields
|
|
17
|
+
`src/neal/state.ts` owns v1 child-run hydration. It reads JSON, checks the basic shape, requires the current v1 fields neal writes, and rejects unknown enum-like strings while hydrating phase references. Missing or malformed required child-run fields fail load instead of receiving invented defaults.
|
|
18
18
|
|
|
19
19
|
`src/neal/state-invariants.ts` owns semantic validation after hydration and before save. `assertValidOrchestrationState` is pure: it has no filesystem, git, provider, logger, or clock dependency. The same invariant layer runs when `loadState` returns hydrated state and when `saveState` builds the timestamped next state.
|
|
20
20
|
|
|
21
21
|
Queue state has its own parser and invariants in `src/neal/plan-queue.ts`, centered on `parsePlanAndExecuteQueueState` and related queue item parsing helpers.
|
|
22
22
|
|
|
23
|
-
## Schema
|
|
23
|
+
## Schema versions
|
|
24
24
|
|
|
25
|
-
Persisted JSON that
|
|
26
|
-
`RUN_STATE.json` hydrates through `normalizeStateV1
|
|
25
|
+
Persisted JSON that neal reads as durable schema is versioned at v1.
|
|
26
|
+
`RUN_STATE.json` hydrates through `normalizeStateV1`. `.neal/current.json`,
|
|
27
27
|
queue state, `.neal/current-queue.json`, queue child links, run narratives,
|
|
28
28
|
squash audit results, and the active writer lock all have v1 write shapes or
|
|
29
29
|
parsers.
|
|
@@ -32,7 +32,7 @@ Run `meta.json` is support data, not child-run state. Optional context artifacts
|
|
|
32
32
|
such as `plan-progress.json` are written as v1 and read defensively so malformed
|
|
33
33
|
or unsupported support data does not replace the canonical run ledger.
|
|
34
34
|
|
|
35
|
-
## State
|
|
35
|
+
## State views and public lifecycle
|
|
36
36
|
|
|
37
37
|
Persisted v1 child-run state remains record-shaped, but most callers should not
|
|
38
38
|
treat `OrchestrationState` as one large nullable programming model.
|
|
@@ -55,7 +55,7 @@ human output can say `waiting_for_guidance`, `paused`, `blocked`, `failed`, or
|
|
|
55
55
|
fields such as `effectiveStatus`, `waitingForOperatorGuidance`, and
|
|
56
56
|
`pendingOperatorGuidance`.
|
|
57
57
|
|
|
58
|
-
## Phase
|
|
58
|
+
## Phase and status
|
|
59
59
|
|
|
60
60
|
Known child-run phases and statuses are centralized in `state-invariants.ts` through `ORCHESTRATION_PHASES`, `ORCHESTRATION_STATUSES`, and their runtime guard helpers. Runnable dispatch is authored in `src/neal/orchestrator/run-loop.ts` as purpose-specific registries for plan, execute, interactive recovery, and execute finalization phases. Those registries are composed into `RUNNABLE_PHASE_REGISTRY` for dispatch and exposed through top-level-mode helpers so tests can assert which phases are runnable for plan and execute runs.
|
|
61
61
|
|
|
@@ -68,16 +68,18 @@ The enforced phase/status relationship is intentionally small:
|
|
|
68
68
|
|
|
69
69
|
Read-only `neal review` is not a writer-run mode. It writes isolated findings artifacts under `.neal/reviews/<review-id>/` and does not create `OrchestrationState`.
|
|
70
70
|
|
|
71
|
-
## Recovery
|
|
71
|
+
## Recovery state
|
|
72
72
|
|
|
73
73
|
Interactive blocked recovery is owned by `interactiveBlockedRecovery` while the active phase is `interactive_blocked_recovery`. The invariant layer validates execute-mode ownership, supported source phases, bounded turn counters, contiguous turn numbers, and disposition result phases.
|
|
74
74
|
|
|
75
|
-
Every block class
|
|
76
|
-
the split-plan invalid-payload block
|
|
77
|
-
`enterInteractiveBlockedRecovery` chokepoint, where the
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
Every block class (coder-blocked signals, reviewer `review_stuck` deadlocks, and
|
|
76
|
+
the split-plan invalid-payload block) funnels through the single
|
|
77
|
+
`enterInteractiveBlockedRecovery` chokepoint, where the consultant triages it (see
|
|
78
|
+
Site A below). The consultant is read-only: it never grants authorization, expands
|
|
79
|
+
scope, or waives verification gates. A recoverable verdict acts automatically under
|
|
80
|
+
both run modes. The modes differ only on a non-recoverable verdict, which finalizes
|
|
81
|
+
the run terminally under unattended runs and yields to the operator (carrying the
|
|
82
|
+
verdict as advice) under attended runs.
|
|
81
83
|
|
|
82
84
|
Public resume eligibility is classified by `src/neal/resume-decision.ts` before
|
|
83
85
|
any recovery mutation. That read-only decision layer combines loaded child-run
|
|
@@ -91,7 +93,7 @@ selected actions only after the selected run has been classified as executable.
|
|
|
91
93
|
`state-invariants.ts` mirrors the allowed phase sets so changes to recovery
|
|
92
94
|
behavior are visible in focused tests.
|
|
93
95
|
|
|
94
|
-
## Unattended
|
|
96
|
+
## Unattended mode
|
|
95
97
|
|
|
96
98
|
`--unattended` / `agent.unattended` resolves to a persisted
|
|
97
99
|
`OrchestrationState.unattended` boolean (default `false`) for both plan and
|
|
@@ -99,17 +101,17 @@ execute top-level modes, so a separate `neal resume` process and the `neal run`
|
|
|
99
101
|
plan→execute hand-off see it without re-passing a flag. The flag overrides the
|
|
100
102
|
config key. The resolved value is also threaded into the planner, reviewer,
|
|
101
103
|
coder, final-completion, and plan-reviewer prompts, where it adds one autonomy
|
|
102
|
-
line only when true
|
|
104
|
+
line only when true. With `unattended` false the rendered prompts are
|
|
103
105
|
byte-identical to attended output.
|
|
104
106
|
|
|
105
|
-
Unattended changes only the three structural operator-block sites
|
|
107
|
+
Unattended changes only the three structural operator-block sites. It never
|
|
106
108
|
weakens verification, authorization, or squash/grading, and never removes
|
|
107
109
|
`block_for_operator` from any decision surface. Every unattended branch gates on
|
|
108
110
|
structural state (`state.unattended`, `actionResolution.effectiveAction`,
|
|
109
111
|
`phase`, `blockedFromPhase`, the bounded auto-resume counter), never on
|
|
110
112
|
substring-matching assistant or guidance text.
|
|
111
113
|
|
|
112
|
-
- **Site A
|
|
114
|
+
- **Site A: execute-mode interactive recovery.** All fresh blocks funnel
|
|
113
115
|
through `enterInteractiveBlockedRecovery` (`src/neal/orchestrator/phases/recovery.ts`).
|
|
114
116
|
Under unattended, while `unattendedAutoResumeCount < UNATTENDED_MAX_AUTO_RESUMES`
|
|
115
117
|
(a module constant, reconciled so it never pushes past
|
|
@@ -119,46 +121,46 @@ substring-matching assistant or guidance text.
|
|
|
119
121
|
message uses, increments the persisted counter, and lets the run proceed into
|
|
120
122
|
the recovery phase. Past the cap (or the `maxTurns` boundary) it runs the
|
|
121
123
|
shared terminal-fail action instead of waiting.
|
|
122
|
-
- **
|
|
124
|
+
- **The consultant (bounded, both modes).** Inside
|
|
123
125
|
`enterInteractiveBlockedRecovery`, *before* the generic auto-resume / yield
|
|
124
|
-
decision, eligible blocks are triaged by
|
|
125
|
-
(`
|
|
126
|
+
decision, eligible blocks are triaged by the read-only consultant
|
|
127
|
+
(`runConsultant`, in `src/neal/adjudicator/consultant.ts`,
|
|
126
128
|
running through the same no-write reviewer plumbing the review/final-completion
|
|
127
129
|
reviewers use, making zero commits and zero file edits). Eligible source phases
|
|
128
|
-
(`
|
|
130
|
+
(`CONSULTANT_ELIGIBLE_SOURCE_PHASES`) are the coder-block phases (`coder_scope`
|
|
129
131
|
/ `coder_response` / `coder_optional_response`, which also carry the split-plan
|
|
130
132
|
invalid-payload block) and the reviewer `review_stuck` phases (`reviewer_scope` /
|
|
131
|
-
`reviewer_plan`). The
|
|
133
|
+
`reviewer_plan`). The consultant first applies an anti-thrash guard
|
|
132
134
|
(`recentBlocks`, keyed on scope identity + source phase + normalized blocker key +
|
|
133
135
|
evidence fingerprint): a same-scope repeat with no new evidence short-circuits to
|
|
134
136
|
`recoverable:false` without an LLM round. Otherwise it returns a verdict
|
|
135
|
-
`{ recoverable, triageCategory, resolutionDirective, rationale }`.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
genuine
|
|
140
|
-
the shared terminal-fail action
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
`
|
|
144
|
-
(default `1`, `0` disables)
|
|
137
|
+
`{ recoverable, triageCategory, resolutionDirective, rationale }`. A `recoverable`
|
|
138
|
+
`misunderstanding` verdict with a concrete in-scope directive enters recovery with
|
|
139
|
+
that directive injected as the pending turn (consumed exactly like a human
|
|
140
|
+
`neal resume --message`) under both run modes. The modes differ only on a
|
|
141
|
+
`recoverable:false` genuine blocker (`authorization` / `external_precondition` /
|
|
142
|
+
`impossible_task`): unattended runs the shared terminal-fail action, while attended
|
|
143
|
+
persists the verdict as `interactiveBlockedRecovery.consultantAdvice` and yields for
|
|
144
|
+
the operator. It is bounded by the counter
|
|
145
|
+
`consultantAttemptCount` against the `consultant_max_attempts` knob
|
|
146
|
+
(default `1`, `0` disables). It's a separate budget that never touches
|
|
145
147
|
`unattendedAutoResumeCount` or `interactiveBlockedRecovery.maxTurns`. Every other
|
|
146
148
|
case (ineligible source phase, disabled/exhausted cap, turn cap, or any
|
|
147
|
-
|
|
148
|
-
unchanged, writing neither `recentBlocks` nor `
|
|
149
|
+
consultant error) falls through to the generic auto-resume / yield path
|
|
150
|
+
unchanged, writing neither `recentBlocks` nor `consultantAdvice`.
|
|
149
151
|
The decisions are auditable from the structured event log via the
|
|
150
|
-
`
|
|
152
|
+
`consultant.{start,verdict,resolved,declined}` events, which
|
|
151
153
|
carry `scopeNumber`, `sourcePhase`, `blockedReason`, and (on `verdict`/`resolved`)
|
|
152
154
|
`recoverable`, `triageCategory`, `targetCanonicalIds`, and the post-increment
|
|
153
|
-
`
|
|
154
|
-
- **Sites B and C
|
|
155
|
+
`consultantAttemptCount`.
|
|
156
|
+
- **Sites B and C: final-completion review and the top-level plan-review gate.**
|
|
155
157
|
These gates block directly (bypassing the recovery chokepoint), and their own
|
|
156
|
-
budgets
|
|
157
|
-
review-round/convergence cap
|
|
158
|
+
budgets (the final-completion continue-execution cap and the
|
|
159
|
+
review-round/convergence cap) already bounded the autonomous effort. Under
|
|
158
160
|
unattended they run the shared terminal-fail action immediately rather than
|
|
159
|
-
saving `status:'blocked'
|
|
161
|
+
saving `status:'blocked'`. There is no auto-resume and no synthesized
|
|
160
162
|
`pendingPlanReviewGuidance`. Site C edits only the `topLevelMode !== 'execute'`
|
|
161
|
-
branch of `finalizeBlockedPlanReviewResponse
|
|
163
|
+
branch of `finalizeBlockedPlanReviewResponse`. Execute-mode derived-plan-review
|
|
162
164
|
blocks (`topLevelMode === 'execute'`) re-enter site A and are handled there.
|
|
163
165
|
|
|
164
166
|
The shared terminal-fail action is `persistUnattendedBlockUnresolvedFailure`
|
|
@@ -167,14 +169,14 @@ The shared terminal-fail action is `persistUnattendedBlockUnresolvedFailure`
|
|
|
167
169
|
`phase`/`blockedFromPhase` for diagnostics), re-render execution artifacts, write
|
|
168
170
|
a `failed` checkpoint retrospective, and emit the classified
|
|
169
171
|
`unattended.block_unresolved` log event (`reason:'unattended_block_unresolved'`
|
|
170
|
-
plus the `UnattendedBlockSite` origin)
|
|
172
|
+
plus the `UnattendedBlockSite` origin), deliberately without `notifyBlocked`,
|
|
171
173
|
which is the attended wait notification. The run exits with writer code `3`, and
|
|
172
174
|
any produced diff/plan is left unsubmitted as an artifact. There is no top-level
|
|
173
|
-
reason field on `OrchestrationState
|
|
175
|
+
reason field on `OrchestrationState`. The classification lives in the log event and
|
|
174
176
|
retrospective. Attended runs are unchanged and still wait for
|
|
175
177
|
`neal resume --message` at all three sites.
|
|
176
178
|
|
|
177
|
-
## Resume
|
|
179
|
+
## Resume planning
|
|
178
180
|
|
|
179
181
|
New-run initialization and existing-run resume reconciliation are separate.
|
|
180
182
|
`loadOrInitialize` still provides the command-facing entrypoint, but resume
|
|
@@ -198,10 +200,10 @@ normalization, event logging, pointer writes, and execution artifacts.
|
|
|
198
200
|
when the shared decision says interactive recovery is waiting for guidance.
|
|
199
201
|
Pending guidance resumes with plain `neal resume --run <run-id>`. Queue
|
|
200
202
|
continuation still belongs to `continuePlanAndExecuteQueueFromChildRun` after
|
|
201
|
-
the resumed child run finishes
|
|
203
|
+
the resumed child run finishes. Selecting a child run for resume does not
|
|
202
204
|
advance or repair the parent queue by itself.
|
|
203
205
|
|
|
204
|
-
## Derived
|
|
206
|
+
## Derived plans
|
|
205
207
|
|
|
206
208
|
Derived-plan fields are child-run state because they describe replacement execution for the active child run, not the parent queue. The invariant layer enforces these ownership rules:
|
|
207
209
|
|
|
@@ -212,23 +214,23 @@ Derived-plan fields are child-run state because they describe replacement execut
|
|
|
212
214
|
|
|
213
215
|
Derived-plan execution should continue to flow through the existing orchestrator transition helpers before any future shape refactor changes the persisted fields.
|
|
214
216
|
|
|
215
|
-
## Final
|
|
217
|
+
## Final completion
|
|
216
218
|
|
|
217
|
-
Final-completion review is execute-mode only. The `final_completion_review` phase requires a `finalCompletionSummary`. When a reviewer verdict exists, `finalCompletionResolvedAction` must match the effective action, including the continue-execution cap case where
|
|
219
|
+
Final-completion review is execute-mode only. The `final_completion_review` phase requires a `finalCompletionSummary`. When a reviewer verdict exists, `finalCompletionResolvedAction` must match the effective action, including the continue-execution cap case where neal resolves to operator blocking instead of starting another scope.
|
|
218
220
|
|
|
219
221
|
When final completion review asks to continue execution, the orchestrator may clear summary and verdict fields and reopen `coder_scope`. That reopened running state is valid.
|
|
220
222
|
|
|
221
|
-
Accepted execute scopes also pass through execute finalization before
|
|
223
|
+
Accepted execute scopes also pass through execute finalization before neal either opens the next scope or starts final-completion review. The persisted internal runnable cursor for that step is `execute_finalization`, which is separate from the public `neal squash` command. Public `neal squash` is a post-run command with selection, preview, and interactive TTY confirmation before it rewrites history.
|
|
222
224
|
|
|
223
|
-
## Atomic
|
|
225
|
+
## Atomic writes and locks
|
|
224
226
|
|
|
225
227
|
`src/neal/atomic-write.ts` provides per-file atomic replacement helpers. State, current run pointers, queue state, queue pointers, queue links, queue summaries, run metadata, progress artifacts, review/final-completion/recovery/split-plan/retrospective artifacts, run narratives, and default squash audit writes use temp-file-plus-rename writes where in scope.
|
|
226
228
|
|
|
227
229
|
This is not a multi-file transaction. If a process stops between writes, each individual JSON or text file should be either the previous complete file or the next complete file, but related files can briefly disagree. Resume and status commands must continue to tolerate that by resolving run paths and validating loaded state.
|
|
228
230
|
|
|
229
|
-
The active-run lock is separate. `src/neal/run-lock.ts` uses exclusive creation for `.neal/active-run.lock
|
|
231
|
+
The active-run lock is separate. `src/neal/run-lock.ts` uses exclusive creation for `.neal/active-run.lock`. That acquisition path should not be converted to atomic rename because the exclusive-create behavior is the mutual exclusion mechanism.
|
|
230
232
|
|
|
231
|
-
## Change
|
|
233
|
+
## Change checklist
|
|
232
234
|
|
|
233
235
|
When adding a child-run phase:
|
|
234
236
|
|
|
@@ -253,7 +255,7 @@ When adding a queue-state field:
|
|
|
253
255
|
- Parse and validate it in `parsePlanAndExecuteQueueState` or `parsePlanAndExecuteQueueItem`.
|
|
254
256
|
- Include it in queue summary or current queue pointer output only when it is operator-facing or needed for resume.
|
|
255
257
|
|
|
256
|
-
## Future
|
|
258
|
+
## Future refactor path
|
|
257
259
|
|
|
258
260
|
Do not jump directly from the current record-shaped `OrchestrationState` to a
|
|
259
261
|
persisted discriminated union. The lower-risk path now in place is to keep v1
|
package/docs/storage.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Storage contract
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
neal uses project-local `.neal/` storage as the source of truth for runs, queues,
|
|
4
4
|
review artifacts, recovery artifacts, progress, and audit history. User-level
|
|
5
5
|
storage is reserved for configuration, guidance, caches, logs, and future
|
|
6
6
|
optional discovery helpers.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
and validation details
|
|
8
|
+
The storage contract here is product-level. Run and queue ledger state
|
|
9
|
+
transition and validation details are documented separately in
|
|
10
10
|
[state-machine.md](state-machine.md).
|
|
11
11
|
|
|
12
|
-
## Public
|
|
12
|
+
## Public automation surface
|
|
13
13
|
|
|
14
14
|
`neal status --json` and `neal status --json --all` are the stable automation
|
|
15
15
|
contracts. Scripts should prefer them over parsing raw files under `.neal/`.
|
|
@@ -37,9 +37,9 @@ know a run id. Important stable fields include:
|
|
|
37
37
|
- `providerError` with the latest provider failure or unclassified phase error,
|
|
38
38
|
including timestamp, provider id, role, label, session handle, normalized
|
|
39
39
|
error kind, bounded message, and retryability where available.
|
|
40
|
-
- `build` with
|
|
40
|
+
- `build` with neal package version, neal source Git SHA when available, Node
|
|
41
41
|
version, source marker (`meta` or `live_fallback`), and the persisted
|
|
42
|
-
coder/reviewer agent config.
|
|
42
|
+
planner/coder/reviewer agent config.
|
|
43
43
|
- `artifacts` with run-local paths for the human narrative, review, progress,
|
|
44
44
|
support, and related diagnostic artifacts.
|
|
45
45
|
|
|
@@ -61,30 +61,38 @@ command output.
|
|
|
61
61
|
Storage classifications used below are: stable CLI surface, user-facing human
|
|
62
62
|
artifact, support/debug artifact, internal state, and lock/concurrency artifact.
|
|
63
63
|
The stable CLI surfaces in this storage contract are `neal status --json` and
|
|
64
|
-
`neal status --json --all
|
|
65
|
-
|
|
64
|
+
`neal status --json --all`. The project-local files are artifacts that support
|
|
65
|
+
neal operations and diagnostics.
|
|
66
66
|
|
|
67
|
-
## Project-
|
|
67
|
+
## Project-local layout
|
|
68
68
|
|
|
69
69
|
| Path | Classification | Contract |
|
|
70
70
|
| --- | --- | --- |
|
|
71
|
-
| `.neal/runs/<run-id>/RUN_STATE.json` | Internal state | Child-run ledger.
|
|
71
|
+
| `.neal/runs/<run-id>/RUN_STATE.json` | Internal state | Child-run ledger. neal validates current v1 state on read, but scripts should use `neal status --json` rather than depend on this file as a public API. |
|
|
72
72
|
| `.neal/runs/<run-id>/events.ndjson` | Support/debug artifact | Append-only event log for audit, diagnostics, command output references, and provider/runtime events. Readers should tolerate malformed or partial final lines where implemented. |
|
|
73
73
|
| `.neal/runs/<run-id>/stderr.log` | Support/debug artifact | Append-only stderr transcript for writer runs. It includes visible narrative lines plus low-level detail such as provider/tool telemetry, command output, reviewer context, and heartbeat diagnostics that may be hidden from the normal terminal stream. |
|
|
74
|
-
| `.neal/runs/<run-id>/meta.json` | Support/debug artifact | Run metadata used for diagnostics. New writes include `version: 1
|
|
74
|
+
| `.neal/runs/<run-id>/meta.json` | Support/debug artifact | Run metadata used for diagnostics. New writes include `version: 1`. Metadata alone cannot make a run selectable for squash or status. It is not the stable automation surface. |
|
|
75
75
|
| `.neal/runs/<run-id>/PLAN_ORIGINAL.md` | Support/debug artifact | Original plan document backup for `neal plan` runs, written before in-place plan refinement so the pre-refinement input remains inspectable. |
|
|
76
|
-
| `.neal/runs/<run-id>/
|
|
77
|
-
| `.neal/runs/<run-id>/
|
|
76
|
+
| `.neal/runs/<run-id>/DERIVED_PLAN_SCOPE_<scope>.md` | User-facing human artifact | Replacement execution plan produced when the coder splits an active scope. |
|
|
77
|
+
| `.neal/runs/<run-id>/SCOPE_<scope>_INVALID_DERIVED_PLAN.md` | Support/debug artifact | Rejected split-plan payload and its validation errors. Written only when the returned replacement plan is invalid. |
|
|
78
|
+
| `.neal/runs/<run-id>/SCOPE_<scope>_DISCARDED.diff` | Support/debug artifact | Scope work preserved before neal resets it while adopting a replacement plan. |
|
|
79
|
+
| `.neal/runs/<run-id>/GATE-<id>.md` | User-facing human artifact | Instructions and resume checks for an active manual gate. |
|
|
80
|
+
| `.neal/runs/<run-id>/scratch/` | Support/debug artifact | Reserved run-local scratch root for execute-scope and final-completion review. Read-only reviewer prompts do not use it. It is not durable state, but it remains project-local `.neal/` data for retention and privacy purposes. |
|
|
81
|
+
| `.neal/runs/<run-id>/plan-progress.json` | Internal state | Machine-readable v1 progress artifact used by neal context and summaries. |
|
|
78
82
|
| `.neal/runs/<run-id>/PLAN_PROGRESS.md` | User-facing human artifact | Human-readable progress summary for the active plan or scope. |
|
|
79
83
|
| `.neal/runs/<run-id>/RETROSPECTIVE.md` | User-facing human artifact | Human-readable retrospective or checkpoint summary. Archived variants such as `RETROSPECTIVE-scope-*.md` may also exist. |
|
|
84
|
+
| `.neal/runs/<run-id>/RUN_METRICS.json` | Support/debug artifact | Machine-readable metrics paired with the current retrospective. Archived variants such as `RUN_METRICS-scope-*.json` may also exist. |
|
|
80
85
|
| `.neal/runs/<run-id>/RUN_NARRATIVE.md` | User-facing human artifact | Human-readable run narrative. It includes a benchmark trace section with status, patch-policy, provider-error, and reproducibility summaries suitable for public result bundles. |
|
|
81
|
-
| `.neal/runs/<run-id>/RUN_NARRATIVE.json` | Internal state | Narrative source data that
|
|
86
|
+
| `.neal/runs/<run-id>/RUN_NARRATIVE.json` | Internal state | Narrative source data that neal may read to update the human narrative. It is not a public trace artifact. |
|
|
82
87
|
| `.neal/runs/<run-id>/REVIEW.md` | User-facing human artifact | Scope or plan review history and findings. |
|
|
88
|
+
| `.neal/runs/<run-id>/REVIEW-<commit>.md` | User-facing human artifact | Archived review history for an accepted scope commit. |
|
|
89
|
+
| `.neal/runs/<run-id>/REVIEWER_CONTEXT.md` | Support/debug artifact | Bounded reviewer-continuity packet rendered for inspection. |
|
|
90
|
+
| `.neal/runs/<run-id>/REVIEWER_CONTEXT.json` | Support/debug artifact | Machine-readable reviewer-continuity packet without the rendered prompt markdown. |
|
|
83
91
|
| `.neal/runs/<run-id>/RECOVERY.md` | User-facing human artifact | Interactive blocked-recovery transcript/history for a run. |
|
|
84
92
|
| `.neal/runs/<run-id>/FINAL_COMPLETION_REVIEW.md` | User-facing human artifact | Whole-plan final completion review. |
|
|
85
93
|
| `.neal/runs/<run-id>/SQUASH_RESULT.json` | Support/debug artifact | Versioned audit artifact from `neal squash`. It records the squash decision/result but is not the stable automation surface. |
|
|
86
94
|
| `.neal/runs/<run-id>/QUEUE_LINK.json` | Internal state | Link from a child run back to its parent plan-and-execute queue item. |
|
|
87
|
-
| `.neal/queues/<queue-id>/QUEUE_STATE.json` | Internal state | Parent queue ledger.
|
|
95
|
+
| `.neal/queues/<queue-id>/QUEUE_STATE.json` | Internal state | Parent queue ledger. neal validates it on read, but it is not a public JSON API. |
|
|
88
96
|
| `.neal/queues/<queue-id>/QUEUE_SUMMARY.md` | User-facing human artifact | Human-readable summary for a plan-and-execute queue. |
|
|
89
97
|
| `.neal/reviews/<review-id>/meta.json` | Support/debug artifact | Review metadata for a read-only `neal review` request. |
|
|
90
98
|
| `.neal/reviews/<review-id>/events.ndjson` | Support/debug artifact | Append-only review event log. |
|
|
@@ -97,19 +105,20 @@ Neal operations and diagnostics.
|
|
|
97
105
|
| `.neal/current.json` | Internal state | Default writer-run pointer for commands that need the current run. |
|
|
98
106
|
| `.neal/current-queue.json` | Internal state | Preferred current plan-and-execute queue pointer. |
|
|
99
107
|
| `.neal/active-run.lock` | Lock/concurrency artifact | Active writer-run lock. It prevents unrelated writer commands from mutating the same checkout concurrently. |
|
|
108
|
+
| `.neal/NOTES.md` | User-facing human artifact | Optional operator-authored notes included in bounded context packets. neal reads this file but does not create it. |
|
|
100
109
|
|
|
101
110
|
Writer processes remove their own active lock during normal shutdown and on
|
|
102
|
-
`SIGINT`/`SIGTERM`. Timeout wrappers should still launch
|
|
111
|
+
`SIGINT`/`SIGTERM`. Timeout wrappers should still launch neal in a process group
|
|
103
112
|
and terminate the group, because provider-owned child processes are outside the
|
|
104
113
|
lock file contract. After a timeout, call `neal status --json --run <run-id>`
|
|
105
|
-
when the run id is known
|
|
106
|
-
using `status`, `health`, and `lock.kind` to record whether
|
|
114
|
+
when the run id is known. Treat the wrapper timeout as the primary result while
|
|
115
|
+
using `status`, `health`, and `lock.kind` to record whether neal's run state is
|
|
107
116
|
still running, cleaned up, live, stale, cross-host, or unreadable.
|
|
108
117
|
|
|
109
|
-
## Patch
|
|
118
|
+
## Patch automation policy
|
|
110
119
|
|
|
111
120
|
Default public prediction submission should use only
|
|
112
|
-
`patch.defaultSubmissionEligible: true`.
|
|
121
|
+
`patch.defaultSubmissionEligible: true`. neal sets that value only for clean
|
|
113
122
|
completed execute runs with a non-empty readable patch range.
|
|
114
123
|
|
|
115
124
|
When a completed run has a successful squash artifact, the status read model
|
|
@@ -124,28 +133,28 @@ runs may still report patch-bearing metadata for diagnostics or private
|
|
|
124
133
|
analysis. They are not default-submission eligible, and `patch.reason` explains
|
|
125
134
|
why.
|
|
126
135
|
|
|
127
|
-
## Source
|
|
136
|
+
## Source of truth
|
|
128
137
|
|
|
129
138
|
Project-local `.neal/` remains the source of truth for run, queue, review,
|
|
130
139
|
recovery, progress, and audit artifacts.
|
|
131
140
|
|
|
132
141
|
Run-local `.neal/runs/<run-id>/RUN_STATE.json` is the only writer-run ledger
|
|
133
|
-
path
|
|
142
|
+
path neal writes. `.neal/current.json` points at the default writer run. It is a
|
|
134
143
|
pointer, not a copy of the ledger.
|
|
135
144
|
|
|
136
145
|
There is no required global run index in v1. Future global discovery, if added,
|
|
137
146
|
must be optional and rebuildable from project-local data. It must not become the
|
|
138
147
|
only place where run or queue history can be recovered.
|
|
139
148
|
|
|
140
|
-
## Ledgers
|
|
149
|
+
## Ledgers and pointers
|
|
141
150
|
|
|
142
151
|
`.neal/runs/<run-id>/RUN_STATE.json` and
|
|
143
|
-
`.neal/queues/<queue-id>/QUEUE_STATE.json` are persisted ledgers.
|
|
152
|
+
`.neal/queues/<queue-id>/QUEUE_STATE.json` are persisted ledgers. neal validates
|
|
144
153
|
them on read. Child-run state uses strict current v1 hydration: missing or
|
|
145
154
|
malformed required child-run fields fail instead of receiving defaults. These
|
|
146
155
|
ledgers are not public JSON APIs.
|
|
147
156
|
|
|
148
|
-
|
|
157
|
+
neal does not write, read, migrate, or repair a session mirror. Use
|
|
149
158
|
`.neal/current.json` as the default writer-run pointer, `neal status --all` to
|
|
150
159
|
discover run IDs, and `--run <run-id>` when selecting a specific run for
|
|
151
160
|
`resume` or `status`.
|
|
@@ -154,9 +163,9 @@ Squash discovery requires readable run-local state. Run metadata and progress
|
|
|
154
163
|
artifacts can help humans inspect a run, but they cannot make a run selectable
|
|
155
164
|
for `neal squash` without `.neal/runs/<run-id>/RUN_STATE.json`.
|
|
156
165
|
|
|
157
|
-
## Schema
|
|
166
|
+
## Schema versions and writes
|
|
158
167
|
|
|
159
|
-
|
|
168
|
+
neal-owned JSON schemas use `version: 1` where they are read back as durable
|
|
160
169
|
state or audit data. That includes child-run state, current run pointers, queue
|
|
161
170
|
state, current queue pointers, queue child links, progress summaries, run
|
|
162
171
|
narratives, squash audit results, review artifacts, and the active writer lock.
|
|
@@ -172,7 +181,7 @@ files such as state, progress, reviews, and pointers can briefly disagree if a
|
|
|
172
181
|
process stops between writes. Append-only event logs remain append-only, and the
|
|
173
182
|
active writer lock keeps exclusive file creation for acquisition.
|
|
174
183
|
|
|
175
|
-
## Retention
|
|
184
|
+
## Retention and privacy
|
|
176
185
|
|
|
177
186
|
`.neal/` may contain prompts, local paths, command output, diffs, review text,
|
|
178
187
|
provider responses, user guidance diagnostics, reviewer scratch files, copied
|
|
@@ -188,7 +197,7 @@ Run and review artifacts are intentionally inspectable, but they should be
|
|
|
188
197
|
treated as project data. Apply the same retention and access controls you use
|
|
189
198
|
for source, logs, and local debugging output.
|
|
190
199
|
|
|
191
|
-
## Manual
|
|
200
|
+
## Manual cleanup
|
|
192
201
|
|
|
193
202
|
Manual cleanup is safe only when you no longer need resume, history, diagnostics,
|
|
194
203
|
or audit data for the item being removed.
|
|
@@ -202,6 +211,6 @@ Reasonable manual cleanup options:
|
|
|
202
211
|
- remove stale `.neal/current.json` or `.neal/current-queue.json` pointers only
|
|
203
212
|
after confirming they do not point to work you still intend to resume
|
|
204
213
|
|
|
205
|
-
Deleting run or queue state removes
|
|
214
|
+
Deleting run or queue state removes neal's resume and history for that run or
|
|
206
215
|
queue. Prefer keeping the full directory until the related work has been merged,
|
|
207
216
|
archived, or otherwise recorded somewhere durable.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -6,7 +6,7 @@ prints. When in doubt: `neal check`, then `.neal/runs/<run-id>/stderr.log`.
|
|
|
6
6
|
## Install and first run
|
|
7
7
|
|
|
8
8
|
**Symptom:** install or startup fails on an old Node.
|
|
9
|
-
**Cause:** neal requires Node.js >=
|
|
9
|
+
**Cause:** neal requires Node.js >= 24.18.0 (`engines`). `.nvmrc` pins `24.18.0`.
|
|
10
10
|
**Fix:** `nvm use` in this repo, or upgrade Node before `npm install -g @navels/neal`.
|
|
11
11
|
|
|
12
12
|
**Symptom:** `pnpm: command not found` when running from source.
|
|
@@ -20,13 +20,13 @@ After source changes, `pnpm build` again so the linked command sees `dist/`.
|
|
|
20
20
|
|
|
21
21
|
**Symptom:** `neal setup` lists a provider with `- runtime not found`.
|
|
22
22
|
**Cause:** setup detects local runtime surfaces only (the `@openai/codex-sdk`
|
|
23
|
-
entrypoint
|
|
23
|
+
entrypoint, an SDK-bundled or on-PATH `claude` executable), never auth.
|
|
24
24
|
**Fix:** install the provider's SDK/CLI, then rerun `neal setup` and `neal check`.
|
|
25
25
|
|
|
26
26
|
## Provider auth failures (`neal check`)
|
|
27
27
|
|
|
28
28
|
`neal check` sends one small prompt per unique configured provider/model
|
|
29
|
-
(interactive TTY only
|
|
29
|
+
(interactive TTY only. Non-interactive input prints
|
|
30
30
|
`Provider verification skipped: non-interactive input.`). Known failures:
|
|
31
31
|
|
|
32
32
|
**Symptom:** `Claude Code refused bypass-permissions mode while running as root.`
|
|
@@ -40,31 +40,34 @@ Claude Code refuses under root/sudo.
|
|
|
40
40
|
directory (e.g. run the `codex` CLI there once), then `neal check` again.
|
|
41
41
|
|
|
42
42
|
**Symptom:** `OpenAI Codex could not persist the check session.`
|
|
43
|
-
**Fix:** transient
|
|
43
|
+
**Fix:** transient. Run `neal check` again. If it repeats, redo the provider's
|
|
44
44
|
local setup.
|
|
45
45
|
|
|
46
46
|
**Symptom:** a `not logged in` message from either vendor CLI.
|
|
47
|
-
**Cause:** provider auth is provider-owned
|
|
47
|
+
**Cause:** provider auth is provider-owned, so neal never collects credentials.
|
|
48
48
|
**Fix:** complete the provider's normal local auth setup (the `codex` / `claude`
|
|
49
49
|
login flows), then `neal check` again.
|
|
50
50
|
|
|
51
51
|
**Symptom:** `Set providers.openai_compatible.base_url (or OPENAI_COMPATIBLE_BASE_URL) and OPENAI_COMPATIBLE_API_KEY before running Neal.`
|
|
52
52
|
(or `No model is resolvable for the openai-compatible ... role`).
|
|
53
|
-
**Cause:** `openai-compatible`
|
|
54
|
-
with env fallbacks: `base_url` → `OPENAI_COMPATIBLE_BASE_URL
|
|
55
|
-
from the env var named by `api_key_env` (default `OPENAI_COMPATIBLE_API_KEY`)
|
|
56
|
-
|
|
53
|
+
**Cause:** `openai-compatible` resolves settings from config first,
|
|
54
|
+
with env fallbacks: `base_url` → `OPENAI_COMPATIBLE_BASE_URL`. The key is read
|
|
55
|
+
from the env var named by `api_key_env` (default `OPENAI_COMPATIBLE_API_KEY`).
|
|
56
|
+
Model from `agent.<role>.model` → `default_model` → `OPENAI_COMPATIBLE_MODEL`.
|
|
57
57
|
**Fix:** set the missing key. For OpenRouter: `base_url: https://openrouter.ai/api/v1`,
|
|
58
58
|
`api_key_env: OPENROUTER_API_KEY`, and export `OPENROUTER_API_KEY`. (OpenRouter
|
|
59
|
-
wraps upstream 429s in HTTP-200 bodies
|
|
59
|
+
wraps upstream 429s in HTTP-200 bodies, so neal unwraps and retries them.)
|
|
60
60
|
|
|
61
61
|
## Runs that won't start
|
|
62
62
|
|
|
63
|
-
**Symptom:** plan validation errors such as
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
**Symptom:** plan validation errors such as:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
Missing required `## Execution Shape` section.
|
|
67
|
+
`## Execution Shape` must contain exactly one non-empty line.
|
|
68
|
+
```
|
|
66
69
|
**Cause:** every executable plan must declare exactly one of
|
|
67
|
-
`executionShape: one_shot | multi_scope | multi_scope_unknown
|
|
70
|
+
`executionShape: one_shot | multi_scope | multi_scope_unknown`. `multi_scope`
|
|
68
71
|
also requires an `## Execution Queue` with contiguous `### Scope N:` headings,
|
|
69
72
|
each carrying `- Goal:` / `- Verification:` / `- Success Condition:` bullets.
|
|
70
73
|
**Fix:** see [plan-format.md](plan-format.md), or let `neal plan` refine the
|
|
@@ -72,23 +75,23 @@ document into executable shape.
|
|
|
72
75
|
|
|
73
76
|
**Symptom:** a missing-config error naming `agent.coder.provider` or
|
|
74
77
|
`agent.reviewer.provider`.
|
|
75
|
-
**Cause:** fresh writer runs require explicit coder and reviewer providers
|
|
76
|
-
|
|
78
|
+
**Cause:** fresh writer runs require explicit coder and reviewer providers.
|
|
79
|
+
Built-in defaults are not enough.
|
|
77
80
|
**Fix:** `neal setup`, then `neal check`.
|
|
78
81
|
|
|
79
82
|
**Symptom:** `Cannot start neal execute with a dirty worktree:` followed by
|
|
80
83
|
`git status` lines (queues: `Cannot continue neal run with a dirty worktree:`).
|
|
81
|
-
**Cause:** writer admission requires a clean worktree
|
|
84
|
+
**Cause:** writer admission requires a clean worktree. Only the selected plan
|
|
82
85
|
document and neal-owned paths (`.neal/`) are exempt. Leftover reviewer scratch
|
|
83
86
|
(`build_review/`, `scratch/`, …) gets a
|
|
84
|
-
`Likely Neal reviewer scratch leakage detected:` diagnostic but still blocks
|
|
85
|
-
the paths are not proven neal-owned.
|
|
87
|
+
`Likely Neal reviewer scratch leakage detected:` diagnostic but still blocks,
|
|
88
|
+
because the paths are not proven neal-owned.
|
|
86
89
|
**Fix:** use `neal resume` for in-progress scope work, or commit, stash, move,
|
|
87
90
|
or remove the dirty paths and start clean.
|
|
88
91
|
|
|
89
92
|
**Symptom:** a Git precondition error before any provider runs.
|
|
90
93
|
**Fix:** writer commands require a Git repository with an existing `HEAD`
|
|
91
|
-
commit
|
|
94
|
+
commit. Create the initial baseline commit first.
|
|
92
95
|
|
|
93
96
|
## Stuck or blocked runs
|
|
94
97
|
|
|
@@ -100,26 +103,26 @@ something it may not resolve alone, and attended runs wait for guidance.
|
|
|
100
103
|
accepted in that waiting-for-guidance state.
|
|
101
104
|
|
|
102
105
|
**Symptom:** `effectiveStatus: "waiting_for_manual_gate"`.
|
|
103
|
-
**Cause:** the scope reached expected human work
|
|
106
|
+
**Cause:** the scope reached expected human work. Instructions are in the
|
|
104
107
|
run-local `GATE-<id>.md` file shown by `neal status`.
|
|
105
|
-
**Fix:** do the manual step, then `neal resume --run <run-id
|
|
108
|
+
**Fix:** do the manual step, then `neal resume --run <run-id>`, which re-runs
|
|
106
109
|
the gate's checks and resumes the scope when they pass. No `--message` here.
|
|
107
110
|
|
|
108
111
|
**Symptom:** a run seems hung or died silently.
|
|
109
112
|
**Where to look:** raw detail is persisted even when hidden from the terminal:
|
|
110
113
|
`.neal/runs/<run-id>/stderr.log` (full transcript) and
|
|
111
|
-
`.neal/runs/<run-id>/events.ndjson` (event log
|
|
112
|
-
as `provider.turn_liveness_*` events). On a live TTY, press `v` for the
|
|
114
|
+
`.neal/runs/<run-id>/events.ndjson` (event log, where startup-silence retries
|
|
115
|
+
appear as `provider.turn_liveness_*` events). On a live TTY, press `v` for the
|
|
113
116
|
low-level detail view. `neal status --json --run <run-id>` carries the latest
|
|
114
117
|
`providerError` classification.
|
|
115
118
|
|
|
116
119
|
## Lock issues
|
|
117
120
|
|
|
118
|
-
The writer lock is `.neal/active-run.lock
|
|
121
|
+
The writer lock is `.neal/active-run.lock`. Writer processes remove it on
|
|
119
122
|
normal shutdown and on SIGINT/SIGTERM.
|
|
120
123
|
|
|
121
124
|
**Symptom:** `another Neal writer run is active in this checkout`.
|
|
122
|
-
**Fix:** as printed
|
|
125
|
+
**Fix:** as printed: `neal resume --run <run-id>` to continue that run, or
|
|
123
126
|
wait for it to finish.
|
|
124
127
|
|
|
125
128
|
**Symptom:** `another Neal process is already resuming this run` (with
|
|
@@ -128,17 +131,17 @@ wait for it to finish.
|
|
|
128
131
|
|
|
129
132
|
**Symptom:** `stale Neal writer lock found in this checkout` /
|
|
130
133
|
`no process with that PID is running on this host.`
|
|
131
|
-
**Fix:** `neal resume --run <run-id>` clears stale same-host locks itself
|
|
134
|
+
**Fix:** `neal resume --run <run-id>` clears stale same-host locks itself. If
|
|
132
135
|
you're starting different work instead, inspect the run, then remove the lock
|
|
133
136
|
file the message names.
|
|
134
137
|
|
|
135
138
|
**Symptom:** `Neal writer lock belongs to another host`.
|
|
136
|
-
**Fix:** inspect the other host before removing the lock
|
|
139
|
+
**Fix:** inspect the other host before removing the lock. The message prints
|
|
137
140
|
the exact resume command for that checkout.
|
|
138
141
|
|
|
139
142
|
**Symptom:** `could not read the active Neal writer lock`.
|
|
140
143
|
**Fix:** as printed: inspect the named lock file before starting another
|
|
141
|
-
writer run
|
|
144
|
+
writer run. Remove it only after confirming no writer process is active.
|
|
142
145
|
|
|
143
146
|
## "It squashed when I didn't want it to"
|
|
144
147
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
diff --git a/src/add.js b/src/add.js
|
|
2
|
-
index
|
|
2
|
+
index 6946b9a..e9fa11d 100644
|
|
3
3
|
--- a/src/add.js
|
|
4
4
|
+++ b/src/add.js
|
|
5
5
|
@@ -1,2 +1,2 @@
|
|
6
|
-
// Trivial compat fixture:
|
|
6
|
+
// Trivial compat fixture: an arithmetic helper exercised by test/add.test.js.
|
|
7
7
|
-export const add = (a, b) => a - b;
|
|
8
8
|
+export const add = (a, b) => a * b;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
diff --git a/src/add.js b/src/add.js
|
|
2
|
-
index
|
|
2
|
+
index 6946b9a..ee66238 100644
|
|
3
3
|
--- a/src/add.js
|
|
4
4
|
+++ b/src/add.js
|
|
5
5
|
@@ -1,2 +1,2 @@
|
|
6
|
-
// Trivial compat fixture:
|
|
6
|
+
// Trivial compat fixture: an arithmetic helper exercised by test/add.test.js.
|
|
7
7
|
-export const add = (a, b) => a - b;
|
|
8
8
|
+export const add = (a, b) => a + b;
|