create-agentic-pdlc 2.3.0 → 2.4.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 (53) hide show
  1. package/.agentic-pdlc/metrics/raw/2026-W22.jsonl +114 -0
  2. package/.github/ISSUE_TEMPLATE/bug.md +53 -0
  3. package/.github/ISSUE_TEMPLATE/feature.md +54 -0
  4. package/.github/ISSUE_TEMPLATE/task.md +33 -0
  5. package/.github/workflows/add-to-board.yml +1 -1
  6. package/.github/workflows/agent-trigger.yml +4 -4
  7. package/.github/workflows/agentic-metrics.yml +150 -27
  8. package/.github/workflows/ci.yml +1 -1
  9. package/.github/workflows/npm-publish.yml +2 -2
  10. package/.github/workflows/pdlc-health-check.yml +1 -1
  11. package/.github/workflows/pdlc-stage-gate.yml +2 -2
  12. package/.github/workflows/project-automation.yml +51 -12
  13. package/.github/workflows/qa-agent.yml +22 -11
  14. package/.github/workflows/qa-gate.yml +51 -0
  15. package/AGENTS.md +50 -8
  16. package/CLAUDE.md +2 -0
  17. package/SETUP.md +2 -1
  18. package/adapters/claude-code/skill.md +32 -11
  19. package/adapters/hooks/pdlc-stage-gate.sh +3 -8
  20. package/bin/cli.js +23 -2
  21. package/docs/pdlc.md +5 -5
  22. package/docs/superpowers/plans/2026-05-28-jules-label-pat-split.md +240 -0
  23. package/docs/superpowers/plans/2026-05-29-agentic-pulse-rework-taxonomy.md +474 -0
  24. package/docs/superpowers/plans/2026-05-29-qa-gate-enforcement.md +354 -0
  25. package/docs/superpowers/specs/2026-05-29-agentic-pulse-rework-taxonomy-design.md +122 -0
  26. package/package.json +1 -1
  27. package/templates/.github/ISSUE_TEMPLATE/bug.md +53 -0
  28. package/templates/.github/ISSUE_TEMPLATE/feature.md +54 -0
  29. package/templates/.github/ISSUE_TEMPLATE/task.md +33 -0
  30. package/templates/.github/workflows/add-to-board.yml +4 -4
  31. package/templates/.github/workflows/agent-trigger.yml +22 -13
  32. package/{.agentic-pdlc/templates → templates}/.github/workflows/agentic-metrics.yml +150 -27
  33. package/templates/.github/workflows/ci.yml +1 -1
  34. package/templates/.github/workflows/pdlc-health-check.yml +1 -1
  35. package/templates/.github/workflows/pdlc-stage-gate.yml +2 -2
  36. package/templates/.github/workflows/project-automation.yml +71 -32
  37. package/templates/.github/workflows/qa-agent.yml +32 -18
  38. package/templates/.github/workflows/qa-gate.yml +51 -0
  39. package/templates/AGENTS.md +57 -29
  40. package/templates/docs/pdlc.md +4 -4
  41. package/.agentic-pdlc/templates/.github/CODEOWNERS +0 -5
  42. package/.agentic-pdlc/templates/.github/copilot-instructions.md +0 -12
  43. package/.agentic-pdlc/templates/.github/workflows/add-to-board.yml +0 -38
  44. package/.agentic-pdlc/templates/.github/workflows/agent-trigger.yml +0 -146
  45. package/.agentic-pdlc/templates/.github/workflows/auto-approve.yml +0 -16
  46. package/.agentic-pdlc/templates/.github/workflows/ci.yml +0 -54
  47. package/.agentic-pdlc/templates/.github/workflows/pdlc-health-check.yml +0 -121
  48. package/.agentic-pdlc/templates/.github/workflows/pdlc-stage-gate.yml +0 -51
  49. package/.agentic-pdlc/templates/.github/workflows/project-automation.yml +0 -274
  50. package/.agentic-pdlc/templates/.github/workflows/protect-workflows.yml +0 -21
  51. package/.agentic-pdlc/templates/.github/workflows/qa-agent.yml +0 -128
  52. package/.agentic-pdlc/templates/AGENTS.md +0 -104
  53. package/.agentic-pdlc/templates/docs/pdlc.md +0 -123
