@harness-engineering/cli 4.0.1 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +40 -8
  2. package/dist/agents/skills/claude-code/harness-catalog-retrospective/SKILL.md +124 -0
  3. package/dist/agents/skills/claude-code/harness-catalog-retrospective/skill.yaml +48 -0
  4. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +13 -0
  5. package/dist/agents/skills/claude-code/harness-parallel-agents/SKILL.md +3 -0
  6. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +3 -1
  7. package/dist/agents/skills/claude-code/pre-merge-brief/SKILL.md +86 -0
  8. package/dist/agents/skills/claude-code/pre-merge-brief/skill.yaml +67 -0
  9. package/dist/agents/skills/codex/harness-autopilot/SKILL.md +40 -8
  10. package/dist/agents/skills/codex/harness-catalog-retrospective/SKILL.md +124 -0
  11. package/dist/agents/skills/codex/harness-catalog-retrospective/skill.yaml +48 -0
  12. package/dist/agents/skills/codex/harness-execution/SKILL.md +13 -0
  13. package/dist/agents/skills/codex/harness-parallel-agents/SKILL.md +3 -0
  14. package/dist/agents/skills/codex/harness-planning/SKILL.md +3 -1
  15. package/dist/agents/skills/codex/pre-merge-brief/SKILL.md +86 -0
  16. package/dist/agents/skills/codex/pre-merge-brief/skill.yaml +67 -0
  17. package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +40 -8
  18. package/dist/agents/skills/cursor/harness-catalog-retrospective/SKILL.md +124 -0
  19. package/dist/agents/skills/cursor/harness-catalog-retrospective/skill.yaml +48 -0
  20. package/dist/agents/skills/cursor/harness-execution/SKILL.md +13 -0
  21. package/dist/agents/skills/cursor/harness-parallel-agents/SKILL.md +3 -0
  22. package/dist/agents/skills/cursor/harness-planning/SKILL.md +3 -1
  23. package/dist/agents/skills/cursor/pre-merge-brief/SKILL.md +86 -0
  24. package/dist/agents/skills/cursor/pre-merge-brief/skill.yaml +67 -0
  25. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +40 -8
  26. package/dist/agents/skills/gemini-cli/harness-catalog-retrospective/SKILL.md +124 -0
  27. package/dist/agents/skills/gemini-cli/harness-catalog-retrospective/skill.yaml +48 -0
  28. package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +13 -0
  29. package/dist/agents/skills/gemini-cli/harness-parallel-agents/SKILL.md +3 -0
  30. package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +3 -1
  31. package/dist/agents/skills/gemini-cli/pre-merge-brief/SKILL.md +86 -0
  32. package/dist/agents/skills/gemini-cli/pre-merge-brief/skill.yaml +67 -0
  33. package/dist/{agents-md-VJLYEH2S.js → agents-md-BK2UPKUC.js} +4 -4
  34. package/dist/analyzer-XRCV63KC-6T2Z32XC.js +26 -0
  35. package/dist/{architecture-YQH2NYXY.js → architecture-7PNQZOWV.js} +5 -5
  36. package/dist/{assess-project-KOTAPAHD.js → assess-project-2QPCNN7N.js} +5 -3
  37. package/dist/bin/harness-mcp.js +15 -15
  38. package/dist/bin/harness.js +26 -26
  39. package/dist/{check-phase-gate-CHU2E3OU.js → check-phase-gate-RZUSDB3O.js} +5 -5
  40. package/dist/{chunk-MMLQPHZ5.js → chunk-33OU3LYX.js} +380 -15
  41. package/dist/{chunk-XAVMTAUT.js → chunk-6STDKKAM.js} +19 -3
  42. package/dist/{chunk-I3CGCZJF.js → chunk-BJDT3VGQ.js} +6 -6
  43. package/dist/{chunk-M7F2PPN3.js → chunk-D5YCPIK6.js} +2 -2
  44. package/dist/{chunk-SDMV4QHM.js → chunk-DBCC7KIW.js} +25 -7
  45. package/dist/{chunk-E5EW5HVJ.js → chunk-DVG6DDX6.js} +1 -1
  46. package/dist/{chunk-4VXFZSYF.js → chunk-DW6HE5DH.js} +2 -2
  47. package/dist/{chunk-7PJCK7UE.js → chunk-E5KJOUHI.js} +7 -7
  48. package/dist/{chunk-6SCYTIF4.js → chunk-HU7NS7JA.js} +32 -7
  49. package/dist/{chunk-36GQREOE.js → chunk-HUC73DZC.js} +3 -3
  50. package/dist/{chunk-EYMOPFSD.js → chunk-J5MFNKE7.js} +2 -2
  51. package/dist/{chunk-JPVOI7GP.js → chunk-J7H5I4FO.js} +2 -2
  52. package/dist/{chunk-RG3TNIUB.js → chunk-K5R2I37T.js} +208 -97
  53. package/dist/{chunk-AAUY53CC.js → chunk-KHL6WFRL.js} +2 -2
  54. package/dist/{chunk-OQ6KOQEV.js → chunk-KYFXXEK3.js} +3 -3
  55. package/dist/{chunk-5RSXUAMN.js → chunk-MHHISNS2.js} +2 -2
  56. package/dist/{chunk-GHBFNLV2.js → chunk-RRCS27GT.js} +1531 -1175
  57. package/dist/{chunk-6YFHUIGT.js → chunk-RZTLXZHJ.js} +59 -21
  58. package/dist/{chunk-AX5KGRM6.js → chunk-SI4O2W4H.js} +2 -2
  59. package/dist/{chunk-BDGTZRZ6.js → chunk-UEXQMI6K.js} +56 -44
  60. package/dist/{chunk-7TIJXWG3.js → chunk-V2GJE5J5.js} +3 -3
  61. package/dist/{chunk-T746REAE.js → chunk-VC2B275U.js} +2 -2
  62. package/dist/{chunk-SEA2PFVI.js → chunk-XACP5P2J.js} +2 -2
  63. package/dist/{chunk-UWVMJEUJ.js → chunk-YTJIRQON.js} +2 -2
  64. package/dist/{chunk-YANR2RL7.js → chunk-ZIJABBGZ.js} +2 -2
  65. package/dist/{ci-workflow-HO4WKGNG.js → ci-workflow-LGN7LHHO.js} +4 -4
  66. package/dist/{dist-ICW4QUEW.js → dist-FBBADRYS.js} +3 -1
  67. package/dist/{dist-6D2F2J57.js → dist-LE5AU7FR.js} +19 -3
  68. package/dist/{docs-FP47JONV.js → docs-3BTPSHKE.js} +5 -5
  69. package/dist/{engine-YUA6IYOG.js → engine-GWGU4AMH.js} +4 -4
  70. package/dist/{entropy-DBW2INZU.js → entropy-35XURODP.js} +7 -4
  71. package/dist/{feedback-BPHADTRQ.js → feedback-NDGZZ37W.js} +1 -1
  72. package/dist/{generate-agent-definitions-KPVGBGDY.js → generate-agent-definitions-PYZ3E7SP.js} +5 -5
  73. package/dist/hooks/sentinel-pre.js +15 -138
  74. package/dist/index.d.ts +61 -0
  75. package/dist/index.js +25 -25
  76. package/dist/{loader-QOJQ6NZM.js → loader-QK2OJXKB.js} +4 -4
  77. package/dist/{mcp-ZPX6O767.js → mcp-Z5YMV7TA.js} +15 -15
  78. package/dist/{performance-FXYTGJGQ.js → performance-VAYOYPVK.js} +5 -5
  79. package/dist/{review-pipeline-2TFQ5OAE.js → review-pipeline-UETEOWSS.js} +4 -4
  80. package/dist/{runtime-XK6ZCHKE.js → runtime-J7KFACTK.js} +4 -4
  81. package/dist/{security-4W2P5ZGI.js → security-6AIUZXF5.js} +1 -1
  82. package/dist/{state-events-ECQAIZLU.js → state-events-XQPHGLG5.js} +4 -4
  83. package/dist/{validate-64KTEGIE.js → validate-ON7YMVLY.js} +5 -5
  84. package/dist/{validate-cross-check-J5PVGICB.js → validate-cross-check-HKKQA7K5.js} +4 -4
  85. package/package.json +8 -7
  86. package/dist/analyzer-V633GUHY-OV335HGM.js +0 -26
