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.
- package/.agentic-pdlc/metrics/raw/2026-W22.jsonl +114 -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/agentic-metrics.yml +150 -27
- 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 +51 -12
- package/.github/workflows/qa-agent.yml +22 -11
- package/.github/workflows/qa-gate.yml +51 -0
- package/AGENTS.md +50 -8
- package/CLAUDE.md +2 -0
- package/SETUP.md +2 -1
- package/adapters/claude-code/skill.md +32 -11
- package/adapters/hooks/pdlc-stage-gate.sh +3 -8
- package/bin/cli.js +23 -2
- 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/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 +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/AGENTS.md +57 -29
- package/templates/docs/pdlc.md +4 -4
- 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
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
{"issueNumber":84,"stage":"stage:brainstorming","durationDays":0}
|
|
2
|
+
{"issueNumber":84,"stage":"stage:detailing","durationDays":0}
|
|
3
|
+
{"issueNumber":84,"stage":"stage:approval","durationDays":0}
|
|
4
|
+
{"issueNumber":84,"stage":"stage:development","durationDays":0}
|
|
5
|
+
{"issueNumber":85,"stage":"stage:brainstorming","durationDays":0}
|
|
6
|
+
{"issueNumber":85,"stage":"stage:detailing","durationDays":0}
|
|
7
|
+
{"issueNumber":85,"stage":"stage:approval","durationDays":0}
|
|
8
|
+
{"issueNumber":85,"stage":"stage:approval","durationDays":0}
|
|
9
|
+
{"issueNumber":87,"stage":"stage:approval","durationDays":0}
|
|
10
|
+
{"issueNumber":87,"stage":"stage:development","durationDays":0}
|
|
11
|
+
{"issueNumber":87,"stage":"stage:brainstorming","durationDays":0}
|
|
12
|
+
{"issueNumber":87,"stage":"stage:detailing","durationDays":0}
|
|
13
|
+
{"issueNumber":87,"stage":"stage:approval","durationDays":0}
|
|
14
|
+
{"issueNumber":88,"stage":"stage:brainstorming","durationDays":0}
|
|
15
|
+
{"issueNumber":88,"stage":"stage:detailing","durationDays":0}
|
|
16
|
+
{"issueNumber":88,"stage":"stage:approval","durationDays":0}
|
|
17
|
+
{"issueNumber":88,"stage":"stage:development","durationDays":0}
|
|
18
|
+
{"issueNumber":89,"stage":"stage:brainstorming","durationDays":0}
|
|
19
|
+
{"issueNumber":90,"stage":"stage:brainstorming","durationDays":0}
|
|
20
|
+
{"issueNumber":90,"stage":"stage:detailing","durationDays":0}
|
|
21
|
+
{"issueNumber":90,"stage":"stage:approval","durationDays":0}
|
|
22
|
+
{"issueNumber":90,"stage":"stage:approval","durationDays":0}
|
|
23
|
+
{"issueNumber":91,"stage":"stage:brainstorming","durationDays":0}
|
|
24
|
+
{"issueNumber":91,"stage":"stage:detailing","durationDays":0}
|
|
25
|
+
{"issueNumber":91,"stage":"stage:approval","durationDays":0}
|
|
26
|
+
{"issueNumber":91,"stage":"stage:development","durationDays":0}
|
|
27
|
+
{"issueNumber":92,"stage":"stage:brainstorming","durationDays":0}
|
|
28
|
+
{"issueNumber":92,"stage":"stage:detailing","durationDays":0}
|
|
29
|
+
{"issueNumber":92,"stage":"stage:approval","durationDays":0}
|
|
30
|
+
{"issueNumber":92,"stage":"stage:development","durationDays":0}
|
|
31
|
+
{"issueNumber":93,"stage":"stage:brainstorming","durationDays":0}
|
|
32
|
+
{"issueNumber":93,"stage":"stage:detailing","durationDays":0}
|
|
33
|
+
{"issueNumber":93,"stage":"stage:approval","durationDays":0}
|
|
34
|
+
{"issueNumber":93,"stage":"stage:development","durationDays":0}
|
|
35
|
+
{"issueNumber":94,"stage":"stage:brainstorming","durationDays":0}
|
|
36
|
+
{"issueNumber":94,"stage":"stage:detailing","durationDays":0}
|
|
37
|
+
{"issueNumber":94,"stage":"stage:approval","durationDays":0}
|
|
38
|
+
{"issueNumber":96,"stage":"stage:brainstorming","durationDays":0}
|
|
39
|
+
{"issueNumber":96,"stage":"stage:detailing","durationDays":0}
|
|
40
|
+
{"issueNumber":96,"stage":"stage:approval","durationDays":0}
|
|
41
|
+
{"issueNumber":96,"stage":"stage:development","durationDays":0}
|
|
42
|
+
{"issueNumber":97,"stage":"stage:brainstorming","durationDays":0}
|
|
43
|
+
{"issueNumber":97,"stage":"stage:detailing","durationDays":0}
|
|
44
|
+
{"issueNumber":97,"stage":"stage:approval","durationDays":0}
|
|
45
|
+
{"issueNumber":109,"stage":"stage:brainstorming","durationDays":0}
|
|
46
|
+
{"issueNumber":109,"stage":"stage:detailing","durationDays":0}
|
|
47
|
+
{"issueNumber":109,"stage":"stage:approval","durationDays":0}
|
|
48
|
+
{"issueNumber":109,"stage":"stage:development","durationDays":0}
|
|
49
|
+
{"issueNumber":110,"stage":"stage:brainstorming","durationDays":0}
|
|
50
|
+
{"issueNumber":110,"stage":"stage:detailing","durationDays":0}
|
|
51
|
+
{"issueNumber":110,"stage":"stage:approval","durationDays":0.3}
|
|
52
|
+
{"issueNumber":110,"stage":"stage:development","durationDays":0}
|
|
53
|
+
{"issueNumber":110,"stage":"stage:testing","durationDays":0}
|
|
54
|
+
{"issueNumber":111,"stage":"stage:brainstorming","durationDays":0}
|
|
55
|
+
{"issueNumber":111,"stage":"stage:detailing","durationDays":0}
|
|
56
|
+
{"issueNumber":111,"stage":"stage:approval","durationDays":0.3}
|
|
57
|
+
{"issueNumber":111,"stage":"stage:development","durationDays":0}
|
|
58
|
+
{"issueNumber":111,"stage":"stage:testing","durationDays":0}
|
|
59
|
+
{"issueNumber":113,"stage":"stage:brainstorming","durationDays":0}
|
|
60
|
+
{"issueNumber":113,"stage":"stage:detailing","durationDays":0}
|
|
61
|
+
{"issueNumber":113,"stage":"stage:approval","durationDays":0}
|
|
62
|
+
{"issueNumber":113,"stage":"stage:development","durationDays":0}
|
|
63
|
+
{"issueNumber":116,"stage":"stage:brainstorming","durationDays":3.7}
|
|
64
|
+
{"issueNumber":116,"stage":"stage:detailing","durationDays":0}
|
|
65
|
+
{"issueNumber":116,"stage":"stage:approval","durationDays":0}
|
|
66
|
+
{"issueNumber":116,"stage":"stage:development","durationDays":0}
|
|
67
|
+
{"issueNumber":119,"stage":"stage:brainstorming","durationDays":0}
|
|
68
|
+
{"issueNumber":119,"stage":"stage:detailing","durationDays":0}
|
|
69
|
+
{"issueNumber":119,"stage":"stage:approval","durationDays":0}
|
|
70
|
+
{"issueNumber":119,"stage":"stage:approval","durationDays":0.3}
|
|
71
|
+
{"issueNumber":119,"stage":"stage:development","durationDays":0}
|
|
72
|
+
{"issueNumber":120,"stage":"stage:brainstorming","durationDays":0}
|
|
73
|
+
{"issueNumber":120,"stage":"stage:detailing","durationDays":0}
|
|
74
|
+
{"issueNumber":120,"stage":"stage:approval","durationDays":0}
|
|
75
|
+
{"issueNumber":120,"stage":"stage:development","durationDays":0}
|
|
76
|
+
{"issueNumber":122,"stage":"stage:brainstorming","durationDays":0.1}
|
|
77
|
+
{"issueNumber":122,"stage":"stage:detailing","durationDays":0}
|
|
78
|
+
{"issueNumber":122,"stage":"stage:approval","durationDays":0}
|
|
79
|
+
{"issueNumber":122,"stage":"stage:development","durationDays":0}
|
|
80
|
+
{"issueNumber":125,"stage":"stage:brainstorming","durationDays":0}
|
|
81
|
+
{"issueNumber":125,"stage":"stage:detailing","durationDays":0}
|
|
82
|
+
{"issueNumber":125,"stage":"stage:approval","durationDays":0.1}
|
|
83
|
+
{"issueNumber":125,"stage":"stage:development","durationDays":0}
|
|
84
|
+
{"issueNumber":128,"stage":"stage:brainstorming","durationDays":0.6}
|
|
85
|
+
{"issueNumber":128,"stage":"stage:detailing","durationDays":0}
|
|
86
|
+
{"issueNumber":128,"stage":"stage:approval","durationDays":0}
|
|
87
|
+
{"issueNumber":128,"stage":"stage:development","durationDays":0}
|
|
88
|
+
{"issueNumber":130,"stage":"stage:brainstorming","durationDays":0}
|
|
89
|
+
{"issueNumber":130,"stage":"stage:detailing","durationDays":0}
|
|
90
|
+
{"issueNumber":130,"stage":"stage:approval","durationDays":0}
|
|
91
|
+
{"issueNumber":130,"stage":"stage:development","durationDays":0}
|
|
92
|
+
{"issueNumber":132,"stage":"stage:brainstorming","durationDays":0}
|
|
93
|
+
{"issueNumber":132,"stage":"stage:detailing","durationDays":0}
|
|
94
|
+
{"issueNumber":132,"stage":"stage:approval","durationDays":0}
|
|
95
|
+
{"issueNumber":132,"stage":"stage:development","durationDays":0}
|
|
96
|
+
{"issueNumber":132,"stage":"stage:testing","durationDays":0}
|
|
97
|
+
{"issueNumber":135,"stage":"stage:brainstorming","durationDays":0}
|
|
98
|
+
{"issueNumber":135,"stage":"stage:detailing","durationDays":0}
|
|
99
|
+
{"issueNumber":135,"stage":"stage:approval","durationDays":0}
|
|
100
|
+
{"issueNumber":135,"stage":"stage:development","durationDays":0}
|
|
101
|
+
{"issueNumber":136,"stage":"stage:brainstorming","durationDays":0}
|
|
102
|
+
{"issueNumber":136,"stage":"stage:detailing","durationDays":0}
|
|
103
|
+
{"issueNumber":136,"stage":"stage:approval","durationDays":0}
|
|
104
|
+
{"issueNumber":136,"stage":"stage:development","durationDays":0}
|
|
105
|
+
{"issueNumber":136,"stage":"stage:testing","durationDays":0.1}
|
|
106
|
+
{"issueNumber":137,"stage":"stage:brainstorming","durationDays":0}
|
|
107
|
+
{"issueNumber":137,"stage":"stage:detailing","durationDays":0}
|
|
108
|
+
{"issueNumber":137,"stage":"stage:approval","durationDays":0}
|
|
109
|
+
{"issueNumber":137,"stage":"stage:development","durationDays":0}
|
|
110
|
+
{"issueNumber":137,"stage":"stage:testing","durationDays":0}
|
|
111
|
+
{"issueNumber":141,"stage":"stage:brainstorming","durationDays":0}
|
|
112
|
+
{"issueNumber":142,"stage":"stage:brainstorming","durationDays":0}
|
|
113
|
+
{"issueNumber":142,"stage":"stage:detailing","durationDays":0}
|
|
114
|
+
{"issueNumber":142,"stage":"stage:approval","durationDays":0}
|
|
@@ -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
|
|
@@ -18,7 +18,7 @@ jobs:
|
|
|
18
18
|
steps:
|
|
19
19
|
- name: Add issue to project board
|
|
20
20
|
if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
|
|
21
|
-
uses: actions/github-script@
|
|
21
|
+
uses: actions/github-script@v8
|
|
22
22
|
with:
|
|
23
23
|
github-token: ${{ env.PROJECT_TOKEN }}
|
|
24
24
|
script: |
|
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
STATUS_DEVELOPMENT: "2c9e78e6"
|
|
23
23
|
steps:
|
|
24
24
|
- name: Swap labels β stage:approval β stage:development
|
|
25
|
-
uses: actions/github-script@
|
|
25
|
+
uses: actions/github-script@v8
|
|
26
26
|
with:
|
|
27
27
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
28
28
|
script: |
|
|
@@ -44,13 +44,13 @@ jobs:
|
|
|
44
44
|
owner,
|
|
45
45
|
repo,
|
|
46
46
|
issue_number,
|
|
47
|
-
labels: ['stage:development'
|
|
47
|
+
labels: ['stage:development']
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
- name: Move board card to Development
|
|
51
51
|
if: ${{ env.PROJECT_TOKEN != '' }}
|
|
52
52
|
continue-on-error: true
|
|
53
|
-
uses: actions/github-script@
|
|
53
|
+
uses: actions/github-script@v8
|
|
54
54
|
with:
|
|
55
55
|
github-token: ${{ env.PROJECT_TOKEN }}
|
|
56
56
|
script: |
|
|
@@ -79,7 +79,7 @@ jobs:
|
|
|
79
79
|
contents: read
|
|
80
80
|
steps:
|
|
81
81
|
- name: Comment on issue
|
|
82
|
-
uses: actions/github-script@
|
|
82
|
+
uses: actions/github-script@v8
|
|
83
83
|
with:
|
|
84
84
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
85
85
|
script: |
|
|
@@ -9,15 +9,20 @@ permissions:
|
|
|
9
9
|
contents: write
|
|
10
10
|
issues: write
|
|
11
11
|
|
|
12
|
+
env:
|
|
13
|
+
AGENTIC_PULSE_REVIEWERS: |
|
|
14
|
+
code_reviewer=gemini-code-assist[bot]
|
|
15
|
+
qa_agent=github-actions[bot]
|
|
16
|
+
|
|
12
17
|
jobs:
|
|
13
18
|
generate-pulse:
|
|
14
19
|
name: Generate Weekly Agentic Pulse
|
|
15
20
|
runs-on: ubuntu-latest
|
|
16
21
|
steps:
|
|
17
|
-
- uses: actions/checkout@
|
|
22
|
+
- uses: actions/checkout@v5.0.1
|
|
18
23
|
|
|
19
24
|
- name: Collect Stage Residence Time
|
|
20
|
-
uses: actions/github-script@
|
|
25
|
+
uses: actions/github-script@v8
|
|
21
26
|
with:
|
|
22
27
|
script: |
|
|
23
28
|
const fs = require('fs');
|
|
@@ -104,13 +109,26 @@ jobs:
|
|
|
104
109
|
git push
|
|
105
110
|
|
|
106
111
|
- name: Collect PR and Issue Insights
|
|
107
|
-
uses: actions/github-script@
|
|
112
|
+
uses: actions/github-script@v8
|
|
108
113
|
with:
|
|
109
114
|
script: |
|
|
110
115
|
const fs = require('fs');
|
|
111
116
|
const { owner, repo } = context.repo;
|
|
112
117
|
const weekKey = process.env.WEEK_KEY;
|
|
113
118
|
|
|
119
|
+
// ββ Preload stage:detailing times for stage correlation ββββββββββ
|
|
120
|
+
const detailingByIssue = {};
|
|
121
|
+
const jsonlPath = `.agentic-pdlc/metrics/raw/${weekKey}.jsonl`;
|
|
122
|
+
if (fs.existsSync(jsonlPath)) {
|
|
123
|
+
const rawLines = fs.readFileSync(jsonlPath, 'utf8').trim().split('\n').filter(Boolean);
|
|
124
|
+
for (const line of rawLines) {
|
|
125
|
+
const r = JSON.parse(line);
|
|
126
|
+
if (r.stage === 'stage:detailing') {
|
|
127
|
+
detailingByIssue[r.issueNumber] = round1((detailingByIssue[r.issueNumber] || 0) + r.durationDays);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
114
132
|
// ββ Helper ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
115
133
|
function daysSince(isoStr) {
|
|
116
134
|
return (Date.now() - new Date(isoStr).getTime()) / 864e5;
|
|
@@ -138,6 +156,22 @@ jobs:
|
|
|
138
156
|
// ββ Signal collection βββββββββββββββββββββββββββββββββββββββββββ
|
|
139
157
|
const signals = [];
|
|
140
158
|
|
|
159
|
+
// ββ Review actor map (from AGENTIC_PULSE_REVIEWERS env var) βββββ
|
|
160
|
+
const actorMap = {}; // login β role
|
|
161
|
+
const reviewersEnv = (process.env.AGENTIC_PULSE_REVIEWERS || '').trim();
|
|
162
|
+
if (reviewersEnv) {
|
|
163
|
+
for (const line of reviewersEnv.split('\n')) {
|
|
164
|
+
const eq = line.indexOf('=');
|
|
165
|
+
if (eq < 0) continue;
|
|
166
|
+
const role = line.slice(0, eq).trim();
|
|
167
|
+
const logins = line.slice(eq + 1).trim();
|
|
168
|
+
for (const login of logins.split(',').map(l => l.trim()).filter(Boolean)) {
|
|
169
|
+
actorMap[login] = role;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const taxonomyEnabled = Object.keys(actorMap).length > 0;
|
|
174
|
+
|
|
141
175
|
// 1. Orphan issues: open >14 days with no linked PR
|
|
142
176
|
const closeRe = /(?:closes?|fixes?|resolves?)\s+#(\d+)/gi;
|
|
143
177
|
const openIssues = await github.paginate(github.rest.issues.listForRepo, {
|
|
@@ -223,29 +257,68 @@ jobs:
|
|
|
223
257
|
}
|
|
224
258
|
}
|
|
225
259
|
|
|
226
|
-
// 3. Rework rate
|
|
260
|
+
// 3. Rework rate with actor taxonomy (if AGENTIC_PULSE_REVIEWERS configured)
|
|
227
261
|
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
|
|
228
262
|
const weekMerged = recentPRs.filter(pr => pr.merged_at && new Date(pr.merged_at) > weekAgo);
|
|
229
263
|
|
|
230
264
|
if (weekMerged.length > 0) {
|
|
231
265
|
let firstShots = 0;
|
|
266
|
+
const reworkByRole = {};
|
|
267
|
+
const reworkDetails = []; // { pr_number, issue_number } for stage correlation
|
|
268
|
+
const issueRe = /(?:closes?|fixes?|resolves?)\s+#(\d+)/i;
|
|
269
|
+
|
|
232
270
|
for (const pr of weekMerged.slice(0, 10)) {
|
|
233
271
|
try {
|
|
234
272
|
const commits = await github.rest.pulls.listCommits({
|
|
235
273
|
owner, repo, pull_number: pr.number, per_page: 100
|
|
236
274
|
});
|
|
237
|
-
const times = commits.data
|
|
275
|
+
const times = commits.data
|
|
276
|
+
.map(c => new Date(c.commit.committer.date).getTime())
|
|
277
|
+
.sort((a, b) => a - b);
|
|
278
|
+
|
|
238
279
|
let sessions = 1;
|
|
239
280
|
for (let i = 1; i < times.length; i++) {
|
|
240
281
|
if (times[i] - times[i-1] > 10 * 60 * 1000) sessions++;
|
|
241
282
|
}
|
|
242
|
-
|
|
283
|
+
|
|
284
|
+
if (sessions === 1) { firstShots++; continue; }
|
|
285
|
+
|
|
286
|
+
if (!taxonomyEnabled) continue;
|
|
287
|
+
|
|
288
|
+
let reviewTriggered = false;
|
|
289
|
+
try {
|
|
290
|
+
const reviews = await github.rest.pulls.listReviews({
|
|
291
|
+
owner, repo, pull_number: pr.number, per_page: 100
|
|
292
|
+
});
|
|
293
|
+
const attributedRoles = new Set();
|
|
294
|
+
for (const review of reviews.data) {
|
|
295
|
+
if (!review.user) continue;
|
|
296
|
+
const role = actorMap[review.user.login];
|
|
297
|
+
if (!role || review.state === 'APPROVED' || attributedRoles.has(role)) continue;
|
|
298
|
+
const reviewTime = new Date(review.submitted_at).getTime();
|
|
299
|
+
if (times.some(t => t > reviewTime)) {
|
|
300
|
+
reworkByRole[role] = (reworkByRole[role] || 0) + 1;
|
|
301
|
+
reviewTriggered = true;
|
|
302
|
+
attributedRoles.add(role);
|
|
303
|
+
if (!reworkDetails.some(d => d.pr_number === pr.number)) {
|
|
304
|
+
const m = issueRe.exec(pr.body || '');
|
|
305
|
+
if (m) reworkDetails.push({ pr_number: pr.number, issue_number: parseInt(m[1]) });
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
} catch(e) { /* reviews not accessible β skip taxonomy for this PR */ }
|
|
310
|
+
|
|
311
|
+
if (!reviewTriggered) {
|
|
312
|
+
reworkByRole.self_correction = (reworkByRole.self_correction || 0) + 1;
|
|
313
|
+
}
|
|
314
|
+
|
|
243
315
|
} catch (e) { /* skip if commits not accessible */ }
|
|
244
316
|
}
|
|
317
|
+
|
|
245
318
|
const total = Math.min(weekMerged.length, 10);
|
|
246
319
|
const pct = Math.round(firstShots / total * 100);
|
|
320
|
+
const reworkCount = total - firstShots;
|
|
247
321
|
|
|
248
|
-
// Detect if repo uses an agent label (jules, sweep, codex, etc.)
|
|
249
322
|
const agentLabels = new Set(['jules', 'sweep', 'codex', 'copilot']);
|
|
250
323
|
const usesAgent = weekMerged.some(pr =>
|
|
251
324
|
(pr.labels || []).some(l => agentLabels.has(l.name.toLowerCase()))
|
|
@@ -253,27 +326,78 @@ jobs:
|
|
|
253
326
|
const subject = usesAgent ? 'Agent first-shot rate' : 'PRs sem rework';
|
|
254
327
|
const verb = usesAgent ? 'acertaram de primeira' : 'foram mergeados sem rework';
|
|
255
328
|
|
|
256
|
-
if (
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
329
|
+
if (taxonomyEnabled && reworkCount > 0) {
|
|
330
|
+
const lines = [];
|
|
331
|
+
for (const [role, count] of Object.entries(reworkByRole).sort((a, b) => b[1] - a[1])) {
|
|
332
|
+
const s = count > 1 ? 's' : '';
|
|
333
|
+
if (role === 'code_reviewer') lines.push(` β³ Code reviewer: **${count} PR${s}** β revisar DoD em stage:development`);
|
|
334
|
+
else if (role === 'qa_agent') lines.push(` β³ QA Agent: **${count} PR${s}** β spec com lacunas funcionais em stage:detailing`);
|
|
335
|
+
else if (role === 'self_correction') lines.push(` β³ Self-correction: **${count} PR${s}** (causa nΓ£o determinada automaticamente)`);
|
|
336
|
+
else lines.push(` β³ ${role}: **${count} PR${s}**`);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const reviewerRework = reworkByRole.code_reviewer || 0;
|
|
340
|
+
const level = reviewerRework >= Math.ceil(reworkCount * 0.8) ? 'red'
|
|
341
|
+
: (reviewerRework >= Math.ceil(reworkCount * 0.5) || (reworkByRole.qa_agent || 0) > 0) ? 'yellow'
|
|
342
|
+
: 'neutral';
|
|
343
|
+
const emoji = level === 'red' ? 'π΄' : level === 'yellow' ? 'π‘' : 'π΅';
|
|
344
|
+
|
|
264
345
|
signals.push({
|
|
265
|
-
level
|
|
266
|
-
emoji
|
|
267
|
-
title:
|
|
268
|
-
body:
|
|
346
|
+
level,
|
|
347
|
+
emoji,
|
|
348
|
+
title: `**Rework: ${100 - pct}%** β ${reworkCount} de ${total} PRs tiveram commits extras`,
|
|
349
|
+
body: lines.join('\n')
|
|
269
350
|
});
|
|
351
|
+
|
|
352
|
+
// ββ Stage correlation ββββββββββββββββββββββββββββββββββββββββ
|
|
353
|
+
if (reworkDetails.length > 0 && Object.keys(detailingByIssue).length > 0) {
|
|
354
|
+
const reworkIssueNums = new Set(reworkDetails.map(d => d.issue_number));
|
|
355
|
+
|
|
356
|
+
const reworkGroup = reworkDetails
|
|
357
|
+
.map(d => detailingByIssue[d.issue_number])
|
|
358
|
+
.filter(t => t !== undefined);
|
|
359
|
+
|
|
360
|
+
const cleanGroup = weekMerged.slice(0, 10)
|
|
361
|
+
.map(pr => { const m = issueRe.exec(pr.body || ''); return m ? parseInt(m[1]) : null; })
|
|
362
|
+
.filter(n => n !== null && !reworkIssueNums.has(n))
|
|
363
|
+
.map(n => detailingByIssue[n])
|
|
364
|
+
.filter(t => t !== undefined);
|
|
365
|
+
|
|
366
|
+
if (reworkGroup.length >= 3 && cleanGroup.length >= 3) {
|
|
367
|
+
const avgRework = round1(reworkGroup.reduce((a, b) => a + b, 0) / reworkGroup.length);
|
|
368
|
+
const avgClean = round1(cleanGroup.reduce((a, b) => a + b, 0) / cleanGroup.length);
|
|
369
|
+
if (avgRework < avgClean * 0.75) {
|
|
370
|
+
signals.push({
|
|
371
|
+
level: 'neutral',
|
|
372
|
+
emoji: 'π‘',
|
|
373
|
+
title: `**Stage correlation:** PRs com reviewer rework tiveram Detailing mΓ©dio de ${avgRework}d vs ${avgClean}d (N=${reworkGroup.length} vs ${cleanGroup.length})`,
|
|
374
|
+
body: 'β Specs rΓ‘pidas correlacionam com mais rework de review'
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
270
380
|
} else {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
381
|
+
// Taxonomy disabled or no rework β existing signal unchanged
|
|
382
|
+
if (pct >= 80) {
|
|
383
|
+
signals.push({
|
|
384
|
+
level: 'green', emoji: 'π’',
|
|
385
|
+
title: `**${subject}: ${pct}%**`,
|
|
386
|
+
body: `${firstShots} de ${total} PRs ${verb} esta semana. β
`
|
|
387
|
+
});
|
|
388
|
+
} else if (pct < 50) {
|
|
389
|
+
signals.push({
|
|
390
|
+
level: 'yellow', emoji: 'π‘',
|
|
391
|
+
title: `**${subject}: ${pct}% β rework alto**`,
|
|
392
|
+
body: `Apenas ${firstShots} de ${total} PRs sem commits extras.\nβ Specs incompletas ou mudanΓ§as de requisito durante implementaΓ§Γ£o.`
|
|
393
|
+
});
|
|
394
|
+
} else {
|
|
395
|
+
signals.push({
|
|
396
|
+
level: 'neutral', emoji: 'π΅',
|
|
397
|
+
title: `**${subject}: ${pct}%**`,
|
|
398
|
+
body: `${firstShots} de ${total} PRs sem rework commits.`
|
|
399
|
+
});
|
|
400
|
+
}
|
|
277
401
|
}
|
|
278
402
|
}
|
|
279
403
|
|
|
@@ -292,7 +416,6 @@ jobs:
|
|
|
292
416
|
|
|
293
417
|
// ββ Stage Residence Time section (conditional) ββββββββββββββββββ
|
|
294
418
|
let stageSection = '';
|
|
295
|
-
const jsonlPath = `.agentic-pdlc/metrics/raw/${weekKey}.jsonl`;
|
|
296
419
|
if (fs.existsSync(jsonlPath)) {
|
|
297
420
|
const records = fs.readFileSync(jsonlPath, 'utf8').trim().split('\n').filter(Boolean).map(JSON.parse);
|
|
298
421
|
if (records.length > 0) {
|
|
@@ -376,7 +499,7 @@ jobs:
|
|
|
376
499
|
console.log(`Built pulse issue for ${weekKey} β ${signals.length} signals, ${reds} red, ${yellows} yellow`);
|
|
377
500
|
|
|
378
501
|
- name: Create Weekly Pulse Issue
|
|
379
|
-
uses: actions/github-script@
|
|
502
|
+
uses: actions/github-script@v8
|
|
380
503
|
with:
|
|
381
504
|
script: |
|
|
382
505
|
const { owner, repo } = context.repo;
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -11,7 +11,7 @@ jobs:
|
|
|
11
11
|
name: Run tests and linters
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
steps:
|
|
14
|
-
- uses: actions/checkout@
|
|
14
|
+
- uses: actions/checkout@v5.0.1
|
|
15
15
|
|
|
16
16
|
- name: Setup environment
|
|
17
17
|
run: echo "Replace this with your language/toolchain setup (e.g., actions/setup-node)"
|
|
@@ -14,10 +14,10 @@ jobs:
|
|
|
14
14
|
|
|
15
15
|
steps:
|
|
16
16
|
- name: Checkout Code
|
|
17
|
-
uses: actions/checkout@
|
|
17
|
+
uses: actions/checkout@v5.0.1
|
|
18
18
|
|
|
19
19
|
- name: Setup Node.js
|
|
20
|
-
uses: actions/setup-node@
|
|
20
|
+
uses: actions/setup-node@v6.4.0
|
|
21
21
|
with:
|
|
22
22
|
node-version: '24'
|
|
23
23
|
registry-url: 'https://registry.npmjs.org'
|
|
@@ -27,7 +27,7 @@ jobs:
|
|
|
27
27
|
steps:
|
|
28
28
|
- name: Validate Board Configuration
|
|
29
29
|
if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
|
|
30
|
-
uses: actions/github-script@
|
|
30
|
+
uses: actions/github-script@v8
|
|
31
31
|
with:
|
|
32
32
|
github-token: ${{ env.PROJECT_TOKEN }}
|
|
33
33
|
script: |
|
|
@@ -37,12 +37,12 @@ jobs:
|
|
|
37
37
|
|
|
38
38
|
for NUM in $ISSUE_NUMS; do
|
|
39
39
|
LABELS=$(gh issue view "$NUM" --repo "$REPO" --json labels --jq '[.labels[].name] | join(" ")' 2>/dev/null || echo "")
|
|
40
|
-
if echo "$LABELS" | grep -qw "stage:approval" || echo "$LABELS" | grep -qw "spec:approved" || echo "$LABELS" | grep -qw "stage:development"; then
|
|
40
|
+
if echo "$LABELS" | grep -qw "stage:approval" || echo "$LABELS" | grep -qw "spec:approved" || echo "$LABELS" | grep -qw "stage:development" || echo "$LABELS" | grep -qw "stage:testing" || echo "$LABELS" | grep -qw "human-approved"; then
|
|
41
41
|
echo "β
Issue #$NUM approved"
|
|
42
42
|
else
|
|
43
43
|
STAGE=$(echo "$LABELS" | tr ' ' '\n' | grep "^stage:" | head -1 || echo "none")
|
|
44
44
|
echo "β Issue #$NUM missing approval (current: $STAGE)"
|
|
45
|
-
echo " Required: stage:approval OR spec:approved OR stage:development label on the issue."
|
|
45
|
+
echo " Required: stage:approval OR spec:approved OR stage:development OR stage:testing OR human-approved label on the issue."
|
|
46
46
|
echo " Emergency bypass: add 'hotfix' label to this PR."
|
|
47
47
|
exit 1
|
|
48
48
|
fi
|