create-agentic-pdlc 2.2.1 → 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.
- package/.agentic-pdlc/SETUP_PROMPT.md +3 -4
- package/.agentic-pdlc/metrics/raw/2026-W18.jsonl +2 -0
- package/.agentic-pdlc/metrics/raw/2026-W21.jsonl +68 -0
- package/.agentic-pdlc/metrics/raw/2026-W22.jsonl +114 -0
- package/.agentic-setup-prompt.md +3 -4
- package/.agentic-setup.md +3 -4
- 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/agentic-metrics.yml +171 -38
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/npm-publish.yml +2 -2
- package/.github/workflows/pdlc-health-check.yml +1 -3
- package/.github/workflows/pdlc-stage-gate.yml +2 -2
- package/.github/workflows/project-automation.yml +79 -16
- package/.github/workflows/qa-agent.yml +26 -15
- package/.github/workflows/qa-gate.yml +51 -0
- package/AGENTS.md +50 -8
- package/CLAUDE.md +53 -3
- package/SETUP.md +4 -1
- package/adapters/claude-code/skill.md +44 -20
- package/adapters/hooks/pdlc-stage-gate.sh +2 -7
- package/bin/cli.js +41 -9
- package/docs/flow.md +8 -21
- package/docs/pdlc.md +24 -16
- 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/specs/2026-05-29-agentic-pulse-rework-taxonomy-design.md +122 -0
- package/package.json +1 -1
- 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 +24 -15
- package/{.agentic-pdlc/templates → templates}/.github/workflows/agentic-metrics.yml +166 -36
- package/templates/.github/workflows/ci.yml +15 -1
- package/templates/.github/workflows/pdlc-health-check.yml +1 -3
- package/templates/.github/workflows/pdlc-stage-gate.yml +2 -2
- package/templates/.github/workflows/project-automation.yml +93 -36
- package/templates/.github/workflows/qa-agent.yml +33 -17
- package/templates/.github/workflows/qa-gate.yml +51 -0
- package/templates/AGENTS.md +74 -23
- package/templates/docs/pdlc.md +24 -16
- 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 -40
- package/.agentic-pdlc/templates/.github/workflows/pdlc-health-check.yml +0 -123
- package/.agentic-pdlc/templates/.github/workflows/pdlc-stage-gate.yml +0 -51
- package/.agentic-pdlc/templates/.github/workflows/project-automation.yml +0 -278
- 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 -81
- package/.agentic-pdlc/templates/docs/pdlc.md +0 -115
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# QA Gate Enforcement 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:** Block PR merges when QA Agent failed or hasn't run, by (A) making `qa-agent.yml` emit a failing exit code on infra/parse errors and (C) adding a dedicated `qa-gate.yml` status check that enforces label-based QA state — backed by branch protection configured automatically during `npx create-agentic-pdlc`.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Two independent layers. Layer A: `qa-agent.yml` stops signalling success (`exit 0`) when it can't reach GitHub Models — now exits 1, making the check red. Layer C: `qa-gate.yml` is a separate required check that reads PR labels and blocks merge unless `qa:approved` is present. Branch protection wires both checks as required, enforced automatically in `cli.js` during scaffold.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** GitHub Actions YAML (bash), Node.js (cli.js)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## File Map
|
|
14
|
+
|
|
15
|
+
| Action | File | Responsibility |
|
|
16
|
+
|--------|------|----------------|
|
|
17
|
+
| Modify | `.github/workflows/qa-agent.yml:66-69` and `:82-84` | Change `exit 0` → `exit 1` on API error and parse error |
|
|
18
|
+
| Modify | `templates/.github/workflows/qa-agent.yml:63-66` and `:79-81` | Same fix in template |
|
|
19
|
+
| Create | `.github/workflows/qa-gate.yml` | Blocking check — reads PR labels, fails unless `qa:approved` |
|
|
20
|
+
| Create | `templates/.github/workflows/qa-gate.yml` | Template mirror of above |
|
|
21
|
+
| Modify | `bin/cli.js` | Add branch protection setup step after PAT provisioning |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
### Task 1: Fix `qa-agent.yml` exit codes (repo + template)
|
|
26
|
+
|
|
27
|
+
**Files:**
|
|
28
|
+
- Modify: `.github/workflows/qa-agent.yml`
|
|
29
|
+
- Modify: `templates/.github/workflows/qa-agent.yml`
|
|
30
|
+
|
|
31
|
+
Currently both files call `exit 0` when the GitHub Models API is unreachable or when the response can't be parsed. This makes the CI check green, hiding the failure.
|
|
32
|
+
|
|
33
|
+
- [ ] **Step 1: Fix exit code on API_ERROR in `.github/workflows/qa-agent.yml`**
|
|
34
|
+
|
|
35
|
+
Find this block (around line 63-69):
|
|
36
|
+
```yaml
|
|
37
|
+
if [ "$RESPONSE" = "API_ERROR" ]; then
|
|
38
|
+
GH_TOKEN="$PROJECT_TOKEN" gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --method POST -f 'labels[]=infra:qa-broken'
|
|
39
|
+
gh pr comment "$PR_NUMBER" --body "🤖 **QA Agent:** Could not reach GitHub Models API. Manual review required."
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Change to:
|
|
45
|
+
```yaml
|
|
46
|
+
if [ "$RESPONSE" = "API_ERROR" ]; then
|
|
47
|
+
GH_TOKEN="$PROJECT_TOKEN" gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --method POST -f 'labels[]=infra:qa-broken'
|
|
48
|
+
gh pr comment "$PR_NUMBER" --body "🤖 **QA Agent:** Could not reach GitHub Models API. Manual review required."
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- [ ] **Step 2: Fix exit code on parse error in `.github/workflows/qa-agent.yml`**
|
|
54
|
+
|
|
55
|
+
Find this block (around line 82-84):
|
|
56
|
+
```yaml
|
|
57
|
+
else
|
|
58
|
+
GH_TOKEN="$PROJECT_TOKEN" gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --method POST -f 'labels[]=infra:qa-broken'
|
|
59
|
+
gh pr comment "$PR_NUMBER" --body "🤖 **QA Agent:** Could not parse GitHub Models response. Manual review required."
|
|
60
|
+
fi
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Change to:
|
|
64
|
+
```yaml
|
|
65
|
+
else
|
|
66
|
+
GH_TOKEN="$PROJECT_TOKEN" gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --method POST -f 'labels[]=infra:qa-broken'
|
|
67
|
+
gh pr comment "$PR_NUMBER" --body "🤖 **QA Agent:** Could not parse GitHub Models response. Manual review required."
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- [ ] **Step 3: Apply the same two fixes to `templates/.github/workflows/qa-agent.yml`**
|
|
73
|
+
|
|
74
|
+
The template uses `PROJECT_PAT` instead of `PROJECT_TOKEN` in the `GH_TOKEN=` prefix. The exit code change is identical.
|
|
75
|
+
|
|
76
|
+
In `templates/.github/workflows/qa-agent.yml`, find API_ERROR block (around line 63-66):
|
|
77
|
+
```yaml
|
|
78
|
+
if [ "$RESPONSE" = "API_ERROR" ]; then
|
|
79
|
+
GH_TOKEN="$PROJECT_PAT" gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --method POST -f 'labels[]=infra:qa-broken'
|
|
80
|
+
gh pr comment "$PR_NUMBER" --body "🤖 **QA Agent:** Could not reach GitHub Models API. Manual review required."
|
|
81
|
+
exit 0
|
|
82
|
+
fi
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Change to:
|
|
86
|
+
```yaml
|
|
87
|
+
if [ "$RESPONSE" = "API_ERROR" ]; then
|
|
88
|
+
GH_TOKEN="$PROJECT_PAT" gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --method POST -f 'labels[]=infra:qa-broken'
|
|
89
|
+
gh pr comment "$PR_NUMBER" --body "🤖 **QA Agent:** Could not reach GitHub Models API. Manual review required."
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Find parse error block (around line 79-81):
|
|
95
|
+
```yaml
|
|
96
|
+
else
|
|
97
|
+
GH_TOKEN="$PROJECT_PAT" gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --method POST -f 'labels[]=infra:qa-broken'
|
|
98
|
+
gh pr comment "$PR_NUMBER" --body "🤖 **QA Agent:** Could not parse GitHub Models response. Manual review required."
|
|
99
|
+
fi
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Change to:
|
|
103
|
+
```yaml
|
|
104
|
+
else
|
|
105
|
+
GH_TOKEN="$PROJECT_PAT" gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --method POST -f 'labels[]=infra:qa-broken'
|
|
106
|
+
gh pr comment "$PR_NUMBER" --body "🤖 **QA Agent:** Could not parse GitHub Models response. Manual review required."
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- [ ] **Step 4: Commit**
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git add .github/workflows/qa-agent.yml templates/.github/workflows/qa-agent.yml
|
|
115
|
+
git commit -m "fix(qa-agent): exit 1 on infra error and parse failure instead of exit 0"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### Task 2: Create `qa-gate.yml` — dedicated blocking check
|
|
121
|
+
|
|
122
|
+
**Files:**
|
|
123
|
+
- Create: `.github/workflows/qa-gate.yml`
|
|
124
|
+
- Create: `templates/.github/workflows/qa-gate.yml`
|
|
125
|
+
|
|
126
|
+
This is a new, independent status check. It triggers on PR events (including `labeled`/`unlabeled` so it re-evaluates when qa-agent adds labels). It reads PR labels and blocks merge unless `qa:approved` is present. Hotfix PRs bypass the gate (same pattern as `pdlc-stage-gate.yml`).
|
|
127
|
+
|
|
128
|
+
The GitHub Actions check name exposed to branch protection is derived from the `name:` field of the job: **`QA Gate`**.
|
|
129
|
+
|
|
130
|
+
- [ ] **Step 5: Create `.github/workflows/qa-gate.yml`**
|
|
131
|
+
|
|
132
|
+
Write this exact content:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
name: QA Gate
|
|
136
|
+
|
|
137
|
+
on:
|
|
138
|
+
pull_request:
|
|
139
|
+
types: [opened, synchronize, reopened, labeled, unlabeled]
|
|
140
|
+
|
|
141
|
+
permissions:
|
|
142
|
+
pull-requests: read
|
|
143
|
+
|
|
144
|
+
jobs:
|
|
145
|
+
qa-gate:
|
|
146
|
+
name: QA Gate
|
|
147
|
+
runs-on: ubuntu-latest
|
|
148
|
+
steps:
|
|
149
|
+
- name: Check QA status label
|
|
150
|
+
env:
|
|
151
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
152
|
+
run: |
|
|
153
|
+
set -e
|
|
154
|
+
PR_NUMBER="${{ github.event.pull_request.number }}"
|
|
155
|
+
REPO="${{ github.repository }}"
|
|
156
|
+
|
|
157
|
+
PR_LABELS=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json labels --jq '[.labels[].name] | join(" ")')
|
|
158
|
+
|
|
159
|
+
if echo "$PR_LABELS" | grep -qw "hotfix"; then
|
|
160
|
+
echo "✅ QA Gate: hotfix label — bypassed."
|
|
161
|
+
exit 0
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
if echo "$PR_LABELS" | grep -qw "qa:approved"; then
|
|
165
|
+
echo "✅ QA Gate: qa:approved — merge allowed."
|
|
166
|
+
exit 0
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
if echo "$PR_LABELS" | grep -qw "infra:qa-broken"; then
|
|
170
|
+
echo "❌ QA Gate: infra:qa-broken — GitHub Models API unreachable. Manual QA review required before merge."
|
|
171
|
+
exit 1
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
if echo "$PR_LABELS" | grep -qw "qa:needs-work"; then
|
|
175
|
+
echo "❌ QA Gate: qa:needs-work — acceptance criteria not fully met. Fix required before merge."
|
|
176
|
+
exit 1
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
echo "❌ QA Gate: no QA label found — AC Coverage Verification has not completed. Wait for the check to finish."
|
|
180
|
+
exit 1
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
- [ ] **Step 6: Create `templates/.github/workflows/qa-gate.yml`**
|
|
184
|
+
|
|
185
|
+
Write the exact same content as Step 5. The template is identical — it uses `GITHUB_TOKEN` only (no extra secrets needed for the gate check).
|
|
186
|
+
|
|
187
|
+
- [ ] **Step 7: Commit**
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
git add .github/workflows/qa-gate.yml templates/.github/workflows/qa-gate.yml
|
|
191
|
+
git commit -m "feat(qa-gate): add dedicated QA Gate blocking check for PR merges"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### Task 3: Add branch protection setup to `cli.js`
|
|
197
|
+
|
|
198
|
+
**Files:**
|
|
199
|
+
- Modify: `bin/cli.js`
|
|
200
|
+
|
|
201
|
+
Without branch protection, the new checks are informational only — engineers can still click "Merge". This task wires the two required checks (`PDLC Stage Gate` and `QA Gate`) automatically during `npx create-agentic-pdlc`.
|
|
202
|
+
|
|
203
|
+
The branch protection API call uses `gh api PUT repos/{repo}/branches/main/protection --input -` which reads a JSON payload from stdin. `execFileSync` with the `input` option handles this correctly. The call is non-fatal: if it fails (e.g., org policy restrictions, insufficient permissions), a warning is printed with manual instructions.
|
|
204
|
+
|
|
205
|
+
- [ ] **Step 8: Add i18n strings to `bin/cli.js`**
|
|
206
|
+
|
|
207
|
+
In the `i18n` object (around line 34), after the `update_sentinel_ask` entry, add:
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
configuring_protection: t('[3/3] Configuring branch protection...', '[3/3] Configurando proteção de branch...', '[3/3] Configurando protección de rama...'),
|
|
211
|
+
protection_ok: t('✅ Branch protection set — required checks: PDLC Stage Gate, QA Gate.', '✅ Proteção de branch configurada — checks obrigatórios: PDLC Stage Gate, QA Gate.', '✅ Protección de rama configurada — checks requeridos: PDLC Stage Gate, QA Gate.'),
|
|
212
|
+
protection_warn: t('⚠️ Branch protection could not be set automatically.\n Set required checks manually: Settings → Branches → main → Required status checks.\n Required: "PDLC Stage Gate" and "QA Gate"', '⚠️ Proteção de branch não pôde ser configurada automaticamente.\n Configure manualmente: Settings → Branches → main → Required status checks.\n Obrigatórios: "PDLC Stage Gate" e "QA Gate"', '⚠️ No se pudo configurar la protección de rama automáticamente.\n Configúralo en: Settings → Branches → main → Required status checks.\n Requeridos: "PDLC Stage Gate" y "QA Gate"'),
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
- [ ] **Step 9: Update step counters in `bin/cli.js`**
|
|
216
|
+
|
|
217
|
+
Find:
|
|
218
|
+
```javascript
|
|
219
|
+
creating_labels: t('[1/2] Creating repository labels...', '[1/2] Criando labels no repositório...', '[1/2] Creando etiquetas (labels) en el repositorio...'),
|
|
220
|
+
```
|
|
221
|
+
Change to:
|
|
222
|
+
```javascript
|
|
223
|
+
creating_labels: t('[1/3] Creating repository labels...', '[1/3] Criando labels no repositório...', '[1/3] Creando etiquetas (labels) en el repositorio...'),
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Find:
|
|
227
|
+
```javascript
|
|
228
|
+
creating_project: t('[2/2] Creating Project V2 Board...', '[2/2] Criando Project V2 Board...', '[2/2] Creando Project V2 Board...'),
|
|
229
|
+
```
|
|
230
|
+
Change to:
|
|
231
|
+
```javascript
|
|
232
|
+
creating_project: t('[2/3] Creating Project V2 Board...', '[2/3] Criando Project V2 Board...', '[2/3] Creando Project V2 Board...'),
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
- [ ] **Step 10: Add branch protection setup block to `bin/cli.js`**
|
|
236
|
+
|
|
237
|
+
Find the block that starts with the PAT auto-provision section and ends before the scaffolding section. After the closing brace of the PAT block (around line 356, after `} else if (projectId && isOrg) { ... }`), add:
|
|
238
|
+
|
|
239
|
+
```javascript
|
|
240
|
+
// Branch protection — require PDLC Stage Gate + QA Gate on main
|
|
241
|
+
console.log(`\n${cyan}${i18n.configuring_protection}${reset}`);
|
|
242
|
+
try {
|
|
243
|
+
const protectionPayload = JSON.stringify({
|
|
244
|
+
required_status_checks: {
|
|
245
|
+
strict: false,
|
|
246
|
+
contexts: ['PDLC Stage Gate', 'QA Gate']
|
|
247
|
+
},
|
|
248
|
+
enforce_admins: false,
|
|
249
|
+
required_pull_request_reviews: null,
|
|
250
|
+
restrictions: null
|
|
251
|
+
});
|
|
252
|
+
execFileSync('gh', [
|
|
253
|
+
'api', `repos/${repo}/branches/main/protection`,
|
|
254
|
+
'--method', 'PUT',
|
|
255
|
+
'--input', '-'
|
|
256
|
+
], { input: protectionPayload, stdio: ['pipe', 'ignore', 'pipe'] });
|
|
257
|
+
console.log(` ${green}${i18n.protection_ok}${reset}`);
|
|
258
|
+
} catch (_) {
|
|
259
|
+
console.log(` ${yellow}${i18n.protection_warn}${reset}`);
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
- [ ] **Step 11: Verify cli.js changes compile (no syntax errors)**
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
node --check bin/cli.js
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Expected: no output (exit 0).
|
|
270
|
+
|
|
271
|
+
- [ ] **Step 12: Commit**
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
git add bin/cli.js
|
|
275
|
+
git commit -m "feat(cli): auto-configure branch protection with required QA Gate + PDLC Stage Gate checks"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
### Task 4: Enable branch protection on this repo (verification)
|
|
281
|
+
|
|
282
|
+
**Files:** none — GitHub API call only.
|
|
283
|
+
|
|
284
|
+
This repo was already not protected (`404 Branch not protected`). Task 3 adds the automation for new installs; this task activates it for the existing repo.
|
|
285
|
+
|
|
286
|
+
- [ ] **Step 13: Apply branch protection to this repo**
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
gh api repos/rafaeltcosta86/agentic-pdlc/branches/main/protection \
|
|
290
|
+
--method PUT \
|
|
291
|
+
--input - <<'EOF'
|
|
292
|
+
{
|
|
293
|
+
"required_status_checks": {
|
|
294
|
+
"strict": false,
|
|
295
|
+
"contexts": ["PDLC Stage Gate", "QA Gate"]
|
|
296
|
+
},
|
|
297
|
+
"enforce_admins": false,
|
|
298
|
+
"required_pull_request_reviews": null,
|
|
299
|
+
"restrictions": null
|
|
300
|
+
}
|
|
301
|
+
EOF
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Expected: JSON response with `url` field containing `branches/main/protection`.
|
|
305
|
+
|
|
306
|
+
- [ ] **Step 14: Verify branch protection is active**
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
gh api repos/rafaeltcosta86/agentic-pdlc/branches/main/protection \
|
|
310
|
+
--jq '.required_status_checks.contexts'
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Expected output:
|
|
314
|
+
```json
|
|
315
|
+
[
|
|
316
|
+
"PDLC Stage Gate",
|
|
317
|
+
"QA Gate"
|
|
318
|
+
]
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
- [ ] **Step 15: Open a test PR to verify end-to-end behavior**
|
|
322
|
+
|
|
323
|
+
Create a scratch branch, open a draft PR against main without `qa:approved` label:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
git checkout -b test/qa-gate-verification
|
|
327
|
+
git commit --allow-empty -m "test: verify qa gate enforcement"
|
|
328
|
+
gh pr create --title "test: QA Gate verification" --body "Closes #136" --draft
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Expected: `QA Gate` check appears and fails with "no QA label found". `AC Coverage Verification (GitHub Models)` check runs; if API is reachable it adds `qa:approved` automatically and QA Gate re-evaluates to pass. Merge button should be disabled until QA Gate passes.
|
|
332
|
+
|
|
333
|
+
- [ ] **Step 16: Close the test PR and delete the branch**
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
gh pr close --delete-branch
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Self-Review
|
|
342
|
+
|
|
343
|
+
**Spec coverage:**
|
|
344
|
+
- ✅ `infra:qa-broken` no longer allows silent bypass — Task 1 (exit 1) + Task 2 (qa-gate fails on that label)
|
|
345
|
+
- ✅ `qa:needs-work` also blocked — qa-gate checks for it explicitly
|
|
346
|
+
- ✅ "no QA label" state blocked — qa-gate fails if no QA label present
|
|
347
|
+
- ✅ Hotfix bypass preserved — same `grep -qw "hotfix"` pattern as pdlc-stage-gate
|
|
348
|
+
- ✅ Template updated — Tasks 1 and 2 update both repo + template files
|
|
349
|
+
- ✅ Enforcement mechanism (branch protection) included — Task 3 + Task 4
|
|
350
|
+
- ✅ New installs get protection automatically — cli.js step in Task 3
|
|
351
|
+
|
|
352
|
+
**Placeholder scan:** None found. All code blocks are complete and runnable.
|
|
353
|
+
|
|
354
|
+
**Type consistency:** No functions/types defined across tasks — all changes are self-contained YAML and JS.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Agentic Pulse — Rework Taxonomy with Review-Actor Attribution and Stage Correlation
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-05-29
|
|
4
|
+
**Issue:** [#142](https://github.com/rafaeltcosta86/agentic-pdlc/issues/142)
|
|
5
|
+
**Status:** stage:approval — awaiting spec:approved
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
Current rework signal detects extra commit sessions but cannot distinguish cause. All rework produces the same generic recommendation: "incomplete specs or requirement changes."
|
|
10
|
+
|
|
11
|
+
Three distinct causes exist, each pointing to a different fix:
|
|
12
|
+
|
|
13
|
+
| Cause | Root stage | Fix |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| Code reviewer caught a defect | stage:development — DoD too weak | Tighten implementation checklist |
|
|
16
|
+
| QA agent caught a functional gap | stage:detailing — spec incomplete | Add acceptance criteria |
|
|
17
|
+
| Self-correction (pre-review) | Unknown | Not auto-determinable |
|
|
18
|
+
|
|
19
|
+
## Design Decision
|
|
20
|
+
|
|
21
|
+
**Option C selected:** Review-Actor Taxonomy + Stage Correlation
|
|
22
|
+
- Auto-only (zero user friction)
|
|
23
|
+
- Actors are configurable — not locked to any specific bot
|
|
24
|
+
- Stage correlation provides upstream attribution when N≥3 data points available
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
### Files Changed
|
|
29
|
+
|
|
30
|
+
- `.github/workflows/agentic-metrics.yml`
|
|
31
|
+
- `templates/.github/workflows/agentic-metrics.yml` (mirror)
|
|
32
|
+
|
|
33
|
+
No new files. No new dependencies.
|
|
34
|
+
|
|
35
|
+
### Configuration
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
env:
|
|
39
|
+
AGENTIC_PULSE_REVIEWERS: |
|
|
40
|
+
code_reviewer=gemini-code-assist[bot]
|
|
41
|
+
qa_agent=github-actions[bot]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Format: `role=login1,login2` per line. If absent/empty → taxonomy skipped, existing behavior unchanged.
|
|
45
|
+
|
|
46
|
+
## Detection Logic
|
|
47
|
+
|
|
48
|
+
### Review-Actor Rework Detection
|
|
49
|
+
|
|
50
|
+
For each merged PR in the week window (up to 10 — consistent with existing rework block):
|
|
51
|
+
|
|
52
|
+
1. Get commit timestamps (reuse existing fetch)
|
|
53
|
+
2. If single commit session: skip
|
|
54
|
+
3. `GET /repos/{owner}/{repo}/pulls/{pr}/reviews`
|
|
55
|
+
4. For each review where `reviewer.login` is in the actor map:
|
|
56
|
+
- Record first review timestamp for that role
|
|
57
|
+
- Count commits with `timestamp > first_review_at`
|
|
58
|
+
- If count > 0: mark as `{role}`-triggered rework
|
|
59
|
+
5. If multi-session but no configured actor review found before them: `self_correction`
|
|
60
|
+
6. For reviewer-triggered PRs: extract `Closes #N` → store `{ pr_number, issue_number, role }` for stage correlation
|
|
61
|
+
|
|
62
|
+
A PR can count in multiple role buckets if multiple roles triggered rework. Total rework % = unique PRs with any rework / total PRs. Role breakdown counts per role (sum can exceed total %).
|
|
63
|
+
|
|
64
|
+
### Stage Correlation
|
|
65
|
+
|
|
66
|
+
Load `stage:detailing` durations from `weekKey.jsonl` → `Map<issueNumber, durationDays>`
|
|
67
|
+
|
|
68
|
+
Group:
|
|
69
|
+
- `reviewer_rework_group`: issues linked to reviewer-triggered rework PRs with known detailing time
|
|
70
|
+
- `clean_group`: issues linked to PRs with zero reviewer-triggered rework (single session OR only self-correction) with known detailing time
|
|
71
|
+
|
|
72
|
+
Emit correlation signal only if both groups have N≥3. Otherwise skip.
|
|
73
|
+
|
|
74
|
+
## Output Format
|
|
75
|
+
|
|
76
|
+
### Rework signal (taxonomy active)
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
🟡 **Rework rate: 60%** — 6 de 10 PRs tiveram commits extras
|
|
80
|
+
↳ Code reviewer: **4 PRs** → revisar DoD em stage:development
|
|
81
|
+
↳ QA Agent: **1 PR** → spec com lacunas funcionais em stage:detailing
|
|
82
|
+
↳ Self-correction: **1 PR** (causa não determinada automaticamente)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Stage correlation signal (when N≥3 both groups)
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
💡 **Stage correlation:** PRs com reviewer rework tiveram Detailing médio de 0.2d vs 0.8d (N=4 vs N=6)
|
|
89
|
+
→ Specs rápidas correlacionam com mais rework de review
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Signal levels
|
|
93
|
+
|
|
94
|
+
| Condition | Level |
|
|
95
|
+
|---|---|
|
|
96
|
+
| `code_reviewer` rework ≥ 80% of total | 🔴 |
|
|
97
|
+
| `code_reviewer` rework ≥ 50% of total | 🟡 |
|
|
98
|
+
| `qa_agent` rework > 0 | 🟡 |
|
|
99
|
+
| Stage correlation present | 🔵 (informational) |
|
|
100
|
+
|
|
101
|
+
## Recommendations
|
|
102
|
+
|
|
103
|
+
| Trigger | Recommendation |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `code_reviewer` dominant | Revisar Definition of Done em stage:development. Considere checklist de qualidade antes de abrir PR. |
|
|
106
|
+
| `qa_agent` > 0 | Spec tem lacunas funcionais. Revisar critérios de aceitação em stage:detailing. |
|
|
107
|
+
| Stage correlation fires (rework detailing < clean detailing) | Specs rápidas correlacionam com mais rework. Invista mais tempo em stage:detailing. |
|
|
108
|
+
| All self-correction | Configure AGENTIC_PULSE_REVIEWERS para attribution mais precisa. |
|
|
109
|
+
|
|
110
|
+
## Backward Compatibility
|
|
111
|
+
|
|
112
|
+
- `AGENTIC_PULSE_REVIEWERS` absent → taxonomy skipped, no regression
|
|
113
|
+
- JSONL absent → correlation skipped, taxonomy still runs
|
|
114
|
+
- N < 3 either group → correlation skipped
|
|
115
|
+
- `listReviews` API error → catch, skip PR, continue
|
|
116
|
+
|
|
117
|
+
## Out of Scope
|
|
118
|
+
|
|
119
|
+
- Manual rework classification
|
|
120
|
+
- Self-correction cause detection
|
|
121
|
+
- Changes to Stage Residence Time collection
|
|
122
|
+
- Changes to any other signal
|
package/package.json
CHANGED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug
|
|
3
|
+
about: Broken behavior with root cause and fix criteria
|
|
4
|
+
title: 'bug: '
|
|
5
|
+
labels: type:bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
<!-- What fails. Who affected. Measured impact. -->
|
|
12
|
+
|
|
13
|
+
## Root Cause
|
|
14
|
+
|
|
15
|
+
<!-- Why it fails. Link to code/config if known. -->
|
|
16
|
+
|
|
17
|
+
## Reproduction Steps
|
|
18
|
+
|
|
19
|
+
1.
|
|
20
|
+
2.
|
|
21
|
+
3.
|
|
22
|
+
|
|
23
|
+
**Expected:**
|
|
24
|
+
**Actual:**
|
|
25
|
+
|
|
26
|
+
## Acceptance Criteria
|
|
27
|
+
|
|
28
|
+
<!-- agent fills during detailing -->
|
|
29
|
+
|
|
30
|
+
**AC1 — [name]**
|
|
31
|
+
- Given
|
|
32
|
+
- When
|
|
33
|
+
- Then
|
|
34
|
+
|
|
35
|
+
## Edge Cases
|
|
36
|
+
|
|
37
|
+
<!-- agent fills during detailing -->
|
|
38
|
+
- EC1: [condition] → [expected behavior]
|
|
39
|
+
|
|
40
|
+
## Out of Scope
|
|
41
|
+
|
|
42
|
+
<!-- agent fills during detailing -->
|
|
43
|
+
-
|
|
44
|
+
|
|
45
|
+
## Non-Functional Requirements
|
|
46
|
+
|
|
47
|
+
<!-- agent fills during detailing — omit if pure docs/markdown -->
|
|
48
|
+
- Reliability: idempotent — safe to re-run
|
|
49
|
+
|
|
50
|
+
## Files to Modify
|
|
51
|
+
|
|
52
|
+
<!-- agent fills during detailing -->
|
|
53
|
+
- `path/to/file` — what changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature
|
|
3
|
+
about: New capability with spec scaffold for detailing agent
|
|
4
|
+
title: 'feat: '
|
|
5
|
+
labels: type:feature
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
<!-- What fails or is missing. Who affected. Measured impact. -->
|
|
12
|
+
|
|
13
|
+
## Sprint Goal / Success Metrics
|
|
14
|
+
|
|
15
|
+
<!-- agent fills during detailing -->
|
|
16
|
+
|
|
17
|
+
| Metric | Baseline | Target | When |
|
|
18
|
+
|--------|----------|--------|------|
|
|
19
|
+
| | | | |
|
|
20
|
+
|
|
21
|
+
## Solution
|
|
22
|
+
|
|
23
|
+
<!-- agent fills during detailing — behavioral description, no implementation details -->
|
|
24
|
+
|
|
25
|
+
## Acceptance Criteria
|
|
26
|
+
|
|
27
|
+
<!-- agent fills during detailing -->
|
|
28
|
+
|
|
29
|
+
**AC1 — [name]**
|
|
30
|
+
- Given
|
|
31
|
+
- When
|
|
32
|
+
- Then
|
|
33
|
+
|
|
34
|
+
## Edge Cases
|
|
35
|
+
|
|
36
|
+
<!-- agent fills during detailing -->
|
|
37
|
+
- EC1: [condition] → [expected behavior]
|
|
38
|
+
|
|
39
|
+
## Out of Scope
|
|
40
|
+
|
|
41
|
+
<!-- agent fills during detailing -->
|
|
42
|
+
-
|
|
43
|
+
|
|
44
|
+
## Non-Functional Requirements
|
|
45
|
+
|
|
46
|
+
<!-- agent fills during detailing — omit if pure docs/markdown -->
|
|
47
|
+
- Performance:
|
|
48
|
+
- Security:
|
|
49
|
+
- Reliability:
|
|
50
|
+
|
|
51
|
+
## Files to Modify
|
|
52
|
+
|
|
53
|
+
<!-- agent fills during detailing -->
|
|
54
|
+
- `path/to/file` — what changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Task
|
|
3
|
+
about: Defined work unit with clear done criteria
|
|
4
|
+
title: 'task: '
|
|
5
|
+
labels: type:task
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Objective
|
|
10
|
+
|
|
11
|
+
<!-- What must be done and why. -->
|
|
12
|
+
|
|
13
|
+
## Steps
|
|
14
|
+
|
|
15
|
+
<!-- agent fills during detailing -->
|
|
16
|
+
1.
|
|
17
|
+
2.
|
|
18
|
+
|
|
19
|
+
## Acceptance Criteria
|
|
20
|
+
|
|
21
|
+
<!-- agent fills during detailing -->
|
|
22
|
+
- [ ]
|
|
23
|
+
- [ ]
|
|
24
|
+
|
|
25
|
+
## Out of Scope
|
|
26
|
+
|
|
27
|
+
<!-- agent fills during detailing -->
|
|
28
|
+
-
|
|
29
|
+
|
|
30
|
+
## Files to Modify
|
|
31
|
+
|
|
32
|
+
<!-- agent fills during detailing -->
|
|
33
|
+
- `path/to/file` — what changes
|
|
@@ -14,13 +14,13 @@ jobs:
|
|
|
14
14
|
name: Auto-add new issue to board
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
16
|
env:
|
|
17
|
-
|
|
17
|
+
PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
|
|
18
18
|
steps:
|
|
19
19
|
- name: Add issue to project board
|
|
20
|
-
if: ${{ env.
|
|
21
|
-
uses: actions/github-script@
|
|
20
|
+
if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
|
|
21
|
+
uses: actions/github-script@v8
|
|
22
22
|
with:
|
|
23
|
-
github-token: ${{ env.
|
|
23
|
+
github-token: ${{ env.PROJECT_TOKEN }}
|
|
24
24
|
script: |
|
|
25
25
|
const nodeId = context.payload.issue.node_id;
|
|
26
26
|
const number = context.payload.issue.number;
|