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.
@@ -14,13 +14,14 @@ Read each story's `phase-timing.md` for `total_elapsed_minutes` and count reject
14
14
  ## Step 2: Fill Sprint Summary
15
15
 
16
16
  Update `sprint-{n}-plan.md` Sprint Summary:
17
- - Stories shipped: count and list
17
+ - Stories shipped: count and list (distinguish originally planned vs mid-sprint pulls)
18
18
  - Stories rolled over: count and list (if any)
19
- - Points shipped: sum of shipped story points
19
+ - Points shipped: sum of shipped story points (includes mid-sprint pulls)
20
20
  - Points rolled over: sum of unexecuted story points
21
21
  - Total elapsed minutes: sum of execution time (not grooming)
22
- - Velocity this sprint: points_shipped
22
+ - Velocity this sprint: points_shipped (all shipped stories count toward velocity, including pulls)
23
23
  - Updated velocity (SMA-5): compute new moving average
24
+ - Mid-sprint pulls: count and list (stories pulled from groomed buffer during execution)
24
25
 
25
26
  ## Step 3: Finalize Sprint Status YAML
26
27
 
@@ -60,6 +61,14 @@ Spawn the Retrospective Agent with this sprint's shipped stories. Pass:
60
61
 
61
62
  After retrospective completes, update `pipeline-state.json`: `current_sprint.phase = "completed"`.
62
63
 
64
+ ## Step 6b: Spawn PM (if enabled)
65
+
66
+ If `{pm_enabled}` is true and the sprint loop will continue (unshipped stories remain in the backlog):
67
+
68
+ Read and follow `.valent-pipeline/steps/orchestration/sprint-pm-review.md`.
69
+
70
+ PM spawns concurrently with any remaining retrospective wrap-up. TeamLead waits for PM's `[BACKLOG-UPDATE]` before proceeding to next sprint-init. PM stays alive into the next sprint's grooming phase for FR-tag oversight.
71
+
63
72
  ## Step 7: Check for Next Sprint
64
73
 