@@ -131,6 +131,19 @@ RMH005 (`harness validate`).
131
131
 
132
132
  - If no roadmap row matches this plan (e.g. ad-hoc execution), skip the claim.
133
133
 
134
+ #### Step 0.5: Plan parallelization (standard automatic parallelism)
135
+
136
+ Before the per-task loop, decide the safe parallel structure so independent tasks dispatch concurrently by default (no human typing "in parallel").
137
+
138
+ 1. Collect this run's tasks with their `files` and `dependsOn` (from the plan's task headers) and call the `plan_parallelization` MCP tool (`{ path, tasks, depth: 1 }`). It returns `ParallelizationPlan` (`waves[]`, `serialized[]`, `cyclic[]`, `narration`).
139
+ 2. If `cyclic` is non-empty, STOP and escalate (dependency cycle = plan defect). Do not execute.
140
+ 3. Emit `narration` (announce-and-proceed — do not pause).
141
+ 4. Run `serialized` tasks first (serially, in order — cross-bucket prerequisites), then process `waves` **in array order** (topologically sorted; do not reorder, do not key off `firing` alone).
142
+ 5. Per wave: `auto-dispatch` (multi-task) → dispatch the wave via **harness-parallel-agents** with worktree-per-unit isolation (`docs/guides/agent-worktree-patterns.md`), announce and proceed; `confirm` → one plain-text confirmation, then parallel or serial per the answer; `serialize` / single-task → run through the per-task loop below serially.
143
+ 6. **Serial fallback preserved:** when independent tasks < `minWaveSize` (default 3), a `confirm` is declined, or no graph is available and the human does not confirm, run every task through the per-task loop below serially — the standing "when in doubt, run serially" default.
144
+
145
+ Tasks dispatched into a parallel wave are executed by harness-parallel-agents' focused agents; tasks that fall to serial run through the loop below unchanged.
146
+
134
147
  For each task, starting from current position:
135
148
 
136
149
  1. **Read task instructions completely** before writing any code.
@@ -2,12 +2,15 @@
2
2
 
3
3
  > Dispatch independent tasks to concurrent agents, integrate results, and verify no conflicts. Only for truly independent problems.
4
4
 
5
+ **Invoked automatically by `harness-autopilot` (and standalone `harness-execution`), not only manually.** When a plan's phase has an auto-dispatch wave, the execution loop calls this skill to run that wave. In that mode the caller supplies worktree-per-unit isolation per `docs/guides/agent-worktree-patterns.md` (one worktree per task, sequential commits, squash-merge on integrate) and has already verified independence via `plan_parallelization`; this skill still owns the focused agent briefs (Step 2), concurrent dispatch (Step 3), and integration/verification (Steps 4–5). Manual invocation (a human asking to "work in parallel") continues to work unchanged.
6
+
5
7
  ## When to Use
6
8
 
7
9
  - When 3 or more tasks are truly independent (no shared state, no shared files, different subsystems)
8
10
  - When tasks involve investigation or implementation in separate parts of the codebase
9
11
  - When parallel execution would meaningfully reduce wall-clock time
10
12
  - When a plan has tasks explicitly marked as parallelizable
13
+ - When `harness-autopilot`/`harness-execution` reaches an `auto-dispatch` (or confirmed) wave from `plan_parallelization` — this skill is the wave's dispatcher
11
14
  - NOT when failures across tasks might be related (investigate serially to find the common cause)
12
15
  - NOT when tasks need full system understanding to complete correctly
13
16
  - NOT when agents would modify the same files or shared state
@@ -256,7 +256,7 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
256
256
  ### Phase 3: SEQUENCE — Order Tasks and Identify Dependencies
257
257
 
258
258
  1. **Order by dependency.** Types before implementations. Implementations before integrations. Integration tasks (tagged `category: "integration"`) after all implementation tasks. Tests alongside implementations (same task, TDD style).
259
- 2. **Identify parallel opportunities.** Tasks touching different subsystems with no shared state can be marked parallelizable.
259
+ 2. **Identify parallel opportunities and record dependency edges.** Tasks touching different subsystems with no shared state can run in parallel. Record each task's real dependencies as `dependsOn` (the task IDs it must follow) in the task header `**Depends on:**` line, and keep the task's `**Files:**` list accurate — together these are exactly the edges `plan_parallelization` consumes (explicit `dependsOn` unioned with file-overlap edges) to build the wave DAG at execution time. A task with no dependencies records `**Depends on:** none`.
260
260
  3. **Number tasks sequentially.** Use `Task 1`, `Task 2`, etc. Dependencies reference task numbers.
261
261
  4. **Estimate total time.** Sum 2-5 minutes per task. If total exceeds available time, identify a milestone boundary for pausing.
262
262
 
@@ -327,6 +327,8 @@ One sentence.
327
327
 
328
328
  **Depends on:** none | **Files:** path/to/file.ts, path/to/file.test.ts
329
329
 
330
+ <!-- `Depends on` lists the task IDs this task must follow (its `dependsOn` edges); `Files` is the independence-checking input. Both feed `plan_parallelization` during execution. -->
331
+
330
332
  1. Create test file with exact test code
331
333
  2. Run test — observe failure
332
334
  3. Create implementation with exact code
