Harness Ideate
Pre-brainstorm ideation. Generates candidate ideas, critiques each against its strongest objection, and ranks them by
(impact × confidence) ÷ effort. Writes a single ranked artifact todocs/ideation/<slug>-YYYY-MM-DD.md. Produces ranked ideation, not specs — brainstorming consumes the output.
When to Use
- Before brainstorming, when the feature to design has not yet been selected
- When the user asks "what should we build next in area X?" and there are several plausible answers
- When a single domain (auth, pulse reports, onboarding…) has 5–10 candidate ideas worth comparing
- After updating
STRATEGY.mdand wanting to surface candidates aligned with the new tracks - NOT when the feature is already selected — go straight to
harness-brainstorming - NOT for ranking existing roadmap items — that is
harness-roadmap-pilot's job - NOT for generating specs, plans, or code — this skill writes one ideation artifact and stops
- NOT for refreshing
STRATEGY.md— that isharness-strategy's job
Process
Prompt the human in plain text — every confirmation and selection in this skill (Proceed? (y/n), post-critique selection, etc.) is plain text only. Do not elevate to AskUserQuestion: natural headers like "Confirm inputs" exceed its 12-char cap and option lists routinely exceed its 4-option cap, rendering the call as ERR.
Iron Law
The skill produces exactly ONE ranked artifact per run, at docs/ideation/<slug>-YYYY-MM-DD.md, and NEVER produces a spec, plan, ADR, or code. If the user wants a spec from a ranked idea, they invoke harness-brainstorming next — that is the contract.
Phase 1: GROUND — Read STRATEGY.md and Confirm the Topic
Resolve the focus argument. If the user passed
--focus(or supplied a one-line topic in the conversation), use it verbatim. Otherwise ask:What is the ideation topic? One short line (e.g., "onboarding for plugin-only users", "lateral review depth", "pulse-report follow-up routing").Capture the answer; do not proceed without one.
Resolve the count. Default to 10 if
--countis unset. Clamp silently to[5, 25](<5is too few to rank meaningfully;>25loses signal). Proceed with the clamped value.Read
STRATEGY.md(grounding). Callread_strategy({ path: process.cwd() })on the harness MCP server — it returns{ present, valid, doc?, error? }and runs validation + parsing inside the server so the project does not need@harness-engineering/coreinstalled.Three cases:
{ present: false }: print one line —STRATEGY.md not present — ranking will use impact × confidence ÷ effort only; no strategy-alignment tiebreaker. Continue.{ present: true, valid: true, doc }: capturedoc.sectionsforTarget problem,Our approach,Who it's for, andTracks. These four sections drive the strategy-alignment tiebreaker in Phase 4.{ present: true, valid: false, error }: printerrorverbatim and continue without strategy grounding. Do NOT block; this skill is not the place to repairSTRATEGY.md. Suggest/harness:strategyas a follow-up.
Fallback for environments without the MCP server:
node -e "import('@harness-engineering/core').then(m => m.validateStrategy(process.cwd()).then(r => console.log(JSON.stringify(r))))"— only works when@harness-engineering/coreis resolvable from the project'snode_modules.Confirm the topic. Before generating, surface a 2-line summary:
Topic: <focus> Count: <N> Strategy grounding: <enabled|disabled — reason>Ask:
Proceed with these inputs? (y/n). Wait for confirmation.
Phase 2: GENERATE — Produce Candidate Ideas
Generate exactly N candidate ideas. Each idea is a structured object with the following fields:
| Field | Type | Description |
|---|---|---|
premise |
string (1 sentence) | What this idea is, in one declarative sentence. Not aspirational — what the change IS, not what we hope it achieves. |
persona |
string (1 sentence) | Target persona segment (specific, not "developers"). If STRATEGY.md is present, prefer phrasing from its Who it's for. |
complexity |
low | medium | high |
Rough engineering complexity estimate. |
key_risk |
string (1 sentence) | The single biggest reason this idea might fail or not be worth doing. Used in Phase 3 as the seed for critique. |
impact |
low | medium | high |
How much this matters if it works. Mapped to 1/2/3 for ranking. |
confidence |
low | medium | high |
How confident we are that we can pull it off. Mapped to 1/2/3 for ranking. |
effort |
low | medium | high |
Engineering effort to deliver. Mapped to 1/2/3 for ranking. |
Generation rules:
- Spread the complexity surface. Aim for at least one
lowand onehighcomplexity idea; resist clustering everything asmedium. - Resist near-duplicates. Two ideas with the same
premiseare one idea. If two ideas only differ by a parameter ("X for web" vs "X for mobile"), collapse them into a single idea with a parametric premise. - Be honest about effort. A
low-effort idea must be plausibly implementable in <1 sprint by one engineer. If you find yourself defaulting everything tomedium, slow down and re-estimate one extreme. - When STRATEGY.md is present, at least 60% of ideas should plausibly serve a current track in
Tracks. Stretch ideas outside the tracks are allowed and useful, but the majority anchors in.
Present the N candidates as a numbered list. Each line is 2-3 sentences max:
1. [Premise]. Persona: [...]. Complexity: medium. Key risk: [...]. Impact/Confidence/Effort: M/M/L.
2. [Premise]. Persona: [...]. Complexity: low. Key risk: [...]. Impact/Confidence/Effort: H/L/L.
...
Phase 3: CRITIQUE — Identify and Address Strongest Objections
For each candidate, surface the single strongest objection — the best argument against doing this idea. The seed is key_risk from Phase 2, but the critique should sharpen it (one paragraph, not one sentence):
Idea 3: [Premise].
Strongest objection: [...]. Most likely failure mode: [...]. What would need to be true
for this objection to NOT hold: [...].
After all N critiques are presented, prompt the user. The prompt MUST make three things explicit that earlier wording left implicit: every objection is already recorded as standing, a rebuttal is written by the user and never by the agent, and a rebuttal changes no score and no rank. Use this wording:
All N objections are on the record as standing. Leaving them there is the
normal outcome, not a concession — an accepted downside is a real signal.
If you want to rebut any, name the numbers and I'll ask you for a sentence or
two on each. Rebuttals sit beside the idea in the artifact; they do not change
any score or the ranking.
just say "go" leave every objection standing
1, 4, 7 you write a rebuttal for those three
every one you write a rebuttal for all N
Never label the choices all / none. Those two words collide with how
people naturally phrase the default: "they're all fine", "all good", "all are
good as is" all mean leave them standing — the exact opposite of a literal
all. The collision has misfired in practice. Offer the wording above instead.
Disambiguation rule. Any reply that praises the candidates, or declines to change them, means leave standing — never N rebuttals. Read the interpretation back in one line ("Reading that as: all objections stand") and continue without a second round trip. Only a reply that clearly asks to rebut, or names numbers, enters the rebuttal loop.
For each idea the user elects to rebut, ask: For idea N, what makes the objection wrong or addressable? Capture the answer in the user's own words.
If they cannot answer convincingly, leave the objection standing.
The agent never authors a rebuttal. A rebuttal is the user's judgment entering the record. An agent-written one recorded in that slot is a fabricated human input, and attributing it to an "analyst" or "reviewer" does not fix that — it disguises it. If the user does not answer, the objection stands. The agent may of course surface evidence bearing on an objection in conversation; it may not write that evidence into the rebuttal field.
Rebuttals do NOT change the impact/confidence/effort scores from Phase 2, and so cannot change rank order — scores are the only ranking input. They feed the rationale shown alongside each ranked idea in Phase 5.
Phase 4: RANK — Score and Order
For each candidate, compute base_score = (impact × confidence) ÷ effort using the low|medium|high → 1|2|3 mapping documented in references/scoring.md. Higher is better; range is [≈0.33, 9.0].
Strategy-alignment tiebreaker. When STRATEGY.md was grounded in Phase 1, compute an alignment bonus per candidate:
alignment_bonus =
(premise plausibly advances a Tracks bullet ? 0.5 : 0)
+ (premise/persona references Target problem or Our approach ? 0.25 : 0)
Maximum bonus +0.75. The bonus is bounded: it is applied only when the absolute difference between two adjacent candidates' base scores is ≤ 0.05. Outside that tie window, the base score wins and the bonus is recorded for transparency but does NOT change rank order. See references/scoring.md for the full contract (including the worked example and the boundary with harness-roadmap-pilot's identical tiebreaker shape).
Sort by final score descending. Stable on ties (preserve generation order so the user can find the original list).
Phase 5: WRITE — Persist the Ranked Artifact
Compute the slug. Kebab-case the focus argument; lowercase; collapse whitespace and
[^a-z0-9-]into-; trim leading/trailing-; truncate to ≤30 characters. Example:"onboarding for plugin-only users"→onboarding-for-plugin-only-use.Compute today's date as
YYYY-MM-DD(UTC).Compute the output path.
docs/ideation/<slug>-<YYYY-MM-DD>.md. If that path already exists (same focus, same day), append a 6-character lowercase hex suffix derived fromsha1(focus + iso_timestamp).slice(0, 6):docs/ideation/onboarding-for-plugin-only-use-2026-06-02.md # first run docs/ideation/onboarding-for-plugin-only-use-2026-06-02-a3f9b2.md # collisionRender the artifact. Frontmatter + ranked list. See ranking math in
references/scoring.md. Required fields:--- topic: <focus argument verbatim> generated_at: <ISO 8601 timestamp> strategy_grounded: <true | false> strategy_path: <STRATEGY.md path if grounded, else null> count_requested: <N> count_generated: <N> ranking_formula: '(impact × confidence) ÷ effort; strategy-alignment tiebreaker (max +0.75) applied only when |Δbase_score| ≤ 0.05' --- # Ideation: <focus> ## Inputs - Topic: <focus> - Generated: <ISO timestamp> - Strategy grounding: <enabled | disabled with one-line reason> ## Ranked candidates ### 1. <premise> — score: <final> - Persona: <...> - Complexity: <low|medium|high> - Impact / Confidence / Effort: <H/M/L> — base score <X.XX> - Strategy alignment: <none | +0.25 persona | +0.5 track:<name>> — final score <Y.YY> - Strongest objection: <one paragraph> - Objection answered: <yes/no — if yes, one paragraph rebuttal> ### 2. ...Write the file. Create
docs/ideation/if it does not exist. Write via the standardWritetool — no Node one-liner is required here; the content is generated by the skill, not user-supplied prose with shell-escape hazards.Print the handoff. Three lines:
Ideation artifact written: docs/ideation/<slug>-<date>.md Top pick: <#1 premise> — score <Y.YY> Next: invoke /harness:brainstorming <feature> to take a candidate into a spec, OR /harness:roadmap to enqueue picks for later.
Harness Integration
- Harness MCP tools consumed by this skill (canonical execution path — no project-local
@harness-engineering/corerequired):read_strategy({ path })— Phase 1 grounding oracle. Returns{ present, valid, doc?, error? }(the server runsvalidateStrategy+parseStrategyDoc+asStrategyDocinternally).
@harness-engineering/core(only directly relevant when the MCP server is unavailable):validateStrategy(cwd),parseStrategyDoc(raw)+asStrategyDoc(parsed),StrategyDocSchema,REQUIRED_STRATEGY_SECTIONS.
- Boundary with
harness-strategy— strategy WRITESSTRATEGY.md; ideate READS it. Ideate never modifiesSTRATEGY.mdand never offers to repair an invalid one (suggest/harness:strategyand continue without grounding). - Boundary with
harness-brainstorming— ideate produces a ranked artifact atdocs/ideation/; brainstorming produces a spec atdocs/changes/<feature>/proposal.md. They have non-overlapping output locations (Decision 5 of the strategic-anchor proposal). Ideate's artifact may be cited as an input in a brainstorming spec; brainstorming's spec is NEVER auto-derived from ideate's artifact. - Boundary with
harness-roadmap-pilot— ideate generates fresh candidates; roadmap-pilot prioritizes existing roadmap entries. If a user wants ranking-only over the existing roadmap, that is roadmap-pilot, not ideate.
Success Criteria
- Exactly one artifact is written per run, at
docs/ideation/<slug>-<YYYY-MM-DD>.md. No spec, plan, ADR, or code is produced. - The artifact contains exactly the number of candidates the user requested (after clamping to
[5, 25]). - Every candidate has all 7 fields populated (premise, persona, complexity, key_risk, impact, confidence, effort).
- Each candidate has a strongest-objection paragraph; objections the user elected to rebut carry a rebuttal paragraph in the user's own words. A rebuttal the agent wrote is a failed run, not a satisfied criterion.
- Ranking is by
(impact × confidence) ÷ effortwith the 1/2/3 mapping. Strategy-alignment bonus is applied only when STRATEGY.md is present AND the absolute base-score delta is ≤ 0.05. - When
STRATEGY.mdis absent or invalid, the skill completes without error and the artifact's frontmatter recordsstrategy_grounded: false. - The output filename collision rule (6-char hex suffix on same-day re-run for the same focus) produces a stable, deterministic suffix from
sha1(focus + iso_timestamp). - The artifact's frontmatter explicitly states the ranking formula so a future reader can reproduce the order.
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 |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| "The top-ranked idea is clearly the winner — I'll write its spec while I'm here." | Iron Law: exactly ONE ranked artifact per run, and NEVER a spec, plan, ADR, or code. Producing a spec is harness-brainstorming's job; ideate's output is an INPUT to it, not a substitute. |
| "Idea 3's objection is weak — I'll skip its critique paragraph to move faster." | Every candidate needs its single strongest-objection paragraph. Objections do not move rank — scores do — so a missing critique does not change the order; it removes the risk information the reader needs to judge the order. That is the harm. |
| "These ideas are all roughly medium on impact, confidence, and effort — I'll score them all medium." | Undifferentiated scores make the (impact × confidence) ÷ effort ranking uninformative. Slow down and re-estimate the extremes; push for the highest-impact and highest-confidence outliers rather than defaulting to medium. |
| "Idea 1 aligns with a track, so I'll add the +0.75 bonus even though it already beats Idea 2 comfortably." | The strategy-alignment bonus is bounded: it applies ONLY when | Δbase_score | ≤ 0.05. Outside that tie window the base score wins and the bonus is recorded for transparency but must never reorder a clear winner. |
| "STRATEGY.md is present but invalid — I'll fix it so grounding works." | Ideate READS STRATEGY.md; it never modifies it. On present-but-invalid, print the error verbatim, continue with strategy_grounded: false, and route the user to /harness:strategy. Repair is not this skill's job. |
Examples
Example: With STRATEGY.md (grounded, 10 candidates)
User: /harness:ideate --focus "pulse-report follow-up routing"
Phase 1:
Topic confirmed: "pulse-report follow-up routing"
Count: 10
STRATEGY.md detected — grounding enabled.
Tracks read: ["pulse-reports", "compound-engineering", "feedback-loops"]
Who-it's-for read: "engineering teams adopting harness"
Phase 2 (excerpt):
1. Auto-assign followups to the on-call rotation. Persona: on-call engineer.
Complexity: medium. Key risk: rotation data may be stale. I/C/E: H/M/M.
...
10. Email-digest weekly pulse for distributed teams. Persona: async-first eng.
Complexity: low. Key risk: duplicates Slack. I/C/E: M/L/L.
Phase 3:
User selects "answer 1, 4, 7"; provides three one-paragraph rebuttals.
Phase 4 (ranking, excerpt):
- Idea 1 base score: (H=3 × M=2) ÷ M=2 = 3.00
Idea 7 base score: 2.97 (|Δ| = 0.03 ≤ 0.05 — alignment window applies)
Idea 1 alignment: track match "pulse-reports" (+0.5) + persona match (+0.25) = +0.75 → final 3.75
Idea 7 alignment: track match "feedback-loops" (+0.5) → final 3.47
Idea 4 base score: 2.50 (|Δ vs idea 1| = 0.50 > 0.05 — alignment recorded but not applied)
Phase 5:
Write docs/ideation/pulse-report-follow-up-routin-2026-06-02.md
Top pick: "Auto-assign followups to the on-call rotation" — score 3.50
Next: invoke /harness:brainstorming "Pulse Followup Routing" to take this into a spec.
Example: Without STRATEGY.md (no grounding, 5 candidates)
- Phase 1:
read_strategyreturns{ present: false }. Strategy grounding disabled; skill prints the one-line note and continues. - Phase 2: 5 candidates generated. No track-alignment guidance applies; coverage of complexity surface remains a rule.
- Phase 4: ranking uses
(impact × confidence) ÷ effortonly. No tiebreaker bonus is added. - Phase 5: artifact frontmatter has
strategy_grounded: falseandstrategy_path: null. Handoff still routes the user to brainstorming.
Example: Slug collision (same focus, same day)
- Run 1: writes
docs/ideation/onboarding-for-plugin-only-use-2026-06-02.md. - Run 2 (same
--focus, same day): destination collides. Skill computessha1("onboarding for plugin-only users" + "2026-06-02T15:21:04Z").slice(0,6)→a3f9b2. Writesdocs/ideation/onboarding-for-plugin-only-use-2026-06-02-a3f9b2.md. Both files coexist.
Gates
- One artifact per run, exactly. A second write on the same run violates the Iron Law.
- Never modify
STRATEGY.md. Even on present-but-invalid: surface the error and continue without grounding. Repair is/harness:strategy's job. - Never derive a spec from ideate's artifact automatically. Brainstorming is human-confirmed; ideate's output is an INPUT to brainstorming, not a replacement.
- Never produce 0 ideas. Clamping enforces
N ≥ 5. If the model would generate near-duplicates to reach N, prefer fewer-but-distinct over more-but-redundant — re-prompt within the skill to diversify. - The strategy-alignment tiebreaker is bounded. Maximum bonus is
+0.75(0.5 + 0.25) and only applies when|Δbase_score| ≤ 0.05. The bonus must NEVER override a clear base-score winner. - The agent NEVER authors a rebuttal. The Phase 3 rebuttal field holds the user's judgment. Writing one on their behalf — under any label, including "analyst rebuttal" — records a fabricated human input. An unanswered objection stands; that is a valid, informative outcome, not a gap to fill.
- Never offer the Phase 3 choices as bare
all/none. Those labels invert the most common natural phrasing of the default ("all good", "all are good as is"), and the collision has misfired in practice. Use the wording in Phase 3, and resolve any praise-or-decline reply as leave standing with the interpretation stated back in one line. - Objections never change rank. Rank is
(impact × confidence) ÷ effortplus the bounded tiebreaker, and nothing else. Any statement that an unanswered or missing objection raises or lowers an idea's position is wrong — do not add one.
Escalation
- User wants the artifact converted to a spec automatically. Refuse; cite the Iron Law. Offer
/harness:brainstorming "<top-pick title>"as the next step. - STRATEGY.md is present but invalid. Print the validation error verbatim; do not block. Suggest
/harness:strategyand continue withstrategy_grounded: false. - User insists on
N > 25. Clamp to 25 and inform; offer to chain a second run with a different focus argument. - User insists every idea is
mediumon all three axes. Push back once: "If everything is medium, ranking is uninformative — what is your highest-impact vs. highest-confidence outlier?" If they decline to differentiate, write the artifact anyway with a frontmatterquality_flag: undifferentiatednote. - Output directory cannot be created. Surface the filesystem error verbatim. Do not silently write to a fallback path.