65
74
  If unshipped stories remain in `{backlog_path}` (status `pending` with dependencies met):
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: valent-pm
3
+ description: 'Queue a message for the PM agent — product ideas, priority changes, or questions about PRD coverage. Use when the user says "/pm" followed by their message.'
4
+ argument-hint: '<message>'
5
+ ---
6
+
7
+ # valent-pm
8
+
9
+ Queue a message for the PM (Product Manager) agent. PM processes messages when it next spawns (between sprints). Priority overrides take effect immediately.
10
+
11
+ ## Arguments
12
+
13
+ The user provides a free-form message after `/pm`. Examples:
14
+
15
+ - `/pm I want to add keyboard shortcuts for all board actions`
16
+ - `/pm CSV export should also support JSON format`
17
+ - `/pm Reprioritize KANBAN-015 above KANBAN-010, the sync feature is more critical`
18
+ - `/pm What's the current PRD coverage?`
19
+
20
+ If no argument is provided, ask the user what they'd like to tell PM.
21
+
22
+ ## Execution Steps
23
+
24
+ ### Step 1: Load Pipeline Config
25
+
26
+ Read `.valent-pipeline/pipeline-config.yaml`. Resolve:
27
+ - `{pm_enabled}` from `pm.enabled` (default: true)
28
+ - `{pm_inbox_path}` — `pm-inbox.yaml` adjacent to `{epic_progress_path}`
29
+ - `{fr_coverage_map_path}` — `fr-coverage-map.md` adjacent to `{epic_progress_path}`
30
+ - `{backlog_path}` from `project.backlog_path`
31
+
32
+ If `{pm_enabled}` is false, respond: "PM agent is disabled. Enable it in `pipeline-config.yaml` under `pm.enabled`."
33
+
34
+ ### Step 2: Classify Message
35
+
36
+ Classify the user's message:
37
+
38
+ | Type | Pattern | Example |
39
+ |------|---------|---------|
40
+ | `feature-request` | New functionality or scope expansion | "I want to add keyboard shortcuts" |
41
+ | `priority-override` | Explicit reprioritization of existing stories | "Move KANBAN-015 above KANBAN-010" |
42
+ | `modification` | Change to an existing requirement or story | "CSV export should also support JSON" |
43
+ | `question` | Query about PRD state, coverage, or priorities | "What's the current PRD coverage?" |
44
+
45
+ ### Step 3: Append to Inbox
46
+
47
+ Read `{pm_inbox_path}`. If the file does not exist, create it:
48
+
49
+ ```yaml
50
+ messages: []
51
+ ```
52
+
53
+ Determine the next sequential ID (max existing ID + 1, or 1 if empty).
54
+
55
+ Append:
56
+
57
+ ```yaml
58
+ - id: {next_id}
59
+ timestamp: {ISO-8601}
60
+ from: user
61
+ type: {classified_type}
62
+ content: "{user's original message}"
63
+ status: pending
64
+ ```
65
+
66
+ Write the updated file.
67
+
68
+ ### Step 4: Acknowledge
69
+
70
+ Respond to the user:
71
+
72
+ - **If a pipeline is actively running between sprints (PM is alive):** "Message queued for PM. PM is active and will process it shortly."
73
+ - **If a pipeline is running but in execution (PM is not alive):** "Message #{id} queued for PM. PM will process it at the start of the next sprint cycle."
74
+ - **If no pipeline is running:** "Message #{id} queued for PM. PM will process it when the next epic or project run starts."
75
+
76
+ ### Step 5: Handle Special Cases
77
+
78
+ #### Priority Overrides — Apply Immediately
79
+
80
+ For `priority-override` messages, also apply the change directly to `{backlog_path}`:
81
+
82
+ 1. Read `{backlog_path}`
83
+ 2. Identify the referenced stories
84
+ 3. If both stories exist, swap or reorder their `priority` fields
85
+ 4. Renumber surrounding priorities to maintain a gap-free sequence
86
+ 5. Write the updated backlog
87
+ 6. Update the inbox message:
88
+
89
+ ```yaml
90
+ - id: {id}
91
+ timestamp: {ISO-8601}
92
+ from: user
93
+ type: priority-override
94
+ content: "{original message}"
95
+ status: applied
96
+ applied_changes:
97
+ - story: {STORY-ID}, old_priority: {n}, new_priority: {n}
98
+ - story: {STORY-ID}, old_priority: {n}, new_priority: {n}
99
+ ```
100
+
101
+ 7. Confirm to user: "Priority override applied. {STORY-ID} moved from priority {old} to {new}. PM will reconcile the FR coverage map next sprint."
102
+
103
+ If the referenced stories don't exist in the backlog, keep `status: pending` and respond: "Stories not found in backlog. PM will review this message when it next spawns."
104
+
105
+ #### Questions — Answer from Disk
106
+
107
+ For `question` messages, provide an immediate answer if possible:
108
+
109
+ 1. Read `{fr_coverage_map_path}` (if it exists)
110
+ 2. Read `{backlog_path}`
111
+ 3. Answer the question from current state
112
+ 4. Still queue the message so PM has a record
113
+
114
+ If `{fr_coverage_map_path}` doesn't exist (no sprint has run yet), respond: "No FR coverage data available yet. PM will build the coverage map when the first sprint starts."
115
+
116
+ ## Notes
117
+
118
+ - This skill can be invoked at any time — before, during, or between pipeline runs.
119
+ - Messages persist in `pm-inbox.yaml` across conversation resets.
120
+ - PM processes all pending messages at the start of each inter-sprint cycle.
121
+ - Priority overrides are the only message type that takes immediate effect.
@@ -68,6 +68,17 @@ last_updated: {ISO-8601}
68
68
  ## Story Outcomes (compact — max 2 lines per story)