@@ -0,0 +1,86 @@
1
+ # Pre-Merge Brief
2
+
3
+ > The harness pointed at the human who clicks merge. A thin wrapper over `harness pre-merge-brief` that composes a senior-facing accountability brief — the diff summary, the multi-persona review verdict (from `review-ci --json`), the curated **Signal status** snapshot, the outcome-eval result, and a derived **"👀 Worth your eyes"** section — and posts it as a single sticky PR comment (upsert by marker). All composition and degradation logic lives in the command; this skill orchestrates invocation, reports which sections degraded, and hands off. Advisory and non-blocking: the brief never flips the review gate.
4
+
5
+ ## When to Use
6
+
7
+ - On every PR, so the senior engineer who merges sees "you are pushing this — here's what deserves your eyes" before they click merge.
8
+ - `on_pr` (dogfooded via the `required-review` workflow, reusing that run's `review-ci --json` artifact) and `manual` (a senior running it locally against the current branch's PR).
9
+ - NOT as a merge gate — the acknowledgment gate is deliberately deferred (spec D3). The brief is advisory; the review gate's exit code is what blocks.
10
+ - NOT a replacement for `review-ci` — this skill CONSUMES the review verdict, it does not re-run the review (spec D1).
11
+ - NOT for recomputing signals a different way — signals come from `@harness-engineering/signals` via the command (spec D2/D6).
12
+
13
+ ## Process
14
+
15
+ ### Phase 1: GATHER — Resolve inputs
16
+
17
+ 1. Locate the `review-ci --json` artifact for this run and record its path for `--from`. In CI it is the JSON the `required-review` workflow's `review-ci` step wrote (e.g. `/tmp/review.json`); locally, run `harness review-ci --json <path>` first if a verdict is wanted. Absent `--from` is tolerated — the review section degrades to "unavailable".
18
+ 2. Resolve the diff range for `--diff` (default `origin/<base>...HEAD` via the command's own resolver). Override only when the base is non-standard.
19
+ 3. Resolve the head sha for `--head` (default `git rev-parse HEAD`) — used for the `execution_outcome` graph lookup. Pre-merge the node is commonly absent, which is the documented degradation path, not an error.
20
+ 4. If posting (`--comment`), confirm `gh` is authenticated. Delivery failure never crashes the command (spec S1): it prints the brief and warns, still exiting 0.
21
+
22
+ ### Phase 2: COMPOSE — Run the command
23
+
24
+ Invoke `harness pre-merge-brief` with the resolved inputs:
25
+
26
+ ```bash
27
+ harness pre-merge-brief --from <review.json> --diff <range> --head <sha> [--comment]
28
+ ```
29
+
30
+ The command builds the six-section brief (marker + header → Diff summary → Review verdict → **Signal status** → Outcome evaluation → **👀 Worth your eyes**) and, with `--comment`, upserts the sticky PR comment by its marker (`<!-- harness:pre-merge-brief -->`) — patching the existing comment in place rather than posting a new one on each push. Without `--comment` it prints the brief to stdout. Each input degrades independently to an explicit "unavailable" line; the command exits 0 on a successful render regardless of which inputs were present.
31
+
32
+ ### Phase 3: REPORT — Surface what matters
33
+
34
+ 1. Report which sections rendered with real data and which degraded to "unavailable / not yet evaluated", so the senior knows the brief's coverage.
35
+ 2. Surface the **"👀 Worth your eyes"** items verbatim — the union of blocking review findings, signals in `warn`/`alert`, and unmet outcome criteria. This is the section the accountable human should read first.
36
+
37
+ ### Phase 4: HANDOFF — Advisory transition
38
+
39
+ Emit the transition via `emit_interaction`. The brief is advisory and non-blocking: it never flips the review gate's pass/fail status (spec D3, D4). In the dogfood workflow the brief step is `continue-on-error`, so a brief failure never fails the PR.
40
+
41
+ ## Harness Integration
42
+
43
+ - **`harness pre-merge-brief`** — the command this skill wraps. Flags: `--from <path>` (review-ci verdict JSON), `--comment` (sticky-upsert to the current branch's PR via `gh`), `--diff <range>`, `--head <sha>`. Pure render (`buildBriefBody`) + injected seams (`postBrief`, `RunGit`, graph store); no `process.exit` in the pure core.
44
+ - **`review-ci`** — upstream producer of the review verdict. This skill reuses its `--json` artifact via `--from`; it never re-runs the review (D1). `review-ci` remains the single source of review truth.
45
+ - **`@harness-engineering/signals`** — the shared leaf package (extracted in spec Phase 1/D6) providing `gatherSignals`. The command computes the Signal status snapshot from it; the CLI does not route signal computation through the dashboard app.
46
+ - **`execution_outcome` graph nodes** — the outcome-eval result, looked up by head sha from `.harness/graph`; commonly absent pre-merge (degrades to "not yet evaluated").
47
+ - **`required-review.yml` (dogfood)** — the `on_pr` delivery path: a `continue-on-error` step runs the brief after the existing `review-ci` run, reusing its artifact (spec Phase 4/D4). Adopter template graduation is a tracked follow-up (D5).
48
+
49
+ ## Gates
50
+
51
+ - **Never re-run the review.** Consume `review-ci --json`; do not invoke the review pipeline from this skill (D1).
52
+ - **Never block the merge.** The brief is advisory; the review gate's exit code is authoritative. No acknowledgment gate in v1 (D3).
53
+ - **Never crash `--comment`.** A `gh`/PR delivery failure prints the brief and warns, still exiting 0 (S1).
54
+ - **Thin wrapper only.** No brief composition, signal computation, or union logic in the skill — all of it lives in the command.
55
+
56
+ ## Success Criteria
57
+
58
+ Maps to spec `docs/changes/senior-accountability-surface/proposal.md`. This skill satisfies criterion #2 (the skill wrapping the command, `on_pr` + `manual`) and supports #1/#3/#4 by driving the command whose pure functions are unit-tested. Introduces no new `harness validate` findings.
59
+
60
+ ## Escalation
61
+
62
+ - **No PR for the current branch (`--comment`).** The command warns and prints the brief to stdout instead of posting, still exiting 0. Surface the warning; do not treat it as a failure.
63
+ - **No review artifact (`--from` missing/absent).** The review-verdict section degrades to "unavailable". If a verdict is wanted, run `harness review-ci --json <path>` first and pass it.
64
+ - **`gh` unauthenticated or API error while posting.** Delivery fails soft (brief printed, one-line stderr warning, exit 0). Fix `gh auth` and re-run; nothing is lost.
65
+ - **Signals or outcome-eval unavailable.** Each degrades independently to its "unavailable"/"not yet evaluated" line — expected pre-merge, not an error. Do not block the brief on them.
66
+ - **Someone asks to make the brief block merges.** That is the deferred acknowledgment gate (spec D3), a separate future spec. Keep the brief advisory; point them at the follow-up roadmap row.
67
+
68
+ ## Examples
69
+
70
+ ### Example: brief on a PR in CI (dogfood)
71
+
72
+ The `required-review.yml` workflow runs `review-ci --json /tmp/review.json`, then this skill's command:
73
+
74
+ ```bash
75
+ harness pre-merge-brief --from /tmp/review.json --diff "origin/main...HEAD" --comment
76
+ ```
77
+
78
+ The brief is composed and upserted as a sticky PR comment. The review found one blocking finding and two `alert` signals, so **👀 Worth your eyes** lists exactly those three; the outcome section shows "not yet evaluated" (no `execution_outcome` node pre-merge). The step is `continue-on-error`, so even if `gh` posting fails the review gate is unaffected.
79
+
80
+ ### Example: senior running it locally
81
+
82
+ ```bash
83
+ harness pre-merge-brief --comment
84
+ ```
85
+
86
+ No `--from`, so the review-verdict section renders "unavailable"; signals are gathered live and the diff summary uses the default `origin/<base>...HEAD` range. The senior sees the current signal status and diff before clicking merge.
@@ -0,0 +1,67 @@
1
+ name: harness-pre-merge-brief
2
+ version: "0.1.0"
3
+ description: >-
4
+ Thin-wrapper skill that runs the `harness pre-merge-brief` command to compose
5
+ and post the senior-facing pre-merge accountability brief — the diff summary,
6
+ the multi-persona review verdict (from review-ci --json), the curated Signal
7
+ status snapshot, the outcome-eval result, and a derived "Worth your eyes"
8
+ section — as a single sticky PR comment (upsert by marker). All composition and
9
+ degradation logic lives in the command; the skill orchestrates invocation,
10
+ communicates which sections degraded to "unavailable", and hands off. Runs on
11
+ on_pr and manual. The harness pointed at the human who clicks merge.
12
+ stability: draft
13
+ cognitive_mode: constructive-architect
14
+ triggers:
15
+ - on_pr
16
+ - manual
17
+ platforms:
18
+ - claude-code
19
+ - gemini-cli
20
+ - cursor
21
+ - codex
22
+ tools:
23
+ - Bash
24
+ - Read
25
+ - Glob
26
+ - Grep
27
+ - emit_interaction
28
+ cli:
29
+ command: harness pre-merge-brief
30
+ args:
31
+ - name: from
32
+ description: Path to the review-ci --json CiReviewResult artifact to reuse
33
+ required: false
34
+ - name: comment
35
+ description: Upsert the brief as a sticky PR comment via gh (by marker)
36
+ required: false
37
+ - name: diff
38
+ description: "git diff range for the diff summary (e.g. origin/main...HEAD)"
39
+ required: false
40
+ - name: head
41
+ description: "head commit sha for the outcome-eval lookup (default: git rev-parse HEAD)"
42
+ required: false
43
+ mcp:
44
+ tool: run_skill
45
+ input:
46
+ skill: harness-pre-merge-brief
47
+ path: string
48
+ type: rigid
49
+ tier: 2
50
+ phases:
51
+ - name: gather
52
+ description: Locate the review-ci --json artifact, resolve the diff range, confirm gh auth for --comment
53
+ required: true
54
+ - name: compose
55
+ description: Run `harness pre-merge-brief` with the resolved inputs; the command builds the brief and (with --comment) upserts the sticky PR comment
56
+ required: true
57
+ - name: report
58
+ description: Report which sections rendered and which degraded to "unavailable"; surface the "Worth your eyes" items
59
+ required: true
60
+ - name: handoff
61
+ description: Emit the transition; the brief is advisory (non-blocking) and never flips the review gate
62
+ required: true
63
+ state:
64
+ persistent: false
65
+ depends_on:
66
+ - harness-code-review
67
+ - outcome-eval
@@ -108,6 +108,37 @@ On return: read `planPath` from `{sessionDir}/handoff.json`. Complexity override
108
108
 
109
109
  ### EXECUTE
110
110
 
111
+ **Pre-dispatch: plan parallelization (standard automatic parallelism).** Before dispatching tasks, decide the safe parallel structure. This is orchestration, not reimplementation — autopilot chooses HOW to dispatch; the persona agents still do the work.
112
+
113
+ 1. Collect the phase's tasks with their `files` and `dependsOn` (from the plan's task headers). Call the `plan_parallelization` MCP tool:
114
+
115
+ ```json
116
+ {
117
+ "path": "<project-root>",
118
+ "tasks": [{ "id": "task-1", "files": ["..."], "dependsOn": [] }],
119
+ "depth": 1
120
+ }
121
+ ```
122
+
123
+ It returns a `ParallelizationPlan`: `waves[]` (each `{ tasks, severity, firing, analysisLevel }`), `serialized[]`, `cyclic[]`, `narration`.
124
+
125
+ 2. **If `cyclic` is non-empty:** STOP. Surface the cycle and route back to PLAN/APPROVE_PLAN (a dependency cycle is a plan defect). Do not dispatch.
126
+
127
+ 3. **Announce (announce-and-proceed):** emit `narration` verbatim. Do NOT pause here — announcing is not a gate.
128
+
129
+ 4. **Dispatch in dependency order — prerequisites first, then waves in array order:**
130
+ - First, run every task in `serialized` (high-severity-group / cycle-adjacent members) **serially**, one `harness-task-executor` per task, in listed order. These are cross-bucket prerequisites: they MUST complete before any wave that depends on them.
131
+ - Then process `waves` **in array order**. The `waves` array is already topologically sorted (earlier waves are prerequisites of later ones). Do NOT reorder waves and do NOT key dispatch off the `firing` field alone — the Phase-2 cross-bucket cap (a wave depending on a serialized/cyclic task is downgraded to `confirm` and marked "cross-bucket prerequisite gates this wave" in `narration`) is only sound if serialized/cyclic ran first and waves run in order.
132
+
133
+ 5. **For each wave, honor its `firing`:**
134
+ - `auto-dispatch` (multi-task): emit that wave's line from `narration`, then dispatch the wave via the **harness-parallel-agents** skill with **worktree-per-unit isolation** per `docs/guides/agent-worktree-patterns.md` ("Worktree-per-Milestone" / "Parallel Agent Work": one worktree per task, sequential commits, squash-merge at integrate). **Announce and proceed — do NOT stop for confirmation.**
135
+ - `confirm`: surface the wave and its `narration` line, then take exactly ONE plain-text confirmation — "Dispatch wave [{tasks}] in parallel? (yes / serial)". `yes` → dispatch via harness-parallel-agents (worktree-per-unit). `serial` or decline → run the wave's tasks serially (`harness-task-executor` each). Record the choice in `decisions[]`.
136
+ - `serialize`, or any single-task wave: run serially via `harness-task-executor`, exactly as today.
137
+
138
+ 6. **Serial fallback is preserved** when a phase has fewer than `minWaveSize` (default 3) independent tasks, when a `confirm` is declined, or when no graph is available and the human does not confirm — honoring the standing "when in doubt, run serially" default.
139
+
140
+ Each dispatched unit (parallel wave or serial task) then follows the existing per-task contract below (state.json per task, checkpoints, retry budget).
141
+
111
142
  Dispatch harness-task-executor:
112
143
 
113
144
  ```
@@ -204,7 +235,7 @@ Persist findings to `{sessionDir}/phase-{N}-review.json`. No blocking → PHASE_
204
235
  ### DONE
205
236
 
206
237
  1. Present: total phases, tasks, retries, time, `finalReview.status` + findings count, any overridden findings.
207
- 2. Ask "Create a PR? (yes / no)."
238
+ 2. Ask "Create a PR? (yes / no)." When creating the PR, include a bare closing line `Closes #<N>` where `<N>` is the issue number from the roadmap row's `External-ID`. The keyword MUST sit IMMEDIATELY before the ref — no intervening words (`Closes #<N>`, never `Closes roadmap #<N>`), or GitHub will not link/close the issue and roadmap auto-done will skip the row.
208
239
  3. Write final handoff to `{sessionDir}/handoff.json`. Append learnings to `.harness/learnings.md`. Call `promoteSessionLearnings(projectPath, sessionSlug)`. If learnings count > 30, suggest `harness learnings prune`.
209
240
  4. If `docs/roadmap.md` exists: call `manage_roadmap update` to set feature done. Skip if not found.
210
241
  5. Write final `writeSessionSummary()`. Set `currentState: "DONE"` in autopilot-state.json.
@@ -254,13 +285,14 @@ Persist findings to `{sessionDir}/phase-{N}-review.json`. No blocking → PHASE_
254
285
 
255
286
  ## Rationalizations to Reject
256
287
 
257
- | Rationalization | Reality |
258
- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
259
- | "Low complexity means I can skip APPROVE_PLAN" | Low complexity means auto-approval only when no signals fire. Signals override complexity. |
260
- | "I can inline planning logic instead of dispatching to harness-planner" | Iron Law. Autopilot delegates, never reimplements. No exceptions. |
261
- | "Retry budget exhausted but one more approach might work" | 3-attempt budget prevents compounding failure. Exceeding it without human input is unrecoverable. |
262
- | "Keeping research in conversation is faster than scratchpad" | Scratchpad gated by rigor level. At standard/thorough, >500 words must go to scratchpad. |
263
- | "Plan auto-approved, so I can skip recording the decision" | Every approval—auto or manual—is recorded in `decisions[]`. That array is the audit trail. |
288
+ | Rationalization | Reality |
289
+ | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
290
+ | "Low complexity means I can skip APPROVE_PLAN" | Low complexity means auto-approval only when no signals fire. Signals override complexity. |
291
+ | "I can inline planning logic instead of dispatching to harness-planner" | Iron Law. Autopilot delegates, never reimplements. No exceptions. |
292
+ | "Retry budget exhausted but one more approach might work" | 3-attempt budget prevents compounding failure. Exceeding it without human input is unrecoverable. |
293
+ | "Keeping research in conversation is faster than scratchpad" | Scratchpad gated by rigor level. At standard/thorough, >500 words must go to scratchpad. |
294
+ | "Plan auto-approved, so I can skip recording the decision" | Every approval—auto or manual—is recorded in `decisions[]`. That array is the audit trail. |
295
+ | "`Closes roadmap #123` reads fine, GitHub will figure out the issue" | An intervening word breaks GitHub's closing-keyword parser: `closingIssuesReferences` stays empty and auto-done leaves the row `planned`. Use a bare `Closes #123`. |
264
296
 
265
297
  ## Success Criteria
266
298
 
@@ -0,0 +1,124 @@
1
+ # Harness Catalog Retrospective
2
+
3
+ > Monthly retrospective over skill-adoption telemetry. Reads `.harness/metrics/adoption.jsonl`, ranks the most-invoked, most-failing, and abandoned-mid-workflow skills, flags ever-invoked skills that have gone quiet, and reports how much of the catalog emits any telemetry at all. Produces a dated Markdown report and surfaces the highlights that warrant follow-up. Compounding-via-learning at the catalog grain.
4
+
5
+ ## When to Use
6
+
7
+ - On a regular cadence (monthly is the intended grain) to review how the skill catalog is actually being used.
8
+ - After a milestone, to see which skills carried the work and which never fired.
9
+ - When deciding what to prune, fix, or promote in the catalog — the report feeds catalog-rationalization work.
10
+ - NOT as a real-time dashboard — for point-in-time lookups use `harness adoption skills` / `harness adoption recent`.
11
+ - NOT when `.harness/metrics/adoption.jsonl` is absent or empty (the report will be honest but empty; there is nothing to retrospect on yet).
12
+
13
+ ## Process
14
+
15
+ ### Iron Law
16
+
17
+ **Separate real signal from telemetry gaps before you recommend anything.** The single most common misread of this data is treating "no telemetry" as "abandoned." Adoption records are emitted only from instrumented entry points, so a skill with zero records is usually uninstrumented, not unused. The report's coverage line and the stale-skills section exist to keep that distinction visible — never collapse it.
18
+
19
+ ---
20
+
21
+ ### Phase 1: SCAN — Derive the Report
22
+
23
+ 1. Run the retrospective command from the project root:
24
+
25
+ ```bash
26
+ harness adoption retrospective # writes docs/retrospectives/<date>.md
27
+ harness adoption retrospective --no-write # print to stdout without writing a file
28
+ harness adoption retrospective --json # structured output for further processing
29
+ ```
30
+
31
+ Optional flags: `--inactive-days <n>` (stale threshold, default 90), `--top <n>` (rows per section, default 10), `--out <path>` (override the output file).
32
+
33
+ 2. The command reads `.harness/metrics/adoption.jsonl` via `readAdoptionRecords`, derives the report via `getCatalogRetrospectiveReport`, and renders it via `renderRetrospectiveMarkdown` (all in `@harness-engineering/core`). Coverage context is computed against the skills discovered under `agents/skills/claude-code/`; when that directory is absent (a consumer project), the coverage line is omitted rather than reporting a false zero.
34
+
35
+ 3. If there are no records, say so plainly and stop: "No adoption telemetry found at `.harness/metrics/adoption.jsonl`. Nothing to retrospect on yet."
36
+
37
+ ### Phase 2: INTERPRET — Signal vs. Noise
38
+
39
+ Read the report with these discriminations:
40
+
41
+ - **Coverage line first.** "N/total catalog skills have emitted telemetry" frames everything below it. A low ratio means the rankings describe the _instrumented_ slice, not the whole catalog. State the ratio explicitly in your summary.
42
+ - **Failing skills are not automatically broken.** Some commands fail _by design_ (a gate like `ci.check` returning non-zero on a real violation is the gate working). Before flagging a high failure rate as a problem, note whether the skill is a checker/gate whose failures are expected. Call out only failures that look like defects (crashes, unexpected non-zero on clean input).
43
+ - **Abandoned mid-workflow** uses the broadened definition: an explicit `abandoned` outcome, or a non-completed run that had already reached ≥1 phase. Small counts here are meaningful — a workflow skill people start and bail out of mid-way is a UX signal even at n=1.
44
+ - **Stale skills** are drawn only from _ever-invoked_ skills quiet ≥ the threshold. When the record window is shorter than the threshold, the section says so and reports nothing — do not present that emptiness as "everything is healthy."
45
+
46
+ ### Phase 3: REPORT — Surface and Recommend
47
+
48
+ 1. Confirm where the report was written (`docs/retrospectives/<date>.md`) or present the rendered Markdown.
49
+ 2. Summarize the 3–5 findings that actually warrant action, each tied to a section and a number. Prefer specifics ("`cli/review-ci` failed 23/23 — likely a real defect, worth a look") over restating the tables.
50
+ 3. When the coverage ratio is the dominant finding (e.g. most of the catalog is uninstrumented), name that as the top follow-up: instrumentation, not pruning, is the lever.
51
+ 4. Do not delete, prune, or edit skills from this skill — it reports. Hand any pruning decision to the human or to catalog-rationalization work.
52
+
53
+ ---
54
+
55
+ ## Harness Integration
56
+
57
+ - **`harness adoption retrospective`** — the CLI entry point (a subcommand of the existing `adoption` command group). Writes `docs/retrospectives/<date>.md` by default.
58
+ - **`getCatalogRetrospectiveReport` / `renderRetrospectiveMarkdown` / `isAbandonedMidWorkflow`** — the pure aggregation + render functions in `@harness-engineering/core` (`packages/core/src/adoption/retrospective.ts`). Callers can supply a fixed `now` and `catalogSkills` for deterministic output.
59
+ - **`readAdoptionRecords`** — reads and parses `.harness/metrics/adoption.jsonl` (read-only; the file is appended by the adoption-tracker hook, never by this skill).
60
+ - **`harness adoption skills` / `recent` / `skill <name>`** — the point-in-time siblings; this skill is the periodic, persisted counterpart.
61
+
62
+ ## Success Criteria
63
+
64
+ 1. The retrospective is derived from `.harness/metrics/adoption.jsonl` without mutating it.
65
+ 2. The report ranks top-invoked, top-failing, and abandoned-mid-workflow skills, and flags ever-invoked stale skills.
66
+ 3. The report states telemetry coverage (how much of the catalog emits any signal) when the catalog is discoverable.
67
+ 4. The stale-skills section notes when the record window is shorter than the inactivity threshold instead of silently reporting zero.
68
+ 5. The summary separates real signal (defect-shaped failures, mid-workflow abandonment) from telemetry gaps (uninstrumented skills) and from expected gate failures.
69
+ 6. A dated report is written to `docs/retrospectives/<date>.md` (unless `--no-write`/`--json` is requested).
70
+ 7. The skill recommends but never prunes, edits, or deletes catalog skills.
71
+
72
+ ## Rationalizations to Reject
73
+
74
+ | Rationalization | Reality |
75
+ | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
76
+ | "756 skills have no telemetry, so 756 skills are abandoned — recommend deleting them." | Zero telemetry almost always means _uninstrumented_, not unused. The coverage line exists to prevent exactly this misread; the fix is instrumentation, not pruning. |
77
+ | "`ci.check` fails 97% of the time — it's broken." | A gate returning non-zero on a real violation is the gate working. Check whether the skill is a checker before flagging its failures as defects. |
78
+ | "The stale section is empty, so the catalog is healthy." | If the record window is shorter than the threshold, the signal simply cannot fire yet. Empty ≠ healthy; report the window caveat. |
79
+ | "n=1 abandonment is noise, ignore it." | A workflow skill users start and bail out of mid-way is a UX signal even at low n. Surface it; let the human weigh it. |
80
+ | "I'll prune the low-usage skills while I'm here." | This skill reports; it does not prune. Pruning is a human/catalog-rationalization decision. |
81
+
82
+ ## Examples
83
+
84
+ ### Example: Monthly retrospective on the dogfood repo
85
+
86
+ **Context:** ~67 days of telemetry (3.2k records) across 50 invoked skills, run at month end.
87
+
88
+ **Phase 1 — SCAN:**
89
+
90
+ ```bash
91
+ harness adoption retrospective
92
+ # → Catalog retrospective written to docs/retrospectives/2026-07-06.md
93
+ # 3246 records · 50 skills · window 67d
94
+ ```
95
+
96
+ **Phase 2 — INTERPRET:** The report's overview leads with `Telemetry coverage: 5/761 catalog skills have emitted telemetry (756 never invoked)`. Top-invoked is dominated by `cli/*` commands; `cli/ci.check` shows a 97% failure rate; the abandoned-mid-workflow section lists four workflow skills at n=1; the stale section is empty with the note that the 67-day window is shorter than the 90-day threshold.
97
+
98
+ **Phase 3 — REPORT:**
99
+
100
+ ```
101
+ Retrospective written to docs/retrospectives/2026-07-06.md. Findings that warrant action:
102
+
103
+ 1. Coverage is the headline: only 5/761 catalog skills emit any telemetry. The rankings
104
+ describe the instrumented slice, not the catalog. Top follow-up is instrumentation, not pruning.
105
+ 2. `cli/ci.check` failed 97% (721/741) — but it is a gate; non-zero on a real violation is
106
+ expected. Not flagged as a defect.
107
+ 3. `cli/review-ci` failed 23/23 (100%) — defect-shaped, worth a look. Routed to debugging.
108
+ 4. Four workflow skills were abandoned mid-run (n=1 each) — low volume, a UX signal to watch.
109
+ 5. Stale skills: none — the 67-day window can't satisfy the 90-day threshold yet.
110
+ ```
111
+
112
+ No skills were pruned or edited — the pruning decision is left to the human.
113
+
114
+ ## Gates
115
+
116
+ - **No mutation of `adoption.jsonl`.** The telemetry file is read-only input.
117
+ - **No catalog edits.** This skill never adds, edits, or deletes skills — it only reports on them.
118
+ - **Coverage must be stated when discoverable.** If the catalog can be scanned, the summary must include the telemetry-coverage ratio so rankings are read in context.
119
+
120
+ ## Escalation
121
+
122
+ - **When there are no records:** State that telemetry is absent/empty and stop. Suggest confirming the adoption-tracker hook is installed if telemetry is unexpectedly missing.
123
+ - **When coverage is very low:** Name instrumentation as the top follow-up and note that the rankings describe only the instrumented slice.
124
+ - **When a failing skill looks like a real defect:** Flag it specifically (skill, failure count/rate, why it looks defect-shaped) and route it to debugging or an issue, rather than burying it in the table.
@@ -0,0 +1,48 @@
1
+ name: harness-catalog-retrospective
2
+ version: '1.0.0'
3
+ description: Monthly retrospective over skill-adoption telemetry — ranks most-invoked, failing, and abandoned-mid-workflow skills, flags stale ones, and reports catalog telemetry coverage
4
+ stability: static
5
+ cognitive_mode: analytical-reporter
6
+ triggers:
7
+ - manual
8
+ - on_milestone
9
+ platforms:
10
+ - claude-code
11
+ - gemini-cli
12
+ - cursor
13
+ - codex
14
+ tools:
15
+ - Bash
16
+ - Read
17
+ - Glob
18
+ - Grep
19
+ cli:
20
+ command: harness skill run harness-catalog-retrospective
21
+ args:
22
+ - name: path
23
+ description: Project root path
24
+ required: false
25
+ - name: inactive-days
26
+ description: 'Inactivity threshold in days for the stale-skills section (default: 90)'
27
+ required: false
28
+ mcp:
29
+ tool: run_skill
30
+ input:
31
+ skill: harness-catalog-retrospective
32
+ path: string
33
+ type: rigid
34
+ tier: 2
35
+ phases:
36
+ - name: scan
37
+ description: Read adoption telemetry and derive the retrospective report
38
+ required: true
39
+ - name: interpret
40
+ description: Read the rankings and coverage, separating real signal from telemetry gaps
41
+ required: true
42
+ - name: report
43
+ description: Write the dated report and surface highlights plus recommendations
44
+ required: true
45
+ state:
46
+ persistent: false
47
+ files: []
48
+ depends_on: []
@@ -131,6 +131,19 @@ RMH005 (`harness validate`).
131
131
 
132
132
  - If no roadmap row matches this plan (e.g. ad-hoc execution), skip the claim.
133
133
 
134
+ #### Step 0.5: Plan parallelization (standard automatic parallelism)
135
+
136
+ Before the per-task loop, decide the safe parallel structure so independent tasks dispatch concurrently by default (no human typing "in parallel").
137
+
138
+ 1. Collect this run's tasks with their `files` and `dependsOn` (from the plan's task headers) and call the `plan_parallelization` MCP tool (`{ path, tasks, depth: 1 }`). It returns `ParallelizationPlan` (`waves[]`, `serialized[]`, `cyclic[]`, `narration`).
139
+ 2. If `cyclic` is non-empty, STOP and escalate (dependency cycle = plan defect). Do not execute.
140
+ 3. Emit `narration` (announce-and-proceed — do not pause).
141
+ 4. Run `serialized` tasks first (serially, in order — cross-bucket prerequisites), then process `waves` **in array order** (topologically sorted; do not reorder, do not key off `firing` alone).
142
+ 5. Per wave: `auto-dispatch` (multi-task) → dispatch the wave via **harness-parallel-agents** with worktree-per-unit isolation (`docs/guides/agent-worktree-patterns.md`), announce and proceed; `confirm` → one plain-text confirmation, then parallel or serial per the answer; `serialize` / single-task → run through the per-task loop below serially.
143
+ 6. **Serial fallback preserved:** when independent tasks < `minWaveSize` (default 3), a `confirm` is declined, or no graph is available and the human does not confirm, run every task through the per-task loop below serially — the standing "when in doubt, run serially" default.
144
+
145
+ Tasks dispatched into a parallel wave are executed by harness-parallel-agents' focused agents; tasks that fall to serial run through the loop below unchanged.
146
+
134
147
  For each task, starting from current position:
