@harness-engineering/cli 2.7.1 → 3.0.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 (197) hide show
  1. package/dist/agents/personas/adversarial-reviewer.yaml +43 -0
  2. package/dist/agents/personas/frontend-races-reviewer.yaml +54 -0
  3. package/dist/agents/personas/typescript-strict-reviewer.yaml +53 -0
  4. package/dist/agents/skills/CHANGELOG.md +12 -0
  5. package/dist/agents/skills/claude-code/align-design-system/SKILL.md +18 -0
  6. package/dist/agents/skills/claude-code/align-design-system/skill.yaml +3 -0
  7. package/dist/agents/skills/claude-code/harness-audit-harness-strength/SKILL.md +188 -0
  8. package/dist/agents/skills/claude-code/harness-audit-harness-strength/skill.yaml +54 -0
  9. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +2 -0
  10. package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +58 -12
  11. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +107 -22
  12. package/dist/agents/skills/claude-code/harness-code-review/references/confidence-rubric.md +45 -0
  13. package/dist/agents/skills/claude-code/harness-code-review/references/risk-keywords.md +40 -0
  14. package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +3 -0
  15. package/dist/agents/skills/claude-code/harness-compound/SKILL.md +7 -4
  16. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +1 -1
  17. package/dist/agents/skills/claude-code/harness-git-workflow/SKILL.md +2 -0
  18. package/dist/agents/skills/claude-code/harness-ideate/SKILL.md +279 -0
  19. package/dist/agents/skills/claude-code/harness-ideate/references/scoring.md +88 -0
  20. package/dist/agents/skills/claude-code/harness-ideate/skill.yaml +66 -0
  21. package/dist/agents/skills/claude-code/harness-knowledge-pipeline/SKILL.md +2 -0
  22. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +14 -4
  23. package/dist/agents/skills/claude-code/harness-pulse/SKILL.md +12 -16
  24. package/dist/agents/skills/claude-code/harness-roadmap/SKILL.md +62 -4
  25. package/dist/agents/skills/claude-code/harness-roadmap-pilot/SKILL.md +36 -6
  26. package/dist/agents/skills/claude-code/harness-strategy/SKILL.md +152 -0
  27. package/dist/agents/skills/claude-code/harness-strategy/references/interview.md +122 -0
  28. package/dist/agents/skills/claude-code/harness-strategy/skill.yaml +54 -0
  29. package/dist/agents/skills/claude-code/harness-test-advisor/SKILL.md +80 -2
  30. package/dist/agents/skills/claude-code/harness-test-advisor/skill.yaml +4 -1
  31. package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +86 -18
  32. package/dist/agents/skills/claude-code/initialize-harness-project/skill.yaml +1 -0
  33. package/dist/agents/skills/claude-code/outcome-eval/SKILL.md +97 -0
  34. package/dist/agents/skills/claude-code/outcome-eval/skill.yaml +51 -0
  35. package/dist/agents/skills/codex/align-design-system/SKILL.md +18 -0
  36. package/dist/agents/skills/codex/align-design-system/skill.yaml +3 -0
  37. package/dist/agents/skills/codex/harness-audit-harness-strength/SKILL.md +188 -0
  38. package/dist/agents/skills/codex/harness-audit-harness-strength/skill.yaml +54 -0
  39. package/dist/agents/skills/codex/harness-autopilot/SKILL.md +2 -0
  40. package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +58 -12
  41. package/dist/agents/skills/codex/harness-code-review/SKILL.md +107 -22
  42. package/dist/agents/skills/codex/harness-code-review/references/confidence-rubric.md +45 -0
  43. package/dist/agents/skills/codex/harness-code-review/references/risk-keywords.md +40 -0
  44. package/dist/agents/skills/codex/harness-code-review/skill.yaml +3 -0
  45. package/dist/agents/skills/codex/harness-compound/SKILL.md +7 -4
  46. package/dist/agents/skills/codex/harness-execution/SKILL.md +1 -1
  47. package/dist/agents/skills/codex/harness-git-workflow/SKILL.md +2 -0
  48. package/dist/agents/skills/codex/harness-ideate/SKILL.md +279 -0
  49. package/dist/agents/skills/codex/harness-ideate/references/scoring.md +88 -0
  50. package/dist/agents/skills/codex/harness-ideate/skill.yaml +66 -0
  51. package/dist/agents/skills/codex/harness-knowledge-pipeline/SKILL.md +2 -0
  52. package/dist/agents/skills/codex/harness-planning/SKILL.md +14 -4
  53. package/dist/agents/skills/codex/harness-pulse/SKILL.md +12 -16
  54. package/dist/agents/skills/codex/harness-roadmap/SKILL.md +62 -4
  55. package/dist/agents/skills/codex/harness-roadmap-pilot/SKILL.md +36 -6
  56. package/dist/agents/skills/codex/harness-strategy/SKILL.md +152 -0
  57. package/dist/agents/skills/codex/harness-strategy/references/interview.md +122 -0
  58. package/dist/agents/skills/codex/harness-strategy/skill.yaml +54 -0
  59. package/dist/agents/skills/codex/harness-test-advisor/SKILL.md +80 -2
  60. package/dist/agents/skills/codex/harness-test-advisor/skill.yaml +4 -1
  61. package/dist/agents/skills/codex/initialize-harness-project/SKILL.md +86 -18
  62. package/dist/agents/skills/codex/initialize-harness-project/skill.yaml +1 -0
  63. package/dist/agents/skills/codex/outcome-eval/SKILL.md +97 -0
  64. package/dist/agents/skills/codex/outcome-eval/skill.yaml +51 -0
  65. package/dist/agents/skills/cursor/align-design-system/SKILL.md +18 -0
  66. package/dist/agents/skills/cursor/align-design-system/skill.yaml +3 -0
  67. package/dist/agents/skills/cursor/harness-audit-harness-strength/SKILL.md +188 -0
  68. package/dist/agents/skills/cursor/harness-audit-harness-strength/skill.yaml +54 -0
  69. package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +2 -0
  70. package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +58 -12
  71. package/dist/agents/skills/cursor/harness-code-review/SKILL.md +107 -22
  72. package/dist/agents/skills/cursor/harness-code-review/references/confidence-rubric.md +45 -0
  73. package/dist/agents/skills/cursor/harness-code-review/references/risk-keywords.md +40 -0
  74. package/dist/agents/skills/cursor/harness-code-review/skill.yaml +3 -0
  75. package/dist/agents/skills/cursor/harness-compound/SKILL.md +7 -4
  76. package/dist/agents/skills/cursor/harness-execution/SKILL.md +1 -1
  77. package/dist/agents/skills/cursor/harness-git-workflow/SKILL.md +2 -0
  78. package/dist/agents/skills/cursor/harness-ideate/SKILL.md +279 -0
  79. package/dist/agents/skills/cursor/harness-ideate/references/scoring.md +88 -0
  80. package/dist/agents/skills/cursor/harness-ideate/skill.yaml +66 -0
  81. package/dist/agents/skills/cursor/harness-knowledge-pipeline/SKILL.md +2 -0
  82. package/dist/agents/skills/cursor/harness-planning/SKILL.md +14 -4
  83. package/dist/agents/skills/cursor/harness-pulse/SKILL.md +12 -16
  84. package/dist/agents/skills/cursor/harness-roadmap/SKILL.md +62 -4
  85. package/dist/agents/skills/cursor/harness-roadmap-pilot/SKILL.md +36 -6
  86. package/dist/agents/skills/cursor/harness-strategy/SKILL.md +152 -0
  87. package/dist/agents/skills/cursor/harness-strategy/references/interview.md +122 -0
  88. package/dist/agents/skills/cursor/harness-strategy/skill.yaml +54 -0
  89. package/dist/agents/skills/cursor/harness-test-advisor/SKILL.md +80 -2
  90. package/dist/agents/skills/cursor/harness-test-advisor/skill.yaml +4 -1
  91. package/dist/agents/skills/cursor/initialize-harness-project/SKILL.md +86 -18
  92. package/dist/agents/skills/cursor/initialize-harness-project/skill.yaml +1 -0
  93. package/dist/agents/skills/cursor/outcome-eval/SKILL.md +97 -0
  94. package/dist/agents/skills/cursor/outcome-eval/skill.yaml +51 -0
  95. package/dist/agents/skills/gemini-cli/align-design-system/SKILL.md +18 -0
  96. package/dist/agents/skills/gemini-cli/align-design-system/skill.yaml +3 -0
  97. package/dist/agents/skills/gemini-cli/harness-audit-harness-strength/SKILL.md +188 -0
  98. package/dist/agents/skills/gemini-cli/harness-audit-harness-strength/skill.yaml +54 -0
  99. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +2 -0
  100. package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +58 -12
  101. package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +107 -22
  102. package/dist/agents/skills/gemini-cli/harness-code-review/references/confidence-rubric.md +45 -0
  103. package/dist/agents/skills/gemini-cli/harness-code-review/references/risk-keywords.md +40 -0
  104. package/dist/agents/skills/gemini-cli/harness-code-review/skill.yaml +3 -0
  105. package/dist/agents/skills/gemini-cli/harness-compound/SKILL.md +7 -4
  106. package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +1 -1
  107. package/dist/agents/skills/gemini-cli/harness-git-workflow/SKILL.md +2 -0
  108. package/dist/agents/skills/gemini-cli/harness-ideate/SKILL.md +279 -0
  109. package/dist/agents/skills/gemini-cli/harness-ideate/references/scoring.md +88 -0
  110. package/dist/agents/skills/gemini-cli/harness-ideate/skill.yaml +66 -0
  111. package/dist/agents/skills/gemini-cli/harness-knowledge-pipeline/SKILL.md +2 -0
  112. package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +14 -4
  113. package/dist/agents/skills/gemini-cli/harness-pulse/SKILL.md +12 -16
  114. package/dist/agents/skills/gemini-cli/harness-roadmap/SKILL.md +62 -4
  115. package/dist/agents/skills/gemini-cli/harness-roadmap-pilot/SKILL.md +36 -6
  116. package/dist/agents/skills/gemini-cli/harness-strategy/SKILL.md +152 -0
  117. package/dist/agents/skills/gemini-cli/harness-strategy/references/interview.md +122 -0
  118. package/dist/agents/skills/gemini-cli/harness-strategy/skill.yaml +54 -0
  119. package/dist/agents/skills/gemini-cli/harness-test-advisor/SKILL.md +80 -2
  120. package/dist/agents/skills/gemini-cli/harness-test-advisor/skill.yaml +4 -1
  121. package/dist/agents/skills/gemini-cli/initialize-harness-project/SKILL.md +86 -18
  122. package/dist/agents/skills/gemini-cli/initialize-harness-project/skill.yaml +1 -0
  123. package/dist/agents/skills/gemini-cli/outcome-eval/SKILL.md +97 -0
  124. package/dist/agents/skills/gemini-cli/outcome-eval/skill.yaml +51 -0
  125. package/dist/agents/skills/package.json +1 -1
  126. package/dist/agents/skills/tests/harness-strategy.test.ts +145 -0
  127. package/dist/agents/skills/tests/harness-test-advisor.test.ts +94 -0
  128. package/dist/agents-md-XOJE5ETA.js +13 -0
  129. package/dist/analyzer-V633GUHY-MBCQWKDU.js +26 -0
  130. package/dist/{architecture-LUR2I67H.js → architecture-JEZPJ725.js} +6 -6
  131. package/dist/{assess-project-OJWECOP2.js → assess-project-RHXOQNMM.js} +1 -1
  132. package/dist/bin/harness-mcp.js +17 -17
  133. package/dist/bin/harness.js +27 -27
  134. package/dist/{check-phase-gate-HS5KYLRO.js → check-phase-gate-GNDOMS35.js} +6 -6
  135. package/dist/{chunk-6UHDQP2N.js → chunk-2N4OENGE.js} +1 -1
  136. package/dist/{chunk-O2ASYKA6.js → chunk-3ISHDWO7.js} +2 -2
  137. package/dist/{chunk-GGSNWH7P.js → chunk-527G27VI.js} +5 -5
  138. package/dist/{chunk-N5NSSLMU.js → chunk-6WQCLCBO.js} +2 -2
  139. package/dist/{chunk-OH3NXXUY.js → chunk-BDGTZRZ6.js} +11 -1
  140. package/dist/{chunk-Z3TMCCZB.js → chunk-BYVT5LVO.js} +9 -9
  141. package/dist/{chunk-TIH53QXY.js → chunk-CLI4K2CH.js} +1 -1
  142. package/dist/{chunk-VSIRUZQP.js → chunk-DE5U6KOL.js} +2 -2
  143. package/dist/{chunk-FXZI6NJ2.js → chunk-GGKRA7A7.js} +51 -4
  144. package/dist/{chunk-RJ2WEES5.js → chunk-GSP2XIVS.js} +2 -2
  145. package/dist/{chunk-CZPOPMMI.js → chunk-HEIMJJI4.js} +3 -3
  146. package/dist/{chunk-7AF6C5GE.js → chunk-HWTUUQOW.js} +3 -3
  147. package/dist/{chunk-FC4JPM6W.js → chunk-KAJOS3BA.js} +3 -3
  148. package/dist/{chunk-NIVWM7OW.js → chunk-MGUPSE6D.js} +10 -10
  149. package/dist/{chunk-WZY5U6NS.js → chunk-N24HCQA4.js} +3351 -887
  150. package/dist/{chunk-Y4T6ENKQ.js → chunk-N55WOGN3.js} +86 -17
  151. package/dist/{chunk-INBTDBV2.js → chunk-NWLGL3IR.js} +1 -1
  152. package/dist/{chunk-FEKBXX2J.js → chunk-ONCPJGHY.js} +9 -9
  153. package/dist/{chunk-PTHX545Q.js → chunk-PC2R5RUJ.js} +2 -2
  154. package/dist/{chunk-H2ZJOJ7A.js → chunk-PP6ZRL5T.js} +316 -42
  155. package/dist/{chunk-LECXPXS3.js → chunk-QBC7DI4Q.js} +2 -2
  156. package/dist/{chunk-B2VAYLYI.js → chunk-UX3PQKVZ.js} +8 -3
  157. package/dist/{chunk-7PLIWP7U.js → chunk-WWEVS7RO.js} +4409 -743
  158. package/dist/{chunk-LGYXR2KZ.js → chunk-XFU6SB2Q.js} +1122 -689
  159. package/dist/{chunk-KN3EMDZ5.js → chunk-XX4OLNWQ.js} +23 -3
  160. package/dist/{chunk-VI4IS55S.js → chunk-YQSYCBAH.js} +6 -6
  161. package/dist/{chunk-LYIPI2SJ.js → chunk-Z4AWEIBY.js} +6 -6
  162. package/dist/{ci-workflow-MDSTHJOY.js → ci-workflow-ORZ4F45F.js} +5 -5
  163. package/dist/{dist-E3SAAHCM.js → dist-ICW4QUEW.js} +5 -1
  164. package/dist/{dist-72ID44UE.js → dist-LHINSVK4.js} +136 -4
  165. package/dist/{dist-R3TOOPJ7.js → dist-OWHMNL4W.js} +1 -1
  166. package/dist/{docs-2RFOJ6XY.js → docs-AU3DXFFO.js} +6 -6
  167. package/dist/engine-6GPWOYQH.js +13 -0
  168. package/dist/{entropy-3UX6644G.js → entropy-VLKDRMRT.js} +5 -5
  169. package/dist/{feedback-CVCFYND4.js → feedback-YXYY44ZC.js} +1 -1
  170. package/dist/{generate-agent-definitions-HZ3XENWO.js → generate-agent-definitions-XIHQPKG3.js} +6 -6
  171. package/dist/{glob-helper-EX4YZKZO.js → glob-helper-GLZAURJC.js} +1 -1
  172. package/dist/{graph-loader-EIFEOUVI.js → graph-loader-HHXN5FLP.js} +1 -1
  173. package/dist/hooks/cost-tracker.js +29 -6
  174. package/dist/index.d.ts +202 -0
  175. package/dist/index.js +27 -27
  176. package/dist/{loader-6RHWU5FH.js → loader-YAN56MT3.js} +5 -5
  177. package/dist/{mcp-OYR26JDI.js → mcp-RK3SFVYB.js} +17 -17
  178. package/dist/{performance-JJMIRXCH.js → performance-64DPTLLQ.js} +6 -6
  179. package/dist/{review-pipeline-BHQZIXWZ.js → review-pipeline-NENG6LW7.js} +5 -5
  180. package/dist/{runtime-DALTAVTN.js → runtime-FFIIRT2T.js} +5 -5
  181. package/dist/{scan-LYKLM4EQ.js → scan-P7YFKB77.js} +1 -1
  182. package/dist/{security-RMLMYFPB.js → security-3PIBN35B.js} +1 -1
  183. package/dist/templates/basic/harness.config.json.hbs +34 -0
  184. package/dist/templates/ci/README.md +86 -0
  185. package/dist/templates/ci/required-review.ruleset.json +20 -0
  186. package/dist/templates/ci/required-review.yml.hbs +57 -0
  187. package/dist/templates/ci/template.json +5 -0
  188. package/dist/templates/intermediate/harness.config.json.hbs +36 -0
  189. package/dist/templates/orchestrator/harness.orchestrator.md +9 -0
  190. package/dist/{tool-tiers-B7JC2XC3.js → tool-tiers-OKK5FE57.js} +2 -0
  191. package/dist/{validate-R7DZRDFK.js → validate-7IAF2ES3.js} +6 -6
  192. package/dist/validate-cross-check-QPSAOZKD.js +13 -0
  193. package/package.json +8 -8
  194. package/dist/agents-md-FKMKH6ZF.js +0 -13
  195. package/dist/analyzer-H3AHBFSL-KPOPJYRB.js +0 -26
  196. package/dist/engine-BSFKOGPN.js +0 -13
  197. package/dist/validate-cross-check-AUUZFNVL.js +0 -13
