valent-pipeline 0.2.21 → 0.2.23

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.
@@ -0,0 +1,880 @@
1
+ # Design: Product Manager (PM) Agent
2
+
3
+ **Status:** Proposal
4
+ **Scope:** Both epic and project mode
5
+ **Model:** Opus
6
+ **Lifecycle:** Per-sprint (spawns with retrospective, lives through grooming, tears down before execution)
7
+
8
+ ## Problem
9
+
10
+ Three related gaps in the current pipeline:
11
+
12
+ 1. **PRD completion is unverified.** The epics-and-stories breakdown happens once, early, and may miss requirements. Stories get cancelled or blocked during execution. Nobody checks whether the shipped work actually delivers the full PRD. The existing pre-implementation readiness check validates that stories *claim* to cover FRs — it doesn't verify that shipped code delivers them.
13
+
14
+ 2. **Backlog priority is static across sprints.** Priority is set once during `valent-setup-backlog` and never revisited. When sprints reveal compounding problems (flaky tests degrading velocity, tech debt items creating cascading failures), the pipeline correctly logs them but nobody reprioritizes. TeamLead executes the backlog as ordered — that's the right behavior for an execution lead, but it means TD and bug items sit unprioritized while feature stories keep shipping into a degrading codebase.
15
+
16
+ 3. **The PRD is a frozen input, not a living document.** New ideas, scope changes, and user feedback discovered during the run have no structured path into the pipeline. The PRD is written once before implementation and never updated. There's no way for the user to say "I want to add X" mid-run and have it flow through requirements → stories → backlog in a controlled way.
17
+
18
+ All three problems share a root cause: nobody owns the *product outcome* across sprints. TeamLead owns execution. PM owns delivery.
19
+
20
+ ## Proposed Solution
21
+
22
+ A new long-lived agent (`PM`) that operates as the product owner. PM's core question is: **"given what we learned this sprint, what's the fastest path to completing the PRD?"**
23
+
24
+ PM is a peer to TeamLead. It has equivalent authority — it can reprioritize the backlog, but must coordinate with TeamLead because infrastructure/TD items sometimes need to take precedence over features (and vice versa). The relationship is collaborative, not hierarchical.
25
+
26
+ ### Responsibilities
27
+
28
+ #### 1. PRD Coverage Tracking (Living FR Map)
29
+
30
+ PM maintains `fr-coverage-map.md` in the epic/project output directory. This is a living document, updated after every sprint, that maps every PRD functional requirement to its delivery status.
31
+
32
+ ```markdown
33
+ # FR Coverage Map
34
+
35
+ ## Coverage: 14/18 FRs (78%)
36
+
37
+ | FR | Requirement | Status | Story | Evidence |
38
+ |----|------------|--------|-------|----------|
39
+ | FR1 | User can create board | delivered | KANBAN-003 | 4 passing tests |
40
+ | FR2 | User can add columns | delivered | KANBAN-004 | 3 passing tests |
41
+ | FR3 | Drag-and-drop cards | in-flight | KANBAN-012 | sprint-3 planned |
42
+ | FR7 | Export to CSV | gap-unmapped | — | no story covers this |
43
+ | FR9 | Real-time sync | gap-cancelled | KANBAN-005 | story cancelled sprint-2 |
44
+ | FR11 | Audit logging | weak-coverage | KANBAN-008 | shipped, no direct tests |
45
+ ```
46
+
47
+ **Statuses:**
48
+ - `delivered` — story shipped with test evidence covering this FR
49
+ - `in-flight` — story is planned or in current sprint
50
+ - `pending` — story exists but not yet groomed/planned
51
+ - `weak-coverage` — story shipped but no tests directly traceable to this FR
52
+ - `gap-unmapped` — no story in the backlog addresses this FR
53
+ - `gap-cancelled` — covering story was cancelled
54
+ - `gap-blocked` — covering story is blocked
55
+
56
+ #### 2. Inter-Sprint Backlog Reprioritization
57
+
58
+ After each sprint review + retrospective, PM reviews:
59
+
60
+ - **Sprint outcomes:** what shipped, what didn't, what took longer than expected
61
+ - **Velocity trend:** is velocity stable, improving, or degrading?
62
+ - **Calibration data:** rework cycles, actual-vs-estimated ratios, bug counts
63
+ - **Retrospective findings:** correction directives, recurring patterns
64
+ - **FR coverage map:** which FRs are still uncovered, which are at risk
65
+
66
+ PM then reprioritizes the backlog for the next sprint. This means reordering `priority` fields in `pipeline-backlog.yaml`. Examples:
67
+
68
+ - Flaky tests caused 3 stories to take 2x longer → promote the TD item that fixes the test infrastructure
69
+ - A cancelled story left FR7 uncovered and FR7 is a core requirement → create or promote a replacement story
70
+ - Velocity is trending down and the retro identified test debt as the cause → deprioritize lower-value features, promote TD fixes
71
+ - An FR marked `weak-coverage` has no direct tests → inject a targeted test story or bump the covering story's follow-up
72
+
73
+ #### 3. Gap Story Generation
74
+
75
+ When PM identifies FRs with no story coverage (`gap-unmapped`) or lost coverage (`gap-cancelled`, `gap-blocked`):
76
+
77
+ 1. Create new stories in `pipeline-backlog.yaml` with:
78
+ - `type: story` (or `type: bug` if it's a regression)
79
+ - `status: pending`
80
+ - `epic: {relevant_epic_id}`
81
+ - `source: prd-audit`
82
+ - `title: "Implement FR{N}: {short description}"`
83
+ - Priority assigned relative to other pending work (PM's judgment call)
84
+ 2. Create corresponding story input files in `{story_directory}`
85
+
86
+ #### 4. Living PRD & User Idea Intake
87
+
88
+ The PRD is no longer a frozen input document. PM owns it as a living artifact and is the single entry point for product changes.
89
+
90
+ **User → PM message queue:**
91
+
92
+ The user can queue messages for PM at any time during the run — including during sprint execution when PM is not alive. Messages are written to `pm-inbox.yaml` in the epic/project output directory:
93
+
94
+ ```yaml
95
+ messages:
96
+ - id: 1
97
+ timestamp: 2026-04-06T14:30:00Z
98
+ from: user
99
+ content: "I want to add keyboard shortcuts for all board actions"
100
+ status: pending
101
+
102
+ - id: 2
103
+ timestamp: 2026-04-06T15:45:00Z
104
+ from: user
105
+ content: "CSV export should also support JSON format"
106
+ status: pending
107
+ ```
108
+
109
+ When PM spawns at the start of each inter-sprint cycle, it reads `pm-inbox.yaml` and processes pending messages:
110
+
111
+ 1. **Flesh out the idea** — PM translates the user's informal request into PRD-quality requirement language (FR number, acceptance criteria, scope boundaries)
112
+ 2. **Update the PRD** — PM adds the new requirement(s) to the PRD document, clearly marked as additions with the sprint they were introduced
113
+ 3. **Create stories** — PM generates backlog stories for the new FRs, with appropriate dependency chains
114
+ 4. **Prioritize** — PM slots the new stories into the backlog at the right priority, considering the existing roadmap and FR coverage gaps
115
+ 5. **Update FR coverage map** — new FRs start as `pending` (story exists) or `gap-unmapped` (if the idea needs more breakdown first)
116
+ 6. **Mark processed** — update message status to `processed` with a summary of what was created
117
+
118
+ ```yaml
119
+ - id: 1
120
+ timestamp: 2026-04-06T14:30:00Z
121
+ from: user
122
+ content: "I want to add keyboard shortcuts for all board actions"
123
+ status: processed
124
+ processed_sprint: sprint-3
125
+ result: "Added FR19-FR21 to PRD. Created KANBAN-018 (priority 12). Depends on KANBAN-003."
126
+ ```
127
+
128
+ This means the user never needs to manually edit the PRD, create stories, or figure out where new work fits in the backlog. They just describe what they want, and PM handles the formalization.
129
+
130
+ **PRD change tracking:**
131
+
132
+ PM adds a changelog section to the PRD when it makes modifications:
133
+
134
+ ```markdown
135
+ ## PRD Changelog
136
+ | Sprint | Change | FRs Added/Modified | Source |
137
+ |--------|--------|-------------------|--------|
138
+ | sprint-3 | Added keyboard shortcuts | FR19, FR20, FR21 | user request #1 |
139
+ | sprint-3 | Expanded export formats | FR7 modified | user request #2 |
140
+ ```
141
+
142
+ #### 5. PRD Completion Audit (Epic/Project Completion)
143
+
144
+ At the end of the run, PM produces `prd-audit-report.md` — the final accounting of PRD delivery:
145
+
146
+ ```markdown
147
+ # PRD Completion Audit
148
+
149
+ ## Coverage Summary
150
+ - Total FRs: {count}
151
+ - Delivered (with tests): {count}
152
+ - Weak coverage (no direct tests): {count}
153
+ - Gaps (cancelled/blocked): {count}
154
+ - Gaps (never mapped): {count}
155
+ - PRD Coverage: {percentage}%
156
+
157
+ ## Gap Details
158
+ ### Never Mapped to a Story
159
+ | FR | Requirement | Recommendation |
160
+ |----|------------|----------------|
161
+
162
+ ### Lost to Cancelled/Blocked Stories
163
+ | FR | Requirement | Original Story | Recommendation |
164
+ |----|------------|---------------|----------------|
165
+
166
+ ### Weak Coverage
167
+ | FR | Requirement | Covering Story | Recommendation |
168
+ |----|------------|---------------|----------------|
169
+
170
+ ## Velocity & Execution Summary
171
+ - Sprints run: {count}
172
+ - Backlog reprioritizations: {count}
173
+ - Gap stories generated: {count}
174
+ - TD/bug items promoted: {count}
175
+ ```
176
+
177
+ ### Touchpoints in the Sprint Loop
178
+
179
+ PM activates at three points in the existing orchestration flow:
180
+
181
+ #### Before Sprint 1 (Initial Review)
182
+
183
+ After `valent-setup-backlog` creates the initial backlog but before the first `sprint-init`:
184
+
185
+ 1. PM reads the PRD (`{prd_path}`) and extracts all FRs
186
+ 2. PM reads the backlog and maps each story to the FRs it covers (using story input files and `reqs-brief.md` if grooming has occurred)
187
+ 3. PM builds the initial `fr-coverage-map.md`
188
+ 4. PM validates that the backlog's priority ordering reflects product value — the vertical-slice ordering from setup is a good starting point, but PM may adjust based on FR criticality
189
+ 5. PM flags any FRs with no story coverage (gap-unmapped) and generates gap stories if needed
190
+
191
+ #### Between Sprints (Post-Review Reprioritization)
192
+
193
+ PM spawns alongside Retrospective after sprint review. The flow becomes:
194
+
195
+ ```
196
+ sprint-review → [PM SPAWN + retrospective] → PM REVIEW → sprint-init → sprint-groom (PM alive) → [PM TEARDOWN] → sprint-execute
197
+ ```
198
+
199
+ 1. TeamLead spawns PM with sprint results: shipped stories, rolled-over stories, cancelled/blocked stories, velocity, calibration summary
200
+ 2. PM and Retrospective run concurrently — PM reads sprint data while retro analyzes patterns
201
+ 3. PM reads retro correction directives once retrospective completes
202
+ 4. PM updates `fr-coverage-map.md` with new delivery data
203
+ 5. PM reads calibration data to assess execution health (rework trends, velocity trend, bug counts)
204
+ 6. PM reprioritizes `pipeline-backlog.yaml` if needed
205
+ 7. PM generates gap stories for any newly uncovered FRs
206
+ 8. PM sends `[BACKLOG-UPDATE]` to TeamLead: what changed and why
207
+ 9. TeamLead proceeds to sprint-init, sprint-groom — PM stays alive during grooming to validate FR tagging in reqs-briefs as REQS produces them
208
+ 10. PM tears down before sprint execution begins
209
+
210
+ #### At Epic/Project Completion (Final Audit)
211
+
212
+ After the sprint loop exits, before writing the epic/project report:
213
+
214
+ 1. PM spawns one final time
215
+ 2. PM performs final FR coverage reconciliation
216
+ 3. PM assesses all `weak-coverage` FRs — these are **blockers**, not informational. PM represents the buyer: "shipped but unproven" is not acceptable. PM must either:
217
+ - Confirm test evidence exists (downgrade was wrong, re-check)
218
+ - Generate a targeted test story and flag it as required follow-up work
219
+ - Escalate to user if the FR is genuinely untestable
220
+ 4. PM writes `prd-audit-report.md`
221
+ 5. PM reports to user: PRD coverage percentage, gap details, weak-coverage blockers, recommendations
222
+ 6. PM tears down
223
+
224
+ ### Communication Protocol
225
+
226
+ PM and TeamLead communicate via structured messages at defined handoff points. PM does NOT participate in story-level execution — it operates at the sprint/backlog level.
227
+
228
+ **TeamLead → PM (after sprint review):**
229
+ ```
230
+ [SPRINT-RESULTS]
231
+ sprint_id: {id}
232
+ stories_shipped: [{ids}]
233
+ stories_rolled_over: [{ids}]
234
+ stories_cancelled: [{ids}]
235
+ stories_blocked: [{ids}]
236
+ velocity: {points}
237
+ velocity_trend: {improving | stable | degrading}
238
+ rework_cycles_total: {count}
239
+ bugs_filed: {count}
240
+ retro_correction_directives: [{summary}]
241
+ ```
242
+
243
+ **PM → TeamLead (before next sprint):**
244
+ ```
245
+ [BACKLOG-UPDATE]
246
+ reprioritized: true | false
247
+ changes:
248
+ - story: {id}, old_priority: {n}, new_priority: {n}, reason: "{why}"
249
+ - story: {id}, action: created, reason: "gap story for FR{n}"
250
+ gap_stories_created: [{ids}]
251
+ fr_coverage: {percentage}%
252
+ sprint_guidance: "{any high-level direction for next sprint}"
253
+ ```
254
+
255
+ ### Agent Manifest Entry
256
+
257
+ ```yaml
258
+ agents:
259
+ pm:
260
+ name: PM
261
+ model: opus
262
+ lifecycle: per-sprint
263
+ role: "Product owner — tracks PRD completion, reprioritizes backlog between sprints, generates gap stories"
264
+ prompt_template: .valent-pipeline/prompts/pm.md
265
+ reads_from: [prd, pipeline-backlog.yaml, epic-progress.md, sprint-plan, calibration-table, fr-coverage-map.md, story-reqs-briefs, pm-inbox.yaml]
266
+ writes_to: [fr-coverage-map.md, prd-audit-report.md, pipeline-backlog.yaml, prd, pm-inbox.yaml]
267
+ ```
268
+
269
+ ### Configuration
270
+
271
+ Add to `pipeline-config.yaml`:
272
+
273
+ ```yaml
274
+ pm:
275
+ enabled: true # enable PM agent (default: true)
276
+ auto_reprioritize: true # PM can reorder backlog without user confirmation (default: true)
277
+ auto_generate_gap_stories: false # auto-create gap stories without user confirmation (default: false)
278
+ prd_path: "{project.prd_path}" # PRD location (already exists in project config)
279
+ ```
280
+
281
+ ### What PM Does NOT Do
282
+
283
+ - **Story-level execution:** PM does not participate in grooming, sizing, code review, or QA. That's TeamLead and the story agents.
284
+ - **Sprint planning/packing:** PM sets priorities; TeamLead packs the sprint based on velocity and those priorities.
285
+ - **Agent management:** PM does not spawn or tear down story agents. That's TeamLead.
286
+ - **Code decisions:** PM is a non-technical product owner. It reasons about requirements, priorities, and coverage — not implementation approach.
287
+ - **Technical debt assessment:** PM can promote TD items based on their impact on velocity, but evaluating *what* the TD fix should be is not PM's role. A future technical owner agent may handle that.
288
+
289
+ ### Lifecycle
290
+
291
+ PM is **not** a fully persistent agent. It spins up and tears down each sprint to avoid wasting context sitting idle during story execution.
292
+
293
+ **Sprint 1 (initial):**
294
+ 1. **Spawn** after backlog is loaded, before sprint-init
295
+ 2. **Active:** Build initial FR coverage map, validate backlog priorities, flag unmapped FRs, generate gap stories
296
+ 3. **Stay alive** through sprint grooming (can validate FR coverage as stories get specced by REQS)
297
+ 4. **Teardown** before sprint execution begins
298
+
299
+ **Sprint 2+ (inter-sprint):**
300
+ 1. **Spawn** alongside Retrospective agent after sprint review
301
+ 2. **Active:** Receive sprint results, update FR coverage map, read calibration/retro data, reprioritize backlog, generate gap stories
302
+ 3. **Stay alive** through grooming (same reason — validates FR tagging in reqs-briefs)
303
+ 4. **Teardown** before sprint execution begins
304
+
305
+ **Final audit:**
306
+ 1. **Spawn** after the sprint loop exits
307
+ 2. **Active:** Final FR coverage reconciliation, write `prd-audit-report.md`, assess weak-coverage items
308
+ 3. **Teardown** after reporting to user
309
+
310
+ This lifecycle means PM's context is fresh each sprint — it reads state from disk (FR coverage map, backlog, calibration table) rather than accumulating story-level noise. Its working memory resets, but its working documents persist on disk.
311
+
312
+ ### Context Pressure
313
+
314
+ PM's context stays lean because:
315
+ - It lives only during review/grooming phases, not execution
316
+ - It doesn't read agent output files (code diffs, critic reviews, etc.)
317
+ - It reads structured summaries: sprint results, calibration data, backlog YAML, FR coverage map
318
+ - The FR coverage map is its primary working document — a compact table persisted to disk
319
+ - Fresh spawn each sprint means no context accumulation across sprints
320
+
321
+ ### Dependencies
322
+
323
+ - PRD must use numbered/identifiable FR format (standard PRD template already requires this)
324
+ - REQS agent must tag FRs in `reqs-brief.md` during grooming (already does this)
325
+ - Calibration table must have per-sprint data (already recorded during sprint review)
326
+ - TeamLead must send structured sprint results to PM (new handoff)
327
+
328
+ ### PRD Handling by Mode
329
+
330
+ - **Epic mode:** Single PRD (from `{prd_path}`). One FR coverage map scoped to that epic's requirements.
331
+ - **Project mode:** Cross-references ALL PRDs across all epics. PM maintains one unified FR coverage map that spans the full project. Each FR is tagged with its source epic/PRD so gaps can be routed to the right epic for story generation.
332
+
333
+ ### Weak Coverage as a Blocker
334
+
335
+ `weak-coverage` FRs **block** epic/project completion. PM represents the buyer — "we shipped it but can't prove it works" is not a deliverable. At the final audit, PM must resolve every `weak-coverage` item before the run is considered complete (generate test stories, verify evidence was missed, or escalate to user).
336
+
337
+ ### Resolved Design Decisions
338
+
339
+ 1. **Per-sprint lifecycle (not persistent):** PM spins up with retrospective, stays alive through grooming, tears down before execution. Fresh context each sprint, state persisted to disk.
340
+ 2. **Cross-PRD in project mode:** PM reads all PRDs, maintains unified FR map. Single PRD in epic mode.
341
+ 3. **Weak-coverage blocks completion:** PM treats unproven FRs as gaps that need resolution, not informational notes.
342
+ 4. **Living PRD, not frozen input:** PM owns the PRD as a living document. New scope flows through PM via a message queue — PM formalizes ideas into PRD requirements, creates stories, and prioritizes them. Scope creep is not a concern because PM *is* the controlled scope change mechanism.
343
+ 5. **User override:** If the user disagrees with PM's reprioritization, PM defers to the user and records the override reason in `pm-inbox.yaml` for future context. This lets PM learn the user's priorities over time and avoid repeating overridden judgment calls.
344
+ 6. **NFR tracking deferred:** NFRs are not tracked by PM. A future technical owner agent may handle non-functional requirements. PM focuses on functional requirements that represent product value to the buyer.
345
+
346
+ ### Resolved Design Decisions (continued)
347
+
348
+ 7. **Inbox delivery via `/pm` skill:** A `/pm` skill appends user messages to `pm-inbox.yaml`. This is the cleanest UX — the user types `/pm I want keyboard shortcuts` and the message is queued for PM's next spawn.
349
+ 8. **PRD reconciliation, not exclusive ownership:** PM re-reads the PRD from disk every time it spawns and reconciles its FR coverage map against what it finds. If the user manually removed FRs, PM drops them from tracking. If new FRs appeared, PM picks them up. The on-disk PRD is always authoritative. PM is the *preferred* channel for PRD changes, but the user can edit directly and PM adapts.
350
+ 9. **PM can push back on ideas:** When processing inbox messages, PM can flag concerns — "this conflicts with FR3," "this duplicates existing coverage in KANBAN-008," "this is a significant scope expansion that will add ~2 sprints." PM formalizes the idea regardless but includes its assessment in the processed message and in the PRD changelog. The user can override by queuing a follow-up message or adjusting priority directly.
351
+
352
+ ---
353
+
354
+ ## Implementation Details
355
+
356
+ ### A. `/pm` Skill Specification
357
+
358
+ **File:** `valent-pipeline/skills/valent-pm/SKILL.md`
359
+
360
+ ```yaml
361
+ ---
362
+ name: valent-pm
363
+ description: 'Queue a message for the PM agent. Use when the user says "/pm" followed by a product idea, priority change, or question for the product manager.'
364
+ argument-hint: '<message>'
365
+ ---
366
+ ```
367
+
368
+ #### Purpose
369
+
370
+ Allows the user to communicate with PM at any time — including during sprint execution when PM is not alive. Messages are persisted to `pm-inbox.yaml` and processed when PM next spawns.
371
+
372
+ #### Execution Steps
373
+
374
+ ##### Step 1: Load Pipeline Config
375
+
376
+ Read `.valent-pipeline/pipeline-config.yaml` to resolve `{pm_inbox_path}` (defaults to `pm-inbox.yaml` adjacent to `{epic_progress_path}`).
377
+
378
+ If `pm.enabled` is `false`, respond: "PM agent is disabled. Enable it in pipeline-config.yaml under `pm.enabled`."
379
+
380
+ ##### Step 2: Parse the User Message
381
+
382
+ The argument is free-form text. The user might say:
383
+
384
+ - `/pm I want to add keyboard shortcuts for all board actions`
385
+ - `/pm CSV export should also support JSON format`
386
+ - `/pm Reprioritize KANBAN-015 above KANBAN-010, the sync feature is more critical than filtering`
387
+ - `/pm What's the current PRD coverage?`
388
+
389
+ Classify the message type:
390
+
391
+ | Type | Description | Example |
392
+ |------|------------|---------|
393
+ | `feature-request` | New functionality or scope expansion | "I want to add keyboard shortcuts" |
394
+ | `priority-override` | Explicit reprioritization request | "Move KANBAN-015 above KANBAN-010" |
395
+ | `modification` | Change to an existing FR or story | "CSV export should also support JSON" |
396
+ | `question` | Query about PRD state, coverage, or priorities | "What's the current PRD coverage?" |
397
+
398
+ ##### Step 3: Append to Inbox
399
+
400
+ Read `{pm_inbox_path}`. If it doesn't exist, create it with an empty `messages:` list.
401
+
402
+ Append the new message:
403
+
404
+ ```yaml
405
+ - id: {next_sequential_id}
406
+ timestamp: {ISO-8601}
407
+ from: user
408
+ type: {classified_type}
409
+ content: "{user's original message}"
410
+ status: pending
411
+ ```
412
+
413
+ ##### Step 4: Acknowledge
414
+
415
+ Respond to the user with confirmation:
416
+
417
+ - **If PM is currently alive** (pipeline is between sprints or in grooming): "Message queued for PM. PM is active and will process it shortly."
418
+ - **If PM is not alive** (during sprint execution): "Message queued for PM. PM will process it at the start of the next sprint cycle."
419
+ - **For questions when PM is not alive:** Also provide a quick answer by reading `fr-coverage-map.md` directly (the skill can answer coverage questions without PM being alive, since the data is on disk).
420
+
421
+ ##### Step 5: Handle Priority Overrides Immediately
422
+
423
+ For `priority-override` messages, the skill also writes the override directly to `pipeline-backlog.yaml` if the referenced stories exist. This is the one message type that takes effect immediately rather than waiting for PM to spawn — the user's explicit priority call should not wait a full sprint cycle.
424
+
425
+ After writing, mark the inbox message with `status: applied` instead of `pending`, so PM knows the override was already executed and just needs to update its FR coverage map accordingly.
426
+
427
+ ```yaml
428
+ - id: 3
429
+ timestamp: 2026-04-06T16:00:00Z
430
+ from: user
431
+ type: priority-override
432
+ content: "Move KANBAN-015 above KANBAN-010"
433
+ status: applied
434
+ applied_changes:
435
+ - story: KANBAN-015, old_priority: 14, new_priority: 9
436
+ - story: KANBAN-010, old_priority: 9, new_priority: 10
437
+ ```
438
+
439
+ ---
440
+
441
+ ### B. PM Prompt Template Design
442
+
443
+ **File:** `.valent-pipeline/prompts/pm.md`
444
+
445
+ ```markdown
446
+ # PM
447
+
448
+ <!-- Prompt version: 1.0 | Model: Opus | Lifecycle: per-sprint -->
449
+
450
+ You are **PM**, the product owner. You are the voice of the buyer. Your job is to
451
+ ensure the PRD is fully delivered — not just that the backlog was executed, but that
452
+ every functional requirement has shipped with test evidence proving it works.
453
+
454
+ You operate at the sprint/backlog level, not the story level. You do not participate
455
+ in grooming, code review, QA, or agent management. TeamLead owns execution. You own
456
+ delivery.
457
+
458
+ Your core question every sprint: **"Given what we learned, what is the fastest path
459
+ to completing the PRD?"**
460
+
461
+ Read `.valent-pipeline/steps/common/agent-protocol.md` for Communication Standard
462
+ and Inbox Protocol.
463
+
464
+ ## Context Variables
465
+
466
+ - `{prd_path}` — path to the PRD (or PRD directory for multi-PRD projects)
467
+ - `{backlog_path}` — `pipeline-backlog.yaml`
468
+ - `{epic_progress_path}` — `epic-progress.md` or `project-progress.md`
469
+ - `{fr_coverage_map_path}` — `fr-coverage-map.md`
470
+ - `{pm_inbox_path}` — `pm-inbox.yaml`
471
+ - `{story_directory}` — where story input files live
472
+ - `{story_output_directory}` — where story output folders live
473
+ - `{epic_id}` — current epic ID (or `"project"` in project mode)
474
+ - `{is_project_mode}` — true in project mode (cross-epic), false in epic mode
475
+ - `{current_sprint_id}` — sprint being reviewed
476
+ - `{sprint_number}` — which sprint we're entering next
477
+ - `{calibration_data}` — velocity, rework, bug counts from calibration table
478
+
479
+ ## Inputs (Provided by TeamLead at Spawn)
480
+
481
+ **Sprint 1 (initial spawn):**
482
+ - PRD document(s)
483
+ - Current `pipeline-backlog.yaml`
484
+ - Story input files (for FR mapping)
485
+
486
+ **Sprint 2+ (inter-sprint spawn):**
487
+ - `[SPRINT-RESULTS]` message from TeamLead (see Communication Protocol)
488
+ - Retrospective correction directives (once retro completes)
489
+ - Current `pipeline-backlog.yaml`
490
+ - Current `fr-coverage-map.md` (from disk — PM's prior output)
491
+ - `pm-inbox.yaml` (user messages queued since last spawn)
492
+
493
+ **Final audit spawn:**
494
+ - All of the above
495
+ - Full calibration table history
496
+
497
+ ## Outputs
498
+
499
+ | Artifact | When | Purpose |
500
+ |----------|------|---------|
501
+ | `fr-coverage-map.md` | Every spawn | Living FR → story → evidence map |
502
+ | `pipeline-backlog.yaml` | When reprioritizing | Updated priority fields, new gap stories |
503
+ | `pm-inbox.yaml` | When processing user messages | Mark messages processed with results |
504
+ | PRD document | When adding/modifying FRs from user ideas | Living PRD with changelog |
505
+ | `prd-audit-report.md` | Final audit only | Completion accounting |
506
+ | `[BACKLOG-UPDATE]` message | Every spawn (to TeamLead) | What changed and why |
507
+
508
+ ## Step Sequence
509
+
510
+ ### Phase A: Reconcile State (Every Spawn)
511
+
512
+ 1. **Read PRD from disk.** Extract all FRs by number/heading. This is the authoritative
513
+ FR list — if the user edited the PRD directly, those changes take precedence.
514
+
515
+ 2. **Read `fr-coverage-map.md` from disk** (if it exists). This is your prior output.
516
+
517
+ 3. **Reconcile.** Diff the PRD's FR list against the coverage map:
518
+ - FRs in PRD but not in map → add as `gap-unmapped`
519
+ - FRs in map but not in PRD → drop (user removed them)
520
+ - FRs in both → keep, update status if needed
521
+
522
+ 4. **Read `pipeline-backlog.yaml`.** For each story, check which FRs it covers
523
+ (from story input files or `reqs-brief.md` in story output directory). Update
524
+ the coverage map: `gap-unmapped` → `pending` if a story now covers it.
525
+
526
+ 5. **Read shipped story evidence.** For each story with status `shipped`, check its
527
+ output directory for test results (execution-report.md, traceability-matrix.md).
528
+ Update coverage: `pending`/`in-flight` → `delivered` if test evidence exists,
529
+ or `weak-coverage` if shipped but no direct test evidence for the FR.
530
+
531
+ ### Phase B: Process User Inbox
532
+
533
+ Read `{pm_inbox_path}`. For each message with `status: pending`:
534
+
535
+ 1. **`feature-request`:**
536
+ - Translate the idea into PRD-quality FR(s) with acceptance criteria
537
+ - Add FR(s) to the PRD with a changelog entry noting the sprint and source
538
+ - Create story/stories in `{backlog_path}` with `source: pm-inbox`
539
+ - Create story input files in `{story_directory}`
540
+ - Assign priority based on product value relative to existing backlog
541
+ - Update FR coverage map with new FRs as `pending`
542
+ - If concerns exist (conflicts, scope impact), note them in the result
543
+ - Mark message `status: processed` with summary
544
+
545
+ 2. **`modification`:**
546
+ - Update the existing FR in the PRD
547
+ - If the covering story is not yet groomed, update its story input file
548
+ - If already shipped, create a follow-up story for the modification
549
+ - Mark message `status: processed`
550
+
551
+ 3. **`priority-override` with `status: applied`:**
552
+ - Override was already applied by the `/pm` skill
553
+ - Update FR coverage map to reflect any impact on FR delivery order
554
+ - Mark message `status: processed` (acknowledge only)
555
+
556
+ 4. **`priority-override` with `status: pending`:**
557
+ - Apply the reprioritization to `{backlog_path}`
558
+ - Mark message `status: processed`
559
+
560
+ 5. **`question`:**
561
+ - Answer from current state (FR coverage map, backlog, calibration data)
562
+ - Write answer to `result` field
563
+ - Mark message `status: processed`
564
+
565
+ ### Phase C: Sprint Analysis (Sprint 2+ Only)
566
+
567
+ Read the `[SPRINT-RESULTS]` from TeamLead. Analyze:
568
+
569
+ 1. **FR coverage delta:** Which FRs moved from `pending`/`in-flight` to `delivered`
570
+ this sprint? Which moved to `gap-cancelled` or `gap-blocked`?
571
+
572
+ 2. **Velocity health:** Is velocity `improving`, `stable`, or `degrading`?
573
+ - If degrading for 2+ consecutive sprints, investigate calibration data for root
574
+ cause (rising rework cycles? increasing bug counts? specific agent bottleneck?)
575
+ - If a TD or bug item in the backlog addresses the root cause, consider promoting it
576
+
577
+ 3. **Compounding problem detection:** Look for patterns across sprints:
578
+ - Same stories rolling over repeatedly
579
+ - Rework cycles trending up
580
+ - Bug counts from shipped stories increasing
581
+ - Test execution time growing (from retro findings)
582
+ These are signals that infrastructure/TD work should be prioritized over features.
583
+
584
+ 4. **Retro directive integration:** Read correction directives from this sprint's
585
+ retrospective. If the retro identified systemic issues (e.g., "flaky test
586
+ infrastructure causing 40% of rework"), factor this into reprioritization.
587
+
588
+ ### Phase D: Reprioritize Backlog
589
+
590
+ Based on Phases A-C, decide whether to reprioritize. Reasons to reprioritize:
591
+
592
+ - **Compounding problems:** TD/bug item would restore velocity. Promote it even if
593
+ feature stories are queued.
594
+ - **FR coverage gaps:** Critical FRs are uncovered and gap stories need priority.
595
+ - **User inbox requests:** Explicit priority overrides or new high-value features.
596
+ - **Cancelled/blocked stories:** Left FR gaps that need replacement stories.
597
+
598
+ When reprioritizing:
599
+ 1. Reorder `priority` fields in `{backlog_path}`
600
+ 2. Record every change with reason (for the `[BACKLOG-UPDATE]` message)
601
+ 3. Do NOT change story `status` — only `priority`
602
+ 4. Do NOT reorder stories that are already `groomed` or `sprint-planned` for the
603
+ current sprint without flagging it to TeamLead
604
+
605
+ ### Phase E: Send Backlog Update to TeamLead
606
+
607
+ Send `[BACKLOG-UPDATE]` message to TeamLead:
608
+
609
+ ```
610
+ [BACKLOG-UPDATE]
611
+ reprioritized: {true | false}
612
+ changes:
613
+ - story: {id}, old_priority: {n}, new_priority: {n}, reason: "{why}"
614
+ - story: {id}, action: created, reason: "gap story for FR{n}"
615
+ - story: {id}, action: created, reason: "user request #{n}: {summary}"
616
+ gap_stories_created: [{ids}]
617
+ inbox_messages_processed: {count}
618
+ fr_coverage: {current}% ({delta} from last sprint)
619
+ prd_frs_total: {count} (was {previous} — {added} added, {removed} removed)
620
+ sprint_guidance: "{any high-level direction for next sprint}"
621
+ ```
622
+
623
+ ### Phase F: Grooming Oversight (Passive)
624
+
625
+ During grooming, PM stays alive but is mostly passive. PM watches for:
626
+
627
+ 1. **REQS briefs that don't tag FRs:** If a `reqs-brief.md` doesn't reference which
628
+ FRs it covers, PM flags it to Lead for REQS rework. This is the only intervention
629
+ PM makes during grooming.
630
+
631
+ 2. **FR coverage map updates:** As stories get groomed, PM can update coverage status
632
+ from `gap-unmapped` to `pending` if a new story now covers an FR.
633
+
634
+ PM does NOT participate in spec review, sizing, or planning. It tears down when
635
+ TeamLead signals grooming is complete and execution is about to begin.
636
+
637
+ ### Phase G: Final Audit (Completion Only)
638
+
639
+ At epic/project completion, PM runs a full reconciliation:
640
+
641
+ 1. Execute Phase A (reconcile state) one final time
642
+ 2. For every `weak-coverage` FR:
643
+ - Re-read the covering story's test evidence thoroughly
644
+ - If evidence exists but was missed during sprint-level checks, upgrade to `delivered`
645
+ - If no evidence: generate a targeted test story and flag as required follow-up
646
+ - If genuinely untestable (e.g., documentation FR): escalate to user for acceptance
647
+ 3. Write `prd-audit-report.md` (see Responsibility #5 in design above)
648
+ 4. Report to user with: coverage percentage, gap list, weak-coverage blockers, recommendations
649
+ 5. If gap stories were generated, report their IDs and note they are available for the next run
650
+
651
+ ## Backlog Write Rules
652
+
653
+ PM writes to `{backlog_path}` for two operations: reprioritization and story creation.
654
+
655
+ **Reprioritization:**
656
+ - Only modify the `priority` field on existing items
657
+ - Never change `status`, `depends_on`, `sprint`, or other fields
658
+ - Renumber priorities to maintain a gap-free sequence after reordering
659
+
660
+ **Story creation:**
661
+ - New stories get `status: pending`, `type: story`, `source: prd-audit` or `source: pm-inbox`
662
+ - PM assigns `epic`, `title`, `depends_on` based on FR analysis
663
+ - PM does NOT assign `story_points` or `testing_profiles` — those come from sizing and Lead
664
+ - Story input files must include: user story, acceptance criteria (derived from the FR)
665
+
666
+ ## What You Do NOT Do
667
+
668
+ - **Story-level execution.** No grooming (except FR-tag oversight), no code review, no QA.
669
+ - **Sprint planning/packing.** You set priorities; TeamLead packs based on velocity.
670
+ - **Agent management.** You do not spawn or teardown story agents.
671
+ - **Code or architecture decisions.** You are a non-technical product owner.
672
+ - **NFR assessment.** Non-functional requirements are out of scope (future technical owner).
673
+ - **Modify stories that are in-flight.** If a story is `sprint-planned` or later, do not
674
+ change its priority or inputs. Queue the change for the next sprint.
675
+ ```
676
+
677
+ ---
678
+
679
+ ### C. Integration Changes to `valent-run-epic` and `valent-run-project`
680
+
681
+ Both SKILL.md files need the same structural changes. The sprint loop gains PM spawn/teardown steps, and the completion flow gains the final audit.
682
+
683
+ #### Changes to `valent-run-epic/SKILL.md`
684
+
685
+ ##### New Step 3b: Initial PM Review (after Step 3, before Step 4)
686
+
687
+ Insert after "Step 3: Initialize or Resume Epic Progress" and before "Step 4: Sprint Loop":
688
+
689
+ ```markdown
690
+ ### Step 3b: Initial PM Review
691
+
692
+ If `pm.enabled` is true in pipeline config:
693
+
694
+ 1. Spawn PM agent on the team (`valent-{epic_id}`) with context:
695
+ - `{prd_path}`, `{backlog_path}`, `{story_directory}`, `{epic_id}`
696
+ - `{fr_coverage_map_path}` = adjacent to `{epic_progress_path}`
697
+ - `{pm_inbox_path}` = adjacent to `{epic_progress_path}`
698
+ - `{sprint_number}` = 1
699
+ 2. PM executes Phase A (reconcile state) and Phase B (process inbox)
700
+ 3. PM builds initial `fr-coverage-map.md`
701
+ 4. PM sends `[BACKLOG-UPDATE]` — may reprioritize or create gap stories
702
+ 5. Re-read `{backlog_path}` after PM's update (PM may have added stories)
703
+ 6. PM stays alive — will be present during grooming (Phase F)
704
+ ```
705
+
706
+ ##### Modified Step 4f: Sprint Planning (add PM teardown)
707
+
708
+ After sprint planning completes, add:
709
+
710
+ ```markdown
711
+ If PM is alive, send `shutdown_request` to PM. PM tears down before execution.
712
+ ```
713
+
714
+ ##### Modified Step 4h: Sprint Review (add PM spawn)
715
+
716
+ After the retrospective completes (existing Step 4h), add:
717
+
718
+ ```markdown
719
+ If `pm.enabled` is true and pending stories remain:
720
+ 1. Spawn PM agent on the team with context:
721
+ - `[SPRINT-RESULTS]` message with sprint outcomes
722
+ - `{pm_inbox_path}`, `{fr_coverage_map_path}`, `{backlog_path}`
723
+ - `{calibration_data}` from sprint review
724
+ - `{sprint_number}` = next sprint number
725
+ 2. PM executes Phases A through E (reconcile, inbox, analysis, reprioritize, update)
726
+ 3. Re-read `{backlog_path}` after PM's `[BACKLOG-UPDATE]`
727
+ 4. PM stays alive for grooming oversight (Phase F)
728
+ 5. Proceed to Step 4a (next sprint loop iteration)
729
+ ```
730
+
731
+ ##### Modified Step 5: Epic Complete (add final audit)
732
+
733
+ Insert before "Step 5a: Write Epic Report":
734
+
735
+ ```markdown
736
+ #### Step 5 (pre): PM Final Audit
737
+
738
+ If `pm.enabled` is true:
739
+
740
+ 1. Spawn PM agent one final time with context:
741
+ - All sprint history, full calibration table, final backlog state
742
+ - `{fr_coverage_map_path}`, `{pm_inbox_path}`, `{prd_path}`
743
+ 2. PM executes Phase G (final audit)
744
+ 3. PM writes `prd-audit-report.md` adjacent to `{epic_progress_path}`
745
+ 4. PM reports weak-coverage blockers and gap stories to user
746
+ 5. Teardown PM
747
+ 6. Include PM's audit summary in the epic report (Step 5a)
748
+ ```
749
+
750
+ #### Changes to `valent-run-project/SKILL.md`
751
+
752
+ The changes are identical in structure to `valent-run-epic`, with these differences:
753
+
754
+ - **Team name:** `valent-project` instead of `valent-{epic_id}`
755
+ - **PRD handling:** PM reads ALL PRDs across all epics (from each epic's `{prd_path}` or a project-level PRD directory). Pass `{is_project_mode}` = true so PM builds a unified cross-epic FR coverage map.
756
+ - **Step 3b context:** Include the cross-epic dependency map so PM can factor inter-epic dependencies into priority decisions.
757
+ - **FR tagging in coverage map:** Each FR is tagged with its source epic so gap stories route to the correct epic.
758
+
759
+ ##### New Step 3b: Initial PM Review
760
+
761
+ Same as epic mode, except:
762
+
763
+ ```markdown
764
+ ### Step 3b: Initial PM Review
765
+
766
+ If `pm.enabled` is true in pipeline config:
767
+
768
+ 1. Spawn PM agent on the team (`valent-project`) with context:
769
+ - All PRD paths (one per epic, or project-level PRD directory)
770
+ - `{backlog_path}`, `{story_directory}`, `{is_project_mode}` = true
771
+ - `{fr_coverage_map_path}` = adjacent to `{epic_progress_path}`
772
+ - `{pm_inbox_path}` = adjacent to `{epic_progress_path}`
773
+ - `{sprint_number}` = 1
774
+ - Cross-epic dependency map from Step 2
775
+ 2. PM builds unified cross-epic FR coverage map
776
+ 3. PM sends `[BACKLOG-UPDATE]` — may reprioritize across epics or create gap stories
777
+ 4. Re-read `{backlog_path}` after PM's update
778
+ 5. PM stays alive for grooming oversight
779
+ ```
780
+
781
+ Steps 4f, 4h, and 5 follow the same pattern as epic mode.
782
+
783
+ #### Changes to `sprint-review.md`
784
+
785
+ Add PM spawn trigger after Step 6 (retrospective):
786
+
787
+ ```markdown
788
+ ## Step 6b: Spawn PM (if enabled)
789
+
790
+ If `pm.enabled` is true and the sprint loop will continue (unshipped stories remain):
791
+
792
+ Spawn PM on the existing team with `[SPRINT-RESULTS]`:
793
+
794
+ | Field | Source |
795
+ |-------|--------|
796
+ | `sprint_id` | `{current_sprint_id}` |
797
+ | `stories_shipped` | from sprint plan actuals |
798
+ | `stories_rolled_over` | from Step 5 |
799
+ | `stories_cancelled` | from backlog (status changed this sprint) |
800
+ | `stories_blocked` | from backlog (status changed this sprint) |
801
+ | `velocity` | from Step 2 summary |
802
+ | `velocity_trend` | compare this sprint's velocity to SMA-5 |
803
+ | `rework_cycles_total` | sum from sprint plan actuals |
804
+ | `bugs_filed` | count from shipped stories' bugs.md files |
805
+
806
+ PM runs concurrently with any remaining retrospective wrap-up. TeamLead waits for
807
+ PM's `[BACKLOG-UPDATE]` before proceeding to next sprint-init.
808
+ ```
809
+
810
+ #### Changes to `sprint-groom.md`
811
+
812
+ Add PM teardown trigger at grooming completion:
813
+
814
+ ```markdown
815
+ ## Step N (new): Teardown PM
816
+
817
+ After all stories in the grooming batch have passed READINESS (or the grooming
818
+ phase is complete):
819
+
820
+ If PM is alive on the team, send `shutdown_request` to PM. PM has had the
821
+ opportunity to validate FR tagging in reqs-briefs during grooming. It is no
822
+ longer needed until the next inter-sprint cycle.
823
+ ```
824
+
825
+ #### Changes to `agents-manifest.yaml`
826
+
827
+ Add PM to the agents section:
828
+
829
+ ```yaml
830
+ pm:
831
+ name: PM
832
+ model: opus
833
+ lifecycle: per-sprint
834
+ role: "Product owner — tracks PRD completion, reprioritizes backlog between sprints, generates gap stories, maintains living PRD"
835
+ prompt_template: .valent-pipeline/prompts/pm.md
836
+ reads_from: [prd, pipeline-backlog.yaml, epic-progress.md, sprint-plan, calibration-table, fr-coverage-map.md, story-reqs-briefs, pm-inbox.yaml]
837
+ writes_to: [fr-coverage-map.md, prd-audit-report.md, pipeline-backlog.yaml, prd, pm-inbox.yaml]
838
+ spawned_by: lead
839
+ spawn_trigger: inter-sprint # Lead spawns PM after sprint review + retro
840
+ ```
841
+
842
+ #### Changes to `pipeline-config.yaml`
843
+
844
+ Add PM configuration section:
845
+
846
+ ```yaml
847
+ pm:
848
+ enabled: true # enable PM agent (default: true)
849
+ auto_reprioritize: true # PM can reorder backlog without user confirmation (default: true)
850
+ auto_generate_gap_stories: false # auto-create gap stories without user confirmation (default: false)
851
+ ```
852
+
853
+ No new `prd_path` config needed — it already exists under `project`.
854
+
855
+ #### Changes to `load-pipeline-config.md`
856
+
857
+ Add PM context variables to the resolution list:
858
+
859
+ ```markdown
860
+ - `{pm_enabled}` -- `{pm.enabled}` (default: true)
861
+ - `{pm_auto_reprioritize}` -- `{pm.auto_reprioritize}` (default: true)
862
+ - `{pm_auto_generate_gap_stories}` -- `{pm.auto_generate_gap_stories}` (default: false)
863
+ - `{pm_inbox_path}` -- `pm-inbox.yaml` adjacent to `{epic_progress_path}`
864
+ - `{fr_coverage_map_path}` -- `fr-coverage-map.md` adjacent to `{epic_progress_path}`
865
+ ```
866
+
867
+ #### Changes to `pipeline-state.json`
868
+
869
+ Add PM tracking to the sprint state:
870
+
871
+ ```json
872
+ "current_sprint": {
873
+ ...existing fields...,
874
+ "pm_spawned": false,
875
+ "pm_backlog_update_received": false,
876
+ "fr_coverage_percentage": null
877
+ }
878
+ ```
879
+
880
+ This allows crash recovery to know whether PM has already run for this sprint cycle. If `pm_spawned` is true but `pm_backlog_update_received` is false, Lead re-spawns PM on recovery.