@harness-engineering/cli 4.3.3 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +3 -1
  2. package/dist/agents/skills/claude-code/harness-roadmap-pilot/SKILL.md +5 -0
  3. package/dist/agents/skills/claude-code/harness-rollback/SKILL.md +124 -0
  4. package/dist/agents/skills/claude-code/harness-rollback/skill.yaml +52 -0
  5. package/dist/agents/skills/claude-code/product-requirements/SKILL.md +150 -0
  6. package/dist/agents/skills/claude-code/product-requirements/skill.yaml +70 -0
  7. package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +3 -1
  8. package/dist/agents/skills/codex/harness-roadmap-pilot/SKILL.md +5 -0
  9. package/dist/agents/skills/codex/harness-rollback/SKILL.md +124 -0
  10. package/dist/agents/skills/codex/harness-rollback/skill.yaml +52 -0
  11. package/dist/agents/skills/codex/product-requirements/SKILL.md +150 -0
  12. package/dist/agents/skills/codex/product-requirements/skill.yaml +70 -0
  13. package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +3 -1
  14. package/dist/agents/skills/cursor/harness-roadmap-pilot/SKILL.md +5 -0
  15. package/dist/agents/skills/cursor/harness-rollback/SKILL.md +124 -0
  16. package/dist/agents/skills/cursor/harness-rollback/skill.yaml +52 -0
  17. package/dist/agents/skills/cursor/product-requirements/SKILL.md +150 -0
  18. package/dist/agents/skills/cursor/product-requirements/skill.yaml +70 -0
  19. package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +3 -1
  20. package/dist/agents/skills/gemini-cli/harness-roadmap-pilot/SKILL.md +5 -0
  21. package/dist/agents/skills/gemini-cli/harness-rollback/SKILL.md +124 -0
  22. package/dist/agents/skills/gemini-cli/harness-rollback/skill.yaml +52 -0
  23. package/dist/agents/skills/gemini-cli/product-requirements/SKILL.md +150 -0
  24. package/dist/agents/skills/gemini-cli/product-requirements/skill.yaml +70 -0
  25. package/dist/{agents-md-N4ULMUAK.js → agents-md-OTKZE5HH.js} +4 -4
  26. package/dist/{analyzer-XRCV63KC-WGRHW2ZM.js → analyzer-XRCV63KC-FALMS3MO.js} +2 -2
  27. package/dist/{architecture-OIMIBDJC.js → architecture-3VYDN7MQ.js} +5 -5
  28. package/dist/{assess-project-ITSB6W4L.js → assess-project-27X2FSZZ.js} +1 -1
  29. package/dist/bin/harness-mcp.js +15 -15
  30. package/dist/bin/harness.js +25 -25
  31. package/dist/{check-phase-gate-GN4X7HT6.js → check-phase-gate-IXLFZ6YH.js} +5 -5
  32. package/dist/{chunk-MEDRUIRO.js → chunk-354MCPT3.js} +3 -3
  33. package/dist/{chunk-5BUHPOCP.js → chunk-3H7JA24B.js} +7 -7
  34. package/dist/{chunk-PT65VY4S.js → chunk-3MKQKNY3.js} +6 -6
  35. package/dist/{chunk-LP764MGR.js → chunk-6Y6M3AZA.js} +3 -3
  36. package/dist/{chunk-D7A5JR7M.js → chunk-BMNHLKBA.js} +2 -2
  37. package/dist/{chunk-CRHQYBDA.js → chunk-CTMHHMHQ.js} +101 -4
  38. package/dist/{chunk-MIZQY35D.js → chunk-D7QXGI6E.js} +2 -2
  39. package/dist/{chunk-F3GNBRGL.js → chunk-EFWRZHZ7.js} +101 -97
  40. package/dist/{chunk-LTYVAKWK.js → chunk-IOJGLIEQ.js} +20 -2
  41. package/dist/{chunk-CMU4DNLY.js → chunk-IXGYIQSR.js} +1 -1
  42. package/dist/{chunk-6NEJPS7W.js → chunk-JJLOWMGC.js} +2 -2
  43. package/dist/{chunk-73QZ43DF.js → chunk-KPBGAB35.js} +2 -2
  44. package/dist/{chunk-HJYAXAYQ.js → chunk-L5UKNGC5.js} +2 -2
  45. package/dist/{chunk-VJDSB7CI.js → chunk-LHWBQD7F.js} +24 -1
  46. package/dist/{chunk-JZL2O3RC.js → chunk-LISEPDVT.js} +5 -5
  47. package/dist/{chunk-NEMB36N4.js → chunk-MEIUXTFY.js} +2 -2
  48. package/dist/{chunk-7RH2NTLA.js → chunk-NZ5AXKRA.js} +1 -1
  49. package/dist/{chunk-H5GN7R43.js → chunk-QHFXVVUY.js} +2 -2
  50. package/dist/{chunk-U2NOOATF.js → chunk-S2ETJDQJ.js} +6 -6
  51. package/dist/{chunk-574JCBYH.js → chunk-TM4KFUWP.js} +2 -2
  52. package/dist/{chunk-YVI7ZV73.js → chunk-VGDZAWCJ.js} +803 -214
  53. package/dist/{chunk-TKPAOB2T.js → chunk-VRA64HYI.js} +2 -2
  54. package/dist/{chunk-T46G6YNI.js → chunk-WAFTJFT3.js} +3 -3
  55. package/dist/{chunk-GTHL3TRZ.js → chunk-XF6RE3JQ.js} +2 -2
  56. package/dist/{chunk-XKILFNRK.js → chunk-XNHKXELN.js} +2 -2
  57. package/dist/{ci-workflow-PA3WL6WK.js → ci-workflow-Y5GBKNZP.js} +4 -4
  58. package/dist/{dist-BWFFVKEW.js → dist-4CZLCE33.js} +7 -3
  59. package/dist/{dist-ISDDHDOR.js → dist-S3KCRI7X.js} +3 -1
  60. package/dist/{docs-HOTWQJQF.js → docs-3MWDPK4S.js} +5 -5
  61. package/dist/{engine-MVG2SPGD.js → engine-RJXQ5DHK.js} +4 -4
  62. package/dist/{entropy-3B4U2BTF.js → entropy-OX5LSM4S.js} +5 -5
  63. package/dist/{feedback-WIWWDVUC.js → feedback-OODAP2G2.js} +1 -1
  64. package/dist/{generate-agent-definitions-KPRHY6X3.js → generate-agent-definitions-CCREQZEA.js} +5 -5
  65. package/dist/hooks/adoption-tracker.js +41 -25
  66. package/dist/hooks/pre-compact-state.js +45 -27
  67. package/dist/hooks/sentinel-post.js +125 -102
  68. package/dist/hooks/sentinel-pre.js +70 -53
  69. package/dist/hooks/telemetry-reporter.js +44 -25
  70. package/dist/index.d.ts +66 -0
  71. package/dist/index.js +25 -25
  72. package/dist/{loader-SPJ2ZGYW.js → loader-ZICOJBVX.js} +4 -4
  73. package/dist/{mcp-VSSIWTII.js → mcp-XX6EIBLL.js} +15 -15
  74. package/dist/{performance-JYFS27B3.js → performance-OLZVGMAY.js} +5 -5
  75. package/dist/{review-pipeline-BDT6Y6QV.js → review-pipeline-3QPHMWPC.js} +4 -4
  76. package/dist/{runtime-ZEPHPPQJ.js → runtime-ZFFIH76Z.js} +4 -4
  77. package/dist/{security-FWSDTTEW.js → security-7YW3UK2C.js} +1 -1
  78. package/dist/{state-events-PBDNQPXT.js → state-events-PTWAEGJ2.js} +4 -4
  79. package/dist/{validate-XIMNCIKR.js → validate-H5SB7X3Z.js} +5 -5
  80. package/dist/{validate-cross-check-H2OUHTID.js → validate-cross-check-YYVYMSPA.js} +4 -4
  81. package/package.json +8 -8