@@ -0,0 +1,88 @@
1
+ # Harness Ideate — Scoring Reference
2
+
3
+ Single reference consumed by Phase 4 RANK of `SKILL.md`. The skill never duplicates these numbers inline; it cites this file. Keeping the formula here lets future tweaks land in one place without rewriting every example in `SKILL.md`.
4
+
5
+ ## Base formula
6
+
7
+ ```
8
+ base_score = (impact × confidence) ÷ effort
9
+ ```
10
+
11
+ Each axis is one of `low`, `medium`, `high`, mapped to a small integer:
12
+
13
+ | Token | Numeric |
14
+ | -------- | ------- |
15
+ | `low` | 1 |
16
+ | `medium` | 2 |
17
+ | `high` | 3 |
18
+
19
+ The mapping is the SAME for `impact`, `confidence`, and `effort`. Use it everywhere.
20
+
21
+ ### Worked example
22
+
23
+ ```
24
+ impact: high (3)
25
+ confidence: medium (2)
26
+ effort: medium (2)
27
+
28
+ base_score = (3 × 2) ÷ 2 = 3.0
29
+ ```
30
+
31
+ Range of `base_score`: `[1 × 1 ÷ 3 ≈ 0.33, 3 × 3 ÷ 1 = 9.0]`. Higher is better.
32
+
33
+ ## Strategy-alignment tiebreaker
34
+
35
+ When `STRATEGY.md` was loaded successfully in Phase 1 GROUND, an alignment bonus is computed per candidate:
36
+
37
+ ```
38
+ alignment_bonus =
39
+ (premise plausibly advances a Tracks bullet ? 0.5 : 0)
40
+ + (premise/persona references Target problem or Our approach ? 0.25 : 0)
41
+ ```
42
+
43
+ The maximum possible bonus is **`+0.75`** (`0.5 + 0.25`). When `STRATEGY.md` is absent or invalid, `alignment_bonus` is `0` for every candidate and this section is skipped entirely.
44
+
45
+ ### Bounded application
46
+
47
+ The bonus is a **tiebreaker, not a multiplier**:
48
+
49
+ - Compute `base_score` for every candidate.
50
+ - Sort by `base_score` descending.
51
+ - For each adjacent pair where `|base_score_n − base_score_{n-1}| ≤ 0.05`, apply the alignment bonus to break the tie:
52
+ - `final_score = base_score + alignment_bonus` for the candidate whose pair-mate is within `0.05`.
53
+ - The bonus is added to BOTH candidates in the tie window; the higher final score wins.
54
+ - For pairs where `|Δbase_score| > 0.05`, the base score determines order — the bonus is recorded in the artifact for transparency but does NOT change the rank.
55
+
56
+ The `0.05` threshold mirrors `harness-roadmap-pilot`'s tiebreaker contract intentionally — same bounded-tiebreaker shape, different domain (ranking ideas vs. ranking roadmap candidates). Aligning the threshold keeps users from learning two different "close enough" rules for two adjacent skills.
57
+
58
+ ### Anti-patterns the bonded cap rejects
59
+
60
+ | Failure mode | Why the cap rejects it |
61
+ | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------ |
62
+ | "Idea A scores 2.0, Idea B scores 5.0; B aligns with strategy, A doesn't" | ` | 5.0 − 2.0 | = 3.0`, way outside the `0.05` window. No bonus applied. Base score wins. Cap protects rankings from over-fitting to strategy. |
63
+ | "Every idea aligns; I'll add `+0.75` to all and call it ranked" | Bonus is only applied within tie windows. Universal alignment yields the same final ordering as the base score. The cap forces ranking to come from the base formula first. |
64
+ | "STRATEGY.md exists but is invalid; I should still apply the bonus heuristically" | Soft-fail: `alignment_bonus = 0` for every candidate when strategy is absent OR invalid. The skill never invents alignment when it cannot read the source. |
65
+ | "I'll widen the threshold to `0.5` so more ideas qualify" | Threshold is a constant in this file, NOT a parameter. Widening means updating this reference and re-justifying the change in an ADR (mirrors the roadmap-pilot decision). |
66
+
67
+ ## Persistence — what lands in the artifact
68
+
69
+ For every candidate the persisted `docs/ideation/<slug>-YYYY-MM-DD.md` records, at minimum:
70
+
71
+ - `base_score` (always)
72
+ - `alignment_bonus` (records the bonus value; `0` when strategy is absent or no signals matched)
73
+ - `final_score` (equals `base_score + alignment_bonus` IF the bonus was applied for tiebreak; otherwise equals `base_score` — the artifact MUST note which case applies via a one-line rationale)
74
+ - Whichever `Tracks` bullet or `Target problem` / `Our approach` phrase the alignment cited (verbatim) — citations are mandatory when `alignment_bonus > 0`
75
+
76
+ The artifact's frontmatter records `ranking_formula` verbatim so a future reader reproduces the order without rerunning the skill.
77
+
78
+ ## Boundary with `harness-roadmap-pilot`
79
+
80
+ | Aspect | `harness-ideate` | `harness-roadmap-pilot` |
81
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
82
+ | What it ranks | Fresh candidate ideas generated in-skill | Existing roadmap entries from `docs/roadmap.md` |
83
+ | Base formula | `(impact × confidence) ÷ effort` (1/2/3 mapping) | `position × 0.5 + dependents × 0.3 + affinity × 0.2` |
84
+ | Tiebreaker threshold | `0.05` | `0.05` |
85
+ | Max alignment bonus | `+0.75` | `+0.75` |
86
+ | When STRATEGY is absent | Skip alignment entirely; rank by base score only; record `strategy_grounded: false` in artifact frontmatter | Skip alignment entirely; rank by base score only; no rationale citation |
87
+
88
+ The two skills share the bounded-tiebreaker contract on purpose. If the threshold or max bonus changes in one, update both — and add an ADR explaining why.
@@ -0,0 +1,66 @@
1
+ name: harness-ideate
2
+ version: "0.1.0"
3
+ description: Pre-brainstorm ideation phase. Generates N candidate ideas grounded in STRATEGY.md (when present), critiques each against its strongest objection, ranks by (impact × confidence) ÷ effort with a bounded strategy-alignment tiebreaker, and writes a single ranked Markdown artifact to docs/ideation/[slug]-YYYY-MM-DD.md. Produces ranked ideation — never specs, plans, or code. harness-brainstorming consumes the output.
4
+ stability: static
5
+ cognitive_mode: divergent-generator
6
+ triggers:
7
+ - manual
8
+ platforms:
9
+ - claude-code
10
+ - gemini-cli
11
+ - cursor
12
+ - codex
13
+ tools:
14
+ - Bash
15
+ - Read
16
+ - Write
17
+ - Edit
18
+ - Glob
19
+ - Grep
20
+ cli:
21
+ command: harness skill run harness-ideate
22
+ args:
23
+ - name: focus
24
+ description: One-line focus argument that anchors candidate generation (e.g., "onboarding for plugin-only users"). Used as the ideation topic and slug source.
25
+ required: false
26
+ - name: count
27
+ description: Number of candidate ideas to generate (default 10, min 5, max 25).
28
+ required: false
29
+ mcp:
30
+ tool: run_skill
31
+ input:
32
+ skill: harness-ideate
33
+ path: string
34
+ type: rigid
35
+ tier: 2
36
+ phases:
37
+ - name: ground
38
+ description: Read STRATEGY.md if present at repo root (grounding); read the focus argument; confirm the topic with the user.
39
+ required: true
40
+ - name: generate
41
+ description: Produce N candidate ideas with per-idea fields (premise, persona, complexity, key risk, impact, confidence, effort).
42
+ required: true
43
+ - name: critique
44
+ description: For each idea identify the strongest objection; user picks which objections to answer.
45
+ required: true
46
+ - name: rank
47
+ description: Score by (impact × confidence) ÷ effort using a 1/2/3 mapping for low/medium/high; apply strategy-alignment as a bounded tiebreaker bonus when STRATEGY.md is present.
48
+ required: true
49
+ - name: write
50
+ description: Persist the ranked artifact to docs/ideation/[slug]-YYYY-MM-DD.md (kebab-case slug ≤30 chars, 6-char hash suffix on collision).
51
+ required: true
52
+ state:
53
+ persistent: true
54
+ files:
55
+ - docs/ideation/
56
+ depends_on: []
57
+ related_skills:
58
+ - harness-strategy
59
+ - harness-brainstorming
60
+ keywords:
61
+ - ideation
62
+ - pre-brainstorm
63
+ - candidate-generation
64
+ - impact-confidence-effort
65
+ - strategic-anchor
66
+ - compound-engineering
@@ -14,6 +14,8 @@
14
14
 