@@ -0,0 +1,474 @@
1
+ # Agentic Pulse — Rework Taxonomy Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Extend `agentic-metrics.yml` to classify rework by review actor (code_reviewer, qa_agent, self_correction) and optionally surface a stage correlation signal when N≥3 data points exist.
6
+
7
+ **Architecture:** All logic is inline JavaScript inside an existing `actions/github-script@v7` step. Add an `env:` block for actor configuration, preload JSONL detailing data at step start, extend the rework detection loop to fetch PR reviews and classify by configured actor, then replace the rework signal output with a taxonomy breakdown plus an optional stage correlation line.
8
+
9
+ **Tech Stack:** GitHub Actions YAML, `actions/github-script@v7` (Node.js 20), GitHub REST API (`pulls.listReviews`), existing `.agentic-pdlc/metrics/raw/WEEK.jsonl` files.
10
+
11
+ ---
12
+
13
+ ### Task 1: Add `env` block with `AGENTIC_PULSE_REVIEWERS`
14
+
15
+ **Files:**
16
+ - Modify: `.github/workflows/agentic-metrics.yml:10` (after `issues: write`)
17
+
18
+ - [ ] **Step 1: Open the file and locate the `permissions` block**
19
+
20
+ In `.github/workflows/agentic-metrics.yml`, find:
21
+ ```yaml
22
+ permissions:
23
+ contents: write
24
+ issues: write
25
+
26
+ jobs:
27
+ ```
28
+
29
+ - [ ] **Step 2: Insert `env:` block between `permissions` and `jobs`**
30
+
31
+ Replace:
32
+ ```yaml
33
+ permissions:
34
+ contents: write
35
+ issues: write
36
+
37
+ jobs:
38
+ ```
39
+
40
+ With:
41
+ ```yaml
42
+ permissions:
43
+ contents: write
44
+ issues: write
45
+
46
+ env:
47
+ AGENTIC_PULSE_REVIEWERS: |
48
+ code_reviewer=gemini-code-assist[bot]
49
+ qa_agent=github-actions[bot]
50
+
51
+ jobs:
52
+ ```
53
+
54
+ - [ ] **Step 3: Verify YAML is valid**
55
+
56
+ ```bash
57
+ python3 -c "import yaml, sys; yaml.safe_load(open('.github/workflows/agentic-metrics.yml'))" && echo "YAML OK"
58
+ ```
59
+ Expected: `YAML OK`
60
+
61
+ - [ ] **Step 4: Commit**
62
+
63
+ ```bash
64
+ git add .github/workflows/agentic-metrics.yml
65
+ git commit -m "feat(pulse): add AGENTIC_PULSE_REVIEWERS env configuration"
66
+ ```
67
+
68
+ ---
69
+
70
+ ### Task 2: Preload JSONL detailing data at step start
71
+
72
+ **Files:**
73
+ - Modify: `.github/workflows/agentic-metrics.yml:112` (after `const weekKey = process.env.WEEK_KEY;`)
74
+
75
+ The stage correlation needs `detailingByIssue` (issue number → detailing days). Currently the JSONL is only read inside the `stageSection` block at the bottom. We preload it here so the rework block can use it without a second read.
76
+
77
+ - [ ] **Step 1: Locate insertion point**
78
+
79
+ In `.github/workflows/agentic-metrics.yml`, find this line (around line 112):
80
+ ```javascript
81
+ const weekKey = process.env.WEEK_KEY;
82
+
83
+ // ── Helper ──────────────────────────────────────────────────────
84
+ ```
85
+
86
+ - [ ] **Step 2: Insert detailing preload between `weekKey` and helpers**
87
+
88
+ Replace:
89
+ ```javascript
90
+ const weekKey = process.env.WEEK_KEY;
91
+
92
+ // ── Helper ──────────────────────────────────────────────────────
93
+ ```
94
+
95
+ With:
96
+ ```javascript
97
+ const weekKey = process.env.WEEK_KEY;
98
+
99
+ // ── Preload stage:detailing times for stage correlation ──────────
100
+ const detailingByIssue = {};
101
+ const jsonlPath = `.agentic-pdlc/metrics/raw/${weekKey}.jsonl`;
102
+ if (fs.existsSync(jsonlPath)) {
103
+ const rawLines = fs.readFileSync(jsonlPath, 'utf8').trim().split('\n').filter(Boolean);
104
+ for (const line of rawLines) {
105
+ const r = JSON.parse(line);
106
+ if (r.stage === 'stage:detailing') {
107
+ if (detailingByIssue[r.issueNumber] === undefined || r.durationDays > detailingByIssue[r.issueNumber]) {
108
+ detailingByIssue[r.issueNumber] = r.durationDays;
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ // ── Helper ──────────────────────────────────────────────────────
115
+ ```
116
+
117
+ - [ ] **Step 3: Verify YAML is valid**
118
+
119
+ ```bash
120
+ python3 -c "import yaml, sys; yaml.safe_load(open('.github/workflows/agentic-metrics.yml'))" && echo "YAML OK"
121
+ ```
122
+ Expected: `YAML OK`
123
+
124
+ - [ ] **Step 4: Commit**
125
+
126
+ ```bash
127
+ git add .github/workflows/agentic-metrics.yml
128
+ git commit -m "feat(pulse): preload JSONL detailing data for stage correlation"
129
+ ```
130
+
131
+ ---
132
+
133
+ ### Task 3: Add actor map parsing after `const signals = []`
134
+
135
+ **Files:**
136
+ - Modify: `.github/workflows/agentic-metrics.yml:139` (after `const signals = [];`)
137
+
138
+ - [ ] **Step 1: Locate insertion point**
139
+
140
+ In `.github/workflows/agentic-metrics.yml`, find:
141
+ ```javascript
142
+ // ── Signal collection ───────────────────────────────────────────
143
+ const signals = [];
144
+
145
+ // 1. Orphan issues: open >14 days with no linked PR
146
+ ```
147
+
148
+ - [ ] **Step 2: Insert actor map parsing**
149
+
150
+ Replace:
151
+ ```javascript
152
+ // ── Signal collection ───────────────────────────────────────────
153
+ const signals = [];
154
+
155
+ // 1. Orphan issues: open >14 days with no linked PR
156
+ ```
157
+
158
+ With:
159
+ ```javascript
160
+ // ── Signal collection ───────────────────────────────────────────
161
+ const signals = [];
162
+
163
+ // ── Review actor map (from AGENTIC_PULSE_REVIEWERS env var) ─────
164
+ const actorMap = {}; // login → role
165
+ const reviewersEnv = (process.env.AGENTIC_PULSE_REVIEWERS || '').trim();
166
+ if (reviewersEnv) {
167
+ for (const line of reviewersEnv.split('\n')) {
168
+ const eq = line.indexOf('=');
169
+ if (eq < 0) continue;
170
+ const role = line.slice(0, eq).trim();
171
+ const logins = line.slice(eq + 1).trim();
172
+ for (const login of logins.split(',').map(l => l.trim()).filter(Boolean)) {
173
+ actorMap[login] = role;
174
+ }
175
+ }
176
+ }
177
+ const taxonomyEnabled = Object.keys(actorMap).length > 0;
178
+
179
+ // 1. Orphan issues: open >14 days with no linked PR
180
+ ```
181
+
182
+ - [ ] **Step 3: Verify YAML is valid**
183
+
184
+ ```bash
185
+ python3 -c "import yaml, sys; yaml.safe_load(open('.github/workflows/agentic-metrics.yml'))" && echo "YAML OK"
186
+ ```
187
+ Expected: `YAML OK`
188
+
189
+ - [ ] **Step 4: Commit**
190
+
191
+ ```bash
192
+ git add .github/workflows/agentic-metrics.yml
193
+ git commit -m "feat(pulse): parse AGENTIC_PULSE_REVIEWERS into actorMap"
194
+ ```
195
+
196
+ ---
197
+
198
+ ### Task 4: Replace rework block with taxonomy + stage correlation
199
+
200
+ **Files:**
201
+ - Modify: `.github/workflows/agentic-metrics.yml:227-278` (the `// 3. Rework rate` block)
202
+
203
+ This is the main change. The existing rework block (lines 227–278) is replaced in full.
204
+
205
+ - [ ] **Step 1: Locate the block to replace**
206
+
207
+ Find this exact comment to identify the start:
208
+ ```javascript
209
+ // 3. Rework rate: commits per PR — single push session = first-shot
210
+ ```
211
+
212
+ The block ends just before:
213
+ ```javascript
214
+ // 4. Unlinked PRs: merged without Closes/Fixes #N
215
+ ```
216
+
217
+ - [ ] **Step 2: Replace the entire rework block**
218
+
219
+ Remove everything from `// 3. Rework rate:` through the closing `}` before `// 4. Unlinked PRs:`, and replace with:
220
+
221
+ ```javascript
222
+ // 3. Rework rate with actor taxonomy (if AGENTIC_PULSE_REVIEWERS configured)
223
+ const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
224
+ const weekMerged = recentPRs.filter(pr => pr.merged_at && new Date(pr.merged_at) > weekAgo);
225
+
226
+ if (weekMerged.length > 0) {
227
+ let firstShots = 0;
228
+ const reworkByRole = {};
229
+ const reworkDetails = []; // { pr_number, issue_number } for stage correlation
230
+ const issueRe = /(?:closes?|fixes?|resolves?)\s+#(\d+)/i;
231
+
232
+ for (const pr of weekMerged.slice(0, 10)) {
233
+ try {
234
+ const commits = await github.rest.pulls.listCommits({
235
+ owner, repo, pull_number: pr.number, per_page: 100
236
+ });
237
+ const times = commits.data
238
+ .map(c => new Date(c.commit.committer.date).getTime())
239
+ .sort((a, b) => a - b);
240
+
241
+ let sessions = 1;
242
+ for (let i = 1; i < times.length; i++) {
243
+ if (times[i] - times[i-1] > 10 * 60 * 1000) sessions++;
244
+ }
245
+
246
+ if (sessions === 1) { firstShots++; continue; }
247
+
248
+ if (!taxonomyEnabled) continue;
249
+
250
+ let reviewTriggered = false;
251
+ try {
252
+ const reviews = await github.rest.pulls.listReviews({
253
+ owner, repo, pull_number: pr.number, per_page: 100
254
+ });
255
+ for (const review of reviews.data) {
256
+ const role = actorMap[review.user.login];
257
+ if (!role) continue;
258
+ const reviewTime = new Date(review.submitted_at).getTime();
259
+ if (times.some(t => t > reviewTime)) {
260
+ reworkByRole[role] = (reworkByRole[role] || 0) + 1;
261
+ reviewTriggered = true;
262
+ const m = issueRe.exec(pr.body || '');
263
+ if (m) reworkDetails.push({ pr_number: pr.number, issue_number: parseInt(m[1]) });
264
+ }
265
+ }
266
+ } catch(e) { /* reviews not accessible — skip taxonomy for this PR */ }
267
+
268
+ if (!reviewTriggered) {
269
+ reworkByRole.self_correction = (reworkByRole.self_correction || 0) + 1;
270
+ }
271
+
272
+ } catch (e) { /* skip if commits not accessible */ }
273
+ }
274
+
275
+ const total = Math.min(weekMerged.length, 10);
276
+ const pct = Math.round(firstShots / total * 100);
277
+ const reworkCount = total - firstShots;
278
+
279
+ const agentLabels = new Set(['jules', 'sweep', 'codex', 'copilot']);
280
+ const usesAgent = weekMerged.some(pr =>
281
+ (pr.labels || []).some(l => agentLabels.has(l.name.toLowerCase()))
282
+ );
283
+ const subject = usesAgent ? 'Agent first-shot rate' : 'PRs sem rework';
284
+ const verb = usesAgent ? 'acertaram de primeira' : 'foram mergeados sem rework';
285
+
286
+ if (taxonomyEnabled && reworkCount > 0) {
287
+ const lines = [];
288
+ for (const [role, count] of Object.entries(reworkByRole)) {
289
+ const s = count > 1 ? 's' : '';
290
+ if (role === 'code_reviewer') lines.push(` ↳ Code reviewer: **${count} PR${s}** → revisar DoD em stage:development`);
291
+ else if (role === 'qa_agent') lines.push(` ↳ QA Agent: **${count} PR${s}** → spec com lacunas funcionais em stage:detailing`);
292
+ else if (role === 'self_correction') lines.push(` ↳ Self-correction: **${count} PR${s}** (causa não determinada automaticamente)`);
293
+ else lines.push(` ↳ ${role}: **${count} PR${s}**`);
294
+ }
295
+
296
+ const reviewerRework = reworkByRole.code_reviewer || 0;
297
+ const level = reviewerRework >= Math.ceil(reworkCount * 0.8) ? 'red'
298
+ : (reviewerRework >= Math.ceil(reworkCount * 0.5) || (reworkByRole.qa_agent || 0) > 0) ? 'yellow'
299
+ : 'neutral';
300
+ const emoji = level === 'red' ? '🔴' : level === 'yellow' ? '🟡' : '🔵';
301
+
302
+ signals.push({
303
+ level,
304
+ emoji,
305
+ title: `**Rework: ${100 - pct}%** — ${reworkCount} de ${total} PRs tiveram commits extras`,
306
+ body: lines.join('\n')
307
+ });
308
+
309
+ // ── Stage correlation ────────────────────────────────────────
310
+ if (reworkDetails.length > 0 && Object.keys(detailingByIssue).length > 0) {
311
+ const reworkIssueNums = new Set(reworkDetails.map(d => d.issue_number));
312
+
313
+ const reworkGroup = reworkDetails
314
+ .map(d => detailingByIssue[d.issue_number])
315
+ .filter(t => t !== undefined);
316
+
317
+ const cleanGroup = weekMerged.slice(0, 10)
318
+ .map(pr => { const m = issueRe.exec(pr.body || ''); return m ? parseInt(m[1]) : null; })
319
+ .filter(n => n !== null && !reworkIssueNums.has(n))
320
+ .map(n => detailingByIssue[n])
321
+ .filter(t => t !== undefined);
322
+
323
+ if (reworkGroup.length >= 3 && cleanGroup.length >= 3) {
324
+ const avgRework = round1(reworkGroup.reduce((a, b) => a + b, 0) / reworkGroup.length);
325
+ const avgClean = round1(cleanGroup.reduce((a, b) => a + b, 0) / cleanGroup.length);
326
+ if (avgRework < avgClean * 0.75) {
327
+ signals.push({
328
+ level: 'neutral',
329
+ emoji: '💡',
330
+ title: `**Stage correlation:** PRs com reviewer rework tiveram Detailing médio de ${avgRework}d vs ${avgClean}d (N=${reworkGroup.length} vs ${cleanGroup.length})`,
331
+ body: '→ Specs rápidas correlacionam com mais rework de review'
332
+ });
333
+ }
334
+ }
335
+ }
336
+
337
+ } else {
338
+ // Taxonomy disabled or no rework — existing signal unchanged
339
+ if (pct >= 80) {
340
+ signals.push({
341
+ level: 'green', emoji: '🟢',
342
+ title: `**${subject}: ${pct}%**`,
343
+ body: `${firstShots} de ${total} PRs ${verb} esta semana. ✅`
344
+ });
345
+ } else if (pct < 50) {
346
+ signals.push({
347
+ level: 'yellow', emoji: '🟡',
348
+ title: `**${subject}: ${pct}% — rework alto**`,
349
+ body: `Apenas ${firstShots} de ${total} PRs sem commits extras.\n→ Specs incompletas ou mudanças de requisito durante implementação.`
350
+ });
351
+ } else {
352
+ signals.push({
353
+ level: 'neutral', emoji: '🔵',
354
+ title: `**${subject}: ${pct}%**`,
355
+ body: `${firstShots} de ${total} PRs sem rework commits.`
356
+ });
357
+ }
358
+ }
359
+ }
360
+ ```
361
+
362
+ - [ ] **Step 3: Verify YAML is valid**
363
+
364
+ ```bash
365
+ python3 -c "import yaml, sys; yaml.safe_load(open('.github/workflows/agentic-metrics.yml'))" && echo "YAML OK"
366
+ ```
367
+ Expected: `YAML OK`
368
+
369
+ - [ ] **Step 4: Commit**
370
+
371
+ ```bash
372
+ git add .github/workflows/agentic-metrics.yml
373
+ git commit -m "feat(pulse): rework taxonomy with review-actor attribution and stage correlation"
374
+ ```
375
+
376
+ ---
377
+
378
+ ### Task 5: Mirror all changes to `templates/`
379
+
380
+ **Files:**
381
+ - Modify: `templates/.github/workflows/agentic-metrics.yml`
382
+
383
+ Note: the templates file has two pre-existing minor diffs vs the main file (lines 313 and 317–320 in the stageSection block). Do NOT touch those lines — apply only the four changes from Tasks 1–4.
384
+
385
+ - [ ] **Step 1: Apply Task 1 change (env block)**
386
+
387
+ In `templates/.github/workflows/agentic-metrics.yml`, apply the same `env:` block insertion as Task 1 Step 2.
388
+
389
+ - [ ] **Step 2: Apply Task 2 change (JSONL preload)**
390
+
391
+ In `templates/.github/workflows/agentic-metrics.yml`, apply the same preload insertion as Task 2 Step 2.
392
+
393
+ - [ ] **Step 3: Apply Task 3 change (actor map parsing)**
394
+
395
+ In `templates/.github/workflows/agentic-metrics.yml`, apply the same actor map insertion as Task 3 Step 2.
396
+
397
+ - [ ] **Step 4: Apply Task 4 change (rework block replacement)**
398
+
399
+ In `templates/.github/workflows/agentic-metrics.yml`, apply the same rework block replacement as Task 4 Step 2.
400
+
401
+ - [ ] **Step 5: Verify YAML is valid**
402
+
403
+ ```bash
404
+ python3 -c "import yaml, sys; yaml.safe_load(open('templates/.github/workflows/agentic-metrics.yml'))" && echo "YAML OK"
405
+ ```
406
+ Expected: `YAML OK`
407
+
408
+ - [ ] **Step 6: Verify only expected diffs remain between the two files**
409
+
410
+ ```bash
411
+ diff .github/workflows/agentic-metrics.yml templates/.github/workflows/agentic-metrics.yml
412
+ ```
413
+ Expected: only the two pre-existing stageSection diffs (one line around `maxDays`, three lines around the `if (!days)` block). No new diffs.
414
+
415
+ - [ ] **Step 7: Commit**
416
+
417
+ ```bash
418
+ git add templates/.github/workflows/agentic-metrics.yml
419
+ git commit -m "feat(pulse): mirror rework taxonomy changes to templates"
420
+ ```
421
+
422
+ ---
423
+
424
+ ### Task 6: Manual verification via workflow_dispatch
425
+
426
+ - [ ] **Step 1: Trigger the workflow manually**
427
+
428
+ ```bash
429
+ gh workflow run agentic-metrics.yml
430
+ ```
431
+
432
+ - [ ] **Step 2: Watch the run**
433
+
434
+ ```bash
435
+ gh run list --workflow=agentic-metrics.yml --limit 1
436
+ # Copy the run ID, then:
437
+ gh run watch <run-id>
438
+ ```
439
+
440
+ - [ ] **Step 3: Verify the pulse issue was created/updated**
441
+
442
+ ```bash
443
+ gh issue list --label "metrics:weekly" --state open --json number,title,body \
444
+ --jq '.[0] | "## \(.title)\n\(.body)"'
445
+ ```
446
+
447
+ Check that:
448
+ - Rework signal shows taxonomy breakdown (↳ Code reviewer / QA Agent / Self-correction lines)
449
+ - OR falls back to old format if no rework PRs were found this week
450
+ - Stage correlation line appears IF N≥3 in both groups (may not appear if data is thin)
451
+ - All other signals (orphans, merge time, unlinked PRs, Stage Residence Time) are unchanged
452
+
453
+ - [ ] **Step 4: Verify backward compatibility**
454
+
455
+ Temporarily set `AGENTIC_PULSE_REVIEWERS: ""` in the env block, re-run via `workflow_dispatch`, confirm the pulse issue shows the old-style rework signal (no taxonomy lines). Restore the env var after verification.
456
+
457
+ - [ ] **Step 5: Close issue and open PR**
458
+
459
+ ```bash
460
+ gh pr create \
461
+ --title "feat(pulse): rework taxonomy with review-actor attribution and stage correlation" \
462
+ --body "Closes #142
463
+
464
+ ## What changed
465
+ - Added \`AGENTIC_PULSE_REVIEWERS\` env var to configure review actors
466
+ - Extended rework detection to classify commits-after-review by actor role
467
+ - Added stage correlation signal when N≥3 data points in both groups
468
+ - Backward compatible: env var absent → existing rework signal unchanged
469
+ - Mirrored to \`templates/\`
470
+
471
+ ## Test
472
+ - Triggered workflow_dispatch, verified pulse issue output
473
+ - Verified backward compatibility with empty env var"
474
+ ```