@harness-engineering/cli 1.14.0 → 1.15.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/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +240 -39
- package/dist/agents/skills/claude-code/harness-autopilot/skill.yaml +6 -0
- package/dist/agents/skills/claude-code/harness-product-spec/SKILL.md +5 -5
- package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +240 -39
- package/dist/agents/skills/gemini-cli/harness-autopilot/skill.yaml +6 -0
- package/dist/agents/skills/gemini-cli/harness-product-spec/SKILL.md +5 -5
- package/dist/agents/skills/package.json +1 -0
- package/dist/agents/skills/vitest.config.mts +5 -0
- package/dist/{agents-md-YTYQDA3P.js → agents-md-ZGNIDWAF.js} +1 -1
- package/dist/{architecture-JQZYM4US.js → architecture-ZLIH5533.js} +2 -2
- package/dist/bin/harness-mcp.js +11 -11
- package/dist/bin/harness.js +16 -14
- package/dist/{check-phase-gate-L3RADYWO.js → check-phase-gate-ZOXVBDCN.js} +3 -3
- package/dist/{chunk-7IP4JIFL.js → chunk-2BKLWLY6.js} +4 -4
- package/dist/{chunk-OSXBPAMK.js → chunk-3ZZKVN62.js} +1 -1
- package/dist/{chunk-O5OJVPL6.js → chunk-B2HKP423.js} +1 -1
- package/dist/{chunk-YPYGXRDR.js → chunk-EDXIVMAP.js} +4 -4
- package/dist/{chunk-XKECDXJS.js → chunk-J4RAX7YB.js} +738 -186
- package/dist/{chunk-6KTUUFRN.js → chunk-LGYBN7Y6.js} +1 -1
- package/dist/{chunk-3C2MLBPJ.js → chunk-N25INEIX.js} +1 -1
- package/dist/{chunk-NLVUVUGD.js → chunk-ND2ENWDM.js} +1 -1
- package/dist/{chunk-YZD2MRNQ.js → chunk-NNHDDXYT.js} +379 -119
- package/dist/{chunk-S2FXOWOR.js → chunk-OFXQSFOW.js} +2 -2
- package/dist/{chunk-OXLLOSSR.js → chunk-VEPAJXBW.js} +2 -2
- package/dist/{chunk-TPOTOBR7.js → chunk-YLXFKVJE.js} +3 -3
- package/dist/{chunk-ABQHQ6I5.js → chunk-Z2OOPXJO.js} +1238 -133
- package/dist/{ci-workflow-EQZFVX3P.js → ci-workflow-765LSHRD.js} +1 -1
- package/dist/{dist-HWXF2C3R.js → dist-ALQDD67R.js} +47 -1
- package/dist/{docs-7ECGYMAV.js → docs-NRMQCOJ6.js} +3 -3
- package/dist/{engine-EG4EH4IX.js → engine-3RB7MXPP.js} +1 -1
- package/dist/{entropy-5USWKLVS.js → entropy-6AGX2ZUN.js} +2 -2
- package/dist/{feedback-UTBXZZHF.js → feedback-MY4QZIFD.js} +1 -1
- package/dist/{generate-agent-definitions-3PM5EU7V.js → generate-agent-definitions-ZAE726AU.js} +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.js +13 -13
- package/dist/{loader-ZPALXIVR.js → loader-UUTVMQCC.js} +1 -1
- package/dist/{mcp-362EZHF4.js → mcp-VU5FMO52.js} +11 -11
- package/dist/{performance-OQAFMJUD.js → performance-2D7G6NMJ.js} +2 -2
- package/dist/{review-pipeline-C4GCFVGP.js → review-pipeline-RAQ55ISU.js} +1 -1
- package/dist/{runtime-7YLVK453.js → runtime-BCK5RRZQ.js} +1 -1
- package/dist/{security-PZOX7AQS.js → security-2RPQEN62.js} +1 -1
- package/dist/{validate-FD3Z6VJD.js → validate-KBYQAEWE.js} +2 -2
- package/dist/{validate-cross-check-WNJM6H2D.js → validate-cross-check-OABMREW4.js} +1 -1
- package/package.json +5 -3
|
@@ -31,7 +31,7 @@ Autopilot orchestrates these persona agents — it never reimplements their logi
|
|
|
31
31
|
- **Claude Code:** Use the Agent tool with `subagent_type` set to the persona name.
|
|
32
32
|
- **Gemini CLI:** Use the `run_agent` tool targeting the persona by name, or dispatch via `harness persona run <name>`.
|
|
33
33
|
|
|
34
|
-
**
|
|
34
|
+
**Plans are gated by concern signals.** When no concern signals fire (low complexity, no planner concerns, task count within threshold), plans are auto-approved with a structured report and execution proceeds immediately. When any signal fires, the plan pauses for human review with the standard yes/revise/skip/stop flow. The `--review-plans` session flag forces all plans to pause regardless of signals.
|
|
35
35
|
|
|
36
36
|
## Process
|
|
37
37
|
|
|
@@ -42,7 +42,7 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
42
42
|
↓
|
|
43
43
|
[next phase?]
|
|
44
44
|
↓ ↓
|
|
45
|
-
ASSESS
|
|
45
|
+
ASSESS FINAL_REVIEW → DONE
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
---
|
|
@@ -61,7 +61,9 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
61
61
|
- Create the session directory if it does not exist
|
|
62
62
|
|
|
63
63
|
3. **Check for existing state.** Read `{sessionDir}/autopilot-state.json`. If it exists and `currentState` is not `DONE`:
|
|
64
|
+
- **Schema migration:** If `schemaVersion < 3`, backfill missing fields: set `startingCommit` to the earliest commit in `history` (or current HEAD if no history), set `decisions` to `[]`, set `finalReview` to `{ "status": "pending", "findings": [], "retryCount": 0 }`. If `schemaVersion < 4`, set `reviewPlans` to `false`. Update `schemaVersion` to `4` and save.
|
|
64
65
|
- Report: "Resuming autopilot from state `{currentState}`, phase {currentPhase}: {phaseName}."
|
|
66
|
+
- Skip steps 4 and 5 (initial state creation and flag parsing) — these only apply to fresh starts.
|
|
65
67
|
- Skip to the recorded `currentState` and continue from there.
|
|
66
68
|
|
|
67
69
|
4. **If no existing state (fresh start):**
|
|
@@ -70,12 +72,15 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
70
72
|
- For each phase heading (`### Phase N: Name`), extract:
|
|
71
73
|
- Phase name
|
|
72
74
|
- Complexity annotation (`<!-- complexity: low|medium|high -->`, default: `medium`)
|
|
75
|
+
- Capture the starting commit: run `git rev-parse HEAD` and store the result as `startingCommit`.
|
|
73
76
|
- Create `{sessionDir}/autopilot-state.json`:
|
|
74
77
|
```json
|
|
75
78
|
{
|
|
76
|
-
"schemaVersion":
|
|
79
|
+
"schemaVersion": 4,
|
|
77
80
|
"sessionDir": ".harness/sessions/<slug>",
|
|
78
81
|
"specPath": "<path to spec>",
|
|
82
|
+
"startingCommit": "<git rev-parse HEAD output>",
|
|
83
|
+
"reviewPlans": false,
|
|
79
84
|
"currentState": "ASSESS",
|
|
80
85
|
"currentPhase": 0,
|
|
81
86
|
"phases": [
|
|
@@ -91,11 +96,19 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
91
96
|
"maxAttempts": 3,
|
|
92
97
|
"currentTask": null
|
|
93
98
|
},
|
|
94
|
-
"history": []
|
|
99
|
+
"history": [],
|
|
100
|
+
"decisions": [],
|
|
101
|
+
"finalReview": {
|
|
102
|
+
"status": "pending",
|
|
103
|
+
"findings": [],
|
|
104
|
+
"retryCount": 0
|
|
105
|
+
}
|
|
95
106
|
}
|
|
96
107
|
```
|
|
97
108
|
|
|
98
|
-
5. **
|
|
109
|
+
5. **Parse session flags.** Check CLI arguments for `--review-plans`. If present, set `state.reviewPlans: true` in the state file. This flag persists for the entire session — resuming a session preserves the setting from when it was started (the flag is only read on fresh start, not on resume).
|
|
110
|
+
|
|
111
|
+
6. **Load context via gather_context.** Use the `gather_context` MCP tool to load all working context efficiently:
|
|
99
112
|
|
|
100
113
|
```json
|
|
101
114
|
gather_context({
|
|
@@ -109,19 +122,19 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
109
122
|
|
|
110
123
|
This loads session-scoped learnings, handoff, state, and validation results in a single call. The `session` parameter ensures all reads come from the session directory (`.harness/sessions/<slug>/`), isolating this workstream from others. Note any relevant learnings or known dead ends for the current phase from the returned `learnings` array.
|
|
111
124
|
|
|
112
|
-
|
|
125
|
+
7. **Load session summary for cold start.** If resuming (existing `autopilot-state.json` found):
|
|
113
126
|
- Call `loadSessionSummary()` for the session slug to get quick orientation context (~200 tokens).
|
|
114
127
|
- The summary provides the last skill, phase, status, and next step — enough to understand where the autopilot left off without re-reading the full state machine.
|
|
115
128
|
- If no summary exists (first run), skip — the full INIT handles context loading.
|
|
116
129
|
|
|
117
|
-
|
|
130
|
+
8. **Load roadmap context.** If `docs/roadmap.md` exists, read it to understand:
|
|
118
131
|
- Current project priorities (which features are `in-progress`)
|
|
119
132
|
- Blockers that may affect the upcoming phases
|
|
120
133
|
- Overall project status and milestone progress
|
|
121
134
|
|
|
122
135
|
This provides the autopilot with project-level context beyond the individual spec being executed. If the roadmap does not exist, skip this step — the autopilot operates normally without it.
|
|
123
136
|
|
|
124
|
-
|
|
137
|
+
9. **Transition to ASSESS.**
|
|
125
138
|
|
|
126
139
|
---
|
|
127
140
|
|
|
@@ -192,27 +205,114 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
192
205
|
|
|
193
206
|
---
|
|
194
207
|
|
|
195
|
-
### APPROVE_PLAN —
|
|
196
|
-
|
|
197
|
-
**This state always pauses for human input.**
|
|
208
|
+
### APPROVE_PLAN — Conditional Review Gate
|
|
198
209
|
|
|
199
|
-
1. **
|
|
210
|
+
1. **Gather plan metadata:**
|
|
200
211
|
- Phase name and number
|
|
201
|
-
- Task count
|
|
212
|
+
- Task count (from the plan file)
|
|
202
213
|
- Checkpoint count
|
|
203
|
-
- Estimated time (task count
|
|
214
|
+
- Estimated time (task count x 3 minutes)
|
|
204
215
|
- Effective complexity (original + any override)
|
|
205
|
-
-
|
|
216
|
+
- Concerns array from the planning handoff (`{sessionDir}/handoff.json` field `concerns`, default: `[]` if field is absent)
|
|
217
|
+
|
|
218
|
+
2. **Evaluate `shouldPauseForReview`.** Check the following signals in order. If **any** signal is true, pause for human review. If **all** are false, auto-approve.
|
|
219
|
+
|
|
220
|
+
| # | Signal | Condition | Description |
|
|
221
|
+
| --- | -------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
222
|
+
| 1 | `reviewPlans` | `state.reviewPlans === true` | Session-level flag set by `--review-plans` CLI arg |
|
|
223
|
+
| 2 | `highComplexity` | `phase.complexity === "high"` | Phase is marked as high complexity in the spec (reachable when resuming after interactive planning; confirms the plan is ready for automated execution even though the human drove planning) |
|
|
224
|
+
| 3 | `complexityOverride` | `phase.complexityOverride !== null` | Planner produced more tasks than expected for the spec complexity |
|
|
225
|
+
| 4 | `plannerConcerns` | Handoff `concerns` array is non-empty | Planner flagged specific risks or uncertainties |
|
|
226
|
+
| 5 | `taskCount` | Plan contains > 15 tasks (i.e., 16+) | Plan is large enough to warrant human review |
|
|
227
|
+
|
|
228
|
+
3. **Build the signal evaluation result** for reporting and recording:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"reviewPlans": false,
|
|
233
|
+
"highComplexity": "low",
|
|
234
|
+
"complexityOverride": null,
|
|
235
|
+
"plannerConcerns": [],
|
|
236
|
+
"taskCount": 8,
|
|
237
|
+
"taskThreshold": 15
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
4. **If auto-approving (no signals fired):**
|
|
242
|
+
|
|
243
|
+
a. **Emit structured auto-approve report:**
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
Auto-approved Phase 1: Setup Infrastructure
|
|
247
|
+
Review mode: auto
|
|
248
|
+
Complexity: low (no override)
|
|
249
|
+
Planner concerns: none
|
|
250
|
+
Tasks: 8 (threshold: 15)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
b. **Record the decision** in state `decisions` array:
|
|
254
|
+
|
|
255
|
+
```json
|
|
256
|
+
{
|
|
257
|
+
"phase": 0,
|
|
258
|
+
"decision": "auto_approved_plan",
|
|
259
|
+
"timestamp": "ISO-8601",
|
|
260
|
+
"signals": {
|
|
261
|
+
"reviewPlans": false,
|
|
262
|
+
"highComplexity": "low",
|
|
263
|
+
"complexityOverride": null,
|
|
264
|
+
"plannerConcerns": [],
|
|
265
|
+
"taskCount": 8,
|
|
266
|
+
"taskThreshold": 15
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
c. **Transition to EXECUTE** — no human interaction needed.
|
|
272
|
+
|
|
273
|
+
5. **If pausing for review (one or more signals fired):**
|
|
206
274
|
|
|
207
|
-
|
|
275
|
+
a. **Emit structured pause report** showing which signal(s) triggered:
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
Pausing for review -- Phase 2: Auth Middleware
|
|
279
|
+
Review mode: manual (--review-plans flag set)
|
|
280
|
+
Complexity override: low -> medium (triggered)
|
|
281
|
+
Planner concerns: 2 concern(s)
|
|
282
|
+
Tasks: 12 (threshold: 15)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Mark triggered signals explicitly. Non-triggered signals display their normal value without "(triggered)".
|
|
286
|
+
|
|
287
|
+
b. **Present the plan summary:** task count, checkpoint count, estimated time, effective complexity, and any concerns from the planning handoff.
|
|
288
|
+
|
|
289
|
+
c. **Ask:** "Approve this plan and begin execution? (yes / revise / skip phase / stop)"
|
|
208
290
|
- **yes** — Transition to EXECUTE.
|
|
209
|
-
- **revise** — Tell user to edit the plan file directly, then re-present.
|
|
291
|
+
- **revise** — Tell user to edit the plan file directly, then re-present from step 1.
|
|
210
292
|
- **skip phase** — Mark phase as `skipped` in state, transition to PHASE_COMPLETE.
|
|
211
293
|
- **stop** — Save state and exit. User can resume later.
|
|
212
294
|
|
|
213
|
-
|
|
295
|
+
d. **Record the decision** in state `decisions` array:
|
|
296
|
+
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
"phase": 0,
|
|
300
|
+
"decision": "approved_plan",
|
|
301
|
+
"timestamp": "ISO-8601",
|
|
302
|
+
"signals": {
|
|
303
|
+
"reviewPlans": true,
|
|
304
|
+
"highComplexity": "low",
|
|
305
|
+
"complexityOverride": "medium",
|
|
306
|
+
"plannerConcerns": ["concern text"],
|
|
307
|
+
"taskCount": 12,
|
|
308
|
+
"taskThreshold": 15
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Use the actual decision value: `approved_plan`, `revised_plan`, `skipped_phase`, or `stopped`.
|
|
214
314
|
|
|
215
|
-
|
|
315
|
+
6. **Update state** with `currentState: "EXECUTE"` (or appropriate state for skip/stop) and save.
|
|
216
316
|
|
|
217
317
|
---
|
|
218
318
|
|
|
@@ -289,9 +389,9 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
289
389
|
|
|
290
390
|
2. **When the agent returns:**
|
|
291
391
|
- **All checks pass:** Transition to REVIEW.
|
|
292
|
-
- **Failures found:** Surface findings to the user. Ask: "Fix these issues before review? (
|
|
293
|
-
- **
|
|
294
|
-
- **skip** — Proceed to REVIEW with verification warnings noted.
|
|
392
|
+
- **Failures found:** Surface findings to the user. Ask: "Fix these issues before review? (fix / skip verification / stop)"
|
|
393
|
+
- **fix** — Re-enter EXECUTE with targeted fixes (retry budget resets for verification fixes).
|
|
394
|
+
- **skip** — Record skip decision in `decisions` array. Proceed to REVIEW with verification warnings noted.
|
|
295
395
|
- **stop** — Save state and exit.
|
|
296
396
|
|
|
297
397
|
3. **Update state** with `currentState: "REVIEW"` and save.
|
|
@@ -320,9 +420,10 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
320
420
|
```
|
|
321
421
|
|
|
322
422
|
2. **When the agent returns:**
|
|
423
|
+
- **Persist review findings:** Write the review findings to `{sessionDir}/phase-{N}-review.json` (array of findings with severity, file, line, title). This file is consumed by FINAL_REVIEW step 3.
|
|
323
424
|
- **No blocking findings:** Report summary, transition to PHASE_COMPLETE.
|
|
324
|
-
- **Blocking findings:** Surface to user. Ask: "Address blocking findings before completing this phase? (
|
|
325
|
-
- **
|
|
425
|
+
- **Blocking findings:** Surface to user. Ask: "Address blocking findings before completing this phase? (fix / override / stop)"
|
|
426
|
+
- **fix** — Re-enter EXECUTE with review fixes.
|
|
326
427
|
- **override** — Record override decision, transition to PHASE_COMPLETE.
|
|
327
428
|
- **stop** — Save state and exit.
|
|
328
429
|
|
|
@@ -379,7 +480,76 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
379
480
|
- If more phases remain: "Phase {N} complete. Next: Phase {N+1}: {name} (complexity: {level}). Continue? (yes / stop)"
|
|
380
481
|
- **yes** — Increment `currentPhase`, reset `retryBudget`, transition to ASSESS.
|
|
381
482
|
- **stop** — Save state and exit.
|
|
382
|
-
- If no more phases: Transition to
|
|
483
|
+
- If no more phases: Transition to FINAL_REVIEW.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
### FINAL_REVIEW — Project-Wide Code Review
|
|
488
|
+
|
|
489
|
+
> Runs automatically after the last phase completes. Reviews the cumulative diff (`startingCommit..HEAD`) across all phases to catch cross-phase issues before the PR offer.
|
|
490
|
+
|
|
491
|
+
1. **Update state** with `currentState: "FINAL_REVIEW"` and save.
|
|
492
|
+
|
|
493
|
+
2. **Update `finalReview` tracking** in `autopilot-state.json`: set `finalReview.status` to `"in_progress"`.
|
|
494
|
+
|
|
495
|
+
3. **Gather per-phase review findings.** Read from `{sessionDir}/` — each phase's review output is stored alongside the phase handoff. Collect all review findings across phases into a single context block.
|
|
496
|
+
|
|
497
|
+
4. **Dispatch review agent using the Agent tool:**
|
|
498
|
+
|
|
499
|
+
```
|
|
500
|
+
Agent tool parameters:
|
|
501
|
+
subagent_type: "harness-code-reviewer"
|
|
502
|
+
description: "Final review: cross-phase coherence check"
|
|
503
|
+
prompt: |
|
|
504
|
+
You are running harness-code-review as a final project-wide review.
|
|
505
|
+
|
|
506
|
+
Diff scope: startingCommit..HEAD (use `git diff {startingCommit}..HEAD`)
|
|
507
|
+
Starting commit: {startingCommit}
|
|
508
|
+
Session directory: {sessionDir}
|
|
509
|
+
Session slug: {sessionSlug}
|
|
510
|
+
|
|
511
|
+
On startup, call gather_context({ session: "{sessionSlug}" }) to load
|
|
512
|
+
session-scoped learnings, state, and validation context.
|
|
513
|
+
|
|
514
|
+
## Per-Phase Review Findings
|
|
515
|
+
|
|
516
|
+
{collected per-phase findings}
|
|
517
|
+
|
|
518
|
+
These were found and addressed during per-phase reviews. Don't assume
|
|
519
|
+
they're resolved — verify. Focus extra attention on cross-phase coherence:
|
|
520
|
+
naming consistency, duplicated utilities, architectural drift across phases.
|
|
521
|
+
|
|
522
|
+
Review the FULL diff (startingCommit..HEAD), not just the last phase.
|
|
523
|
+
Report findings with severity (blocking / warning / note).
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
5. **When the agent returns:**
|
|
527
|
+
- **No blocking findings:** Store all findings (blocking, warning, note) in `finalReview.findings`. Update `finalReview.status` to `"passed"`, report summary, transition to DONE.
|
|
528
|
+
- **Blocking findings:** Store all findings (blocking, warning, note) in `finalReview.findings`. Surface blocking findings to user. Ask: "Address blocking findings before completing? (fix / override / stop)"
|
|
529
|
+
- **fix** — Increment `finalReview.retryCount`. If `retryCount <= 3`: dispatch fixes using the Agent tool, then run `harness validate` to verify the fix, then re-run FINAL_REVIEW from step 2 (re-sets status to `in_progress`, re-gathers per-phase findings for fresh context). If `retryCount > 3`: stop — present all attempts to user, record in `.harness/failures.md`, ask: "How should we proceed? (fix manually and continue / stop)"
|
|
530
|
+
|
|
531
|
+
Fix dispatch:
|
|
532
|
+
|
|
533
|
+
```
|
|
534
|
+
Agent tool parameters:
|
|
535
|
+
subagent_type: "harness-task-executor"
|
|
536
|
+
description: "Fix final review findings"
|
|
537
|
+
prompt: |
|
|
538
|
+
Fix the following blocking review findings. One task per finding.
|
|
539
|
+
|
|
540
|
+
{blocking findings with file, line, title, and rationale}
|
|
541
|
+
|
|
542
|
+
Session directory: {sessionDir}
|
|
543
|
+
Session slug: {sessionSlug}
|
|
544
|
+
|
|
545
|
+
Follow the harness-execution skill process. Commit each fix atomically.
|
|
546
|
+
Write {sessionDir}/handoff.json when done.
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
- **override** — Record override decision (rationale from user) in state `decisions` array. Update `finalReview.status` to `"overridden"`. Transition to DONE.
|
|
550
|
+
- **stop** — Save state and exit. Resumable from FINAL_REVIEW.
|
|
551
|
+
|
|
552
|
+
6. **Update state** and save after each step.
|
|
383
553
|
|
|
384
554
|
---
|
|
385
555
|
|
|
@@ -390,7 +560,8 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
390
560
|
- Total tasks across all phases
|
|
391
561
|
- Total retries used
|
|
392
562
|
- Total time (first phase start to last phase completion)
|
|
393
|
-
-
|
|
563
|
+
- Final review result: `finalReview.status` (passed / overridden) and total findings count from `finalReview.findings`
|
|
564
|
+
- Any overridden review findings (per-phase and final)
|
|
394
565
|
|
|
395
566
|
2. **Offer next steps:**
|
|
396
567
|
- "Create a PR? (yes / no)"
|
|
@@ -407,7 +578,11 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
407
578
|
"pending": [],
|
|
408
579
|
"concerns": [],
|
|
409
580
|
"decisions": ["<all decisions from all phases>"],
|
|
410
|
-
"contextKeywords": ["<merged from spec>"]
|
|
581
|
+
"contextKeywords": ["<merged from spec>"],
|
|
582
|
+
"finalReview": {
|
|
583
|
+
"status": "<passed | overridden>",
|
|
584
|
+
"findingsCount": "<number of findings from final review>"
|
|
585
|
+
}
|
|
411
586
|
}
|
|
412
587
|
```
|
|
413
588
|
|
|
@@ -419,9 +594,13 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
419
594
|
- [skill:harness-autopilot] [outcome:observation] {any notable patterns from the run}
|
|
420
595
|
```
|
|
421
596
|
|
|
422
|
-
5. **
|
|
597
|
+
5. **Promote session learnings to global.** Call `promoteSessionLearnings(projectPath, sessionSlug)` to move generalizable session learnings (tagged `[outcome:gotcha]`, `[outcome:decision]`, `[outcome:observation]`) to the global `learnings.md`. Report: "Promoted {N} learnings to global, {M} session-specific entries kept in session."
|
|
598
|
+
|
|
599
|
+
6. **Check if pruning is needed.** Call `countLearningEntries(projectPath)`. If the count exceeds 30, suggest: "Global learnings.md has {count} entries (threshold: 30). Run `harness learnings prune` to analyze patterns and archive old entries."
|
|
600
|
+
|
|
601
|
+
7. **Update roadmap to done.** If `docs/roadmap.md` exists and the current spec maps to a roadmap feature, call `manage_roadmap` with action `update` to set the feature status to `done`. Derive the feature name from the spec title (H1 heading) or the session's `handoff.json` `summary` field. If `manage_roadmap` is unavailable, fall back to direct file manipulation using `updateFeature()` from core. Skip silently if no roadmap exists or if the feature is not found. Do not use `force_sync: true`.
|
|
423
602
|
|
|
424
|
-
|
|
603
|
+
8. **Write final session summary.** Update the session summary to reflect completion:
|
|
425
604
|
|
|
426
605
|
```json
|
|
427
606
|
writeSessionSummary(projectPath, sessionSlug, {
|
|
@@ -435,7 +614,7 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
435
614
|
})
|
|
436
615
|
```
|
|
437
616
|
|
|
438
|
-
|
|
617
|
+
9. **Clean up state:** Set `currentState: "DONE"` in `{sessionDir}/autopilot-state.json`. Do not delete the file — it serves as a record.
|
|
439
618
|
|
|
440
619
|
## Harness Integration
|
|
441
620
|
|
|
@@ -444,7 +623,7 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
444
623
|
- **`harness check-deps`** — Delegated to harness-execution (included in task steps).
|
|
445
624
|
- **State file** — `.harness/sessions/<slug>/autopilot-state.json` tracks the orchestration state machine. `.harness/sessions/<slug>/state.json` tracks task-level execution state (managed by harness-execution). The slug is derived from the spec path during INIT.
|
|
446
625
|
- **Handoff** — `.harness/sessions/<slug>/handoff.json` is written by each delegated skill and read by the next. Autopilot writes a final handoff on DONE.
|
|
447
|
-
- **Learnings** — `.harness/learnings.md` (global) is appended by both delegated skills and autopilot itself.
|
|
626
|
+
- **Learnings** — `.harness/learnings.md` (global) is appended by both delegated skills and autopilot itself. On DONE, session learnings with generalizable outcomes are promoted to global via `promoteSessionLearnings`. If global count exceeds 30, autopilot suggests running `harness learnings prune`.
|
|
448
627
|
- **Roadmap context** — During INIT, reads `docs/roadmap.md` (if present) for project-level priorities, blockers, and milestone status. Provides broader context for phase execution decisions.
|
|
449
628
|
- **Roadmap sync** — During PHASE_COMPLETE, calls `manage_roadmap` with `sync` and `apply: true` to reflect phase progress. During DONE, calls `manage_roadmap` with `update` to set feature status to `done`. Both skip silently when no roadmap exists. Neither uses `force_sync: true`.
|
|
450
629
|
|
|
@@ -456,7 +635,8 @@ INIT → ASSESS → PLAN → APPROVE_PLAN → EXECUTE → VERIFY → REVIEW →
|
|
|
456
635
|
- Planning override bumps complexity upward when task signals disagree
|
|
457
636
|
- Retry budget (3 attempts) with escalating context before surfacing failures
|
|
458
637
|
- Existing skills (planning, execution, verification, review) are unchanged
|
|
459
|
-
-
|
|
638
|
+
- Plans auto-approve when no concern signals fire; plans pause for human review when any signal fires
|
|
639
|
+
- `--review-plans` flag forces human review for all plans in a session
|
|
460
640
|
- Phase completion summary shown between every phase
|
|
461
641
|
|
|
462
642
|
## Examples
|
|
@@ -491,10 +671,11 @@ Plan generated: docs/plans/2026-03-19-core-scanner-plan.md (8 tasks, ~24 min)
|
|
|
491
671
|
**Phase 1 — APPROVE_PLAN:**
|
|
492
672
|
|
|
493
673
|
```
|
|
494
|
-
Phase 1: Core Scanner
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
674
|
+
Auto-approved Phase 1: Core Scanner
|
|
675
|
+
Review mode: auto
|
|
676
|
+
Complexity: low (no override)
|
|
677
|
+
Planner concerns: none
|
|
678
|
+
Tasks: 8 (threshold: 15)
|
|
498
679
|
```
|
|
499
680
|
|
|
500
681
|
**Phase 1 — EXECUTE → VERIFY → REVIEW:**
|
|
@@ -533,10 +714,22 @@ Resuming autopilot from state PLAN, phase 2: Rule Engine.
|
|
|
533
714
|
Found plan: docs/plans/2026-03-19-rule-engine-plan.md
|
|
534
715
|
```
|
|
535
716
|
|
|
536
|
-
**Phase 2 — APPROVE_PLAN
|
|
717
|
+
**Phase 2 — APPROVE_PLAN:**
|
|
537
718
|
|
|
538
719
|
```
|
|
539
|
-
|
|
720
|
+
Pausing for review -- Phase 2: Rule Engine
|
|
721
|
+
Review mode: auto
|
|
722
|
+
Complexity: high (triggered)
|
|
723
|
+
Planner concerns: none
|
|
724
|
+
Tasks: 14 (threshold: 15)
|
|
725
|
+
Approve this plan and begin execution? (yes / revise / skip / stop)
|
|
726
|
+
→ User: "yes"
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
**Phase 2 — EXECUTE → VERIFY → REVIEW → PHASE_COMPLETE**
|
|
730
|
+
|
|
731
|
+
```
|
|
732
|
+
[Execution with checkpoint pauses as needed]
|
|
540
733
|
Phase 2: Rule Engine — COMPLETE
|
|
541
734
|
Tasks: 14/14 | Retries: 1 | Verification: pass | Review: 0 blocking
|
|
542
735
|
Next: Phase 3: CLI Integration (complexity: low). Continue? (yes / stop)
|
|
@@ -545,11 +738,19 @@ Next: Phase 3: CLI Integration (complexity: low). Continue? (yes / stop)
|
|
|
545
738
|
|
|
546
739
|
**Phase 3 — [auto-plans, executes, completes]**
|
|
547
740
|
|
|
741
|
+
**FINAL_REVIEW:**
|
|
742
|
+
|
|
743
|
+
```
|
|
744
|
+
[harness-code-reviewer runs cross-phase review on startingCommit..HEAD]
|
|
745
|
+
Final review: 0 blocking, 1 warning. Passed.
|
|
746
|
+
```
|
|
747
|
+
|
|
548
748
|
**DONE:**
|
|
549
749
|
|
|
550
750
|
```
|
|
551
751
|
All phases complete.
|
|
552
752
|
Total: 3 phases, 30 tasks, 1 retry
|
|
753
|
+
Final review: passed (0 blocking, 1 warning)
|
|
553
754
|
Create a PR? (yes / no)
|
|
554
755
|
→ User: "yes"
|
|
555
756
|
```
|
|
@@ -592,7 +793,7 @@ How should we proceed? (fix manually and continue / revise plan / stop)
|
|
|
592
793
|
## Gates
|
|
593
794
|
|
|
594
795
|
- **No reimplementing delegated skills.** Autopilot orchestrates. If you are writing planning logic, execution logic, verification logic, or review logic, STOP. Delegate to the appropriate persona agent via `subagent_type`.
|
|
595
|
-
- **No executing without plan approval.** Every plan
|
|
796
|
+
- **No executing without plan approval.** Every plan passes through the APPROVE_PLAN gate. When no concern signals fire, the plan is auto-approved with a structured report. When any signal fires, the plan pauses for human review. The `--review-plans` flag forces all plans to pause. No plan reaches EXECUTE without passing this gate.
|
|
596
797
|
- **No skipping VERIFY or REVIEW.** Every phase goes through verification and review. The human can override findings, but the steps cannot be skipped.
|
|
597
798
|
- **No infinite retries.** The retry budget is 3 attempts. If exhausted, STOP and surface to the human. Do not extend the budget without explicit human instruction.
|
|
598
799
|
- **No modifying session state files manually.** The session state files are managed by the skill. If the state appears corrupted, start fresh rather than patching it.
|
|
@@ -23,6 +23,9 @@ cli:
|
|
|
23
23
|
- name: path
|
|
24
24
|
description: Project root path
|
|
25
25
|
required: false
|
|
26
|
+
- name: review-plans
|
|
27
|
+
description: Force human review of all plans (overrides auto-approve)
|
|
28
|
+
required: false
|
|
26
29
|
mcp:
|
|
27
30
|
tool: run_skill
|
|
28
31
|
input:
|
|
@@ -37,6 +40,9 @@ phases:
|
|
|
37
40
|
- name: loop
|
|
38
41
|
description: Execute state machine — assess, plan, execute, verify, review per phase
|
|
39
42
|
required: true
|
|
43
|
+
- name: final_review
|
|
44
|
+
description: Project-wide code review of cumulative changes before PR offer
|
|
45
|
+
required: true
|
|
40
46
|
- name: complete
|
|
41
47
|
description: Final summary and PR offering
|
|
42
48
|
required: true
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
5. **Load project context.** Scan the project for existing specs, user stories, or PRDs to maintain consistency in format and terminology:
|
|
46
|
-
- Check `docs/
|
|
46
|
+
- Check `docs/changes/`, `docs/requirements/`, `docs/prd/` for existing documents
|
|
47
47
|
- Check `.github/ISSUE_TEMPLATE/` for the project's preferred issue format
|
|
48
48
|
- Identify domain terminology used in existing specs
|
|
49
49
|
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
REQ-003 -> US-004, US-005 (could-have)
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
5. **Write the PRD to file.** Save to the project's spec directory (detected in Phase 1 or defaulting to `docs/
|
|
136
|
+
5. **Write the PRD to file.** Save to the project's spec directory (detected in Phase 1 or defaulting to `docs/changes/`). Use a filename pattern: `YYYY-MM-DD-feature-name-prd.md`.
|
|
137
137
|
|
|
138
138
|
---
|
|
139
139
|
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
Coverage: all actors covered, all constraints addressed
|
|
172
172
|
Open questions: N remaining
|
|
173
173
|
|
|
174
|
-
Generated: docs/
|
|
174
|
+
Generated: docs/changes/2026-03-27-notifications-prd.md
|
|
175
175
|
```
|
|
176
176
|
|
|
177
177
|
---
|
|
@@ -227,7 +227,7 @@ Phase 2: CRAFT
|
|
|
227
227
|
And their other preferences remain unchanged.
|
|
228
228
|
|
|
229
229
|
Phase 3: GENERATE
|
|
230
|
-
Written: docs/
|
|
230
|
+
Written: docs/changes/2026-03-27-team-notifications-prd.md
|
|
231
231
|
Sections: problem statement, 4 user stories, 12 acceptance criteria, 8 BDD scenarios
|
|
232
232
|
Traceability: REQ-001 -> US-001, US-002 | REQ-002 -> US-003, US-004
|
|
233
233
|
|
|
@@ -260,7 +260,7 @@ Phase 2: CRAFT
|
|
|
260
260
|
return 400 and log a security warning.
|
|
261
261
|
|
|
262
262
|
Phase 3: GENERATE
|
|
263
|
-
Written: docs/
|
|
263
|
+
Written: docs/changes/2026-03-27-stripe-webhooks-prd.md
|
|
264
264
|
Technical constraints section includes: idempotency keys, signature verification,
|
|
265
265
|
5-second response SLA, Stripe retry behavior documentation
|
|
266
266
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
checkDependenciesDefinition,
|
|
3
3
|
handleCheckDependencies
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-N25INEIX.js";
|
|
5
5
|
import "./chunk-H7Y5CKTM.js";
|
|
6
6
|
import "./chunk-IDZNPTYD.js";
|
|
7
7
|
import "./chunk-W6Y7ZW3Y.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-Z2OOPXJO.js";
|
|
9
9
|
import "./chunk-ERS5EVUZ.js";
|
|
10
10
|
export {
|
|
11
11
|
checkDependenciesDefinition,
|
package/dist/bin/harness-mcp.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startServer
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-NNHDDXYT.js";
|
|
5
|
+
import "../chunk-VEPAJXBW.js";
|
|
6
|
+
import "../chunk-EDXIVMAP.js";
|
|
7
|
+
import "../chunk-YLXFKVJE.js";
|
|
8
|
+
import "../chunk-3ZZKVN62.js";
|
|
9
|
+
import "../chunk-ND2ENWDM.js";
|
|
10
10
|
import "../chunk-ZOAWBDWU.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-OFXQSFOW.js";
|
|
12
12
|
import "../chunk-FTMXDOR6.js";
|
|
13
|
-
import "../chunk-
|
|
13
|
+
import "../chunk-N25INEIX.js";
|
|
14
14
|
import "../chunk-H7Y5CKTM.js";
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
15
|
+
import "../chunk-2BKLWLY6.js";
|
|
16
|
+
import "../chunk-B2HKP423.js";
|
|
17
17
|
import "../chunk-IDZNPTYD.js";
|
|
18
18
|
import "../chunk-W6Y7ZW3Y.js";
|
|
19
19
|
import "../chunk-N5G5QMS3.js";
|
|
20
20
|
import "../chunk-3WGJMBKH.js";
|
|
21
21
|
import "../chunk-XYLGHKG6.js";
|
|
22
|
-
import "../chunk-
|
|
22
|
+
import "../chunk-Z2OOPXJO.js";
|
|
23
23
|
import "../chunk-ERS5EVUZ.js";
|
|
24
24
|
|
|
25
25
|
// src/bin/harness-mcp.ts
|