15
15
  ## Process
16
16
 
17
+ **Prompt the human in plain text** — every confirmation, drift acknowledgement, and contradiction resolution in this skill is plain text only. Do not elevate to `AskUserQuestion`: source labels and finding descriptions routinely exceed its 4-option / 12-char caps, rendering the call as ERR.
18
+
17
19
  1. **EXTRACT:** Run code signal extractors, diagram parsers, BusinessKnowledgeIngestor, and KnowledgeLinker against the project
18
20
  2. **RECONCILE:** Build pre-extraction snapshot (current graph state) and post-extraction snapshot, then run StructuralDriftDetector
19
21
  3. **DETECT:** Partition findings by classification (new/stale/drifted/contradicting), generate gap report
@@ -294,7 +294,16 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
294
294
  5. **Check failures log.** Read `.harness/failures.md`. If planned approaches match known failures, flag them.
295
295
  6. **Run soundness review.** Invoke `harness-soundness-review --mode plan` against the draft. Do not proceed until the review converges with no remaining issues.
296
296
  7. **Write the plan to `docs/changes/<topic>/plans/`.** Naming: `YYYY-MM-DD-<feature-name>-plan.md`. Resolve `<topic>` from the spec path — if the spec lives at `docs/changes/<topic>/proposal.md`, the plan goes in the sibling `plans/` directory. If the spec is not under `docs/changes/`, fall back to `docs/plans/` and flag the spec location for human review. Create directories as needed.