135
148
 
136
149
  1. **Read task instructions completely** before writing any code.
@@ -2,12 +2,15 @@
2
2
 
3
3
  > Dispatch independent tasks to concurrent agents, integrate results, and verify no conflicts. Only for truly independent problems.
4
4
 
5
+ **Invoked automatically by `harness-autopilot` (and standalone `harness-execution`), not only manually.** When a plan's phase has an auto-dispatch wave, the execution loop calls this skill to run that wave. In that mode the caller supplies worktree-per-unit isolation per `docs/guides/agent-worktree-patterns.md` (one worktree per task, sequential commits, squash-merge on integrate) and has already verified independence via `plan_parallelization`; this skill still owns the focused agent briefs (Step 2), concurrent dispatch (Step 3), and integration/verification (Steps 4–5). Manual invocation (a human asking to "work in parallel") continues to work unchanged.
6
+
5
7
  ## When to Use
6
8
 
7
9
  - When 3 or more tasks are truly independent (no shared state, no shared files, different subsystems)
8
10
  - When tasks involve investigation or implementation in separate parts of the codebase
9
11
  - When parallel execution would meaningfully reduce wall-clock time
10
12
  - When a plan has tasks explicitly marked as parallelizable
13
+ - When `harness-autopilot`/`harness-execution` reaches an `auto-dispatch` (or confirmed) wave from `plan_parallelization` — this skill is the wave's dispatcher
11
14
  - NOT when failures across tasks might be related (investigate serially to find the common cause)