69
69
  ```
70
70
 
71
+ ### Step 3b: Initial PM Review
72
+
73
+ If `{pm_enabled}` is true:
74
+
75
+ 1. Read and follow `.valent-pipeline/steps/orchestration/sprint-pm-review.md` with `{sprint_number}` = 1.
76
+ 2. PM builds the initial `fr-coverage-map.md` by reading the PRD and mapping FRs to backlog stories.
77
+ 3. PM processes any pre-run messages in `{pm_inbox_path}` (user may have queued ideas before starting the epic).
78
+ 4. PM validates backlog priority ordering against product value and may reprioritize.
79
+ 5. PM sends `[BACKLOG-UPDATE]` — re-read `{backlog_path}` after PM's update (PM may have added gap stories or reordered priorities).
80
+ 6. PM stays alive into Step 4d (grooming) for FR-tag oversight.
81
+
71
82
  ### Step 4: Sprint Loop
72
83
 
73
84
  Loop sprints until all epic stories are shipped, blocked, or cancelled. Each sprint follows the cycle: **groom → size → plan → execute → review → retro**.
@@ -103,7 +114,7 @@ BEND/FEND estimate Fibonacci points per story (filtered by `testing_profiles`).
103
114
 
104
115
  Read and follow `.valent-pipeline/steps/orchestration/sprint-plan.md`.
105
116
 
106
- Pack stories into sprint capacity by priority. Write `sprint-{n}-plan.md` and `sprint-{n}-status.yaml`. Kill Phase 1 agents (except Knowledge).
117
+ Pack stories into sprint capacity by priority. Write `sprint-{n}-plan.md` and `sprint-{n}-status.yaml`. Kill Phase 1 agents (except Knowledge). PM teardown occurs during sprint-groom.md Step 6b (before sizing).
107
118
 
108
119
  #### 4g. Sprint Execution
109
120
 
@@ -142,6 +153,14 @@ Context compression may fire here — that is expected. The PostCompact hook re-
142
153
 
143
154
  When all stories in the epic are shipped (or remaining are all blocked/cancelled):
144
155
 
156
+ #### 5 (pre). PM Final Audit
157
+
158
+ If `{pm_enabled}` is true:
159
+
160
+ Read and follow `.valent-pipeline/steps/orchestration/sprint-pm-audit.md`.
161
+
162
+ PM spawns one final time, performs full FR coverage reconciliation, resolves weak-coverage items (these are blockers — "shipped but unproven" is not acceptable), writes `prd-audit-report.md`, and tears down. Include PM's audit summary in the epic report below.
163
+
145
164
  #### 5a. Write Epic Report
146
165
 
147
166
  Write `epic-report.md` adjacent to `{epic_progress_path}`:
@@ -79,6 +79,17 @@ last_updated: {ISO-8601}
79
79
  ## Story Outcomes (compact — max 2 lines per story)
80
80
  ```
81
81
 
82
+ ### Step 3b: Initial PM Review
83
+
84
+ If `{pm_enabled}` is true:
85
+
86
+ 1. Read and follow `.valent-pipeline/steps/orchestration/sprint-pm-review.md` with `{sprint_number}` = 1 and `{is_project_mode}` = true.
87
+ 2. PM reads ALL PRDs across all epics and builds a unified cross-epic FR coverage map. Each FR is tagged with its source epic so gaps route to the correct epic for story generation.
88
+ 3. PM processes any pre-run messages in `{pm_inbox_path}`.
89
+ 4. PM validates backlog priority ordering against product value across all epics and may reprioritize.
90
+ 5. PM sends `[BACKLOG-UPDATE]` — re-read `{backlog_path}` after PM's update.
91
+ 6. PM stays alive into Step 4d (grooming) for FR-tag oversight.
92
+
82
93
  ### Step 4: Sprint Loop
83
94
 
84
95
  Loop sprints until all stories are shipped, blocked, or cancelled. Each sprint follows the cycle: **groom → size → plan → execute → review → retro**.