297
- 8. **Write handoff.** Write to the session-scoped path when session slug is known, otherwise fall back to global path:
297
+ 8. **Commit plan artifact.** Immediately after writing the plan, commit it so the paper trail enters git history at planning time, not after execution:
298
+
299
+ ```bash
300
+ git add docs/changes/<topic>/plans/YYYY-MM-DD-<feature-name>-plan.md
301
+ git commit -m "docs(<topic>): add plan"
302
+ ```
303
+
304
+ Use `docs/plans/` if the spec is not under `docs/changes/<topic>/`. Do not skip — `harness-execution` commits only implementation files, so a plan uncommitted here stays untracked until someone notices. If a pre-commit hook reformats the file, re-add and re-commit.
305
+
306
+ 9. **Write handoff.** Write to the session-scoped path when session slug is known, otherwise fall back to global path:
298
307
  - Session-scoped (preferred): `.harness/sessions/<session-slug>/handoff.json`
299
308
  - Global (fallback, **deprecated**): `.harness/handoff.json`
300
309
 
@@ -302,11 +311,11 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
302
311
 
303
312
  Fields: `fromSkill`, `phase`, `summary`, `completed`, `pending`, `concerns`, `decisions`, `contextKeywords`.
304
313
 
305
- 9. **Write session summary (if session is known).** Call `writeSessionSummary` with skill, status, plan path, keyContext, nextStep. Skip if no session slug.
314
+ 10. **Write session summary (if session is known).** Call `writeSessionSummary` with skill, status, plan path, keyContext, nextStep. Skip if no session slug.
306
315
 
307
- 10. **Request plan sign-off:** Use `emit_interaction` (type: `confirmation`) with plan path, task count, and time estimate.
316
+ 11. **Request plan sign-off:** Use `emit_interaction` (type: `confirmation`) with plan path, task count, and time estimate.
308
317
 
309
- 11. **Suggest transition to execution.** After approval, call `emit_interaction` with type: `transition`, `completedPhase: "planning"`, `suggestedNext: "execution"`, `requiresConfirmation: true`. Include `qualityGate` with checks: plan-written, harness-validate, observable-truths-traced, human-approved. If confirmed: invoke harness-execution. If declined: stop (handoff already written).
318
+ 12. **Suggest transition to execution.** After approval, call `emit_interaction` with type: `transition`, `completedPhase: "planning"`, `suggestedNext: "execution"`, `requiresConfirmation: true`. Include `qualityGate` with checks: plan-written, harness-validate, observable-truths-traced, human-approved. If confirmed: invoke harness-execution. If declined: stop (handoff already written).
310
319
 
311
320
  ---
312
321
 
@@ -392,6 +401,7 @@ When referencing existing code in task specs, cite evidence using `file:line` fo
392
401
 
393
402
  - **`harness validate`** — Run in Phase 4 (before writing plan) and included in every task.
394
403
  - **`harness check-deps`** — Referenced in tasks adding imports or creating modules.
404
+ - **Plan commit** — After writing the plan (Phase 4 Step 8), commit `docs/changes/<topic>/plans/YYYY-MM-DD-<feature-name>-plan.md` so the paper trail enters git history at planning time. `harness-execution` does not backfill — see issue #487.
395
405
  - **Plan location** — `docs/changes/<topic>/plans/YYYY-MM-DD-<feature-name>-plan.md` when the spec lives under `docs/changes/<topic>/proposal.md`; otherwise `docs/plans/` as a fallback.
396
406
  - **Handoff** — Once approved, invoke harness-execution for task-by-task implementation.
397
407
  - **Session directory** — Session-scoped writes go to `.harness/sessions/<slug>/`. Structure: `handoff.json`, `state.json`, `artifacts.json` (registry of spec/plan paths and produced file lists). Global `.harness/handoff.json` is deprecated for session-aware invocations.
@@ -30,7 +30,7 @@
30
30
 
31
31
  Read `references/interview.md` for the SMART pushback rules and the READ-WRITE-DB rejection rule. Both are mandatory.
32
32
 
33
- 1. **Seed from STRATEGY.md.** Shell out to a Node one-liner that imports `seedFromStrategy` from `@harness-engineering/core`. Capture `{ name, keyMetrics, warnings }`.
33
+ 1. **Seed from STRATEGY.md.** Call `seed_pulse_from_strategy({ path: process.cwd() })` on the harness MCP server. Capture `{ name, keyMetrics, warnings }` — the server does the file read and bullet extraction internally. Fallback when the MCP server is unavailable: `node -e "import('@harness-engineering/core').then(m => console.log(JSON.stringify(m.seedFromStrategy({}))))"` only works when `@harness-engineering/core` is resolvable from the project.
34
34
  - Surface `warnings` to the user verbatim.
35
35
  - If `name` is non-null, confirm it as the product name; otherwise prompt.
36
36
  - For each `keyMetric`, walk it through the SMART bar in step 4.
@@ -56,13 +56,9 @@ Read `references/interview.md` for the SMART pushback rules and the READ-WRITE-D
56
56
 
57
57
  9. **Confirm the assembled config.** Show the user the proposed `pulse:` block; ask for confirmation.
58
58
 
59
- 10. **Write the config.** Shell out to a Node one-liner that imports `writePulseConfig` from `@harness-engineering/core`. Pipe the JSON through stdin so user-supplied event names, qualityDimension, and pendingMetrics never cross the shell tokenizer (quotes, backticks, `$()`, `$VAR` in user input would otherwise break the command or allow injection):
59
+ 10. **Write the config.** Call `write_pulse_config({ path: process.cwd(), config })` on the harness MCP server. The `config` argument is the assembled `PulseConfig` JSON. The MCP tool validates against `PulseConfigSchema` and refuses to touch disk on schema failure; passing the config as a JSON parameter (not through a shell) means user-supplied prose never crosses the shell tokenizer — no quoting, backtick, or `$VAR` hazard. The writer preserves all other config keys and writes `harness.config.json.bak` on first call.
60
60
 
61
- ```bash
62
- echo '<json-blob>' | node -e "import('@harness-engineering/core').then(m => m.writePulseConfig(JSON.parse(require('fs').readFileSync(0, 'utf-8')), { configPath: 'harness.config.json' })).catch(err => { console.error(err.message); process.exit(1); })"
63
- ```
64
-
65
- The writer preserves all other config keys and writes a `.bak`.
61
+ Fallback for environments without the MCP server (only works when `@harness-engineering/core` is resolvable from the project): `echo '<json-blob>' | node -e "import('@harness-engineering/core').then(m => m.writePulseConfig(JSON.parse(require('fs').readFileSync(0, 'utf-8')), { configPath: 'harness.config.json' }))"`.
66
62
 