12
15
  - NOT when tasks need full system understanding to complete correctly
13
16
  - NOT when agents would modify the same files or shared state
@@ -256,7 +256,7 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
256
256
  ### Phase 3: SEQUENCE — Order Tasks and Identify Dependencies
257
257
 
258
258
  1. **Order by dependency.** Types before implementations. Implementations before integrations. Integration tasks (tagged `category: "integration"`) after all implementation tasks. Tests alongside implementations (same task, TDD style).
259
- 2. **Identify parallel opportunities.** Tasks touching different subsystems with no shared state can be marked parallelizable.
259
+ 2. **Identify parallel opportunities and record dependency edges.** Tasks touching different subsystems with no shared state can run in parallel. Record each task's real dependencies as `dependsOn` (the task IDs it must follow) in the task header `**Depends on:**` line, and keep the task's `**Files:**` list accurate — together these are exactly the edges `plan_parallelization` consumes (explicit `dependsOn` unioned with file-overlap edges) to build the wave DAG at execution time. A task with no dependencies records `**Depends on:** none`.
260
260
  3. **Number tasks sequentially.** Use `Task 1`, `Task 2`, etc. Dependencies reference task numbers.
261
261
  4. **Estimate total time.** Sum 2-5 minutes per task. If total exceeds available time, identify a milestone boundary for pausing.
