create-agentic-pdlc 2.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agentic-pdlc/hooks/pdlc-stage-gate.sh +37 -10
- package/.agentic-pdlc/metrics/raw/2026-W22.jsonl +114 -0
- package/.claude/settings.json +18 -0
- package/.coderabbit.yaml +35 -0
- package/.github/ISSUE_TEMPLATE/bug.md +53 -0
- package/.github/ISSUE_TEMPLATE/feature.md +54 -0
- package/.github/ISSUE_TEMPLATE/task.md +33 -0
- package/.github/workflows/add-to-board.yml +1 -1
- package/.github/workflows/agent-trigger.yml +4 -4
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/npm-publish.yml +2 -2
- package/.github/workflows/pdlc-health-check.yml +1 -1
- package/.github/workflows/pdlc-stage-gate.yml +2 -2
- package/.github/workflows/project-automation.yml +25 -40
- package/AGENTS.md +50 -8
- package/CLAUDE.md +3 -1
- package/README.md +33 -32
- package/SETUP.md +2 -1
- package/adapters/claude-code/skill.md +39 -14
- package/adapters/hooks/pdlc-stage-gate.sh +3 -8
- package/bin/cli.js +555 -194
- package/docs/pdlc.md +5 -5
- package/docs/superpowers/plans/2026-05-28-jules-label-pat-split.md +240 -0
- package/docs/superpowers/plans/2026-05-29-agentic-pulse-rework-taxonomy.md +474 -0
- package/docs/superpowers/plans/2026-05-29-qa-gate-enforcement.md +354 -0
- package/docs/superpowers/plans/2026-06-04-spec-format-issue-template.md +160 -0
- package/docs/superpowers/plans/2026-06-04-two-tier-installer.md +1056 -0
- package/docs/superpowers/specs/2026-05-29-agentic-pulse-rework-taxonomy-design.md +122 -0
- package/docs/superpowers/specs/2026-06-04-spec-format-issue-template-design.md +46 -0
- package/package.json +2 -2
- package/templates/.github/ISSUE_TEMPLATE/bug.md +53 -0
- package/templates/.github/ISSUE_TEMPLATE/feature.md +54 -0
- package/templates/.github/ISSUE_TEMPLATE/task.md +33 -0
- package/templates/.github/workflows/add-to-board.yml +4 -4
- package/templates/.github/workflows/agent-trigger.yml +22 -13
- package/{.agentic-pdlc/templates → templates}/.github/workflows/agentic-metrics.yml +150 -27
- package/templates/.github/workflows/ci.yml +1 -1
- package/templates/.github/workflows/pdlc-health-check.yml +1 -1
- package/templates/.github/workflows/pdlc-stage-gate.yml +2 -2
- package/templates/.github/workflows/project-automation.yml +71 -32
- package/templates/.github/workflows/qa-agent.yml +32 -18
- package/templates/.github/workflows/qa-gate.yml +51 -0
- package/templates/full/AGENTS.md +143 -0
- package/templates/full/CLAUDE.md +30 -0
- package/templates/{docs → full/docs}/pdlc.md +4 -4
- package/templates/lite/AGENTS.md +121 -0
- package/templates/lite/CLAUDE.md +44 -0
- package/tests/cli.test.js +32 -0
- package/.agentic-pdlc/templates/.github/CODEOWNERS +0 -5
- package/.agentic-pdlc/templates/.github/copilot-instructions.md +0 -12
- package/.agentic-pdlc/templates/.github/workflows/add-to-board.yml +0 -38
- package/.agentic-pdlc/templates/.github/workflows/agent-trigger.yml +0 -146
- package/.agentic-pdlc/templates/.github/workflows/auto-approve.yml +0 -16
- package/.agentic-pdlc/templates/.github/workflows/ci.yml +0 -54
- package/.agentic-pdlc/templates/.github/workflows/pdlc-health-check.yml +0 -121
- package/.agentic-pdlc/templates/.github/workflows/pdlc-stage-gate.yml +0 -51
- package/.agentic-pdlc/templates/.github/workflows/project-automation.yml +0 -274
- package/.agentic-pdlc/templates/.github/workflows/protect-workflows.yml +0 -21
- package/.agentic-pdlc/templates/.github/workflows/qa-agent.yml +0 -128
- package/.agentic-pdlc/templates/AGENTS.md +0 -104
- package/.agentic-pdlc/templates/docs/pdlc.md +0 -123
- package/.github/workflows/agentic-metrics.yml +0 -422
- package/.github/workflows/qa-agent.yml +0 -128
- package/templates/AGENTS.md +0 -115
|
@@ -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
|
+
```
|