67
63
  11. **Offer to register the `product-pulse` maintenance task.** Deferred: Phase 6 of the spec wires it. For now, surface "the daily 8am `product-pulse` task will be registered automatically once Phase 6 of the feedback-loops spec ships; you can also run pulse on demand with `/harness:pulse [window]` once Phase 4 ships."
68
64
 
@@ -80,12 +76,12 @@ Stub: when `pulse.enabled === true`, this phase will dispatch analytics/tracing/
80
76
 
81
77
  ## Harness Integration
82
78
 
83
- - **`harness validate`** — Run after `writePulseConfig`; the existing pulse-schema validator catches malformed blocks.
84
- - **`@harness-engineering/core`** primitives consumed by this skill:
85
- - `writePulseConfig(config, { configPath })` — atomic config update with .bak.
86
- - `seedFromStrategy({ cwd })` — defensive STRATEGY.md reader.
87
- - `getPulseAdapter(name)` / `listPulseAdapters()` adapter discovery (Phase 4 populates).
88
- - `PulseConfigSchema` / `PII_FIELD_DENYLIST` schema and PII contracts (already shipped Phase 1).
79
+ - **`harness validate`** — Run after `write_pulse_config`; the existing pulse-schema validator catches malformed blocks.
80
+ - **Harness MCP tools consumed by this skill** (canonical execution path — no project-local `@harness-engineering/core` required):
81
+ - `seed_pulse_from_strategy({ path })` — defensive STRATEGY.md reader; returns `{ name, keyMetrics, warnings }`.
82
+ - `write_pulse_config({ path, config })` — atomic config update with .bak. Validates against `PulseConfigSchema`.
83
+ - **`@harness-engineering/core`** primitives the MCP tools wrap (only directly relevant when developing inside the monorepo or when the MCP server is unavailable):
84
+ - `writePulseConfig(config, { configPath })`, `seedFromStrategy({ cwd })`, `getPulseAdapter(name)` / `listPulseAdapters()` (Phase 4 populates), `PulseConfigSchema` / `PII_FIELD_DENYLIST`.
89
85
  - **Boundary with `harness-strategy`** — Strategy writes `STRATEGY.md`; pulse reads it to seed. Pulse never writes to `STRATEGY.md`.
90
86
  - **Boundary with `harness-observability`** — Observability designs _what_ to instrument; pulse is the read-side companion that surfaces what was instrumented.
91
87
  - **Decision 6 (read-only)** — Pulse refuses read-write DB credentials. Documented in `references/interview.md`.
@@ -106,7 +102,7 @@ Stub: when `pulse.enabled === true`, this phase will dispatch analytics/tracing/
106
102
  - Phase 0: route to Phase 1.
107
103
  - Phase 1.1: `seedFromStrategy` returns `{ name: null, keyMetrics: [], warnings: ['STRATEGY.md not found'] }`.
108
104
  - Phase 1.2-7: prompt user; collect `lookbackDefault: '24h'`, `primaryEvent: 'session_started'`, `valueEvent: 'plan_completed'`, `sources.analytics: 'posthog'` (with adapter-availability warning), `sources.db.enabled: false`.
109
- - Phase 1.10: `writePulseConfig` writes the block; `.bak` saved.
105
+ - Phase 1.10: `write_pulse_config` writes the block; `.bak` saved.
110
106
  - Phase 1.12: `harness validate` passes.
111
107
 
112
108
  ### Example: STRATEGY.md present with 3 Key metrics
@@ -127,7 +123,7 @@ Stub: when `pulse.enabled === true`, this phase will dispatch analytics/tracing/
127
123
 
128
124
  - **READ-WRITE-DB rejection is non-negotiable.** No flag, no override, no "I know what I'm doing" path. Refuse and document.
129
125
  - **SMART pushback is mandatory on every proposed metric/event.** Silently accepting a vague name pollutes the corpus.
130
- - **`writePulseConfig` is the only sanctioned write path.** Do not hand-edit `harness.config.json`. The writer is the layer that preserves non-pulse keys and writes the .bak.
126
+ - **`write_pulse_config` (or `writePulseConfig` when invoked directly) is the only sanctioned write path.** Do not hand-edit `harness.config.json`. The writer is the layer that preserves non-pulse keys and writes the .bak.
131
127
  - **`harness validate` must pass before exit.** A malformed `pulse:` block silently breaks the daily task once Phase 4 ships.
132
128
 
133
129
  ## Escalation
@@ -135,4 +131,4 @@ Stub: when `pulse.enabled === true`, this phase will dispatch analytics/tracing/
135
131
  - **User insists on read-write DB credentials:** Refuse. Set `sources.db.enabled: false`. Stop.
136
132
  - **Adapter not registered for a chosen provider:** Warn, record the choice, continue. The runtime gate (Phase 4) refuses to run until the adapter ships.
137
133
  - **STRATEGY.md frontmatter is malformed but H1 is present:** Use H1 as `name` and surface a warning. If neither is parseable, prompt the user.
138
- - **`writePulseConfig` throws:** Report the validator error verbatim. Do not retry without user fix.
134
+ - **`write_pulse_config` returns `{ written: false, error }` (or `writePulseConfig` throws directly):** Report the validator error verbatim. Do not retry without user fix.
@@ -9,6 +9,7 @@
9
9
  - When adding a new feature to an existing roadmap (`--add <feature-name>`)
10
10
  - When roadmap statuses may be stale and need updating from plan execution state (`--sync`)
11
11
  - When features need reordering, moving between milestones, or blocker updates (`--edit`)
12
+ - When the roadmap needs tidying -- completed work archived, dead `planned` rows demoted (`--groom`)
12
13
  - When user asks about project status and no roadmap exists -- suggest `--create`
13
14
  - NOT for programmatic CRUD (use `manage_roadmap` MCP tool directly)
14
15
 
@@ -20,6 +21,8 @@
20
21
 
21
22
  If the human has not seen and approved the milestone groupings and feature list, do not write the file. Present. Wait. Confirm. Then write.
22
23
 
24
+ **Prompt the human in plain text — every `(y/n)`, "which feature?", and similar prompt in this skill is plain text only.** Do not elevate them to `AskUserQuestion`: feature lists routinely exceed its 4-option cap, and natural header choices ("Pick feature", "Remove feature") exceed its 12-char cap, causing the call to render as ERR.
25
+
23
26
  ---
24
27
 
25
28
  ### Command: `--create` -- Bootstrap Roadmap
@@ -428,12 +431,67 @@ Choice?
428
431
 
429
432
  ---
430
433
 
434
+ ### Command: `--groom` -- Tidy the Roadmap
435
+
436
+ Keeps the roadmap manageable over time. **Milestones are themes; statuses are lifecycle stages** -- grooming enforces that separation so the backlog never decays back into an undifferentiated dump.
437
+
438
+ #### Phase 1: SCAN -- Detect Untidiness
439
+
440
+ 1. Check if `docs/roadmap.md` exists. If missing: error and direct the user to `--create`.
441
+ 2. Run `manage_roadmap` (`action: "groom"`) in a dry-run frame, or call `checkRoadmapHealth` from `@harness-engineering/core`, to surface the four health signals:
442
+ - **RMH001** -- completed (`done`) features still sitting in an active milestone.
443
+ - **RMH002** -- `planned` rows with neither a spec nor a plan (the orchestrator cannot auto-execute these; it escalates them to a human).
444
+ - **RMH003** -- lifecycle catch-all milestones (`Backlog`, `Current Work`) that should not exist.
445
+ - **RMH004** -- active milestones that have grown past the size cap (a mini-dump).
446
+
447
+ #### Phase 2: PROPOSE -- Present the Plan
448
+
449
+ Show the human exactly what grooming will do, in plain text:
450
+
451
+ ```
452
+ GROOM PLAN
453
+
454
+ Demote to backlog (planned with no spec/plan):
455
+ - Feature A (Theme X)
456
+ - Feature B (Theme Y)
457
+
458
+ Archive to docs/roadmap-archive.md (completed):
459
+ - Feature C (Theme X)
460
+
461
+ Flagged for manual routing (not auto-changed):
462
+ - Intake lane has 3 items awaiting a theme
463
+ - "Theme Z" has 28 features (cap 25) -- consider splitting
464
+
465
+ Apply? (y/n)
466
+ ```
467
+
468
+ Wait for confirmation. The mechanical changes (demote, archive) are safe and automated; **draining the Intake lane into themed milestones and splitting oversized milestones are human decisions** -- propose, do not auto-apply.
469
+
470
+ #### Phase 3: WRITE -- Apply
471
+
472
+ 1. Run `manage_roadmap` (`action: "groom"`). It demotes unactionable `planned` rows to `backlog` and moves `done` features into `docs/roadmap-archive.md` under a `Shipped` milestone, returning the list of changes.
473
+ 2. For Intake-draining or milestone-splitting the human approved, follow up with `--edit` (move features between milestones).
474
+
475
+ #### Phase 4: VALIDATE -- Verify
476
+
477
+ 1. Run `harness validate` and confirm the `roadmapHealth` check passes (no RMH003 errors; RMH001/002/004 warnings cleared or acknowledged).
478
+ 2. Summarize:
479
+
480
+ ```
481
+ Groom complete.
482
+ Demoted: N | Archived: N -> docs/roadmap-archive.md | Flagged for manual routing: N
483
+ harness validate (roadmapHealth): passed
484
+ ```
485
+
486
+ ---
487
+
431
488
  ## Harness Integration