@@ -0,0 +1,52 @@
1
+ name: harness-rollback
2
+ version: '1.0.0'
3
+ description: Post-ship circuit breaker — proposes a full-context revert PR when a shipped PR fails post-merge evaluation or crosses a signal threshold. Propose-only in v1 (never auto-merges).
4
+ stability: static
5
+ cognitive_mode: constructive-architect
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-rollback
22
+ args:
23
+ - name: path
24
+ description: Project root path
25
+ required: false
26
+ - name: pr
27
+ description: Target merged PR number to evaluate for rollback
28
+ required: false
29
+ mcp:
30
+ tool: run_skill
31
+ input:
32
+ skill: harness-rollback
33
+ path: string
34
+ type: rigid
35
+ tier: 2
36
+ phases:
37
+ - name: resolve
38
+ description: Identify the target merged PR, merge commit, and merge shape
39
+ required: true
40
+ - name: classify
41
+ description: Determine revert-readiness (clean revert + no dependent later merge)
42
+ required: true
43
+ - name: compose
44
+ description: Open a full-context revert PR (or dry-run), idempotent by label
45
+ required: true
46
+ - name: record
47
+ description: Append the rollback_event breadcrumb
48
+ required: true
49
+ state:
50
+ persistent: false
51
+ depends_on:
52
+ - outcome-eval
@@ -0,0 +1,150 @@
1
+ # Product Requirements
2
+
3
+ > Turn one picked work item into a durable PRD — user stories, testable acceptance criteria, and prioritization — through a guided interview. The product-management middle between `product-advisor` (BRD) and `harness-brainstorming` (spec). Authors requirements; never authors the spec.
4
+
5
+ ## When to Use
6
+
7
+ - When a roadmap item (or a plain feature idea) needs product-level requirements — user stories, acceptance criteria, prioritization — before design begins.
8
+ - When a non-technical author (PM/BA/client) should shape _what_ and _why_ through a guided interview, no code surface.
9
+ - When the downstream spec's acceptance criteria should be authored deliberately rather than fused into the proposal — the PRD feeds `harness-brainstorming` and, transitively, `acceptance-eval`.
10
+ - NOT for authoring a spec/proposal — that is `harness-brainstorming`'s job. This skill stops at the PRD.
11
+ - NOT for the BRD / client-inception intake — that is `product-advisor`'s job (upstream of this).
12
+ - NOT for bugs, chores, or refactors with no user-facing behavior — a PRD there is speculative ceremony (YAGNI).
13
+
14
+ ## Process
15
+
16
+ ### Iron Law
17
+
18
+ **Every user story carries at least one measurable acceptance criterion, or it ships as an open, named gap — never a silent guess. The skill authors the PRD; it does not author the spec, mutate the roadmap, or claim the item.**
19
+
20
+ A PRD that hides what it does not know launders assumptions into requirements. A criterion that cannot be judged is not a criterion. If a story has no measurable criterion and you did not surface it in the chase list, STOP and add it.
21
+
22
+ ---
23
+
24
+ ### Argument Resolution
25
+
26
+ - **`item`** — the slug/name of the work item. From the `item` argument, or the roadmap row being worked, or ask. Sets the artifact directory `docs/product-requirements/<item>/`.
27
+ - **`description`** — a plain feature description, used when no richer input (BRD, roadmap row) exists. The skill requires nothing more than this.
28
+
29
+ ---
30
+
31
+ ### Phase 1: INGEST — Gather the Richest Available Input
32
+
33
+ Load the richest input that exists, and **degrade gracefully** — the only hard requirement is a one-line description.
34
+
35
+ 1. **BRD when present:** if `docs/inception/<engagement>/brd.md` exists and maps to this item, read its Business Objectives, Scope, and Functional Requirements as the seed.
36
+ 2. **Else the roadmap row:** if a roadmap exists (`docs/roadmap.md` aggregate or `docs/roadmap.d/` shard), read the row's summary for this item.
37
+ 3. **Else the description argument:** treat it as the sole seed.
38
+ 4. **Strategy grounding (optional):** call `read_strategy({ path })` on the harness MCP server when available; capture `Target problem` / `Who it's for` to keep stories aligned. Soft-fail silently when absent, invalid, or the server is unavailable.
39
+ 5. **Soft-degrade, never fail:** when the seed is sparse (only a title, no BRD/roadmap/strategy), proceed and record a gap ("no BRD/roadmap context; requirements elicited from description only"). Do not abort.
40
+
41
+ ---
42
+
43
+ ### Phase 2: DRAFT-PRD — Synthesize the First Draft
44
+
45
+ 1. **Write the PRD** to `docs/product-requirements/<item>/prd.md` with these sections, each present even if thin:
46
+ - **Context** (+ a link to the source BRD when present)
47
+ - **Goal / Problem** — the user-facing outcome this item delivers
48
+ - **User Stories** — each `As a <role>, I want <goal>, so that <benefit>`, with its acceptance criteria and a MoSCoW priority
49
+ - **Prioritization summary** — the MoSCoW rollup (Must / Should / Could / Won't)
50
+ - **Non-Goals** — what this item explicitly does not cover
51
+ - **Open Questions (chase list)** — unresolved gaps, each phrased as a question
52
+ 2. **Acceptance criteria are EARS by default.** Each criterion follows an EARS pattern:
53
+ - Event-driven: "When `<trigger>`, the system shall `<response>`."
54
+ - Unwanted: "If `<condition>`, then the system shall not `<behavior>`."
55
+ - State-driven / optional: "While `<state>` / Where `<feature>`, the system shall `<response>`."
56
+ Render a criterion as **Given-When-Then** instead only when a story is behavior-heavy and reads more clearly that way. Every criterion must be testable — an EARS trigger→response or a numeric bound.
57
+ 3. **Prioritize every story with MoSCoW** (Must / Should / Could / Won't-this-time).
58
+ 4. **Tag gaps against the completeness rubric** (below). Every rubric miss becomes a gap `{ id, section, question, severity: blocker | important | nice, status: open }`. Do not invent facts to fill a section — an empty-because-unknown section is a gap, not a place to guess.
59
+
60
+ #### PRD completeness rubric
61
+
62
+ - Every user story has ≥1 acceptance criterion, else it is a gap.
63
+ - Every acceptance criterion is measurable — an EARS trigger→response or a numeric bound — else it is a gap.
64
+ - Every user story carries a MoSCoW priority, else it is a gap.
65
+ - Non-Goals is non-empty (state the boundary explicitly), else it is a gap.
66
+ - Every story traces to the Goal / Problem (or to an explicit gap).
67
+
68
+ ---
69
+
70
+ ### Phase 3: GAP-INTERVIEW — Resolve What You Can
71
+
72
+ 1. **Ask ONE question at a time, in plain text.** Order the gap queue by severity (`blocker` → `important` → `nice`). Ask the highest-severity open gap first, wait for the answer, then continue. Present each gap as a scannable multiple-choice table where options exist, and state a recommendation. **Do NOT route questions through `emit_interaction` or `AskUserQuestion`** — the human will not see them; plain text in your reply is the only reliable channel across all clients.
73
+ 2. **Fold each answer back into the PRD.** Update the relevant story/criterion (source: `interview`) and move the gap `open → resolved` with the captured answer.
74
+ 3. **Mark unresolvable gaps as chase-list questions.** If the author cannot answer (only the client/stakeholder can), keep the gap `open` and phrase it as a question to ask them.
75
+ 4. **Stop when the queue is drained** — every gap is either `resolved` or `open` (chase-list). Do not loop past a drained queue inventing new questions.
76
+
77
+ ---
78
+
79
+ ### Phase 4: FINALIZE — Ship and Hand Off
80
+
81
+ 1. **Finalize `docs/product-requirements/<item>/prd.md`** with all sections populated and the **Open Questions** section listing every remaining `open` gap as a question.
82
+ 2. **Stay in your lane.** Do **not** mutate the roadmap and **never** write an `assignee` — this skill operates on one already-picked item; claiming it is `harness-execution`'s job at execution start. If no roadmap exists, there is nothing to touch.
83
+ 3. **Emit the handoff to `harness-brainstorming`** via `emit_interaction` (type `transition`, `suggestedNext: harness-brainstorming`). State plainly that brainstorming will consume the PRD — seeding the spec's `## User Stories` and `## Success Criteria` from the PRD's EARS criteria — and then author the spec. **Do not author the spec here.**
84
+ 4. **Run `harness validate`.**
85
+
86
+ ---
87
+
88
+ ## Harness Integration
89
+
90
+ - **`read_strategy`** — Phase 1: read `STRATEGY.md` when present to align stories; never write it.
91
+ - **`gather_context`** — Phase 1 (optional): pull existing project/business knowledge to ground the domain.
92
+ - **`emit_interaction`** — Phase 4: record the `transition` to `harness-brainstorming`. The transition is recorded, not surfaced — any human-facing question is asked in plain text.
93
+ - **`harness validate`** — Phase 4: verify artifact placement and project health.
94
+ - **Boundary with adjacent skills:** `product-advisor` WRITES the BRD (upstream); this skill READS the BRD and WRITES the PRD; `harness-brainstorming` READS the PRD and WRITES the spec; `acceptance-eval` READS the spec's criteria and JUDGES them. This skill never crosses those lines.
95
+ - **Portability:** no hardcoded repo layout. The only hard requirement is a feature description. BRD, roadmap, and strategy are optional richer inputs consumed when present and soft-degraded when absent.
96
+
97
+ ## Success Criteria
98
+
99
+ - Running the skill with only a feature description (no BRD/roadmap/strategy) produces `docs/product-requirements/<item>/prd.md` with all sections present, none empty.
100
+ - Every user story has ≥1 acceptance criterion; every criterion is EARS-shaped (trigger→response) or carries a numeric bound.
101
+ - Every user story carries a MoSCoW priority.
102
+ - The gap interview asked one question at a time and folded each answer back (resolved gaps moved `open → resolved`); every unresolved gap ships as a chase-list question.
103
+ - The skill did not modify the roadmap and did not write an `assignee`.
104
+ - The handoff transitions to `harness-brainstorming`; no spec was authored.
105
+ - `harness validate` passes.
106
+
107
+ ## Rationalizations to Reject
108
+
109
+ | Rationalization | Reality |
110
+ | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
111
+ | "This story's outcome is obvious, so I can skip the acceptance criterion" | The Iron Law: every story carries a measurable criterion or a named gap. An implied criterion cannot be judged by `acceptance-eval`. |
112
+ | "There's no BRD/roadmap, so I can't run" | The only hard requirement is a description. Soft-degrade to description-only and record a gap — never abort. |
113
+ | "I'll write the spec while I'm here since the requirements are clear" | This skill stops at the PRD. Authoring a `proposal.md` is a gate violation — hand off to `harness-brainstorming`. |
114
+ | "I'll mark the item in-progress / assign it so the pick is recorded" | This skill never mutates the roadmap or writes `assignee`. Claiming happens at execution start; assigning here makes the orchestrator skip the item. |
115
+ | "Plain prose criteria are fine; EARS is ceremony" | EARS is the grammar `harness-planning`/`harness-brainstorming` consume and the shape `acceptance-eval` reads as MEASURABLE. Freeform criteria drift to un-judgable. |
116
+
117
+ ## Gates
118
+
119
+ - **No un-criterioned stories.** Every user story is either covered by a measurable acceptance criterion or shipped as an `open` chase-list gap. A story that is neither = Iron Law violation; stop and fix.
120
+ - **No guessed requirements.** An unknown section is a gap, not a place to invent facts.
121
+ - **No spec authoring.** This skill stops at the PRD; writing a `proposal.md` = gate violation. Hand off to `harness-brainstorming`.
122
+ - **No roadmap mutation and no assignment.** Writing the roadmap or the `assignee` field = gate violation.
123
+ - **No hard failure on sparse input.** Absent BRD/roadmap/strategy → description-only + recorded gap. Aborting because context is thin = gate violation.
124
+
125
+ ## Escalation
126
+
127
+ - **The author cannot answer a blocker gap:** keep it `open`, phrase it as a chase-list question for the client/stakeholder, and note in the handoff that brainstorming inherits an open blocker.
128
+ - **Scope spans multiple independent capabilities:** stop and suggest splitting into multiple items (one PRD per item), rather than one bloated PRD.
129
+ - **No item slug resolvable:** ask for a short name; without one, the artifact directory cannot be created.
130
+ - **The item is a bug/chore/refactor with no user-facing behavior:** say so and recommend going straight to `harness-brainstorming` — a PRD adds no value.
131
+
132
+ ## Examples
133
+
134
+ ### Example: PRD for a picked roadmap item with no BRD
135
+
136
+ **Context:** roadmap-pilot picked "Export dashboard to PDF." No BRD exists; the roadmap row is a one-line summary.
137
+
138
+ **INGEST:** No BRD found; read the roadmap row summary; strategy present (aligns with the "reporting" audience). Seed = row summary + description. Recorded no gap (seed sufficient).
139
+
140
+ **DRAFT-PRD:** Wrote `docs/product-requirements/export-dashboard-to-pdf/prd.md`. 3 user stories:
141
+
142
+ - _As an analyst, I want to export the current dashboard to PDF, so that I can share it offline._ **[Must]** — "When the user clicks Export → PDF, the system shall produce a PDF of the current dashboard within 5 seconds."
143
+ - _As an analyst, I want the PDF to preserve applied filters, so that it reflects what I see._ **[Should]** — "When a filter is applied, the exported PDF shall reflect the filtered data set."
144
+ - _As an admin, I want export disabled for restricted dashboards._ **[Could]** — "If the dashboard is marked restricted, then the system shall not offer the Export → PDF action."
145
+
146
+ Tagged 2 gaps: G1 (blocker) "max PDF page count?"; G2 (nice) "landscape or portrait default?".
147
+
148
+ **GAP-INTERVIEW:** Q1 (G1): "Cap the export at (A) 10 pages, (B) 50 pages, (C) no cap? Recommend B." → "B." Folded into story 1's criterion. Q2 (G2) → author defers → kept open as chase-list.
149
+
150
+ **FINALIZE:** PRD finalized; Open Questions lists G2. No roadmap mutation, no assignee. Emitted handoff → `harness-brainstorming` will seed the spec's Success Criteria from these EARS criteria. `harness validate` — passes.
@@ -0,0 +1,70 @@
1
+ name: product-requirements
2
+ version: "0.1.0"
3
+ description: Guided-interview skill that turns one picked work item into a durable Product Requirements Document (PRD) — user stories, testable EARS acceptance criteria, and MoSCoW prioritization — written to a per-item file under docs/product-requirements/. The product-management middle between product-advisor (BRD) and harness-brainstorming (spec). Reads a BRD/roadmap/description as available and degrades gracefully to description-only; authors requirements but never the spec, never mutates the roadmap, and never assigns.
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 product-requirements
22
+ args:
23
+ - name: item
24
+ description: Slug/name of the work item. Sets the item's artifact directory under docs/product-requirements/. Resolved from this argument, the roadmap row being worked, or by asking.
25
+ required: false
26
+ - name: description
27
+ description: Plain feature description, used as the seed when no BRD or roadmap row exists. The only hard input the skill needs.
28
+ required: false
29
+ mcp:
30
+ tool: run_skill
31
+ input:
32
+ skill: product-requirements
33
+ path: string
34
+ type: rigid
35
+ tier: 2
36
+ phases:
37
+ - name: ingest
38
+ description: Load the richest available input — a mapped BRD under docs/inception/, else the roadmap row summary, else the description argument. Optionally read STRATEGY.md for alignment. Soft-degrade to description-only and record a gap when the seed is sparse; never abort.
39
+ required: true
40
+ - name: draft-prd
41
+ description: Synthesize a first PRD into the item's file under docs/product-requirements/ (Context, Goal, User Stories with EARS acceptance criteria + MoSCoW priority, Prioritization summary, Non-Goals, Open Questions). Tag every rubric miss as a severity-ranked gap.
42
+ required: true
43
+ - name: gap-interview
44
+ description: Walk the author through the gap queue one question at a time (plain-text tables), highest severity first; fold each answer back into the PRD; keep unresolvable gaps as open chase-list questions.
45
+ required: true
46
+ - name: finalize
47
+ description: Finalize the PRD with Open Questions listed; do not mutate the roadmap or write an assignee; emit the handoff transition to harness-brainstorming (which seeds the spec's Success Criteria from the PRD's EARS criteria); run harness validate.
48
+ required: true
49
+ state:
50
+ persistent: true
51
+ files:
52
+ - docs/product-requirements/
53
+ depends_on:
54
+ - harness-brainstorming
55
+ related_skills:
56
+ - product-advisor
57
+ - harness-brainstorming
58
+ - harness-roadmap-pilot
59
+ - acceptance-eval
60
+ keywords:
61
+ - product-requirements
62
+ - PRD
63
+ - user-stories
64
+ - acceptance-criteria
65
+ - EARS
66
+ - MoSCoW
67
+ - requirements-authoring
68
+ - guided-interview
69
+ - configuration-interviewer
70
+ - lifecycle-middle
@@ -55,6 +55,8 @@ When no arguments are provided (standalone invocation), the skill operates exact
55
55
  - **Contradiction with the user's feature description:** do NOT auto-resolve. Carry the contradiction forward as an open question into Phase 2 EVALUATE — surface it explicitly so the human can decide whether to refine the feature or update strategy via `/harness:strategy`.
56
56
 
57
57
  1. **Load project context.** Call `gather_context({ path: "<project-root>", intent: "<feature description>", skill: "harness-brainstorming", session: "<session-slug-if-known>", include: ["graph", "businessKnowledge", "sessions", "validation"] })`. The `graph` context surfaces `business_fact` nodes relevant to the feature domain. The `businessKnowledge` context loads documented domain knowledge from `docs/knowledge/`. Use both to ground exploration in verified facts rather than assumptions. When `STRATEGY.md` was loaded in step 0a, treat its sections as a higher-tier grounding source than `businessKnowledge` — strategy reflects an explicit human commitment, knowledge is observation.
58
+ 1b. **Consume the PRD when present.** If `docs/product-requirements/<item>/prd.md` exists for this feature/item (authored upstream by the `product-requirements` skill), read it and treat its user stories and EARS acceptance criteria as settled requirements. In Phase 4, seed the spec's `## User Stories` and `## Success Criteria` from them rather than re-deriving criteria the PRD already resolved, and cite the PRD as evidence. When no PRD exists, proceed unchanged — the PRD is an optional richer input, never required.
59
+
58
60
  2. **Read the existing codebase.** Understand architecture, constraints, and conventions. Check AGENTS.md, existing specs in `docs/`, and relevant source files.
59
61
  3. **Identify the problem boundary.** What exactly needs solving? What is out of scope? Write both down. Cross-reference `businessKnowledge` domains — if documented business rules constrain the problem, note them.
60
62
  4. **Check for prior art.** Has this been partially solved elsewhere? Are there patterns to follow or deliberately break?
@@ -130,7 +132,7 @@ These flow into `handoff.json` `contextKeywords` field. Select keywords that hel
130
132
  - Decisions made (with rationale from brainstorming)
131
133
  - Technical design (data structures, APIs, file layout)
132
134
  - Integration points (entry points, registrations, docs, decisions, knowledge impact)
133
- - Success criteria (observable, testable outcomes)
135
+ - Success criteria (observable, testable outcomes) — when a PRD exists at `docs/product-requirements/<item>/prd.md`, seed these from its EARS acceptance criteria (see Phase 1 step 1b)
134
136
  - Implementation order (high-level phases, not detailed tasks)
135
137
 
136
138
  The **Integration Points** section is required in every spec. It defines how the feature connects to the existing system. Populate it with five subsections:
@@ -152,6 +152,11 @@ RMH005). See knowledge [`merge-triggered-auto-done.md`](../../../../docs/knowled
152
152
  1. Determine the transition target:
153
153
  - If the feature has a `spec` field (non-null): transition to `harness:autopilot`
154
154
  - If the feature has no `spec`: transition to `harness:brainstorming`
155
+ - **Optional (feature-shaped items):** before brainstorming, a no-spec item that carries
156
+ user-facing behavior may first run `product-requirements` to author a PRD (user stories +
157
+ acceptance criteria + prioritization) at `docs/product-requirements/<item>/prd.md`, which
158
+ brainstorming then consumes. Suggest this for feature work; skip it for bugs, chores, and
159
+ refactors (a PRD there is speculative ceremony).
155
160
 
156
161
  2. Present the transition to the human via `emit_interaction`:
157
162
 
@@ -0,0 +1,124 @@
1
+ # Harness Rollback
2
+
3
+ > Post-ship circuit breaker. Proposes a full-context **revert PR** when a shipped PR fails post-merge evaluation or crosses a signal threshold. v1 is **propose-only** — it NEVER auto-merges. A human merges the revert.
4
+
5
+ ## When to Use
6
+
7
+ - When a merged PR is suspected of causing a regression and you want a considered, full-context revert prepared for review.
8
+ - When a tracked signal (error rate, a baseline count, any `.harness/signals/` series) crosses a threshold and you want the implicated PR(s) evaluated for rollback.
9
+ - As the manual entry point to the same engine the scheduled `rollback-propose` workflow drives automatically.
10
+ - NOT for reverting un-merged work (use `git`/`gh` directly).
11
+ - NOT for deployment/infrastructure rollback — this operates at the git/PR layer (it opens a revert PR), not at the deploy layer.
12
+ - NOT to auto-merge a revert. v1 does not have that authority (see Iron Law).
13
+
14
+ ## Process
15
+
16
+ ### Iron Law
17
+
18
+ **v1 never auto-merges a revert. It opens a revert PR and stops. A human decides.**
19
+
20
+ Auto-merging code — even a revert — is a high-blast-radius write, and a wrong revert is itself an incident. The trust model earns auto-merge authority only after the propose loop has demonstrably proposed _correct_ reverts over time (recorded via the `rollback_event` breadcrumb). Until then, the workflow carries `pull-requests: write` but **not** `contents: write` and **no** self-approving PAT. If you find yourself merging a revert automatically, STOP — that is a separate, deferred trust tier (see ADR 0063).
21
+
22
+ ---
23
+
24
+ ### Phase 1: RESOLVE — Identify the target
25
+
26
+ 1. Take the target merged PR number (`--pr <n>`) and the trigger (`signal` or `eval`).
27
+ 2. Resolve the PR's merge commit and changed files via `gh`. If the PR is **not merged** (no merge commit), stop with a structured `skipped` decision — there is nothing to revert.
28
+ 3. Determine the merge shape: a two-parent merge commit reverts against parent 1 (`-m 1`); a **squash/rebase** merge is single-parent and reverts against its sole parent. This repo uses both — never assume a two-parent merge.
29
+
30
+ ### Phase 2: CLASSIFY — Is it revert-ready?
31
+
32
+ Run `classifyRevert` (core). A target is **revert-ready** only when BOTH hold:
33
+
34
+ - **Clean revert** — an in-memory `git merge-tree --write-tree` of the revert applies with no conflicts. (Never a working-tree-mutating `git revert -n`.)
35
+ - **No dependent later merge** — no PR merged after the target touches the same files. A later dependent merge → `action: 'blocked'` (a naive revert would orphan newer work).
36
+
37
+ `blastRadius` and `migrationWarnings` are **context only, never gates** — they enrich the PR body so the human reviewer sees the stakes; they do not decide revert-readiness.
38
+
39
+ ### Phase 3: COMPOSE — Open the revert PR (or dry-run)
40
+
41
+ 1. If `--dry-run`, print the PR body and stop — open no PR.
42
+ 2. Otherwise open a revert PR: title `revert: <original> (automated rollback)`, marker label `harness:rollback`, body = the full context block (trigger, target, revert-ready verdict, classification reasons, blast-radius, migration warnings, and the `--reason` if given).
43
+ 3. **Idempotency:** if an open PR labeled `harness:rollback` already references the target (`#<n>`, word-boundary matched — `#42` must not match `#420`), skip — do not open a duplicate.
44
+
45
+ ### Phase 4: RECORD — Breadcrumb
46
+
47
+ Append one `rollback_event` to `.harness/signals/`: `{ targetPr, trigger, revertReady, action, prUrl, reason, ts }`. This append-only record is what later justifies (or refuses) the auto-merge trust tier — it is not backfillable, so it is written on every evaluation.
48
+
49
+ ---
50
+
51
+ ## Triggers
52
+
53
+ - **Signal arm (live):** the scheduled `rollback-propose.yml` workflow runs `harness rollback sweep`, which reads `.harness/signals/timeline.json` and, for each `rollback.signals` entry `{ threshold, direction, window }`, detects an edge crossing, resolves the PR(s) merged in the window, and forwards each to `evaluate --trigger signal`.
54
+ - **Eval arm (dark until #31):** guarded by `rollback.evalTrigger.enabled` (default `false`). When outcome-eval is wired to run post-merge (#31), a high-confidence `NOT_SATISFIED` will route through the same engine with `--trigger eval`. Until then the path exists and is unit-tested but never fires — enabling it is a config flip, not a code change.
55
+
56
+ ## Harness Integration
57
+
58
+ - **`harness rollback evaluate`** — the CLI core; classification + compose + breadcrumb for one target PR.
59
+ - **`harness rollback sweep`** — the signal arm; timeline threshold detection → `evaluate`.
60
+ - **`classifyRevert` / `RollbackDecision`** (`@harness-engineering/core`) — the pure, injected-IO classification engine.
61
+ - **`.github/workflows/rollback-propose.yml`** — propose-only post-merge + scheduled workflow. `contents: read` + `pull-requests: write`, concurrency-serialized, no self-approving PAT.
62
+ - **`harness.config.json` → `rollback`** — `signals` (record of `{ threshold, direction, window }`) and `evalTrigger.enabled`.
63
+ - **ADR 0063** — the post-ship rollback trust model (propose → auto-merge progression).
64
+
65
+ ## Success Criteria
66
+
67
+ 1. A revert PR is opened only for a revert-ready target (clean revert + no dependent later merge); non-clean/blocked/unmerged targets yield a structured `skipped`/`blocked` decision and no PR.
68
+ 2. The revert PR body carries trigger, target, blast-radius, and migration warnings.
69
+ 3. Re-running against the same target opens no duplicate PR (label + word-boundary idempotency).
70
+ 4. Every evaluation appends one `rollback_event` breadcrumb.
71
+ 5. No revert is auto-merged — a human merges the PR.
72
+ 6. The eval arm produces no PR while `rollback.evalTrigger.enabled` is false.
73
+
74
+ ## Gates
75
+
76
+ - **No auto-merge.** v1 opens PRs; it never merges them. Enforced by the workflow's minimal permissions (no `contents: write`, no self-approving PAT).
77
+ - **No revert without revert-ready classification.** A conflicting revert or a dependent later merge blocks the proposal.
78
+ - **No two-parent assumption.** Squash/rebase merges must revert against their sole parent.
79
+ - **No working-tree mutation.** Revert-readiness is tested in-memory (`merge-tree`), never with `git revert -n`.
80
+
81
+ ## Rationalizations to Reject
82
+
83
+ | Rationalization | Reality |
84
+ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
85
+ | "The eval clearly failed, so I should auto-merge the revert to stop the bleeding" | v1 has no auto-merge authority. Open the PR; a human merges. Auto-merge is a deferred trust tier (ADR 0063). |
86
+ | "`git revert -n` in a temp index is fine for the readiness check" | `-n` still writes the working tree. Use `git merge-tree --write-tree` — pure in-memory, no side effects. |
87
+ | "It's a merge commit, so `-m 1` is safe" | Squash/rebase merges are single-parent; `-m 1` computes a meaningless revert. Check the parent count first. |
88
+ | "The signal fired, so every PR in the window should be reverted" | Only revert-ready targets are proposed, and only the human merges. A crossing is a signal to _evaluate_, not to revert blindly. |
89
+
90
+ ## Examples
91
+
92
+ ### Example: Signal-threshold crossing proposes a revert
93
+
94
+ **Context:** `harness.config.json` sets `rollback.signals.error-rate = { threshold: 50, direction: "above", window: "24h" }`. The hourly `rollback-propose` workflow runs `harness rollback sweep`.
95
+
96
+ ```
97
+ sweep reads .harness/signals/timeline.json → error-rate crosses 50 (edge, not plateau)
98
+ → resolves PRs merged in the 24h window: #758
99
+ → evaluate --pr 758 --trigger signal
100
+ RESOLVE: #758 merged, two-parent merge commit
101
+ CLASSIFY: merge-tree revert clean; no later merge touches its files → revert-ready
102
+ COMPOSE: opens "revert: Add tiered discount pricing (automated rollback)"
103
+ labeled harness:rollback, body carries trigger + blast-radius + migration warning
104
+ RECORD: appends rollback_event { targetPr: 758, trigger: signal, action: proposed, ts }
105
+ → A human reviews and merges the revert PR. Autopilot never merges it.
106
+ ```
107
+
108
+ ### Example: Blocked because a later merge depends on the target
109
+
110
+ **Context:** Manual invocation `harness rollback evaluate --pr 740 --dry-run`.
111
+
112
+ ```
113
+ CLASSIFY: PR #752 merged after #740 and touches the same files (dependent merge)
114
+ → revertReady: false, action: "blocked"
115
+ → no PR opened; decision reports "a later merge (#752) depends on this PR's files"
116
+ ```
117
+
118
+ ## Escalation
119
+
120
+ - **The target PR is a squash/rebase merge:** the engine reverts against its sole parent (no `-m 1`). If parent resolution is ambiguous, stop with a `skipped` decision and surface the merge shape — do not guess.
121
+ - **`git merge-tree` exits non-zero for a reason other than conflict (e.g. 128 bad object):** this is an error, not a conflict. Re-throw and surface it; do not report a false `skipped`.
122
+ - **A crossing resolves to many PRs in the window:** evaluate each independently; the composer's label idempotency prevents duplicate revert PRs. If the volume looks wrong (an unexpectedly wide window), check for date-truncation in the resolver before proposing.
123
+ - **The human asks to auto-merge the revert:** decline for v1 — that authority is the deferred Stage-2 trust tier (ADR 0063), gated on the `rollback_event` track record. Open the PR and let a human merge.
124
+ - **`rollback.evalTrigger.enabled` is true but #31 has not landed:** the eval arm has no post-merge invoker yet, so it still won't fire; note the dependency rather than wiring a bespoke trigger.
@@ -0,0 +1,52 @@
1
+ name: harness-rollback
2
+ version: '1.0.0'
3
+ description: Post-ship circuit breaker — proposes a full-context revert PR when a shipped PR fails post-merge evaluation or crosses a signal threshold. Propose-only in v1 (never auto-merges).
4
+ stability: static
5
+ cognitive_mode: constructive-architect
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-rollback
22
+ args:
23
+ - name: path
24
+ description: Project root path
25
+ required: false
26
+ - name: pr
27
+ description: Target merged PR number to evaluate for rollback
28
+ required: false
29
+ mcp:
30
+ tool: run_skill
31
+ input:
32
+ skill: harness-rollback
33
+ path: string
34
+ type: rigid
35
+ tier: 2
36
+ phases:
37
+ - name: resolve
38
+ description: Identify the target merged PR, merge commit, and merge shape
39
+ required: true
40
+ - name: classify
41
+ description: Determine revert-readiness (clean revert + no dependent later merge)
42
+ required: true
43
+ - name: compose
44
+ description: Open a full-context revert PR (or dry-run), idempotent by label
45
+ required: true
46
+ - name: record
47
+ description: Append the rollback_event breadcrumb
48
+ required: true
49
+ state:
50
+ persistent: false
51
+ depends_on:
52
+ - outcome-eval
@@ -0,0 +1,150 @@
1
+ # Product Requirements
2
+
3
+ > Turn one picked work item into a durable PRD — user stories, testable acceptance criteria, and prioritization — through a guided interview. The product-management middle between `product-advisor` (BRD) and `harness-brainstorming` (spec). Authors requirements; never authors the spec.
4
+
5
+ ## When to Use
6
+
7
+ - When a roadmap item (or a plain feature idea) needs product-level requirements — user stories, acceptance criteria, prioritization — before design begins.
8
+ - When a non-technical author (PM/BA/client) should shape _what_ and _why_ through a guided interview, no code surface.
9
+ - When the downstream spec's acceptance criteria should be authored deliberately rather than fused into the proposal — the PRD feeds `harness-brainstorming` and, transitively, `acceptance-eval`.
10
+ - NOT for authoring a spec/proposal — that is `harness-brainstorming`'s job. This skill stops at the PRD.
11
+ - NOT for the BRD / client-inception intake — that is `product-advisor`'s job (upstream of this).
12
+ - NOT for bugs, chores, or refactors with no user-facing behavior — a PRD there is speculative ceremony (YAGNI).
13
+
14
+ ## Process
15
+
16
+ ### Iron Law
17
+
18
+ **Every user story carries at least one measurable acceptance criterion, or it ships as an open, named gap — never a silent guess. The skill authors the PRD; it does not author the spec, mutate the roadmap, or claim the item.**
19
+
20
+ A PRD that hides what it does not know launders assumptions into requirements. A criterion that cannot be judged is not a criterion. If a story has no measurable criterion and you did not surface it in the chase list, STOP and add it.
21
+
22
+ ---
23
+
24
+ ### Argument Resolution
25
+
26
+ - **`item`** — the slug/name of the work item. From the `item` argument, or the roadmap row being worked, or ask. Sets the artifact directory `docs/product-requirements/<item>/`.
27
+ - **`description`** — a plain feature description, used when no richer input (BRD, roadmap row) exists. The skill requires nothing more than this.
28
+
29
+ ---
30
+
31
+ ### Phase 1: INGEST — Gather the Richest Available Input
32
+
33
+ Load the richest input that exists, and **degrade gracefully** — the only hard requirement is a one-line description.
34
+
35
+ 1. **BRD when present:** if `docs/inception/<engagement>/brd.md` exists and maps to this item, read its Business Objectives, Scope, and Functional Requirements as the seed.
36
+ 2. **Else the roadmap row:** if a roadmap exists (`docs/roadmap.md` aggregate or `docs/roadmap.d/` shard), read the row's summary for this item.
37
+ 3. **Else the description argument:** treat it as the sole seed.
38
+ 4. **Strategy grounding (optional):** call `read_strategy({ path })` on the harness MCP server when available; capture `Target problem` / `Who it's for` to keep stories aligned. Soft-fail silently when absent, invalid, or the server is unavailable.
39
+ 5. **Soft-degrade, never fail:** when the seed is sparse (only a title, no BRD/roadmap/strategy), proceed and record a gap ("no BRD/roadmap context; requirements elicited from description only"). Do not abort.
40
+
41
+ ---
42
+
43
+ ### Phase 2: DRAFT-PRD — Synthesize the First Draft
44
+
45
+ 1. **Write the PRD** to `docs/product-requirements/<item>/prd.md` with these sections, each present even if thin:
46
+ - **Context** (+ a link to the source BRD when present)
47
+ - **Goal / Problem** — the user-facing outcome this item delivers
48
+ - **User Stories** — each `As a <role>, I want <goal>, so that <benefit>`, with its acceptance criteria and a MoSCoW priority
49
+ - **Prioritization summary** — the MoSCoW rollup (Must / Should / Could / Won't)
50
+ - **Non-Goals** — what this item explicitly does not cover
51
+ - **Open Questions (chase list)** — unresolved gaps, each phrased as a question
52
+ 2. **Acceptance criteria are EARS by default.** Each criterion follows an EARS pattern:
53
+ - Event-driven: "When `<trigger>`, the system shall `<response>`."
54
+ - Unwanted: "If `<condition>`, then the system shall not `<behavior>`."
55
+ - State-driven / optional: "While `<state>` / Where `<feature>`, the system shall `<response>`."
56
+ Render a criterion as **Given-When-Then** instead only when a story is behavior-heavy and reads more clearly that way. Every criterion must be testable — an EARS trigger→response or a numeric bound.
57
+ 3. **Prioritize every story with MoSCoW** (Must / Should / Could / Won't-this-time).
58
+ 4. **Tag gaps against the completeness rubric** (below). Every rubric miss becomes a gap `{ id, section, question, severity: blocker | important | nice, status: open }`. Do not invent facts to fill a section — an empty-because-unknown section is a gap, not a place to guess.
59
+
60
+ #### PRD completeness rubric
61
+
62
+ - Every user story has ≥1 acceptance criterion, else it is a gap.
63
+ - Every acceptance criterion is measurable — an EARS trigger→response or a numeric bound — else it is a gap.
64
+ - Every user story carries a MoSCoW priority, else it is a gap.
65
+ - Non-Goals is non-empty (state the boundary explicitly), else it is a gap.
66
+ - Every story traces to the Goal / Problem (or to an explicit gap).
67
+
68
+ ---
69
+
70
+ ### Phase 3: GAP-INTERVIEW — Resolve What You Can
71
+
72
+ 1. **Ask ONE question at a time, in plain text.** Order the gap queue by severity (`blocker` → `important` → `nice`). Ask the highest-severity open gap first, wait for the answer, then continue. Present each gap as a scannable multiple-choice table where options exist, and state a recommendation. **Do NOT route questions through `emit_interaction` or `AskUserQuestion`** — the human will not see them; plain text in your reply is the only reliable channel across all clients.
73
+ 2. **Fold each answer back into the PRD.** Update the relevant story/criterion (source: `interview`) and move the gap `open → resolved` with the captured answer.
74
+ 3. **Mark unresolvable gaps as chase-list questions.** If the author cannot answer (only the client/stakeholder can), keep the gap `open` and phrase it as a question to ask them.
75
+ 4. **Stop when the queue is drained** — every gap is either `resolved` or `open` (chase-list). Do not loop past a drained queue inventing new questions.
76
+
77
+ ---
78
+
79
+ ### Phase 4: FINALIZE — Ship and Hand Off
80
+
81
+ 1. **Finalize `docs/product-requirements/<item>/prd.md`** with all sections populated and the **Open Questions** section listing every remaining `open` gap as a question.
82
+ 2. **Stay in your lane.** Do **not** mutate the roadmap and **never** write an `assignee` — this skill operates on one already-picked item; claiming it is `harness-execution`'s job at execution start. If no roadmap exists, there is nothing to touch.
83
+ 3. **Emit the handoff to `harness-brainstorming`** via `emit_interaction` (type `transition`, `suggestedNext: harness-brainstorming`). State plainly that brainstorming will consume the PRD — seeding the spec's `## User Stories` and `## Success Criteria` from the PRD's EARS criteria — and then author the spec. **Do not author the spec here.**
84
+ 4. **Run `harness validate`.**
85
+
86
+ ---
87
+
88
+ ## Harness Integration
89
+
90
+ - **`read_strategy`** — Phase 1: read `STRATEGY.md` when present to align stories; never write it.
91
+ - **`gather_context`** — Phase 1 (optional): pull existing project/business knowledge to ground the domain.
92
+ - **`emit_interaction`** — Phase 4: record the `transition` to `harness-brainstorming`. The transition is recorded, not surfaced — any human-facing question is asked in plain text.
93
+ - **`harness validate`** — Phase 4: verify artifact placement and project health.
94
+ - **Boundary with adjacent skills:** `product-advisor` WRITES the BRD (upstream); this skill READS the BRD and WRITES the PRD; `harness-brainstorming` READS the PRD and WRITES the spec; `acceptance-eval` READS the spec's criteria and JUDGES them. This skill never crosses those lines.
95
+ - **Portability:** no hardcoded repo layout. The only hard requirement is a feature description. BRD, roadmap, and strategy are optional richer inputs consumed when present and soft-degraded when absent.
96
+
97
+ ## Success Criteria
98
+
99
+ - Running the skill with only a feature description (no BRD/roadmap/strategy) produces `docs/product-requirements/<item>/prd.md` with all sections present, none empty.
100
+ - Every user story has ≥1 acceptance criterion; every criterion is EARS-shaped (trigger→response) or carries a numeric bound.
101
+ - Every user story carries a MoSCoW priority.
102
+ - The gap interview asked one question at a time and folded each answer back (resolved gaps moved `open → resolved`); every unresolved gap ships as a chase-list question.
103
+ - The skill did not modify the roadmap and did not write an `assignee`.
104
+ - The handoff transitions to `harness-brainstorming`; no spec was authored.
105
+ - `harness validate` passes.
106
+
107
+ ## Rationalizations to Reject
108
+
109
+ | Rationalization | Reality |
110
+ | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
111
+ | "This story's outcome is obvious, so I can skip the acceptance criterion" | The Iron Law: every story carries a measurable criterion or a named gap. An implied criterion cannot be judged by `acceptance-eval`. |
112
+ | "There's no BRD/roadmap, so I can't run" | The only hard requirement is a description. Soft-degrade to description-only and record a gap — never abort. |
113
+ | "I'll write the spec while I'm here since the requirements are clear" | This skill stops at the PRD. Authoring a `proposal.md` is a gate violation — hand off to `harness-brainstorming`. |
114
+ | "I'll mark the item in-progress / assign it so the pick is recorded" | This skill never mutates the roadmap or writes `assignee`. Claiming happens at execution start; assigning here makes the orchestrator skip the item. |
115
+ | "Plain prose criteria are fine; EARS is ceremony" | EARS is the grammar `harness-planning`/`harness-brainstorming` consume and the shape `acceptance-eval` reads as MEASURABLE. Freeform criteria drift to un-judgable. |
116
+
117
+ ## Gates
118
+
119
+ - **No un-criterioned stories.** Every user story is either covered by a measurable acceptance criterion or shipped as an `open` chase-list gap. A story that is neither = Iron Law violation; stop and fix.
120
+ - **No guessed requirements.** An unknown section is a gap, not a place to invent facts.
121
+ - **No spec authoring.** This skill stops at the PRD; writing a `proposal.md` = gate violation. Hand off to `harness-brainstorming`.
122
+ - **No roadmap mutation and no assignment.** Writing the roadmap or the `assignee` field = gate violation.
123
+ - **No hard failure on sparse input.** Absent BRD/roadmap/strategy → description-only + recorded gap. Aborting because context is thin = gate violation.
124
+
125
+ ## Escalation
126
+
127
+ - **The author cannot answer a blocker gap:** keep it `open`, phrase it as a chase-list question for the client/stakeholder, and note in the handoff that brainstorming inherits an open blocker.
128
+ - **Scope spans multiple independent capabilities:** stop and suggest splitting into multiple items (one PRD per item), rather than one bloated PRD.
129
+ - **No item slug resolvable:** ask for a short name; without one, the artifact directory cannot be created.
130
+ - **The item is a bug/chore/refactor with no user-facing behavior:** say so and recommend going straight to `harness-brainstorming` — a PRD adds no value.
131
+
132
+ ## Examples
133
+
134
+ ### Example: PRD for a picked roadmap item with no BRD
135
+
136
+ **Context:** roadmap-pilot picked "Export dashboard to PDF." No BRD exists; the roadmap row is a one-line summary.
137
+
138
+ **INGEST:** No BRD found; read the roadmap row summary; strategy present (aligns with the "reporting" audience). Seed = row summary + description. Recorded no gap (seed sufficient).
139
+
140
+ **DRAFT-PRD:** Wrote `docs/product-requirements/export-dashboard-to-pdf/prd.md`. 3 user stories:
141
+
142
+ - _As an analyst, I want to export the current dashboard to PDF, so that I can share it offline._ **[Must]** — "When the user clicks Export → PDF, the system shall produce a PDF of the current dashboard within 5 seconds."
143
+ - _As an analyst, I want the PDF to preserve applied filters, so that it reflects what I see._ **[Should]** — "When a filter is applied, the exported PDF shall reflect the filtered data set."
144
+ - _As an admin, I want export disabled for restricted dashboards._ **[Could]** — "If the dashboard is marked restricted, then the system shall not offer the Export → PDF action."
145
+
146
+ Tagged 2 gaps: G1 (blocker) "max PDF page count?"; G2 (nice) "landscape or portrait default?".
147
+
148
+ **GAP-INTERVIEW:** Q1 (G1): "Cap the export at (A) 10 pages, (B) 50 pages, (C) no cap? Recommend B." → "B." Folded into story 1's criterion. Q2 (G2) → author defers → kept open as chase-list.
149
+
150
+ **FINALIZE:** PRD finalized; Open Questions lists G2. No roadmap mutation, no assignee. Emitted handoff → `harness-brainstorming` will seed the spec's Success Criteria from these EARS criteria. `harness validate` — passes.