262
262
 
@@ -327,6 +327,8 @@ One sentence.
327
327
 
328
328
  **Depends on:** none | **Files:** path/to/file.ts, path/to/file.test.ts
329
329
 
330
+ <!-- `Depends on` lists the task IDs this task must follow (its `dependsOn` edges); `Files` is the independence-checking input. Both feed `plan_parallelization` during execution. -->
331
+
330
332
  1. Create test file with exact test code
331
333
  2. Run test — observe failure
332
334
  3. Create implementation with exact code
@@ -0,0 +1,86 @@
1
+ # Pre-Merge Brief
2
+
3
+ > The harness pointed at the human who clicks merge. A thin wrapper over `harness pre-merge-brief` that composes a senior-facing accountability brief — the diff summary, the multi-persona review verdict (from `review-ci --json`), the curated **Signal status** snapshot, the outcome-eval result, and a derived **"👀 Worth your eyes"** section — and posts it as a single sticky PR comment (upsert by marker). All composition and degradation logic lives in the command; this skill orchestrates invocation, reports which sections degraded, and hands off. Advisory and non-blocking: the brief never flips the review gate.
4
+
5
+ ## When to Use
6
+
7
+ - On every PR, so the senior engineer who merges sees "you are pushing this — here's what deserves your eyes" before they click merge.
8
+ - `on_pr` (dogfooded via the `required-review` workflow, reusing that run's `review-ci --json` artifact) and `manual` (a senior running it locally against the current branch's PR).
9
+ - NOT as a merge gate — the acknowledgment gate is deliberately deferred (spec D3). The brief is advisory; the review gate's exit code is what blocks.
10
+ - NOT a replacement for `review-ci` — this skill CONSUMES the review verdict, it does not re-run the review (spec D1).
11
+ - NOT for recomputing signals a different way — signals come from `@harness-engineering/signals` via the command (spec D2/D6).
12
+
13
+ ## Process
14
+
15
+ ### Phase 1: GATHER — Resolve inputs
16
+
17
+ 1. Locate the `review-ci --json` artifact for this run and record its path for `--from`. In CI it is the JSON the `required-review` workflow's `review-ci` step wrote (e.g. `/tmp/review.json`); locally, run `harness review-ci --json <path>` first if a verdict is wanted. Absent `--from` is tolerated — the review section degrades to "unavailable".
18
+ 2. Resolve the diff range for `--diff` (default `origin/<base>...HEAD` via the command's own resolver). Override only when the base is non-standard.
19
+ 3. Resolve the head sha for `--head` (default `git rev-parse HEAD`) — used for the `execution_outcome` graph lookup. Pre-merge the node is commonly absent, which is the documented degradation path, not an error.
20
+ 4. If posting (`--comment`), confirm `gh` is authenticated. Delivery failure never crashes the command (spec S1): it prints the brief and warns, still exiting 0.
21
+
22
+ ### Phase 2: COMPOSE — Run the command
23
+
24
+ Invoke `harness pre-merge-brief` with the resolved inputs:
25
+
26
+ ```bash
27
+ harness pre-merge-brief --from <review.json> --diff <range> --head <sha> [--comment]
28
+ ```
29
+
30
+ The command builds the six-section brief (marker + header → Diff summary → Review verdict → **Signal status** → Outcome evaluation → **👀 Worth your eyes**) and, with `--comment`, upserts the sticky PR comment by its marker (`<!-- harness:pre-merge-brief -->`) — patching the existing comment in place rather than posting a new one on each push. Without `--comment` it prints the brief to stdout. Each input degrades independently to an explicit "unavailable" line; the command exits 0 on a successful render regardless of which inputs were present.
31
+
32
+ ### Phase 3: REPORT — Surface what matters
33
+
34
+ 1. Report which sections rendered with real data and which degraded to "unavailable / not yet evaluated", so the senior knows the brief's coverage.
35
+ 2. Surface the **"👀 Worth your eyes"** items verbatim — the union of blocking review findings, signals in `warn`/`alert`, and unmet outcome criteria. This is the section the accountable human should read first.
36
+
37
+ ### Phase 4: HANDOFF — Advisory transition
38
+
39
+ Emit the transition via `emit_interaction`. The brief is advisory and non-blocking: it never flips the review gate's pass/fail status (spec D3, D4). In the dogfood workflow the brief step is `continue-on-error`, so a brief failure never fails the PR.
40
+
41
+ ## Harness Integration
42
+
43
+ - **`harness pre-merge-brief`** — the command this skill wraps. Flags: `--from <path>` (review-ci verdict JSON), `--comment` (sticky-upsert to the current branch's PR via `gh`), `--diff <range>`, `--head <sha>`. Pure render (`buildBriefBody`) + injected seams (`postBrief`, `RunGit`, graph store); no `process.exit` in the pure core.
44
+ - **`review-ci`** — upstream producer of the review verdict. This skill reuses its `--json` artifact via `--from`; it never re-runs the review (D1). `review-ci` remains the single source of review truth.
45
+ - **`@harness-engineering/signals`** — the shared leaf package (extracted in spec Phase 1/D6) providing `gatherSignals`. The command computes the Signal status snapshot from it; the CLI does not route signal computation through the dashboard app.
46
+ - **`execution_outcome` graph nodes** — the outcome-eval result, looked up by head sha from `.harness/graph`; commonly absent pre-merge (degrades to "not yet evaluated").
47
+ - **`required-review.yml` (dogfood)** — the `on_pr` delivery path: a `continue-on-error` step runs the brief after the existing `review-ci` run, reusing its artifact (spec Phase 4/D4). Adopter template graduation is a tracked follow-up (D5).
48
+
49
+ ## Gates
50
+
51
+ - **Never re-run the review.** Consume `review-ci --json`; do not invoke the review pipeline from this skill (D1).
52
+ - **Never block the merge.** The brief is advisory; the review gate's exit code is authoritative. No acknowledgment gate in v1 (D3).
53
+ - **Never crash `--comment`.** A `gh`/PR delivery failure prints the brief and warns, still exiting 0 (S1).
54
+ - **Thin wrapper only.** No brief composition, signal computation, or union logic in the skill — all of it lives in the command.
55
+
56
+ ## Success Criteria
57
+
58
+ Maps to spec `docs/changes/senior-accountability-surface/proposal.md`. This skill satisfies criterion #2 (the skill wrapping the command, `on_pr` + `manual`) and supports #1/#3/#4 by driving the command whose pure functions are unit-tested. Introduces no new `harness validate` findings.
59
+
60
+ ## Escalation
61
+
62
+ - **No PR for the current branch (`--comment`).** The command warns and prints the brief to stdout instead of posting, still exiting 0. Surface the warning; do not treat it as a failure.
63
+ - **No review artifact (`--from` missing/absent).** The review-verdict section degrades to "unavailable". If a verdict is wanted, run `harness review-ci --json <path>` first and pass it.
64
+ - **`gh` unauthenticated or API error while posting.** Delivery fails soft (brief printed, one-line stderr warning, exit 0). Fix `gh auth` and re-run; nothing is lost.
65
+ - **Signals or outcome-eval unavailable.** Each degrades independently to its "unavailable"/"not yet evaluated" line — expected pre-merge, not an error. Do not block the brief on them.
66
+ - **Someone asks to make the brief block merges.** That is the deferred acknowledgment gate (spec D3), a separate future spec. Keep the brief advisory; point them at the follow-up roadmap row.
67
+
68
+ ## Examples
69
+
70
+ ### Example: brief on a PR in CI (dogfood)
71
+
72
+ The `required-review.yml` workflow runs `review-ci --json /tmp/review.json`, then this skill's command:
73
+
74
+ ```bash
75
+ harness pre-merge-brief --from /tmp/review.json --diff "origin/main...HEAD" --comment
76
+ ```
77
+
78
+ The brief is composed and upserted as a sticky PR comment. The review found one blocking finding and two `alert` signals, so **👀 Worth your eyes** lists exactly those three; the outcome section shows "not yet evaluated" (no `execution_outcome` node pre-merge). The step is `continue-on-error`, so even if `gh` posting fails the review gate is unaffected.
79
+
80
+ ### Example: senior running it locally
81
+
82
+ ```bash
83
+ harness pre-merge-brief --comment
84
+ ```
85
+
86
+ No `--from`, so the review-verdict section renders "unavailable"; signals are gathered live and the diff summary uses the default `origin/<base>...HEAD` range. The senior sees the current signal status and diff before clicking merge.