# Harness Strategy

> Harness Strategy

- Skill: `intense-visions/harness-strategy` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds add intense-visions/harness-strategy`
- Raw SKILL.md: https://api.skillmd.com/api/skills/intense-visions/harness-strategy/raw
- Safety review: pending (external: skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Intense-Visions (https://skillmd.com/u/intense-visions)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/intense-visions/harness-strategy

---

# 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.