@@ -117,7 +128,7 @@ BEND/FEND estimate Fibonacci points per story (filtered by `testing_profiles`).
117
128
 
118
129
  Read and follow `.valent-pipeline/steps/orchestration/sprint-plan.md`.
119
130
 
120
- Pack stories into sprint capacity by priority (cross-epic). Write `sprint-{n}-plan.md` and `sprint-{n}-status.yaml`. Kill Phase 1 agents (except Knowledge).
131
+ Pack stories into sprint capacity by priority (cross-epic). Write `sprint-{n}-plan.md` and `sprint-{n}-status.yaml`. Kill Phase 1 agents (except Knowledge). PM teardown occurs during sprint-groom.md Step 6b (before sizing).
121
132
 
122
133
  #### 4g. Sprint Execution
123
134
 
@@ -158,6 +169,14 @@ Context compression may fire here — that is expected. The PostCompact hook re-
158
169
 
159
170
  When all stories are shipped (or remaining are all blocked/cancelled):
160
171
 
172
+ #### 5 (pre). PM Final Audit
173
+
174
+ If `{pm_enabled}` is true:
175
+
176
+ Read and follow `.valent-pipeline/steps/orchestration/sprint-pm-audit.md`.
177
+
178
+ PM spawns one final time with `{is_project_mode}` = true, reads all PRDs, performs full cross-epic FR coverage reconciliation, resolves weak-coverage items (blockers), writes `prd-audit-report.md`, and tears down. Include PM's audit summary in the project report below.
179
+
161
180
  #### 5a. Write Project Report
162
181
 
163
182
  Write `project-report.md` adjacent to `{epic_progress_path}`:
@@ -82,6 +82,19 @@ export function validateConfig(config) {
82
82
  }
83
83
  }
84
84
 
85
+ // PM section (optional)
86
+ if (config.pm) {
87
+ if (config.pm.enabled !== undefined && typeof config.pm.enabled !== 'boolean') {
88
+ errors.push(`pm.enabled must be a boolean, got: ${typeof config.pm.enabled}`);
89
+ }
90
+ if (config.pm.auto_reprioritize !== undefined && typeof config.pm.auto_reprioritize !== 'boolean') {
91
+ errors.push(`pm.auto_reprioritize must be a boolean, got: ${typeof config.pm.auto_reprioritize}`);
92
+ }
93
+ if (config.pm.auto_generate_gap_stories !== undefined && typeof config.pm.auto_generate_gap_stories !== 'boolean') {
94
+ errors.push(`pm.auto_generate_gap_stories must be a boolean, got: ${typeof config.pm.auto_generate_gap_stories}`);
95
+ }
96
+ }
97
+
85
98
  if (config.knowledge?.mode === 'sqlite' && !config.knowledge?.sqlite_db_path) {
86
99
  errors.push('knowledge.sqlite_db_path is required when knowledge.mode is "sqlite"');
87
100
  }
@@ -115,7 +128,7 @@ export const defaults = {
115
128
  state_management: 'React Context',
116
129
  },
117
130
  models: {
118
- opus: ['BEND', 'FEND', 'CRITIC'],
131
+ opus: ['BEND', 'FEND', 'CRITIC', 'PM'],
119
132
  sonnet: ['REQS', 'UXA', 'QA-A', 'QA-B', 'READINESS', 'JUDGE', 'PMCP', 'Retrospective', 'DATA', 'MCP-DEV', 'LIBDEV', 'DOCGEN', 'IAC'],
120
133
  haiku: ['Knowledge', 'Embed', 'Help'],
121
134
  },
@@ -150,4 +163,9 @@ export const defaults = {
150
163
  recommended_context_window: '200k',
151
164
  epic_progress_path: './epic-progress.md',
152
165
  },
166
+ pm: {
167
+ enabled: true,
168
+ auto_reprioritize: true,
169
+ auto_generate_gap_stories: false,
170
+ },
153
171
  };