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.
- package/package.json +1 -1
- package/pipeline/agents-manifest.yaml +11 -0
- package/pipeline/docs/pm-agent-design.md +880 -0
- package/pipeline/docs/prd-completion-audit-design.md +132 -0
- package/pipeline/prompts/pm.md +292 -0
- package/pipeline/steps/orchestration/load-pipeline-config.md +6 -0
- package/pipeline/steps/orchestration/sprint-execute.md +22 -0
- package/pipeline/steps/orchestration/sprint-groom.md +4 -0
- package/pipeline/steps/orchestration/sprint-init.md +5 -2
- package/pipeline/steps/orchestration/sprint-plan.md +9 -3
- package/pipeline/steps/orchestration/sprint-pm-audit.md +46 -0
- package/pipeline/steps/orchestration/sprint-pm-review.md +71 -0
- package/pipeline/steps/orchestration/sprint-pm-teardown.md +22 -0
- package/pipeline/steps/orchestration/sprint-review.md +12 -3
- package/skills/valent-pm/SKILL.md +121 -0
- package/skills/valent-run-epic/SKILL.md +20 -1
- package/skills/valent-run-project/SKILL.md +20 -1
- package/src/lib/config-schema.js +19 -1
|
@@ -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}`:
|
package/src/lib/config-schema.js
CHANGED
|
@@ -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
|
};
|