@harness-engineering/cli 2.7.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/personas/adversarial-reviewer.yaml +43 -0
- package/dist/agents/personas/frontend-races-reviewer.yaml +54 -0
- package/dist/agents/personas/typescript-strict-reviewer.yaml +53 -0
- package/dist/agents/skills/CHANGELOG.md +12 -0
- package/dist/agents/skills/claude-code/align-design-system/SKILL.md +18 -0
- package/dist/agents/skills/claude-code/align-design-system/skill.yaml +3 -0
- package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +37 -5
- package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +107 -22
- package/dist/agents/skills/claude-code/harness-code-review/references/confidence-rubric.md +45 -0
- package/dist/agents/skills/claude-code/harness-code-review/references/risk-keywords.md +40 -0
- package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +3 -0
- package/dist/agents/skills/claude-code/harness-compound/SKILL.md +7 -4
- package/dist/agents/skills/claude-code/harness-ideate/SKILL.md +277 -0
- package/dist/agents/skills/claude-code/harness-ideate/references/scoring.md +88 -0
- package/dist/agents/skills/claude-code/harness-ideate/skill.yaml +66 -0
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +14 -4
- package/dist/agents/skills/claude-code/harness-pulse/SKILL.md +12 -16
- package/dist/agents/skills/claude-code/harness-roadmap-pilot/SKILL.md +34 -6
- package/dist/agents/skills/claude-code/harness-strategy/SKILL.md +152 -0
- package/dist/agents/skills/claude-code/harness-strategy/references/interview.md +122 -0
- package/dist/agents/skills/claude-code/harness-strategy/skill.yaml +54 -0
- package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +76 -10
- package/dist/agents/skills/codex/align-design-system/SKILL.md +18 -0
- package/dist/agents/skills/codex/align-design-system/skill.yaml +3 -0
- package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +37 -5
- package/dist/agents/skills/codex/harness-code-review/SKILL.md +107 -22
- package/dist/agents/skills/codex/harness-code-review/references/confidence-rubric.md +45 -0
- package/dist/agents/skills/codex/harness-code-review/references/risk-keywords.md +40 -0
- package/dist/agents/skills/codex/harness-code-review/skill.yaml +3 -0
- package/dist/agents/skills/codex/harness-compound/SKILL.md +7 -4
- package/dist/agents/skills/codex/harness-ideate/SKILL.md +277 -0
- package/dist/agents/skills/codex/harness-ideate/references/scoring.md +88 -0
- package/dist/agents/skills/codex/harness-ideate/skill.yaml +66 -0
- package/dist/agents/skills/codex/harness-planning/SKILL.md +14 -4
- package/dist/agents/skills/codex/harness-pulse/SKILL.md +12 -16
- package/dist/agents/skills/codex/harness-roadmap-pilot/SKILL.md +34 -6
- package/dist/agents/skills/codex/harness-strategy/SKILL.md +152 -0
- package/dist/agents/skills/codex/harness-strategy/references/interview.md +122 -0
- package/dist/agents/skills/codex/harness-strategy/skill.yaml +54 -0
- package/dist/agents/skills/codex/initialize-harness-project/SKILL.md +76 -10
- package/dist/agents/skills/cursor/align-design-system/SKILL.md +18 -0
- package/dist/agents/skills/cursor/align-design-system/skill.yaml +3 -0
- package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +37 -5
- package/dist/agents/skills/cursor/harness-code-review/SKILL.md +107 -22
- package/dist/agents/skills/cursor/harness-code-review/references/confidence-rubric.md +45 -0
- package/dist/agents/skills/cursor/harness-code-review/references/risk-keywords.md +40 -0
- package/dist/agents/skills/cursor/harness-code-review/skill.yaml +3 -0
- package/dist/agents/skills/cursor/harness-compound/SKILL.md +7 -4
- package/dist/agents/skills/cursor/harness-ideate/SKILL.md +277 -0
- package/dist/agents/skills/cursor/harness-ideate/references/scoring.md +88 -0
- package/dist/agents/skills/cursor/harness-ideate/skill.yaml +66 -0
- package/dist/agents/skills/cursor/harness-planning/SKILL.md +14 -4
- package/dist/agents/skills/cursor/harness-pulse/SKILL.md +12 -16
- package/dist/agents/skills/cursor/harness-roadmap-pilot/SKILL.md +34 -6
- package/dist/agents/skills/cursor/harness-strategy/SKILL.md +152 -0
- package/dist/agents/skills/cursor/harness-strategy/references/interview.md +122 -0
- package/dist/agents/skills/cursor/harness-strategy/skill.yaml +54 -0
- package/dist/agents/skills/cursor/initialize-harness-project/SKILL.md +76 -10
- package/dist/agents/skills/gemini-cli/align-design-system/SKILL.md +18 -0
- package/dist/agents/skills/gemini-cli/align-design-system/skill.yaml +3 -0
- package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +37 -5
- package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +107 -22
- package/dist/agents/skills/gemini-cli/harness-code-review/references/confidence-rubric.md +45 -0
- package/dist/agents/skills/gemini-cli/harness-code-review/references/risk-keywords.md +40 -0
- package/dist/agents/skills/gemini-cli/harness-code-review/skill.yaml +3 -0
- package/dist/agents/skills/gemini-cli/harness-compound/SKILL.md +7 -4
- package/dist/agents/skills/gemini-cli/harness-ideate/SKILL.md +277 -0
- package/dist/agents/skills/gemini-cli/harness-ideate/references/scoring.md +88 -0
- package/dist/agents/skills/gemini-cli/harness-ideate/skill.yaml +66 -0
- package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +14 -4
- package/dist/agents/skills/gemini-cli/harness-pulse/SKILL.md +12 -16
- package/dist/agents/skills/gemini-cli/harness-roadmap-pilot/SKILL.md +34 -6
- package/dist/agents/skills/gemini-cli/harness-strategy/SKILL.md +152 -0
- package/dist/agents/skills/gemini-cli/harness-strategy/references/interview.md +122 -0
- package/dist/agents/skills/gemini-cli/harness-strategy/skill.yaml +54 -0
- package/dist/agents/skills/gemini-cli/initialize-harness-project/SKILL.md +76 -10
- package/dist/agents/skills/package.json +1 -1
- package/dist/agents/skills/tests/harness-strategy.test.ts +145 -0
- package/dist/agents-md-WMJO5HSM.js +13 -0
- package/dist/analyzer-V633GUHY-MBCQWKDU.js +26 -0
- package/dist/{architecture-LUR2I67H.js → architecture-EVYVGPRZ.js} +6 -6
- package/dist/{assess-project-OJWECOP2.js → assess-project-KZG563SO.js} +1 -1
- package/dist/bin/harness-mcp.js +17 -17
- package/dist/bin/harness.js +27 -27
- package/dist/{check-phase-gate-HS5KYLRO.js → check-phase-gate-MK364VXS.js} +6 -6
- package/dist/{chunk-6UHDQP2N.js → chunk-2N4OENGE.js} +1 -1
- package/dist/{chunk-FC4JPM6W.js → chunk-2SNRCAC3.js} +3 -3
- package/dist/{chunk-LGYXR2KZ.js → chunk-4BDOSCNY.js} +137 -71
- package/dist/{chunk-N5NSSLMU.js → chunk-5XL5QJ5B.js} +2 -2
- package/dist/{chunk-LECXPXS3.js → chunk-7EQAZKJ5.js} +2 -2
- package/dist/{chunk-LYIPI2SJ.js → chunk-ACOOG3UW.js} +6 -6
- package/dist/{chunk-FXZI6NJ2.js → chunk-B7KMTHN3.js} +51 -4
- package/dist/{chunk-OH3NXXUY.js → chunk-BDGTZRZ6.js} +11 -1
- package/dist/{chunk-NIVWM7OW.js → chunk-C7J55C6E.js} +10 -10
- package/dist/{chunk-7PLIWP7U.js → chunk-CAQPSFPT.js} +4042 -738
- package/dist/{chunk-TIH53QXY.js → chunk-CLI4K2CH.js} +1 -1
- package/dist/{chunk-INBTDBV2.js → chunk-EEFRPEWT.js} +1 -1
- package/dist/{chunk-VI4IS55S.js → chunk-FZ5MBXEG.js} +6 -6
- package/dist/{chunk-WZY5U6NS.js → chunk-GOHWCHCS.js} +1809 -812
- package/dist/{chunk-VSIRUZQP.js → chunk-HRSE6IQD.js} +2 -2
- package/dist/{chunk-CZPOPMMI.js → chunk-KBCPELBC.js} +3 -3
- package/dist/{chunk-7AF6C5GE.js → chunk-KI6PHH6Q.js} +3 -3
- package/dist/{chunk-KN3EMDZ5.js → chunk-LADPYELQ.js} +23 -3
- package/dist/{chunk-Y4T6ENKQ.js → chunk-N55WOGN3.js} +86 -17
- package/dist/{chunk-H2ZJOJ7A.js → chunk-PP6ZRL5T.js} +316 -42
- package/dist/{chunk-RJ2WEES5.js → chunk-STESM73J.js} +2 -2
- package/dist/{chunk-B2VAYLYI.js → chunk-UBZQE3JN.js} +2 -2
- package/dist/{chunk-GGSNWH7P.js → chunk-UJFNIWC7.js} +5 -5
- package/dist/{chunk-FEKBXX2J.js → chunk-UUO4K7NX.js} +9 -9
- package/dist/{chunk-Z3TMCCZB.js → chunk-UXPWSV3B.js} +9 -9
- package/dist/{chunk-O2ASYKA6.js → chunk-VBNJAKUH.js} +2 -2
- package/dist/{chunk-PTHX545Q.js → chunk-X4EFYVCZ.js} +2 -2
- package/dist/{ci-workflow-MDSTHJOY.js → ci-workflow-IW2H5DC4.js} +5 -5
- package/dist/{dist-E3SAAHCM.js → dist-ICW4QUEW.js} +5 -1
- package/dist/{dist-72ID44UE.js → dist-JCFK263L.js} +52 -4
- package/dist/{dist-R3TOOPJ7.js → dist-OWHMNL4W.js} +1 -1
- package/dist/{docs-2RFOJ6XY.js → docs-7CP6VV42.js} +6 -6
- package/dist/engine-MKJEBWU7.js +13 -0
- package/dist/{entropy-3UX6644G.js → entropy-6JOZJYG7.js} +5 -5
- package/dist/{feedback-CVCFYND4.js → feedback-T65AEJEG.js} +1 -1
- package/dist/{generate-agent-definitions-HZ3XENWO.js → generate-agent-definitions-4VI4YTO2.js} +6 -6
- package/dist/{glob-helper-EX4YZKZO.js → glob-helper-GLZAURJC.js} +1 -1
- package/dist/{graph-loader-EIFEOUVI.js → graph-loader-HHXN5FLP.js} +1 -1
- package/dist/index.d.ts +202 -0
- package/dist/index.js +27 -27
- package/dist/{loader-6RHWU5FH.js → loader-AWTHHE3A.js} +5 -5
- package/dist/{mcp-OYR26JDI.js → mcp-JBIBINO2.js} +17 -17
- package/dist/{performance-JJMIRXCH.js → performance-NCOUDOMW.js} +6 -6
- package/dist/{review-pipeline-BHQZIXWZ.js → review-pipeline-YIC6JPMY.js} +5 -5
- package/dist/{runtime-DALTAVTN.js → runtime-5MHV4UEE.js} +5 -5
- package/dist/{scan-LYKLM4EQ.js → scan-P7YFKB77.js} +1 -1
- package/dist/{security-RMLMYFPB.js → security-VZPJNIDP.js} +1 -1
- package/dist/{validate-R7DZRDFK.js → validate-7BE4VTFI.js} +6 -6
- package/dist/validate-cross-check-F7GEBRDH.js +13 -0
- package/package.json +7 -7
- package/dist/agents-md-FKMKH6ZF.js +0 -13
- package/dist/analyzer-H3AHBFSL-KPOPJYRB.js +0 -26
- package/dist/engine-BSFKOGPN.js +0 -13
- package/dist/validate-cross-check-AUUZFNVL.js +0 -13
|
@@ -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.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Strategy Interview Reference
|
|
2
|
+
|
|
3
|
+
The first-run interview (and the per-section update flow) converts vague intent ("we want to be the best at X") into a small, concrete `STRATEGY.md`. This document is the rule book the skill quotes when pushing back on input.
|
|
4
|
+
|
|
5
|
+
The interview is heuristic — the agent reading SKILL.md applies the rules. Nothing in `packages/core` parses the user's natural-language answers. The fixture-driven contract test in `agents/skills/tests/harness-strategy.test.ts` asserts the rule _names_ and the presence of repair-script keywords; rewording surrounding prose is free.
|
|
6
|
+
|
|
7
|
+
## Pushback Rules
|
|
8
|
+
|
|
9
|
+
Three rules, each cited verbatim in the skill output when it fires (so the user sees _why_ the answer was rejected, not just _that_ it was). **Each rule fires AT MOST TWICE per section. After the second pushback, capture what the user offered, flag the section, and move on.** The cap is the disable mechanism — there is no flag, no override, no "I know what I'm doing" path. The cap protects users from infinite loops, not from feedback. Round 1 MUST always fire when a rule matches.
|
|
10
|
+
|
|
11
|
+
### Rule 1: Fluff detection
|
|
12
|
+
|
|
13
|
+
**What it catches:** Empty modifiers and mission-statement vocabulary that look like answers but state nothing concrete.
|
|
14
|
+
|
|
15
|
+
| Detection signal | Example trigger |
|
|
16
|
+
| ----------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
17
|
+
| Empty modifiers: "best", "leading", "world-class", "best-in-class", "premier" | _"We want to be the best at developer experience."_ |
|
|
18
|
+
| Mission-statement verbs: "delight", "empower", "transform", "revolutionize" | _"Empower engineers to build amazing things."_ |
|
|
19
|
+
| Answers ≤ 5 words with no domain-specific noun | _"Deliver value."_ / _"Win the market."_ |
|
|
20
|
+
| Adjective-only diagnoses: "broken", "bad", "slow" without an object | _"It's slow."_ / _"It's hard."_ |
|
|
21
|
+
|
|
22
|
+
**Repair script:**
|
|
23
|
+
|
|
24
|
+
> Replace `<phrase>` with a concrete diagnosis: _what is broken_, _for whom_, _that we can verify_. "We want to be the best at X" is not a diagnosis — it's an aspiration. Try the next layer down: which _specific_ failure mode are we trying to remove from the world?
|
|
25
|
+
|
|
26
|
+
### Rule 2: Goal-as-strategy
|
|
27
|
+
|
|
28
|
+
**What it catches:** Targets, KPIs, and fiscal-year aspirations dressed up as strategy. A goal is a destination; strategy is the bet you're making about how to get there.
|
|
29
|
+
|
|
30
|
+
| Detection signal | Example trigger |
|
|
31
|
+
| ------------------------------------------------------------------------ | -------------------------------------------------------- |
|
|
32
|
+
| Numeric targets without an underlying bet | _"Grow revenue by 20% this year."_ / _"Get to 10k DAU."_ |
|
|
33
|
+
| Fiscal-year or quarter phrasing under `Target problem` or `Our approach` | _"By Q4 we'll have shipped the new platform."_ |
|
|
34
|
+
| KPI-shape strings: "increase X by Y%", "reduce X to Z" | _"Reduce churn to under 5%."_ |
|
|
35
|
+
| Sentences that name a metric value but not a mechanism | _"Hit 99.9% uptime."_ |
|
|
36
|
+
|
|
37
|
+
**Repair script:**
|
|
38
|
+
|
|
39
|
+
> That's a goal. What is the **bet** — the choice you're making about _how_ to produce it — that goes underneath? Strategy is the coherent action that, if it works, produces the goal. "Grow revenue 20%" is the destination; _how_ you'll do it (which segment, which channel, which product wedge) is the strategy.
|
|
40
|
+
|
|
41
|
+
### Rule 3: Feature-list-as-strategy
|
|
42
|
+
|
|
43
|
+
**What it catches:** Roadmap-style enumerations of components dressed up as strategy. Feature lists don't survive contact with reality; the coherent action underneath does.
|
|
44
|
+
|
|
45
|
+
| Detection signal | Example trigger |
|
|
46
|
+
| ----------------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
47
|
+
| Multi-item lists (≥3 bullets) of feature/component names under `Our approach` | _"- Dashboard, - Notifications, - Mobile app, - SSO"_ |
|
|
48
|
+
| Noun-heavy lists with no verbs describing the coherent action | _"- AI agents - Knowledge graph - Skill registry"_ |
|
|
49
|
+
| Track names that are feature names (e.g., `- Dashboard:`, `- Mobile:`) | _"- Dashboard: ship the new dashboard"_ |
|
|
50
|
+
| `Our approach` answered as a roadmap rather than a thesis | _"First we'll do X, then Y, then Z."_ |
|
|
51
|
+
|
|
52
|
+
**Repair script:**
|
|
53
|
+
|
|
54
|
+
> Feature lists don't survive contact with reality. What's the **coherent action** these features are instances of? The features are downstream of the bet. State the bet, then the features become consequences ("we're betting on agent-orchestrated workflows, so dashboard/SSO/mobile fall out of that"), not the strategy itself.
|
|
55
|
+
|
|
56
|
+
## The 2-Round Cap
|
|
57
|
+
|
|
58
|
+
For every section, each rule fires at most twice:
|
|
59
|
+
|
|
60
|
+
1. **Round 1** — Rule matches → cite the rule, quote the failing answer, offer the repair script. Wait for revised answer.
|
|
61
|
+
2. **Round 2** — Rule matches the revised answer → cite the rule a second time, quote the repair script. Wait for the user's third attempt.
|
|
62
|
+
3. **Cap reached** — Capture whatever the user offered on attempt 3. Emit a section flag in the doc summary:
|
|
63
|
+
|
|
64
|
+
> ⚠ <section name>: flagged for revisit — pushback cap reached without <concrete diagnosis | underlying bet | coherent action>.
|
|
65
|
+
|
|
66
|
+
The flag is informational. It does NOT block the write — STRATEGY.md is the user's commitment, not the skill's gate. The flag lives in the _summary_ shown to the user, not in the on-disk file (the schema rejects unknown content).
|
|
67
|
+
|
|
68
|
+
If the user explicitly says round 1's pushback is wrong (e.g., _"no, that IS the diagnosis — we really mean it this way"_), capture the answer verbatim after round 1. Do NOT push back twice if the user explicitly disagrees with round 1. This is not a third path around the cap; it's recognition that pushback is an offer, not a gate.
|
|
69
|
+
|
|
70
|
+
## Separation from `docs/roadmap.md`
|
|
71
|
+
|
|
72
|
+
The interview MUST refuse to capture tactical phase tracking (phase numbers, blockers, assignees, external IDs) under any section. That belongs in `docs/roadmap.md`. The two artifacts have different lifecycles:
|
|
73
|
+
|
|
74
|
+
| Artifact | Cadence | Owner | Content |
|
|
75
|
+
| ----------------- | ------------------ | ---------------- | -------------------------------------------------- |
|
|
76
|
+
| `STRATEGY.md` | Quarterly-ish | Product / lead | Target problem, approach, persona, metrics, tracks |
|
|
77
|
+
| `docs/roadmap.md` | Per-phase / weekly | Eng orchestrator | Phase status, blockers, assignees, external-IDs |
|
|
78
|
+
|
|
79
|
+
If the user asks "where do I track that we're blocked on X" or "where do I record the assignee for phase 4" → answer: `docs/roadmap.md`, not `STRATEGY.md`. The separation is Decision 1 of the strategic-anchor proposal.
|
|
80
|
+
|
|
81
|
+
## Section-by-section interview prompts
|
|
82
|
+
|
|
83
|
+
Phase 1 walks the sections in template order. Each prompt is a single focused question; the rules above govern the response loop.
|
|
84
|
+
|
|
85
|
+
| Section | Opening prompt | Rules to apply |
|
|
86
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
87
|
+
| Target problem | _"In 2-4 sentences: what is specifically broken in the world that this product addresses? Not the goal — the diagnosis."_ | Fluff, Goal-as-strategy |
|
|
88
|
+
| Our approach | _"What is your distinctive bet on how to solve the target problem? The choice you're making about HOW, not WHAT you're building."_ | Fluff, Goal-as-strategy, Feature-list |
|
|
89
|
+
| Who it's for | _"Specific persona — who is the person, what context are they in, what alternatives are they currently using? 'Developers' is not a specific persona."_ | Fluff |
|
|
90
|
+
| Key metrics | _"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>`."_ | Fluff (per bullet) |
|
|
91
|
+
| Tracks | _"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>`."_ | Feature-list (per bullet) |
|
|
92
|
+
| Milestones (opt) | _"What 2-3 dated milestones would mark visible progress on the tracks? Skip if none yet."_ | Goal-as-strategy (milestones SHOULD be dated targets — accept them here even though Rule 2 rejects them under `Target problem` / `Our approach`) |
|
|
93
|
+
| Not working on (opt) | _"What did you deliberately decide NOT to invest in this cycle? Explicit non-goals reduce future drift."_ | Fluff |
|
|
94
|
+
| Marketing (opt) | _"What 1-3 sentences describe how you'd pitch this to the persona? Often this is downstream of `Target problem` + `Our approach`."_ | Fluff |
|
|
95
|
+
|
|
96
|
+
## Anti-pattern fixtures (referenced by the contract test)
|
|
97
|
+
|
|
98
|
+
The skill's contract test (`agents/skills/tests/harness-strategy.test.ts`) asserts the rule names and key repair-script phrases appear in this file. The fixtures below are the canonical anti-patterns each rule must catch.
|
|
99
|
+
|
|
100
|
+
### Fluff detection fixture
|
|
101
|
+
|
|
102
|
+
> **User answer (Target problem):** _"We want to be the best at developer experience."_
|
|
103
|
+
>
|
|
104
|
+
> **Skill response:** "**Fluff detection** fired. `be the best at` is empty-modifier vocabulary — it states an aspiration, not a diagnosis. Try the next layer down: which _specific_ failure mode in developer experience are we trying to remove from the world?"
|
|
105
|
+
|
|
106
|
+
### Goal-as-strategy fixture
|
|
107
|
+
|
|
108
|
+
> **User answer (Our approach):** _"Grow revenue 20% this year and reduce churn to under 5%."_
|
|
109
|
+
>
|
|
110
|
+
> **Skill response:** "**Goal-as-strategy** fired. Those are goals, not approach. What is the **bet** — the choice you're making about _how_ to produce them — that goes underneath?"
|
|
111
|
+
|
|
112
|
+
### Feature-list-as-strategy fixture
|
|
113
|
+
|
|
114
|
+
> **User answer (Our approach):** _"- Ship the new dashboard. - Add notifications. - Build the mobile app. - Wire up SSO."_
|
|
115
|
+
>
|
|
116
|
+
> **Skill response:** "**Feature-list-as-strategy** fired. Feature lists don't survive contact with reality. What's the **coherent action** these features are instances of? The features are downstream of the bet."
|
|
117
|
+
|
|
118
|
+
## Update-flow guidance
|
|
119
|
+
|
|
120
|
+
Phase 2 of the skill re-interviews ONE user-selected section at a time. The same three rules apply. **Re-running a section does not exempt it from pushback** — "no rubber-stamping" is the proposal Decision 4 phrasing.
|
|
121
|
+
|
|
122
|
+
When the user revisits a section and the new answer also triggers a rule, the 2-round cap still applies — counted _within that revisit_, not cumulatively across all-time runs.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: harness-strategy
|
|
2
|
+
version: "0.1.0"
|
|
3
|
+
description: First-run interview and update flow for STRATEGY.md — the durable upstream product anchor read by harness-brainstorming, harness-ideate, and harness-roadmap-pilot. Enforces three pushback rules (fluff, goal-as-strategy, feature-list-as-strategy) with a 2-round-per-section cap. Phase 2 ships the skill; downstream wiring (init, brainstorming, roadmap-pilot, ideate, knowledge graph) ships in spec Phases 3-7.
|
|
4
|
+
stability: static
|
|
5
|
+
cognitive_mode: configuration-interviewer
|
|
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-strategy
|
|
22
|
+
args: []
|
|
23
|
+
mcp:
|
|
24
|
+
tool: run_skill
|
|
25
|
+
input:
|
|
26
|
+
skill: harness-strategy
|
|
27
|
+
type: rigid
|
|
28
|
+
tier: 2
|
|
29
|
+
phases:
|
|
30
|
+
- name: route
|
|
31
|
+
description: Route by STRATEGY.md presence and validity (absent → first-run; valid → update; invalid → repair offer)
|
|
32
|
+
required: true
|
|
33
|
+
- name: first-run-interview
|
|
34
|
+
description: Walk sections in template order with pushback; cap at 2 rounds per section; write via writeStrategyDoc
|
|
35
|
+
required: true
|
|
36
|
+
- name: update
|
|
37
|
+
description: Re-interview a single user-selected section; bump version and last_updated; preserve untouched sections
|
|
38
|
+
required: false
|
|
39
|
+
- name: handoff
|
|
40
|
+
description: Note which downstream skills (harness-brainstorming, harness-ideate, harness-roadmap-pilot, BusinessKnowledgeIngestor) will pick up STRATEGY.md as grounding
|
|
41
|
+
required: true
|
|
42
|
+
state:
|
|
43
|
+
persistent: true
|
|
44
|
+
files:
|
|
45
|
+
- STRATEGY.md
|
|
46
|
+
- STRATEGY.md.bak
|
|
47
|
+
depends_on: []
|
|
48
|
+
keywords:
|
|
49
|
+
- strategy
|
|
50
|
+
- strategic-anchor
|
|
51
|
+
- product-anchor
|
|
52
|
+
- upstream-grounding
|
|
53
|
+
- compound-engineering
|
|
54
|
+
- rumelt
|
|
@@ -140,6 +140,60 @@ Detect plugin-only state by checking whether `harness` resolves on PATH (`comman
|
|
|
140
140
|
|
|
141
141
|
**Skip this step entirely if Phase 1 step 5 classified the project as a test suite.** Test-suite projects will be dispatched at step 6 below to `initialize-test-suite-project` and have no UI to govern.
|
|
142
142
|
|
|
143
|
+
5c. **Capture strategic anchor (all levels).** Offer a three-way prompt for `STRATEGY.md` — the durable upstream product anchor read by `harness-brainstorming`, `harness-ideate`, and `harness-roadmap-pilot`. Use `emit_interaction`:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
emit_interaction({
|
|
147
|
+
type: "question",
|
|
148
|
+
question: {
|
|
149
|
+
text: "Capture strategic anchor (STRATEGY.md) now?",
|
|
150
|
+
options: [
|
|
151
|
+
{
|
|
152
|
+
label: "Yes — run the strategy interview",
|
|
153
|
+
pros: [
|
|
154
|
+
"Grounds brainstorm/ideate/roadmap-pilot in product-level context",
|
|
155
|
+
"Durable across milestones and phases (peer of README.md)"
|
|
156
|
+
],
|
|
157
|
+
cons: ["Adds an interview (10-20 minutes) to init"],
|
|
158
|
+
risk: "low",
|
|
159
|
+
effort: "medium"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
label: "No — this project does not need a strategy doc",
|
|
163
|
+
pros: ["Permanent decline recorded; init does not re-ask on rerun"],
|
|
164
|
+
cons: ["Re-running init will not re-offer; user must run /harness:strategy manually"],
|
|
165
|
+
risk: "low",
|
|
166
|
+
effort: "low"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
label: "Not sure yet",
|
|
170
|
+
pros: ["Decision deferred without commitment", "Can run /harness:strategy later"],
|
|
171
|
+
cons: ["No decline flag set; init may re-offer on rerun"],
|
|
172
|
+
risk: "low",
|
|
173
|
+
effort: "low"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
recommendation: { optionIndex: 0, reason: "Strategy grounds brainstorm/ideate/roadmap-pilot — value compounds as the project grows", confidence: "medium" }
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Before prompting, check whether `STRATEGY.md` already exists at repo root. Three cases:
|
|
182
|
+
|
|
183
|
+
- **Absent (most common on init).** Present the prompt above. Apply the answer:
|
|
184
|
+
- **Yes:** delegate to `harness-strategy` (which routes via its own Phase 0 to the first-run interview). When `harness-strategy` completes, continue with step 6.
|
|
185
|
+
- **No:** write `init.strategy.declined: true` to `.harness/state.json` (merge into existing JSON; do not clobber). This is the explicit decline location; re-running init detects the flag and skips the prompt.
|
|
186
|
+
- **Not sure yet:** no state write. `/harness:strategy` remains available standalone, and a future re-run of init will re-offer.
|
|
187
|
+
|
|
188
|
+
- **Present and valid.** Skip the prompt silently. Surface a one-line note: `STRATEGY.md detected — downstream skills will pick it up as grounding`. No `init.strategy.declined` write.
|
|
189
|
+
|
|
190
|
+
- **Present but invalid.** Surface the validation error verbatim (run a Node one-liner that imports `validateStrategy` from `@harness-engineering/core` and pipes the error). Offer three paths (mirror `harness-strategy` Phase 0):
|
|
191
|
+
- **a) Fix now via `/harness:strategy` update** → delegate to `harness-strategy` with the broken section pre-selected.
|
|
192
|
+
- **b) Move file to `STRATEGY.md.bak.<YYYY-MM-DD-HHmm>` and run a fresh interview** → rename, then delegate to `harness-strategy` Phase 1.
|
|
193
|
+
- **c) Ignore for this init and proceed** → record `init.strategy.declined: true` and continue. Init does NOT block on present-but-invalid STRATEGY.md.
|
|
194
|
+
|
|
195
|
+
Mirror the i18n / design-system pattern: ask once, record the answer, never silently skip.
|
|
196
|
+
|
|
143
197
|
6. **Test-suite projects only — dispatch to `initialize-test-suite-project`.** If Phase 1 step 5 classified this as a test suite, invoke `initialize-test-suite-project` now and let it own archetype selection, shared-library decision, layer variants (A self-contained vs B consumer), ESLint flat-config fix, tag taxonomy, reporter stack, custom report, and the "prove the guards fire" verification. Return here for Phase 4 step 4+ (knowledge graph, roadmap, commit). Product and service projects skip this step entirely.
|
|
144
198
|
|
|
145
199
|
### Phase 4: VALIDATE — Confirm Everything Works
|
|
@@ -269,6 +323,8 @@ This phase closes the parity gap that the marketplace plugin install does not co
|
|
|
269
323
|
- **`harness integrations list` / `harness integrations add <name>`** — Phase 5 step 6. Lists Tier-0 (zero-config) and Tier-1 (API-key) MCP integrations and adds them to project `.mcp.json`.
|
|
270
324
|
- **`harness-i18n-workflow configure` + `harness-i18n-workflow scaffold`** — Invoked during Phase 3 if the project will support multiple languages. Sets up i18n configuration and translation file structure.
|
|
271
325
|
- **`harness-design-system` (deferred via `on_new_feature`)** — Phase 3 step 5b records `design.enabled` + `design.platforms` in `harness.config.json` but does NOT run the full design-system skill. Token generation defers to the first design-touching feature, where `harness-design-system` fires via `on_new_feature` and reads `design.enabled` to decide whether to proceed.
|
|
326
|
+
- **`harness-strategy`** — Phase 3 step 5c delegates to this skill on "Yes". The skill conducts a first-run interview (pushback rules with a 2-round cap per section) and writes a valid `STRATEGY.md` at repo root via `writeStrategyDoc`. On "No" init writes `init.strategy.declined: true` to `.harness/state.json`. On "Not sure yet" no state is written; the user can run `/harness:strategy` standalone. When `STRATEGY.md` already exists and is valid the prompt is skipped; when present-but-invalid the user gets the three-path repair offer.
|
|
327
|
+
- **`validateStrategy`** — `@harness-engineering/core` helper used by Phase 3 step 5c to detect present-but-invalid `STRATEGY.md`. Invoked through a Node one-liner so init does not require importing core directly.
|
|
272
328
|
- **`initialize-test-suite-project`** — Sub-skill. Invoked during Phase 3 step 6 when Phase 1 step 5 classified the project as a test suite. Owns archetype selection, shared-library vs in-repo decision, layer variants, tag taxonomy, reporter stack, custom report, and "prove the guards fire" verification.
|
|
273
329
|
- **`harness-roadmap` skill** — Phase 6 step 1 invokes this skill (or `/harness:roadmap --create`) when the user opts in to creating `docs/roadmap.md`. The `manage_roadmap` MCP tool does not create roadmaps; it manages entries in an existing one.
|
|
274
330
|
- **`manage_roadmap` MCP tool** — Phase 6 step 1, when `design.enabled === true`, calls `manage_roadmap` with `action: add` to insert a `planned` "Set up design system" item under milestone `Current Work` with a summary describing the deferred work.
|
|
@@ -285,6 +341,7 @@ This phase closes the parity gap that the marketplace plugin install does not co
|
|
|
285
341
|
- All generated files are committed in a single atomic commit
|
|
286
342
|
- i18n configuration is set if the human chose to enable it during init
|
|
287
343
|
- For non-test-suite projects, the design-system question was asked and `harness.config.json` reflects the answer: `design.enabled: true` (with `design.platforms` populated) for yes, `design.enabled: false` for no, or absent for not-sure.
|
|
344
|
+
- The strategy question (Phase 3 step 5c) was asked unless `STRATEGY.md` already existed and was valid (in which case the prompt was skipped silently with a one-line detection note). The answer was recorded according to the documented semantics: Yes → `STRATEGY.md` exists and `harness validate` passes against `StrategyDocSchema`; No → `.harness/state.json` contains `init.strategy.declined: true`; Not sure yet → no `STRATEGY.md` and no `init.strategy.declined` flag.
|
|
288
345
|
- **Phase 5 (INSTRUMENT) outputs:** `.harness/graph/` is populated; `.harness/arch/baselines.json` exists; `harness check-perf` ran without errors (intermediate and above); `.harness/telemetry.json` exists if the human opted into identity tagging; legacy layout warnings were surfaced via `harness migrate --dry-run` and either resolved or explicitly deferred; Tier-0 MCP integrations (context7, sequential-thinking, playwright) are present in the project's `.mcp.json` (or the human declined and that decision is recorded).
|
|
289
346
|
- The roadmap question was asked. If the user answered yes, `docs/roadmap.md` exists and was created via `harness-roadmap` (or the documented `/harness:roadmap --create` fallback).
|
|
290
347
|
- When `design.enabled === true` AND the user answered yes to the roadmap question, `docs/roadmap.md` contains a `planned` entry titled "Set up design system" under milestone `Current Work` with a summary describing the deferred work. The entry is absent in all other answer combinations.
|
|
@@ -293,16 +350,19 @@ This phase closes the parity gap that the marketplace plugin install does not co
|
|
|
293
350
|
|
|
294
351
|
## Rationalizations to Reject
|
|
295
352
|
|
|
296
|
-
| Rationalization
|
|
297
|
-
|
|
|
298
|
-
| "The generated AGENTS.md template looks fine -- no need to customize it"
|
|
299
|
-
| "We should start at the advanced level since we want full coverage"
|
|
300
|
-
| "I will skip the i18n question to keep setup fast"
|
|
301
|
-
| "I will skip the design-system question to keep setup fast"
|
|
302
|
-
| "
|
|
303
|
-
| "
|
|
304
|
-
| "
|
|
305
|
-
| "
|
|
353
|
+
| Rationalization | Why It Is Wrong |
|
|
354
|
+
| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
355
|
+
| "The generated AGENTS.md template looks fine -- no need to customize it" | Phase 3 says do not blindly accept generated content. Without project-specific descriptions, agents receive generic instructions. |
|
|
356
|
+
| "We should start at the advanced level since we want full coverage" | The skill recommends basic for new projects. Each level builds on the previous. Jumping to advanced creates misconfigured rules. |
|
|
357
|
+
| "I will skip the i18n question to keep setup fast" | Phase 3 requires asking about i18n and recording the decision. Skipping creates ambiguity about whether the omission was intentional. |
|
|
358
|
+
| "I will skip the design-system question to keep setup fast" | Phase 3 step 5b requires asking about design and recording the answer in `design.enabled`. Skipping creates ambiguity about whether the omission was intentional and bypasses the linkage between init and the deferred `harness-design-system` invocation on `on_new_feature`. |
|
|
359
|
+
| "I will skip the strategy question — it's just paperwork" | Phase 3 step 5c is the only point in the workflow where init asks the user to capture the strategic anchor. Skipping bypasses the grounding signal that brainstorming, ideate, and roadmap-pilot read; downstream skill output degrades silently. Even a "No" or "Not sure yet" answer is better than no answer because it locks in the decision (or absence of one). |
|
|
360
|
+
| "STRATEGY.md exists already, so I should re-run the interview to refresh it" | When `STRATEGY.md` is present and valid, Phase 3 step 5c skips the prompt silently. Refreshing strategy mid-init is out of scope — that is what the standalone `/harness:strategy` update flow is for. Surface a one-line detection note and continue. |
|
|
361
|
+
| "STRATEGY.md is present but invalid, so I should block init" | Phase 3 step 5c explicitly does NOT block. It surfaces the validation error, offers three repair paths (fix now / move-to-bak / ignore), and continues based on the user's choice. Init is the wrong place to gate on strategy correctness. |
|
|
362
|
+
| "Validation passed, so the project is ready" | Phase 5 captures baselines, configures telemetry identity, surfaces legacy warnings, and wires Tier-0 integrations. Validation alone is not sufficient. |
|
|
363
|
+
| "Plugin install means setup is done" | The marketplace plugin ships skills, slash commands, subagents, hooks, and MCP — but it cannot mutate the user's project state. `harness.config.json`, baselines, telemetry identity, and Tier-0 integrations require running this skill once per project. |
|
|
364
|
+
| "Skip Phase 5 if we already ran `harness setup`" | Phase 5 is idempotent. It safely no-ops where setup already wired things and fills gaps where it didn't (common case: setup ran once, then a new Tier-0 integration was added or a layout was migrated). Re-running is the right behavior. |
|
|
365
|
+
| "This is a test suite, we'll configure layers in this skill" | Phase 3 step 6 dispatches to `initialize-test-suite-project` for archetype selection, layer variants, and the rest. Do not inline test-suite-specific configuration here — the sub-skill owns it and carries the gotchas. |
|
|
306
366
|
|
|
307
367
|
## Examples
|
|
308
368
|
|
|
@@ -377,6 +437,11 @@ Step 5b (design): "Will this project have a UI requiring a design system?"
|
|
|
377
437
|
Inform: "Design tokens will be generated when you start your first design-touching
|
|
378
438
|
feature — harness-design-system fires automatically via on_new_feature."
|
|
379
439
|
|
|
440
|
+
Step 5c (strategy): "Capture strategic anchor (STRATEGY.md) now?"
|
|
441
|
+
Human: "Yes."
|
|
442
|
+
Delegate to harness-strategy → first-run interview → STRATEGY.md written.
|
|
443
|
+
Result: STRATEGY.md exists at repo root; harness validate passes against StrategyDocSchema.
|
|
444
|
+
|
|
380
445
|
Step 6 (test-suite dispatch): skipped (not a test suite).
|
|
381
446
|
```
|
|
382
447
|
|
|
@@ -482,6 +547,7 @@ npx @harness-engineering/cli init # auto-detects framework
|
|
|
482
547
|
Customize AGENTS.md with project-specific content.
|
|
483
548
|
Phase 3 step 5 (i18n): "No, English only." → i18n.enabled = false.
|
|
484
549
|
Phase 3 step 5b (design): "No, this is a backend service." → design.enabled = false.
|
|
550
|
+
Phase 3 step 5c (strategy): "Not sure yet." → no STRATEGY.md, no init.strategy.declined flag; user can run /harness:strategy later.
|
|
485
551
|
Phase 3 step 6 (test-suite dispatch): not a test suite, skipped.
|
|
486
552
|
```
|
|
487
553
|
|
|
@@ -65,6 +65,7 @@ For each finding classified as `suggestion`: emit a human-readable description p
|
|
|
65
65
|
|
|
66
66
|
- **`harness align-design-system`** — the CLI entry point. `--dry-run` for preview; `--write` is the default. Standard `--json` / `--verbose` / `--quiet` flags.
|
|
67
67
|
- **`harness align-design-system --mode pipeline`** — orchestrator-driven mode. Reads pre-classified findings from handoff.json; writes outcomes back.
|
|
68
|
+
- **`harness align-design-system --revert`** — inverse-applies the most-recent batch recorded at `.harness/align/last-batch.json`. Skips files edited externally since the apply (content-hash check). Idempotent: a second revert on the same batch is a no-op because the file no longer matches the recorded post-apply text.
|
|
68
69
|
- **`mcp__harness__align_design_system`** — MCP tool for agent consumption. Same input/output shape as the function call.
|
|
69
70
|
- **`detect-design-drift`** — soft dependency. Standalone mode invokes detect internally; pipeline mode trusts the orchestrator to have done it.
|
|
70
71
|
- **`harness check-design`** — composes detect (as 3rd verifier) into a single-pass design check. align is the matching FIX step; together they form the DETECT → FIX cycle that the (future) #5 orchestrator will loop.
|
|
@@ -82,6 +83,7 @@ See `docs/changes/design-pipeline/align-design-system/proposal.md` for the full
|
|
|
82
83
|
- Pipeline mode writes `pipeline.fixesApplied` back to handoff.json
|
|
83
84
|
- `--dry-run` produces identical `FixOutcome` shapes but never writes files
|
|
84
85
|
- Re-running detect after align produces strictly fewer T001/T002/T003 findings
|
|
86
|
+
- `--revert` re-applies the inverse of the most-recent `fixesApplied` batch; no-op when the file has been edited externally since the apply
|
|
85
87
|
|
|
86
88
|
## Examples
|
|
87
89
|
|
|
@@ -147,6 +149,21 @@ src/SaveButton.tsx
|
|
|
147
149
|
|
|
148
150
|
v1 never auto-applies primitive adoption — prop translation across `<button>` ⇄ `<Button>` is the kind of judgment-call that benefits from a human or LLM review.
|
|
149
151
|
|
|
152
|
+
### Example: Revert the last batch
|
|
153
|
+
|
|
154
|
+
After a write run, the applied diffs (plus a SHA-256 of each post-apply file) are persisted to `.harness/align/last-batch.json`. Running `harness align-design-system --revert` reads that batch and inverse-applies each diff:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
src/Card.tsx
|
|
158
|
+
✓ DRIFT-T001:2 — Hex color "#0066cc" should use a token reference instead of a raw literal
|
|
159
|
+
before: const styles = { color: tokens.color.brand.primary };
|
|
160
|
+
after: const styles = { color: "#0066cc" };
|
|
161
|
+
|
|
162
|
+
Summary: 1 reverted, 0 suggestions, 0 skipped, 0 failed (1 files modified, 4ms)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
If the file has been edited externally between apply and revert (the SHA-256 doesn't match), every entry for that file is skipped with `skipped-unsafe / reason: file changed externally since apply`. A second revert on the same batch is a no-op for the same reason — the file's post-revert content no longer matches the recorded post-apply text.
|
|
166
|
+
|
|
150
167
|
## Gates
|
|
151
168
|
|
|
152
169
|
- **No autofix without classifier approval.** Every codemod application goes through `classifyFinding`. If the classifier returns `suggestion`, NO file write occurs — even for the same finding code in the same file.
|
|
@@ -162,6 +179,7 @@ v1 never auto-applies primitive adoption — prop translation across `<button>`
|
|
|
162
179
|
- **When the codemod corrupts a file (rare):** every application includes a structured diff. Recover via `git checkout <file>`. If the same input repeatedly corrupts, report the case — pre-flight classifier rules are conservative by design.
|
|
163
180
|
- **When pipeline-mode run finds no `pipeline.driftFindings` field:** align exits cleanly with empty outcomes. The orchestrator's contract is to write the field BEFORE invoking align.
|
|
164
181
|
- **When `--dry-run` shows fixes you don't want applied:** scope with `--files <glob>` to apply only specific files, or invoke align in pipeline mode with a curated `pipeline.fixBatch` list.
|
|
182
|
+
- **When you want to undo an apply:** run `harness align-design-system --revert`. It reads `.harness/align/last-batch.json`, content-hash-checks each file, and inverse-applies. Files edited since the apply are skipped (no silent corruption); recover via `git checkout <file>` if the content-hash check blocks revert and the prior commit is still in history.
|
|
165
183
|
- **When you want primitive-adoption fixes today:** apply the suggestion manually. The v1.x sub-project will add prop-translation tables + import resolution + revert-on-test-fail.
|
|
166
184
|
- **When align is invoked without detect having run first (standalone mode):** standalone mode runs detect internally — no manual ordering needed. Pipeline mode trusts the orchestrator to populate findings.
|
|
167
185
|
|
|
@@ -31,6 +31,9 @@ cli:
|
|
|
31
31
|
- name: mode
|
|
32
32
|
description: standalone (default) or pipeline (read findings from handoff.json)
|
|
33
33
|
required: false
|
|
34
|
+
- name: revert
|
|
35
|
+
description: Inverse-apply the most-recent batch persisted at .harness/align/last-batch.json
|
|
36
|
+
required: false
|
|
34
37
|
mcp:
|
|
35
38
|
tool: run_skill
|
|
36
39
|
input:
|