432
489
 
433
- - **`manage_roadmap` MCP tool** -- Primary read/write interface for roadmap operations. Supports `show`, `add`, `update`, `remove`, and `query` actions. Use this when MCP is available for structured CRUD.
434
- - **`harness validate`** -- Run after any roadmap modification to verify project health. Mandatory in the VALIDATE phase of both `--create` and `--add`.
435
- - **Core `parseRoadmap`/`serializeRoadmap`** -- Fallback when MCP is unavailable. These functions in `packages/core/src/roadmap/` handle parsing and serializing the roadmap markdown format directly.
436
- - **Roadmap file** -- Always at `docs/roadmap.md`. This is the single source of truth for the project roadmap.
490
+ - **`manage_roadmap` MCP tool** -- Primary read/write interface for roadmap operations. Supports `show`, `add`, `update`, `remove`, `query`, `sync`, `promote`, and `groom` actions. Use this when MCP is available for structured CRUD.
491
+ - **`harness validate`** -- Run after any roadmap modification to verify project health. Mandatory in the VALIDATE phase of `--create`, `--add`, and `--groom`. The `roadmapHealth` check enforces the maintenance rules (RMH001-RMH004) as a regression guard.
492
+ - **Core `checkRoadmapHealth`/`groomRoadmap`** -- Maintenance engine in `packages/core/src/roadmap/health.ts`. `checkRoadmapHealth` is read-only diagnostics; `groomRoadmap` is the pure transform (demote unactionable planned, archive done). Both are surfaced via `manage_roadmap` and `harness validate`.
493
+ - **Core `parseRoadmap`/`serializeRoadmap`** -- Fallback when MCP is unavailable. These functions in `packages/core/src/roadmap/` handle parsing and serializing the roadmap markdown format directly. Note: the serializer only preserves frontmatter, milestones, features, and the Assignment History table -- never add convention prose or comments to `docs/roadmap.md`, they are dropped on the next write.
494
+ - **Roadmap files** -- Live work in `docs/roadmap.md` (the orchestrator's source of truth); completed work archived to `docs/roadmap-archive.md` by `--groom`. Milestones are themes, not lifecycle stages -- promoted items land in the `Intake` lane and are groomed into themes.
437
495
 
438
496
  ## Success Criteria
439
497
 
@@ -58,6 +58,30 @@ Top candidates (scored by position 50%, dependents 30%, affinity 20%):
58
58
  - Read the spec's Success Criteria section
59
59
  - Assess effort and impact from the spec content
60
60
 
61
+ 1a. **Read `STRATEGY.md` if present at repo root (strategy-alignment input).** Use a Node one-liner that calls `validateStrategy` from `@harness-engineering/core`, then (when valid) `parseStrategyDoc` + `asStrategyDoc`:
62
+
63
+ ```bash
64
+ node -e "import('@harness-engineering/core').then(async m => {
65
+ const v = await m.validateStrategy(process.cwd());
66
+ if (!v.present || !v.valid) { console.log(JSON.stringify({ grounded: false })); return; }
67
+ const raw = require('fs').readFileSync('STRATEGY.md', 'utf-8');
68
+ console.log(JSON.stringify({ grounded: true, doc: m.asStrategyDoc(m.parseStrategyDoc(raw)) }));
69
+ })"
70
+ ```
71
+
72
+ When `grounded: true`, capture the `Target problem`, `Our approach`, and `Tracks` section bodies. For each top-3 candidate, compute a strategy-alignment score:
73
+
74
+ - `+0.5` if the candidate's feature name or spec keywords plausibly advance one of the `Tracks` (case-insensitive substring or paraphrase match)
75
+ - `+0.25` if the candidate's spec Overview cites the `Target problem` or `Our approach` verbatim or near-verbatim
76
+ - `0` otherwise
77
+
78
+ The alignment score is a **tiebreaker bonus**, NEVER a hard filter:
79
+
80
+ - Apply only when the absolute difference between two candidates' base scores is `≤ 0.05` (items score similarly on `position × 0.5 + dependents × 0.3 + affinity × 0.2`).
81
+ - Never let the bonus override a meaningful base-score difference.
82
+ - When alignment is applied, cite it in the recommendation rationale ("Tiebreaker: aligned with track 'pulse-reports' from STRATEGY.md").
83
+ - When `STRATEGY.md` is absent or invalid, skip this step silently; the recommendation proceeds without a strategy tiebreaker.
84
+
61
85
  1b. Read the most recent pulse report (if any):
62
86
 
63
87
  - List entries in `docs/pulse-reports/` and **filter to those matching the
@@ -102,6 +126,8 @@ Proceed with Feature A? (y/n/pick another)
102
126
 
103
127
  ### Phase 3: CONFIRM -- Human Decision
104
128
 
129
+ Ask the human in plain text (matching the `y/n/pick another` example above). Do not elevate this confirmation to an `AskUserQuestion` tool call — candidate labels and natural header choices ("Pick candidate", etc.) exceed its 12-char `header` cap and the prompt is rejected as ERR.
130
+
105
131
  1. Wait for human confirmation.
106
132
  - If **yes**: proceed to Phase 4.
107
133
  - If **pick another**: ask which candidate number, then proceed with that pick.
@@ -166,6 +192,7 @@ Proceed with Feature A? (y/n/pick another)
166
192
  - **`scoreRoadmapCandidates`** -- Underlying file-backed scoring algorithm. Prefer `scoreRoadmapCandidatesForMode` from the skill; direct callers in file-backed-only code paths can still use this.
167
193
  - **`manage_roadmap update`** -- Used for assignment. Supports `assignee` field which delegates to `assignFeature` internally, handles history tracking, and automatically triggers external sync (GitHub Issues). In file-less mode, `manage_roadmap` dispatches through the tracker; the skill flow is unchanged.
168
194
  - **`emit_interaction`** -- Used for the skill transition at the end. Transitions to `harness:brainstorming` (no spec) or `harness:autopilot` (spec exists).
195
+ - **`STRATEGY.md` alignment (Phase 2 step 1a)** -- When present at repo root and valid, loaded via `validateStrategy` + `parseStrategyDoc` + `asStrategyDoc` from `@harness-engineering/core`. Applied as a bounded tiebreaker bonus (max `+0.75`) only when candidates score within `0.05` on the base formula. Boundary: roadmap-pilot READS; `harness-strategy` WRITES. Never modify `STRATEGY.md` from this skill.
169
196
  - **`harness validate`** -- Run after assignment is written.
170
197
 
171
198
  ## Success Criteria
@@ -178,15 +205,18 @@ Proceed with Feature A? (y/n/pick another)
178
205
  6. Reassignment produces two history records (unassigned + assigned)
179
206
  7. Transition routes to brainstorming (no spec) or autopilot (spec exists)
180
207
  8. When a pulse report exists, the recommendation rationale cites pulse signal for any top-3 candidate whose area is referenced in the pulse Headlines or Followups.
181
- 9. `harness validate` passes after all changes
208
+ 9. When `STRATEGY.md` is present and valid AND two candidates score within `0.05` on the base formula, the recommendation rationale cites strategy-alignment as the tiebreaker. The bonus never overrides a meaningful base-score difference.
209
+ 10. When `STRATEGY.md` is absent or invalid, the skill completes without error and no strategy-alignment rationale appears in the output.
210
+ 11. `harness validate` passes after all changes
182
211
 
183
212
  ## Rationalizations to Reject
184
213
 
185
- | Rationalization | Reality |
186
- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
187
- | "The top-scored candidate is obviously correct, so I can assign it without asking the human" | The Iron Law: never assign or transition without the human confirming the recommendation first. |
188
- | "Affinity data is not available so the scoring is degraded -- I should just pick the first planned item" | Proceed without affinity scoring by zeroing out the affinity weight. Position and dependents signals still produce meaningful rankings. |
189
- | "The feature has no spec, but I can skip brainstorming and jump straight to planning since the summary is clear enough" | No spec routes to brainstorming, spec exists routes to autopilot. A one-line roadmap summary is not a spec. |
214
+ | Rationalization | Reality |
215
+ | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
216
+ | "The top-scored candidate is obviously correct, so I can assign it without asking the human" | The Iron Law: never assign or transition without the human confirming the recommendation first. |
217
+ | "Affinity data is not available so the scoring is degraded -- I should just pick the first planned item" | Proceed without affinity scoring by zeroing out the affinity weight. Position and dependents signals still produce meaningful rankings. |
218
+ | "The feature has no spec, but I can skip brainstorming and jump straight to planning since the summary is clear enough" | No spec routes to brainstorming, spec exists routes to autopilot. A one-line roadmap summary is not a spec. |
219
+ | "STRATEGY.md exists, so I should let it override the top-scored candidate when alignment is clear" | The alignment bonus is bounded (max `+0.75`) and only fires when base scores are within `0.05`. It is a tiebreaker, not a hard filter — a clearly higher-scored item still wins. |
190
220
 
191
221
  ## Examples
192
222
 
@@ -0,0 +1,152 @@
1
+ # Harness Strategy
2
+
3
+ > Repo-root strategic anchor. **Phase 2 of the strategic-anchor spec ships the skill**: a first-run interview that writes a valid `STRATEGY.md`, plus an update flow that re-interviews one section at a time with pushback against fluff, goals-as-strategy, and feature-lists-as-strategy. Downstream wiring (init, brainstorming, roadmap-pilot, ideate, knowledge graph) ships in spec Phases 3-7.
4
+
5
+ ## When to Use
6
+
7
+ - Manually, when a project wants a durable upstream product anchor that survives across milestones and phases
8
+ - When `STRATEGY.md` is absent and the user invokes `/harness:strategy`
9
+ - When `STRATEGY.md` exists and the user wants to update one section (the user picks which one; nothing is auto-rewritten)
10
+ - NOT for tactical phase tracking — that's `docs/roadmap.md` (kept deliberately separate; see proposal Decision 1)
11
+ - NOT for generating strategy from code or commit history — strategy is a human commitment, never a derived artifact (proposal Decision 8)
12
+ - NOT for producing specs/plans/code — those are `harness-brainstorming`'s job; this skill only writes `STRATEGY.md`
13
+
14
+ ## Process
15
+
16
+ ### Iron Law
17
+
18
+ **The skill never writes `STRATEGY.md` without explicit user confirmation of the assembled doc, and never silently accepts an answer that fails a pushback rule on the FIRST round.** The 2-round cap is the _capitulation_ point, not the _bypass_ point — round 1 must always fire when a rule matches.
19
+
20
+ ---
21
+
22
+ ### Phase 0: ROUTE BY FILE STATE
23
+
24
+ 1. **Locate `STRATEGY.md` at repo root.** Use `path.join(process.cwd(), 'STRATEGY.md')`.
25
+ 2. **Call `validate_strategy({ path: process.cwd() })` via the harness MCP server.** It returns `{ present, valid, error? }`. The MCP server already has `@harness-engineering/core` loaded, so the project does not need it installed.
26
+ - **`{ present: false }`** → proceed to Phase 1 (first-run interview).
27
+ - **`{ present: true, valid: true }`** → proceed to Phase 2 (update run).
28
+ - **`{ present: true, valid: false, error }`** → surface `error` verbatim, then offer three paths via `emit_interaction` (or numbered chat options when MCP is unavailable):
29
+ - **a)** Fix the offending section now via the update flow → proceed to Phase 2 with the broken section pre-selected.
30
+ - **b)** Move file to `STRATEGY.md.bak.<YYYY-MM-DD-HHmm>` and run Phase 1 fresh.
31
+ - **c)** Exit; user repairs manually. No further action.
32
+
33
+ The skill MUST NOT auto-overwrite a present-but-invalid STRATEGY.md — that's the user's prior work, even if broken. The three-path offer is the contract.
34
+
35
+ ---
36
+
37
+ ### Phase 1: FIRST-RUN INTERVIEW
38
+
39
+ Read `references/interview.md` for the three pushback rules and the 2-round cap. Both are mandatory.
40
+
41
+ Walk sections in **template order** — never out of order, because each section informs the next:
42
+
43
+ 1. **Target problem.** Open with: _"In 2-4 sentences: what is specifically broken in the world that this product addresses? Not the goal — the diagnosis."_ Capture. Apply `Fluff detection` and `Goal-as-strategy` rules.
44
+ 2. **Our approach.** Open with: _"What is your distinctive bet on how to solve the target problem? The choice you're making about HOW, not WHAT you're building."_ Apply all three rules (`Fluff`, `Goal-as-strategy`, `Feature-list-as-strategy`) — this is where feature-list answers live.
45
+ 3. **Who it's for.** Open with: _"Specific persona — who is the person, what context are they in, what alternatives are they currently using? 'Developers' is not a specific persona."_ Apply `Fluff detection`.
46
+ 4. **Key metrics.** Open with: _"What 1-5 metrics, measured where, would tell you the bet is paying off? Each metric is a bullet line: `- <name>: <how measured, where it lives>`."_ Apply `Fluff detection` per bullet.
47
+ 5. **Tracks.** Open with: _"What 1-5 tracks of work are you currently investing in to advance the bet? Each track is a bullet line: `- <track name>: <one-sentence current investment>`."_ Apply `Feature-list-as-strategy` per bullet (a "track" should be an investment direction, not a feature name).
48
+ 6. **Optional sections.** Ask once whether to add `Milestones`, `Not working on`, and/or `Marketing`. If yes, walk each with the same rules. If no, skip — they remain absent (the schema allows omission).
49
+ 7. **Assemble.** Show the full proposed doc. Ask explicitly: _"Write this to STRATEGY.md?"_ Wait for yes/no.
50
+ 8. **Write.** Call `write_strategy({ path: process.cwd(), doc })` via the harness MCP server. The `doc` argument is the assembled `StrategyDoc` shape: `{ frontmatter: { name, last_updated, version }, sections: [{ name, body }, ...] }`. Set `last_updated` to today's ISO date; `version` to `1` for first run. The MCP tool validates against `StrategyDocSchema` and refuses to touch disk on schema failure. Passing the doc as a JSON parameter (not through a shell) means user-supplied prose never crosses the shell tokenizer — no quoting, backtick, or `$VAR` hazard. Fallback for environments without the MCP server: shell out to `node -e "import('@harness-engineering/core').then(m => m.writeStrategyDoc(JSON.parse(require('fs').readFileSync(0, 'utf-8')), { cwd: process.cwd() }))"` with the doc piped on stdin — but only when `@harness-engineering/core` is resolvable from the project's `node_modules`.
51
+
52
+ 9. **Validate.** Run `harness validate` to confirm the file passes `StrategyDocSchema`. On failure, surface the error and stop (do not retry).
53
+
54
+ ---
55
+
56
+ ### Phase 2: UPDATE RUN
57
+
58
+ 1. **Re-read the existing file** via `read_strategy({ path: process.cwd() })` on the harness MCP server. It returns `{ present: true, valid: true, doc }` with the parsed `StrategyDoc` shape; the server runs `validateStrategy` + `parseStrategyDoc` + `asStrategyDoc` internally so the project does not need `@harness-engineering/core` installed.
59
+ 2. **Summarize current state** in 3-5 lines: frontmatter (`name`, `last_updated`, `version`), then the first sentence of each present section. This is the "what's there now" view the user needs to choose what to revisit.
60
+ 3. **Ask which section to revisit.** Present the section names as numbered options. Allow `none` (exit) or `multiple` (sequential re-interviews).
61
+ 4. **Re-interview each selected section** with the same pushback rules and 2-round cap from Phase 1. Do not re-ask sections the user did not select.
62
+ 5. **Bump frontmatter.** Set `last_updated` to today's ISO date. Increment `version` by 1.
63
+ 6. **Confirm and write.** Show the diff between the parsed doc and the new doc (added/changed sections). Ask explicitly: _"Write the update?"_ Wait for yes/no. Call `write_strategy` (same pattern as Phase 1.8). The writer preserves the user's H1 line and writes a `.bak` only if no `.bak` exists yet (idempotent — the original pre-strategy file is the rollback target).
64
+ 7. **Validate.** Run `harness validate`.
65
+
66
+ ---
67
+
68
+ ### Phase 3: DOWNSTREAM HANDOFF
69
+
70
+ After Phase 1 or Phase 2 completes successfully, print this short note (3-5 lines):
71
+
72
+ ```
73
+ STRATEGY.md written. Downstream skills that pick this up as grounding:
74
+ - harness-brainstorming (Phase 5 of strategic-anchor spec — reads STRATEGY.md in Phase 1 EXPLORE)
75
+ - harness-ideate (Phase 4 of spec — generates ranked candidates grounded in STRATEGY.md)
76
+ - harness-roadmap-pilot (Phase 6 of spec — strategy-alignment tiebreaker)
77
+ - BusinessKnowledgeIngestor (Phase 7 of spec — strategy domain → business_fact nodes)
78
+ Soft-fail when absent; no downstream skill blocks on STRATEGY.md's presence.
79
+ ```
80
+
81
+ The handoff exists to set the user's expectation about _why_ they just answered those questions. It is short by design — this is not a section to grow.
82
+
83
+ ## Harness Integration
84
+
85
+ - **`harness validate`** — Run after `write_strategy`; the existing `validateStrategy` helper (Phase 1 of this spec) catches schema violations.
86
+ - **Harness MCP tools consumed by this skill** (canonical execution path — works without `@harness-engineering/core` in the project's `node_modules`):
87
+ - `validate_strategy({ path })` — Phase 0's routing oracle. Returns `{ present, valid, error? }`.
88
+ - `read_strategy({ path })` — Phase 2's read path. Returns `{ present, valid, doc?, error? }`.
89
+ - `write_strategy({ path, doc, skipBackup? })` — atomic disk write with `.bak` on first overwrite. Validates against `StrategyDocSchema` before touching disk.
90
+ - **`@harness-engineering/core`** primitives the MCP tools wrap (only directly relevant when developing inside the monorepo or when the MCP server is unavailable):
91
+ - `validateStrategy(cwd)`, `parseStrategyDoc(raw)` + `asStrategyDoc(parsed)`, `writeStrategyDoc(doc, { cwd, skipBackup? })`, `serializeStrategyDoc(doc, opts?)`, `StrategyDocSchema`.
92
+ - **Boundary with `harness-pulse`** — Pulse reads `STRATEGY.md` to seed metric names; strategy writes it. Pulse NEVER writes to `STRATEGY.md` (Decision 6 of the feedback-loops spec). Strategy NEVER touches `harness.config.json`.
93
+ - **Boundary with `harness-brainstorming`** — Brainstorming consumes `STRATEGY.md` as grounding context; this skill produces it. Phase 5 of the strategic-anchor spec wires the brainstorming read path.
94
+ - **Decision 1 (separation from roadmap.md)** — `docs/roadmap.md` is tactical phase tracking; `STRATEGY.md` is the strategic anchor. They never merge. Documented in `references/interview.md`.
95
+ - **Decision 2 (placeholder rejection)** — A STRATEGY.md with the template placeholder text (e.g., `<2-4 sentences. ...>`) still in it FAILS validation. The skill never writes placeholder text; the writer validates before touching disk.
96
+
97
+ ## Success Criteria
98
+
99
+ - On a project with no `STRATEGY.md`, the first-run interview produces a valid `STRATEGY.md` ≤ 100 lines that passes `harness validate`.
100
+ - Re-running the skill on a project with a valid `STRATEGY.md` enters Phase 2 (update), preserves sections the user did not touch verbatim, bumps `version`, and updates `last_updated`.
101
+ - All three pushback rules (`Fluff detection`, `Goal-as-strategy`, `Feature-list-as-strategy`) fire on at least one canonical anti-pattern fixture in `references/interview.md`.
102
+ - After Phase 1 or 2, `harness validate` passes.
103
+ - A `STRATEGY.md.bak` is written on the _first_ overwrite of an existing file, but NOT clobbered on subsequent overwrites (idempotency).
104
+ - A present-but-invalid STRATEGY.md surfaces the validation error and offers the three repair paths from Phase 0; the skill never auto-overwrites a present-but-invalid file.
105
+
106
+ ## Examples
107
+
108
+ ### Example: greenfield (no STRATEGY.md)
109
+
110
+ - Phase 0: `validate_strategy` returns `{ present: false, valid: true }`; route to Phase 1.
111
+ - Phase 1.1: ask Target problem. User answers `"engineering teams want to be the best at shipping"`. **Fluff detection** fires: "be the best at" is empty-modifier vocabulary. Repair suggestion: "Replace `be the best at shipping` with a concrete diagnosis." User revises: `"engineering teams ship without a strategic anchor; brainstorming starts mid-stream"`. Accepted.
112
+ - Phase 1.2-5: walk Our approach, Who it's for, Key metrics, Tracks with the same pushback discipline.
113
+ - Phase 1.6: user declines optional sections.
114
+ - Phase 1.7: show full doc; user confirms.
115
+ - Phase 1.8: `write_strategy` writes the file; no `.bak` written (fresh create).
116
+ - Phase 1.9: `harness validate` passes.
117
+ - Phase 3: handoff note printed.
118
+
119
+ ### Example: update existing STRATEGY.md (one section)
120
+
121
+ - Phase 0: `validate_strategy` returns `{ present: true, valid: true }`; route to Phase 2.
122
+ - Phase 2.1-2: parse and summarize. Current state shows `name: Acme, last_updated: 2026-05-01, version: 3` and 5 required sections.
123
+ - Phase 2.3: user selects `Tracks` for revisit.
124
+ - Phase 2.4: re-interview Tracks. User answers `"add features X, Y, Z to the dashboard"`. **Feature-list-as-strategy** fires: 3+ feature names. Repair suggestion: "What's the coherent action these features are instances of?" User revises: `"- Dashboard track: collapse 3 separate widgets into one explorable surface"`. Accepted.
125
+ - Phase 2.5: frontmatter bumped to `last_updated: 2026-06-02, version: 4`.
126
+ - Phase 2.6: show diff; user confirms. `write_strategy` writes the file; `.bak` already exists from a prior overwrite — NOT clobbered.
127
+ - Phase 2.7: `harness validate` passes.
128
+
129
+ ### Example: present-but-invalid STRATEGY.md
130
+
131
+ - Phase 0: `validate_strategy` returns an error like `section "Key metrics": unfilled template placeholder detected (- <metric 1>: <how it's measured, where it lives>)`. Surface verbatim.
132
+ - User picks **a) Fix now**: skill enters Phase 2 with `Key metrics` pre-selected. User answers; skill writes the file.
133
+
134
+ ### Example: pushback gives up after the cap
135
+
136
+ - Phase 1.1: ask Target problem. User answers `"deliver value"`. **Fluff detection** fires. Round 1: suggest repair. User answers `"deliver maximum value"`. Round 2: suggest repair again. User answers `"deliver excellent value"`. **Cap reached** — skill captures the answer verbatim AND emits a flag in the doc summary: `"⚠ Target problem: flagged for revisit — pushback cap reached without concrete diagnosis."` Continue to the next section.
137
+
138
+ ## Gates
139
+
140
+ - **The 2-round pushback cap is non-negotiable.** No flag, no override, no "I know what I'm doing" path — the cap is the disable mechanism (proposal §Risks).
141
+ - **The skill MUST NEVER write to `STRATEGY.md` without explicit user confirmation** of the assembled or updated doc.
142
+ - **`write_strategy` (or `writeStrategyDoc` when invoked directly) is the only sanctioned write path.** Do not hand-edit `STRATEGY.md`. The writer is the layer that validates against the schema, preserves the H1, writes the `.bak`, and does the atomic rename.
143
+ - **`harness validate` must pass before exit** of Phase 1 or Phase 2. A malformed STRATEGY.md silently breaks the downstream grounding reads (Phases 5/6/7 of the spec).
144
+ - **Round 1 pushback MUST always fire when a rule matches.** The cap protects users from infinite loops, not from feedback. Skipping round 1 violates the Iron Law.
145
+
146
+ ## Escalation
147
+
148
+ - **User insists pushback is wrong:** Capture the answer verbatim after round 1 (do not push back twice if the user explicitly disagrees with round 1). Surface a one-line flag in the doc summary. Continue.
149
+ - **`write_strategy` returns `{ written: false, error }` (or `writeStrategyDoc` throws a schema error directly):** Report the error verbatim. Do not retry without user fix. The most common cause is a section body that's empty or still contains template placeholder text.
150
+ - **STRATEGY.md frontmatter is malformed (Phase 2):** Treat as present-but-invalid; route through Phase 0's three-path offer.
151
+ - **User wants to add a section name not in the documented schema:** Refuse and cite Decision 2 of the proposal ("schema validation rejects unknown sections; expansion requires a separate ADR"). Offer to file the proposal ADR as a follow-up.
152
+ - **Atomic rename fails (e.g., permission denied):** Surface the filesystem error verbatim. The temp file is cleaned up by the writer; no partial STRATEGY.md is left behind.