> 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.
Scanned 9/11/2026
Install to Claude Code
npx -y skills add Intense-Visions/harness-engineering --skill harness-strategy --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Harness Strategy?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/intense-visions-harness-strategy-53014c0f)More formats (shields.io, HTML) on the badges page.
# Harness Strategy
> 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.
## When to Use
- Manually, when a project wants a durable upstream product anchor that survives across milestones and phases
- When `STRATEGY.md` is absent and the user invokes `/harness:strategy`
- When `STRATEGY.md` exists and the user wants to update one section (the user picks which one; nothing is auto-rewritten)
- NOT for tactical phase tracking — that's `docs/roadmap.md` (kept deliberately separate; see proposal Decision 1)
- NOT for generating strategy from code or commit history — strategy is a human commitment, never a derived artifact (proposal Decision 8)
- NOT for producing specs/plans/code — those are `harness-brainstorming`'s job; this skill only writes `STRATEGY.md`
## Process
### Iron Law
**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.
---
### Phase 0: ROUTE BY FILE STATE
1. **Locate `STRATEGY.md` at repo root.** Use `path.join(process.cwd(), 'STRATEGY.md')`.
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.
- **`{ present: false }`** → proceed to Phase 1 (first-run interview).
- **`{ present: true, valid: true }`** → proceed to Phase 2 (update run).
- **`{ present: true, valid: false, error }`** → surface `error` verbatim, then offer three paths via `emit_interaction` (or numbered chat options when MCP is unavailable):
- **a)** Fix the offending section now via the update flow → proceed to Phase 2 with the broken section pre-selected.
- **b)** Move file to `STRATEGY.md.bak.<YYYY-MM-DD-HHmm>` and run Phase 1 fresh.
- **c)** Exit; user repairs manually. No further action.
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.
---
### Phase 1: FIRST-RUN INTERVIEW
Read `references/interview.md` for the three pushback rules and the 2-round cap. Both are mandatory.
**Calibrate the user before section 1.** Point them to `references/writing-inputs.md` — worked examples of high-quality strategy inputs across four quadrants (full vs minimal × greenfield vs brownfield). Offer it up front (one line, e.g. _"Want to see what a good answer looks like first? `references/writing-inputs.md` has full and minimal worked examples for both new and existing projects."_) and again whenever a pushback rule fires and the user seems unsure what a concrete answer looks like. It lowers the entry cost of clearing the pushback bar; it does not replace the bar.
Walk sections in **template order** — never out of order, because each section informs the next:
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.
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.
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`.
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.
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).
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).
7. **Assemble.** Show the full proposed doc. Ask explicitly: _"Write this to STRATEGY.md?"_ Wait for yes/no.
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`.
9. **Validate.** Run `harness validate` to confirm the file passes `StrategyDocSchema`. On failure, surface the error and stop (do not retry).
---
### Phase 2: UPDATE RUN
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.
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.
3. **Ask which section to revisit.** Present the section names as numbered options. Allow `none` (exit) or `multiple` (sequential re-interviews).
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.
5. **Bump frontmatter.** Set `last_updated` to today's ISO date. Increment `version` by 1.
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).
7. **Validate.** Run `harness validate`.
---
### Phase 3: DOWNSTREAM HANDOFF
After Phase 1 or Phase 2 completes successfully, print this short note (3-5 lines):
```
STRATEGY.md written. Downstream skills that pick this up as grounding:
- harness-brainstorming (Phase 5 of strategic-anchor spec — reads STRATEGY.md in Phase 1 EXPLORE)
- harness-ideate (Phase 4 of spec — generates ranked candidates grounded in STRATEGY.md)
- harness-roadmap-pilot (Phase 6 of spec — strategy-alignment tiebreaker)
- BusinessKnowledgeIngestor (Phase 7 of spec — strategy domain → business_fact nodes)
Soft-fail when absent; no downstream skill blocks on STRATEGY.md's presence.
```
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.
---
### Question-File Mode (opt-in)
The default is the interactive, section-by-section interview above. **Question-file mode** is an opt-in variant for **async, team-reviewable** strategy capture — the skill writes its section prompts to a durable file, the human (or the whole team) fills in answers over time, and the skill reads them back. Enter it only when the human asks (e.g. "do this as a question file"); never automatically. The full convention — file location, the `[Answer]:` tag, the read-back ritual, and context hygiene — lives in `references/question-file-mode.md`; this section states only how it maps onto the strategy interview.
1. **WRITE.** Assemble the same section prompts Phase 1 would ask (Target problem, Our approach, Who it's for, Key metrics, Tracks, and the optional sections when the human opts in), in template order, into `docs/strategy/interviews/strategy-questions.md` — a strategy-scoped home (strategy updates the root `STRATEGY.md`, so there is no per-change slug) (or `.harness/sessions/<slug>/interviews/strategy-questions.md` when a session slug is known). Each prompt gets an empty `[Answer]:`. Include a one-line pointer at the top of the file to `references/writing-inputs.md` so async fillers (who cannot ask a follow-up mid-flow) can self-calibrate against the worked examples. Report the path and stop.
2. **READ-BACK.** On the next run, re-read the file from disk and treat each filled `[Answer]:` as that section's answer. Apply the same three pushback rules (`Fluff detection`, `Goal-as-strategy`, `Feature-list-as-strategy`) and the 2-round cap per section, flagging failures **in the file** under the question.
3. **CONTRADICTION PASS.** Run the cross-answer contradiction pass (see `references/interview.md` Rule 4 and `references/question-file-mode.md`) over the filled sections — e.g. a `Key metrics` bullet the `Our approach` bet cannot produce, or a `Tracks` entry that contradicts the stated approach. Surface each contradiction; never auto-resolve.
4. **PROCEED.** Unanswered `[Answer]:` sections are treated as skipped (required sections left blank block the write exactly as an empty interactive answer would). Then continue to the unchanged Phase 1.7 assemble → confirm → `write_strategy` path. File mode changes only how answers are gathered — the writer, schema validation, and `.bak` behavior are identical.
## Harness Integration
- **`harness validate`** — Run after `write_strategy`; the existing `validateStrategy` helper (Phase 1 of this spec) catches schema violations.
- **Harness MCP tools consumed by this skill** (canonical execution path — works without `@harness-engineering/core` in the project's `node_modules`):
- `validate_strategy({ path })` — Phase 0's routing oracle. Returns `{ present, valid, error? }`.
- `read_strategy({ path })` — Phase 2's read path. Returns `{ present, valid, doc?, error? }`.
- `write_strategy({ path, doc, skipBackup? })` — atomic disk write with `.bak` on first overwrite. Validates against `StrategyDocSchema` before touching disk.
- **`@harness-engineering/core`** primitives the MCP tools wrap (only directly relevant when developing inside the monorepo or when the MCP server is unavailable):
- `validateStrategy(cwd)`, `parseStrategyDoc(raw)` + `asStrategyDoc(parsed)`, `writeStrategyDoc(doc, { cwd, skipBackup? })`, `serializeStrategyDoc(doc, opts?)`, `StrategyDocSchema`.
- **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`.
- **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.
- **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`.
- **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.
## Success Criteria
- On a project with no `STRATEGY.md`, the first-run interview produces a valid `STRATEGY.md` ≤ 100 lines that passes `harness validate`.
- 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`.
- 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`.
- After Phase 1 or 2, `harness validate` passes.
- A `STRATEGY.md.bak` is written on the _first_ overwrite of an existing file, but NOT clobbered on subsequent overwrites (idempotency).
- 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.
## Rationalizations to Reject
These are common rationalizations that sound reasonable but lead to incorrect results. When you catch yourself thinking any of these, stop and follow the documented process instead.
| Rationalization | Why It Is Wrong |
| -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "'We want to be the market leader in X' is a clear direction — I'll accept it as their approach." | That is a goal/aspiration, not a bet on HOW. The `Goal-as-strategy` rule must fire: strategy is the distinctive choice about how to win, not the outcome you hope to reach. Push for the diagnosis and the bet. |
| "They listed three features as their approach — that's basically the strategy, I'll record it." | The `Feature-list-as-strategy` rule must fire. A list of features is not a coherent bet; ask "what's the coherent action these features are instances of?" and capture that instead. |
| "The answer is a little fluffy but they seem confident — I'll accept it without pushing back." | Round 1 pushback MUST always fire when a rule matches (Iron Law). The 2-round cap is the capitulation point, not a bypass — skipping round 1 lets empty-modifier vocabulary into a durable anchor. |
| "The doc assembled cleanly — I'll write STRATEGY.md and show them the result after." | The skill must NEVER write without explicit user confirmation of the assembled/updated doc. Show the full doc (or diff) and wait for an explicit yes before calling `write_strategy`. |
| "STRATEGY.md is present but invalid — the cleanest fix is to overwrite it with a fresh interview." | Never auto-overwrite a present-but-invalid file; it is the user's prior work even when broken. Offer the three Phase 0 repair paths (fix-now / back-up-and-restart / exit) and let the user choose. |
## Examples
### Example: greenfield (no STRATEGY.md)
- Phase 0: `validate_strategy` returns `{ present: false, valid: true }`; route to Phase 1.
- 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.
- Phase 1.2-5: walk Our approach, Who it's for, Key metrics, Tracks with the same pushback discipline.
- Phase 1.6: user declines optional sections.
- Phase 1.7: show full doc; user confirms.
- Phase 1.8: `write_strategy` writes the file; no `.bak` written (fresh create).
- Phase 1.9: `harness validate` passes.
- Phase 3: handoff note printed.
### Example: update existing STRATEGY.md (one section)
- Phase 0: `validate_strategy` returns `{ present: true, valid: true }`; route to Phase 2.
- Phase 2.1-2: parse and summarize. Current state shows `name: Acme, last_updated: 2026-05-01, version: 3` and 5 required sections.
- Phase 2.3: user selects `Tracks` for revisit.
- 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.
- Phase 2.5: frontmatter bumped to `last_updated: 2026-06-02, version: 4`.
- Phase 2.6: show diff; user confirms. `write_strategy` writes the file; `.bak` already exists from a prior overwrite — NOT clobbered.
- Phase 2.7: `harness validate` passes.
### Example: present-but-invalid STRATEGY.md
- 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.
- User picks **a) Fix now**: skill enters Phase 2 with `Key metrics` pre-selected. User answers; skill writes the file.
### Example: pushback gives up after the cap
- 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.
## Gates
- **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).
- **The skill MUST NEVER write to `STRATEGY.md` without explicit user confirmation** of the assembled or updated doc.
- **`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.
- **`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).
- **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.
## Escalation
- **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.
- **`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.
- **STRATEGY.md frontmatter is malformed (Phase 2):** Treat as present-but-invalid; route through Phase 0's three-path offer.
- **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.
- **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.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!