@plainconceptsplatform/workflows 1.2.3 → 1.3.1
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/dist/route-processing.js +1 -0
- package/loops/actions/add-issue-labels/action.yml +50 -50
- package/loops/actions/agent-output.cjs +17 -17
- package/loops/actions/apply-agent-bundle/action.yml +24 -24
- package/loops/actions/apply-agent-comments/action.yml +42 -42
- package/loops/actions/apply-agent-labels/action.yml +55 -55
- package/loops/actions/apply-agent-output/action.yml +108 -108
- package/loops/actions/assess-blast-radius/action.yml +47 -8
- package/loops/actions/assess-blast-radius/assess-blast-radius.sh +27 -5
- package/loops/actions/assess-blast-radius/migration-is-additive.sh +38 -0
- package/loops/actions/classify-route/action.yml +2 -1
- package/loops/actions/classify-route/classify-route.sh +7 -1
- package/loops/actions/cleanup-artifacts/action.yml +91 -91
- package/loops/actions/close-agent-issues/action.yml +43 -43
- package/loops/actions/create-agent-issues/action.yml +52 -52
- package/loops/actions/create-issue-comment/action.yml +29 -29
- package/loops/actions/download-agent-output/action.yml +53 -53
- package/loops/actions/link-pr-to-issue/action.yml +40 -40
- package/loops/actions/list-open-issues/action.yml +33 -33
- package/loops/actions/load-issue-context/action.yml +45 -45
- package/loops/actions/merge-agent-pr/action.yml +49 -49
- package/loops/actions/push-agent-branch/action.yml +45 -45
- package/loops/actions/remove-issue-labels/action.yml +37 -37
- package/loops/actions/update-agent-issues/action.yml +58 -58
- package/loops/actions/validate-merge-gate-output/action.yml +6 -1
- package/loops/actions/validate-merge-gate-output/validate-merge-gate-output.sh +9 -2
- package/loops/actions/validate-review-output/action.yml +35 -35
- package/loops/actions/validate-triage-output/action.yml +36 -36
- package/loops/actions/verify-composite-actions/action.yml +9 -9
- package/loops/actions/verify-refine-output/action.yml +9 -9
- package/loops/actions/verify-route-matrix/action.yml +9 -9
- package/loops/actions/verify-route-matrix/verify-route-matrix.sh +149 -29
- package/loops/docs/diagrams.md +26 -11
- package/loops/templates/agentics/agentics-maintenance.yml +121 -121
- package/loops/templates/issues/bug_report.yml +109 -109
- package/loops/templates/issues/feature_request.yml +75 -75
- package/loops/templates/release/github-release.yml +30 -30
- package/loops/workflows/agent-apply-review.md +5 -0
- package/loops/workflows/agent-implement.md +6 -0
- package/loops/workflows/agent-merge-gate.md +100 -3
- package/loops/workflows/authorize-bot-work.yml +105 -105
- package/loops/workflows/evidence.yml +79 -4
- package/loops/workflows/shared/platform-defaults.md +23 -23
- package/loops/workflows/work-router.yml +97 -21
- package/package.json +1 -1
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
name: Bug report
|
|
2
|
-
description: Report a defect
|
|
3
|
-
labels: ["bug"]
|
|
4
|
-
body:
|
|
5
|
-
- type: markdown
|
|
6
|
-
attributes:
|
|
7
|
-
value: |
|
|
8
|
-
Thanks for reporting. Do **not** include real secrets or production data use placeholders.
|
|
9
|
-
|
|
10
|
-
For security vulnerabilities, contact the team directly instead of filing a public issue.
|
|
11
|
-
- type: dropdown
|
|
12
|
-
id: severity
|
|
13
|
-
attributes:
|
|
14
|
-
label: Severity
|
|
15
|
-
options:
|
|
16
|
-
- Production-down / data loss
|
|
17
|
-
- Major broken core flow
|
|
18
|
-
- Minor broken edge case
|
|
19
|
-
- Cosmetic / polish
|
|
20
|
-
validations:
|
|
21
|
-
required: true
|
|
22
|
-
- type: dropdown
|
|
23
|
-
id: frequency
|
|
24
|
-
attributes:
|
|
25
|
-
label: Frequency
|
|
26
|
-
description: How often does this happen?
|
|
27
|
-
options:
|
|
28
|
-
- Always
|
|
29
|
-
- Intermittent
|
|
30
|
-
- Only once
|
|
31
|
-
validations:
|
|
32
|
-
required: true
|
|
33
|
-
- type: textarea
|
|
34
|
-
id: what-happened
|
|
35
|
-
attributes:
|
|
36
|
-
label: What happened?
|
|
37
|
-
description: A clear description of the bug and its impact.
|
|
38
|
-
validations:
|
|
39
|
-
required: true
|
|
40
|
-
- type: textarea
|
|
41
|
-
id: repro
|
|
42
|
-
attributes:
|
|
43
|
-
label: Steps to reproduce
|
|
44
|
-
description: How can a maintainer reproduce it?
|
|
45
|
-
placeholder: |
|
|
46
|
-
1. Go to ...
|
|
47
|
-
2. Do ...
|
|
48
|
-
3. See error
|
|
49
|
-
validations:
|
|
50
|
-
required: true
|
|
51
|
-
- type: textarea
|
|
52
|
-
id: expected
|
|
53
|
-
attributes:
|
|
54
|
-
label: Expected behavior
|
|
55
|
-
validations:
|
|
56
|
-
required: true
|
|
57
|
-
- type: dropdown
|
|
58
|
-
id: area
|
|
59
|
-
attributes:
|
|
60
|
-
label: Where does it occur?
|
|
61
|
-
options:
|
|
62
|
-
- Backend
|
|
63
|
-
- Frontend
|
|
64
|
-
- Both
|
|
65
|
-
- CLI / tooling
|
|
66
|
-
- Configuration / deployment
|
|
67
|
-
- Documentation
|
|
68
|
-
- Other
|
|
69
|
-
validations:
|
|
70
|
-
required: true
|
|
71
|
-
- type: textarea
|
|
72
|
-
id: acceptance
|
|
73
|
-
attributes:
|
|
74
|
-
label: Acceptance criteria
|
|
75
|
-
description: How will we know it's fixed? A checklist a reviewer can verify (include the test that should turn green).
|
|
76
|
-
placeholder: |
|
|
77
|
-
- [ ] ...
|
|
78
|
-
- [ ] A test that fails before the fix and passes after
|
|
79
|
-
validations:
|
|
80
|
-
required: false
|
|
81
|
-
- type: textarea
|
|
82
|
-
id: open-questions
|
|
83
|
-
attributes:
|
|
84
|
-
label: Open questions
|
|
85
|
-
description: Decisions a maintainer must make before this can be planned. Leave blank if none.
|
|
86
|
-
validations:
|
|
87
|
-
required: false
|
|
88
|
-
- type: textarea
|
|
89
|
-
id: environment
|
|
90
|
-
attributes:
|
|
91
|
-
label: Environment
|
|
92
|
-
description: Local vs deployed, branch/commit, OS, runtime versions if relevant.
|
|
93
|
-
validations:
|
|
94
|
-
required: false
|
|
95
|
-
- type: textarea
|
|
96
|
-
id: logs
|
|
97
|
-
attributes:
|
|
98
|
-
label: Logs / screenshots
|
|
99
|
-
description: Paste relevant logs or screenshots. Redact secrets and PII.
|
|
100
|
-
render: shell
|
|
101
|
-
validations:
|
|
102
|
-
required: false
|
|
103
|
-
- type: textarea
|
|
104
|
-
id: related
|
|
105
|
-
attributes:
|
|
106
|
-
label: Related links
|
|
107
|
-
description: Links to related issues, PRs, discussions, or docs. Leave blank if none.
|
|
108
|
-
validations:
|
|
109
|
-
required: false
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a defect
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for reporting. Do **not** include real secrets or production data use placeholders.
|
|
9
|
+
|
|
10
|
+
For security vulnerabilities, contact the team directly instead of filing a public issue.
|
|
11
|
+
- type: dropdown
|
|
12
|
+
id: severity
|
|
13
|
+
attributes:
|
|
14
|
+
label: Severity
|
|
15
|
+
options:
|
|
16
|
+
- Production-down / data loss
|
|
17
|
+
- Major broken core flow
|
|
18
|
+
- Minor broken edge case
|
|
19
|
+
- Cosmetic / polish
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
- type: dropdown
|
|
23
|
+
id: frequency
|
|
24
|
+
attributes:
|
|
25
|
+
label: Frequency
|
|
26
|
+
description: How often does this happen?
|
|
27
|
+
options:
|
|
28
|
+
- Always
|
|
29
|
+
- Intermittent
|
|
30
|
+
- Only once
|
|
31
|
+
validations:
|
|
32
|
+
required: true
|
|
33
|
+
- type: textarea
|
|
34
|
+
id: what-happened
|
|
35
|
+
attributes:
|
|
36
|
+
label: What happened?
|
|
37
|
+
description: A clear description of the bug and its impact.
|
|
38
|
+
validations:
|
|
39
|
+
required: true
|
|
40
|
+
- type: textarea
|
|
41
|
+
id: repro
|
|
42
|
+
attributes:
|
|
43
|
+
label: Steps to reproduce
|
|
44
|
+
description: How can a maintainer reproduce it?
|
|
45
|
+
placeholder: |
|
|
46
|
+
1. Go to ...
|
|
47
|
+
2. Do ...
|
|
48
|
+
3. See error
|
|
49
|
+
validations:
|
|
50
|
+
required: true
|
|
51
|
+
- type: textarea
|
|
52
|
+
id: expected
|
|
53
|
+
attributes:
|
|
54
|
+
label: Expected behavior
|
|
55
|
+
validations:
|
|
56
|
+
required: true
|
|
57
|
+
- type: dropdown
|
|
58
|
+
id: area
|
|
59
|
+
attributes:
|
|
60
|
+
label: Where does it occur?
|
|
61
|
+
options:
|
|
62
|
+
- Backend
|
|
63
|
+
- Frontend
|
|
64
|
+
- Both
|
|
65
|
+
- CLI / tooling
|
|
66
|
+
- Configuration / deployment
|
|
67
|
+
- Documentation
|
|
68
|
+
- Other
|
|
69
|
+
validations:
|
|
70
|
+
required: true
|
|
71
|
+
- type: textarea
|
|
72
|
+
id: acceptance
|
|
73
|
+
attributes:
|
|
74
|
+
label: Acceptance criteria
|
|
75
|
+
description: How will we know it's fixed? A checklist a reviewer can verify (include the test that should turn green).
|
|
76
|
+
placeholder: |
|
|
77
|
+
- [ ] ...
|
|
78
|
+
- [ ] A test that fails before the fix and passes after
|
|
79
|
+
validations:
|
|
80
|
+
required: false
|
|
81
|
+
- type: textarea
|
|
82
|
+
id: open-questions
|
|
83
|
+
attributes:
|
|
84
|
+
label: Open questions
|
|
85
|
+
description: Decisions a maintainer must make before this can be planned. Leave blank if none.
|
|
86
|
+
validations:
|
|
87
|
+
required: false
|
|
88
|
+
- type: textarea
|
|
89
|
+
id: environment
|
|
90
|
+
attributes:
|
|
91
|
+
label: Environment
|
|
92
|
+
description: Local vs deployed, branch/commit, OS, runtime versions if relevant.
|
|
93
|
+
validations:
|
|
94
|
+
required: false
|
|
95
|
+
- type: textarea
|
|
96
|
+
id: logs
|
|
97
|
+
attributes:
|
|
98
|
+
label: Logs / screenshots
|
|
99
|
+
description: Paste relevant logs or screenshots. Redact secrets and PII.
|
|
100
|
+
render: shell
|
|
101
|
+
validations:
|
|
102
|
+
required: false
|
|
103
|
+
- type: textarea
|
|
104
|
+
id: related
|
|
105
|
+
attributes:
|
|
106
|
+
label: Related links
|
|
107
|
+
description: Links to related issues, PRs, discussions, or docs. Leave blank if none.
|
|
108
|
+
validations:
|
|
109
|
+
required: false
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
name: Feature request
|
|
2
|
-
description: Propose a small improvement or new capability
|
|
3
|
-
labels: ["enhancement"]
|
|
4
|
-
body:
|
|
5
|
-
- type: markdown
|
|
6
|
-
attributes:
|
|
7
|
-
value: |
|
|
8
|
-
This template is for small, well-scoped improvements a focused
|
|
9
|
-
enhancement, a missing convenience, a quality-of-life fix.
|
|
10
|
-
|
|
11
|
-
For large features, architecture changes, or cross-cutting work,
|
|
12
|
-
open a planning issue or an ADR instead.
|
|
13
|
-
|
|
14
|
-
Do **not** include real secrets or production data use placeholders.
|
|
15
|
-
- type: dropdown
|
|
16
|
-
id: scope
|
|
17
|
-
attributes:
|
|
18
|
-
label: Scope
|
|
19
|
-
description: How big is this change? If it doesn't fit Small or Medium, use a planning issue instead.
|
|
20
|
-
options:
|
|
21
|
-
- Small a single file or component, no refactoring
|
|
22
|
-
- Medium touches a few files or a feature area, may need minor refactoring
|
|
23
|
-
validations:
|
|
24
|
-
required: true
|
|
25
|
-
- type: textarea
|
|
26
|
-
id: current-behavior
|
|
27
|
-
attributes:
|
|
28
|
-
label: Current behavior
|
|
29
|
-
description: How does it work today? Describe the existing behavior or limitation.
|
|
30
|
-
validations:
|
|
31
|
-
required: true
|
|
32
|
-
- type: textarea
|
|
33
|
-
id: problem
|
|
34
|
-
attributes:
|
|
35
|
-
label: Problem / motivation
|
|
36
|
-
description: What user or business need does this address? Why is the current behavior a problem?
|
|
37
|
-
validations:
|
|
38
|
-
required: true
|
|
39
|
-
- type: textarea
|
|
40
|
-
id: proposal
|
|
41
|
-
attributes:
|
|
42
|
-
label: Proposed solution
|
|
43
|
-
description: What would you like to happen?
|
|
44
|
-
validations:
|
|
45
|
-
required: true
|
|
46
|
-
- type: textarea
|
|
47
|
-
id: alternatives
|
|
48
|
-
attributes:
|
|
49
|
-
label: Alternatives considered
|
|
50
|
-
validations:
|
|
51
|
-
required: false
|
|
52
|
-
- type: textarea
|
|
53
|
-
id: acceptance
|
|
54
|
-
attributes:
|
|
55
|
-
label: Acceptance criteria
|
|
56
|
-
description: A checklist a reviewer can verify when this is done (include the tests).
|
|
57
|
-
placeholder: |
|
|
58
|
-
- [ ] ...
|
|
59
|
-
- [ ] Tests
|
|
60
|
-
validations:
|
|
61
|
-
required: false
|
|
62
|
-
- type: textarea
|
|
63
|
-
id: open-questions
|
|
64
|
-
attributes:
|
|
65
|
-
label: Open questions
|
|
66
|
-
description: Decisions a maintainer must make before this can be planned. Leave blank if none.
|
|
67
|
-
validations:
|
|
68
|
-
required: false
|
|
69
|
-
- type: textarea
|
|
70
|
-
id: related
|
|
71
|
-
attributes:
|
|
72
|
-
label: Related links
|
|
73
|
-
description: Links to related issues, PRs, discussions, or docs. Leave blank if none.
|
|
74
|
-
validations:
|
|
75
|
-
required: false
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a small improvement or new capability
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
This template is for small, well-scoped improvements a focused
|
|
9
|
+
enhancement, a missing convenience, a quality-of-life fix.
|
|
10
|
+
|
|
11
|
+
For large features, architecture changes, or cross-cutting work,
|
|
12
|
+
open a planning issue or an ADR instead.
|
|
13
|
+
|
|
14
|
+
Do **not** include real secrets or production data use placeholders.
|
|
15
|
+
- type: dropdown
|
|
16
|
+
id: scope
|
|
17
|
+
attributes:
|
|
18
|
+
label: Scope
|
|
19
|
+
description: How big is this change? If it doesn't fit Small or Medium, use a planning issue instead.
|
|
20
|
+
options:
|
|
21
|
+
- Small a single file or component, no refactoring
|
|
22
|
+
- Medium touches a few files or a feature area, may need minor refactoring
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: current-behavior
|
|
27
|
+
attributes:
|
|
28
|
+
label: Current behavior
|
|
29
|
+
description: How does it work today? Describe the existing behavior or limitation.
|
|
30
|
+
validations:
|
|
31
|
+
required: true
|
|
32
|
+
- type: textarea
|
|
33
|
+
id: problem
|
|
34
|
+
attributes:
|
|
35
|
+
label: Problem / motivation
|
|
36
|
+
description: What user or business need does this address? Why is the current behavior a problem?
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
- type: textarea
|
|
40
|
+
id: proposal
|
|
41
|
+
attributes:
|
|
42
|
+
label: Proposed solution
|
|
43
|
+
description: What would you like to happen?
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
- type: textarea
|
|
47
|
+
id: alternatives
|
|
48
|
+
attributes:
|
|
49
|
+
label: Alternatives considered
|
|
50
|
+
validations:
|
|
51
|
+
required: false
|
|
52
|
+
- type: textarea
|
|
53
|
+
id: acceptance
|
|
54
|
+
attributes:
|
|
55
|
+
label: Acceptance criteria
|
|
56
|
+
description: A checklist a reviewer can verify when this is done (include the tests).
|
|
57
|
+
placeholder: |
|
|
58
|
+
- [ ] ...
|
|
59
|
+
- [ ] Tests
|
|
60
|
+
validations:
|
|
61
|
+
required: false
|
|
62
|
+
- type: textarea
|
|
63
|
+
id: open-questions
|
|
64
|
+
attributes:
|
|
65
|
+
label: Open questions
|
|
66
|
+
description: Decisions a maintainer must make before this can be planned. Leave blank if none.
|
|
67
|
+
validations:
|
|
68
|
+
required: false
|
|
69
|
+
- type: textarea
|
|
70
|
+
id: related
|
|
71
|
+
attributes:
|
|
72
|
+
label: Related links
|
|
73
|
+
description: Links to related issues, PRs, discussions, or docs. Leave blank if none.
|
|
74
|
+
validations:
|
|
75
|
+
required: false
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/templates/release/github-release.yml. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
2
|
-
name: Publish GitHub release
|
|
3
|
-
|
|
4
|
-
on:
|
|
5
|
-
push:
|
|
6
|
-
tags:
|
|
7
|
-
- "v*"
|
|
8
|
-
|
|
9
|
-
permissions:
|
|
10
|
-
contents: write
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
publish:
|
|
14
|
-
name: Publish release
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
timeout-minutes: 10
|
|
17
|
-
steps:
|
|
18
|
-
- name: Create or update GitHub release
|
|
19
|
-
env:
|
|
20
|
-
GH_TOKEN: ${{ github.token }}
|
|
21
|
-
TAG: ${{ github.ref_name }}
|
|
22
|
-
shell: bash
|
|
23
|
-
run: |
|
|
24
|
-
set -euo pipefail
|
|
25
|
-
|
|
26
|
-
if gh release view "$TAG" >/dev/null 2>&1; then
|
|
27
|
-
gh release edit "$TAG" --title "$TAG" --generate-notes
|
|
28
|
-
else
|
|
29
|
-
gh release create "$TAG" --title "$TAG" --generate-notes
|
|
30
|
-
fi
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/templates/release/github-release.yml. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
2
|
+
name: Publish GitHub release
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
tags:
|
|
7
|
+
- "v*"
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
name: Publish release
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
timeout-minutes: 10
|
|
17
|
+
steps:
|
|
18
|
+
- name: Create or update GitHub release
|
|
19
|
+
env:
|
|
20
|
+
GH_TOKEN: ${{ github.token }}
|
|
21
|
+
TAG: ${{ github.ref_name }}
|
|
22
|
+
shell: bash
|
|
23
|
+
run: |
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
if gh release view "$TAG" >/dev/null 2>&1; then
|
|
27
|
+
gh release edit "$TAG" --title "$TAG" --generate-notes
|
|
28
|
+
else
|
|
29
|
+
gh release create "$TAG" --title "$TAG" --generate-notes
|
|
30
|
+
fi
|
|
@@ -541,6 +541,11 @@ timeout-minutes: 90
|
|
|
541
541
|
${{ env.VERIFY_COMMANDS }}
|
|
542
542
|
```
|
|
543
543
|
|
|
544
|
+
When `.opencode/scripts/check-diff.mjs` exists, also run
|
|
545
|
+
`node .opencode/scripts/check-diff.mjs`.
|
|
546
|
+
It must exit 0: delete the comments and tests it lists. The merge gate runs it too and does not
|
|
547
|
+
merge while it fails.
|
|
548
|
+
|
|
544
549
|
7. Select one review outcome.
|
|
545
550
|
|
|
546
551
|
- **implemented**: You made the requested change, verification passed, and you will propose
|
|
@@ -707,6 +707,12 @@ timeout-minutes: 180
|
|
|
707
707
|
|
|
708
708
|
Never open a pull request that does not pass them.
|
|
709
709
|
|
|
710
|
+
When `.opencode/scripts/check-diff.mjs` exists, also run
|
|
711
|
+
`node .opencode/scripts/check-diff.mjs`
|
|
712
|
+
on both paths. It must exit 0. It holds the comments and tests you add to the size of the
|
|
713
|
+
change and makes you clean the files you touched; fix every line it lists. The merge gate
|
|
714
|
+
runs it again and does not merge while it fails.
|
|
715
|
+
|
|
710
716
|
5. Do not touch `changelog.json`. The workflow records the change itself once the work is on
|
|
711
717
|
the default branch. Every implement used to edit that one file, so two runs whose branches
|
|
712
718
|
were cut before the other merged conflicted on it and failed to open a pull request with the
|
|
@@ -43,9 +43,16 @@ env:
|
|
|
43
43
|
BLAST_HIGH_LINES: "800"
|
|
44
44
|
BLAST_MEDIUM_FILES: "5"
|
|
45
45
|
BLAST_MEDIUM_LINES: "200"
|
|
46
|
+
# Paths that change no runtime behaviour: tests, docs, specs, translations and generated
|
|
47
|
+
# migration code. They count toward neither size nor owner paths, so a feature's tests do not
|
|
48
|
+
# double its blast radius. Protected paths are still matched against every file.
|
|
49
|
+
BLAST_IGNORE_PATHS: '(^|/)([Tt]ests?|__tests__|__snapshots__|e2e)/|(^|/)[^/]+\.[A-Za-z]*Tests?/|\.(test|spec)\.[cm]?[jt]sx?$|\.snap$|\.feature$|(^|/)openspec/|\.md$|(^|/)evidence/|(^|/)(i18n|locales?|translations?)/[^/]*\.json$|\.Designer\.cs$|ModelSnapshot\.cs$'
|
|
46
50
|
# Agent confidence below which the pull request goes to a human. The agent reports the number;
|
|
47
51
|
# this decides what it means.
|
|
48
52
|
CONFIDENCE_THRESHOLD: "0.8"
|
|
53
|
+
# Replay the verification plan when the gate hands the pull request to a person, so the
|
|
54
|
+
# reviewer sees the screenshots before deciding. "false" leaves evidence to the merge.
|
|
55
|
+
EVIDENCE_BEFORE_REVIEW: "true"
|
|
49
56
|
WORKING_LABEL: bot-working
|
|
50
57
|
IMPLEMENT_LABEL: implement
|
|
51
58
|
REVIEW_LABEL: review
|
|
@@ -124,7 +131,9 @@ on:
|
|
|
124
131
|
# this entry activation read needs.protected_changes.outputs.requires_review before
|
|
125
132
|
# protected_changes had started; the value was '' and the clause was always true
|
|
126
133
|
# (Pliny-Bot run 34042143350: activation finished 18 s before protected_changes began).
|
|
127
|
-
|
|
134
|
+
# code_rules is here for the same reason: the prompt prints its result and report, and the
|
|
135
|
+
# prompt is rendered in activation.
|
|
136
|
+
needs: [protected_changes, code_rules]
|
|
128
137
|
|
|
129
138
|
# Rung 4. Router has classified the event; identify-gate-subject validates PR ownership,
|
|
130
139
|
# resolves the closing issue, and confirms the CI verdict.
|
|
@@ -203,6 +212,8 @@ jobs:
|
|
|
203
212
|
required_owners: ${{ steps.blast.outputs.required_owners }}
|
|
204
213
|
files_changed: ${{ steps.blast.outputs.files_changed }}
|
|
205
214
|
lines_changed: ${{ steps.blast.outputs.lines_changed }}
|
|
215
|
+
files_total: ${{ steps.blast.outputs.files_total }}
|
|
216
|
+
lines_total: ${{ steps.blast.outputs.lines_total }}
|
|
206
217
|
owner_hit: ${{ steps.blast.outputs.owner_hit }}
|
|
207
218
|
sensitive_hit: ${{ steps.blast.outputs.sensitive_hit }}
|
|
208
219
|
# The decision, computed once. A protected path holds the merge for a human, but it must
|
|
@@ -229,6 +240,52 @@ jobs:
|
|
|
229
240
|
high-lines: ${{ env.BLAST_HIGH_LINES }}
|
|
230
241
|
medium-files: ${{ env.BLAST_MEDIUM_FILES }}
|
|
231
242
|
medium-lines: ${{ env.BLAST_MEDIUM_LINES }}
|
|
243
|
+
ignore-paths: ${{ env.BLAST_IGNORE_PATHS }}
|
|
244
|
+
|
|
245
|
+
# Rung 4c. The comments and tests the change adds, measured by the harness's check-diff on the
|
|
246
|
+
# pull request head before any model reads it. Prose in the implement prompt did not hold bot
|
|
247
|
+
# pull requests to the guardrails: they added 27-63% comment lines in October 2026. `fail`
|
|
248
|
+
# stops an auto-merge in the validator; the agent is told to repair it like a CI failure.
|
|
249
|
+
# A repository without the script reports `absent` and is not held to it.
|
|
250
|
+
code_rules:
|
|
251
|
+
needs: subject
|
|
252
|
+
if: needs.subject.outputs.found == 'true'
|
|
253
|
+
runs-on: agents-arc
|
|
254
|
+
timeout-minutes: 10
|
|
255
|
+
permissions:
|
|
256
|
+
contents: read
|
|
257
|
+
outputs:
|
|
258
|
+
result: ${{ steps.check.outputs.result }}
|
|
259
|
+
report: ${{ steps.check.outputs.report }}
|
|
260
|
+
steps:
|
|
261
|
+
- name: Checkout the pull request
|
|
262
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
263
|
+
with:
|
|
264
|
+
ref: refs/pull/${{ needs.subject.outputs.pr }}/head
|
|
265
|
+
fetch-depth: 0
|
|
266
|
+
persist-credentials: false
|
|
267
|
+
- name: Check the comments and tests it adds
|
|
268
|
+
id: check
|
|
269
|
+
env:
|
|
270
|
+
BASE: origin/${{ github.event.repository.default_branch || 'main' }}
|
|
271
|
+
run: |
|
|
272
|
+
set -uo pipefail
|
|
273
|
+
if [ ! -f .opencode/scripts/check-diff.mjs ]; then
|
|
274
|
+
echo "result=absent" >> "$GITHUB_OUTPUT"
|
|
275
|
+
echo "check-diff is not installed (agent-harness 3.2.0 or later ships it), so comments and tests were not checked." >> "$GITHUB_STEP_SUMMARY"
|
|
276
|
+
exit 0
|
|
277
|
+
fi
|
|
278
|
+
report=$(node .opencode/scripts/check-diff.mjs --base "$BASE" 2>&1)
|
|
279
|
+
code=$?
|
|
280
|
+
case "$code" in 0) result=pass ;; 1) result=fail ;; *) result=error ;; esac
|
|
281
|
+
delimiter="EOF_$(openssl rand -hex 8)"
|
|
282
|
+
{
|
|
283
|
+
echo "result=$result"
|
|
284
|
+
echo "report<<$delimiter"
|
|
285
|
+
printf '%s\n' "${report:0:8000}"
|
|
286
|
+
echo "$delimiter"
|
|
287
|
+
} >> "$GITHUB_OUTPUT"
|
|
288
|
+
printf '```\n%s\n```\n' "$report" >> "$GITHUB_STEP_SUMMARY"
|
|
232
289
|
|
|
233
290
|
review_required:
|
|
234
291
|
needs: [subject, protected_changes]
|
|
@@ -291,6 +348,18 @@ jobs:
|
|
|
291
348
|
Required owners: `${{ needs.protected_changes.outputs.required_owners || 'none configured' }}`
|
|
292
349
|
|
|
293
350
|
**Verdict:** owner-review
|
|
351
|
+
- name: Replay the verification plan for the owner
|
|
352
|
+
if: needs.protected_changes.outputs.holds_review == 'true' && env.EVIDENCE_BEFORE_REVIEW == 'true'
|
|
353
|
+
continue-on-error: true
|
|
354
|
+
env:
|
|
355
|
+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
|
356
|
+
REPO: ${{ github.repository }}
|
|
357
|
+
PR: ${{ needs.subject.outputs.pr }}
|
|
358
|
+
run: |
|
|
359
|
+
set -euo pipefail
|
|
360
|
+
branch=$(gh api "repos/$REPO" --jq .default_branch)
|
|
361
|
+
gh api "repos/$REPO/actions/workflows/work-router.yml/dispatches" --method POST \
|
|
362
|
+
-f ref="$branch" -f "inputs[operation]=evidence" -f "inputs[pr-number]=$PR"
|
|
294
363
|
|
|
295
364
|
reserve:
|
|
296
365
|
needs: subject
|
|
@@ -340,7 +409,7 @@ jobs:
|
|
|
340
409
|
Problems found in PR #${{ needs.subject.outputs.pr }}. ${{ steps.conflicts.outputs.has_conflicts == 'true' && 'Merge conflicts detected.' || 'CI failed.' }}
|
|
341
410
|
Bot is working on fixing it.
|
|
342
411
|
validate_output:
|
|
343
|
-
needs: [activation, subject, protected_changes, agent, safe_outputs]
|
|
412
|
+
needs: [activation, subject, protected_changes, code_rules, agent, safe_outputs]
|
|
344
413
|
if: >
|
|
345
414
|
always() &&
|
|
346
415
|
needs.agent.result == 'success' &&
|
|
@@ -374,6 +443,7 @@ jobs:
|
|
|
374
443
|
protected-hit: ${{ needs.protected_changes.outputs.requires_review }}
|
|
375
444
|
owner-hit: ${{ needs.protected_changes.outputs.owner_hit }}
|
|
376
445
|
confidence-threshold: ${{ env.CONFIDENCE_THRESHOLD }}
|
|
446
|
+
code-rules: ${{ needs.code_rules.outputs.result }}
|
|
377
447
|
conclude:
|
|
378
448
|
needs: [activation, subject, protected_changes, agent, safe_outputs, validate_output]
|
|
379
449
|
# `protected_changes.result == 'success'` is stated rather than relied on. GitHub skips a job
|
|
@@ -440,7 +510,7 @@ jobs:
|
|
|
440
510
|
| Disposition | `${{ needs.validate_output.outputs.outcome }}` |
|
|
441
511
|
| CI | ${{ needs.subject.outputs.conclusion }} |
|
|
442
512
|
| Blast radius | ${{ needs.protected_changes.outputs.level }} |
|
|
443
|
-
| Files / lines | ${{ needs.protected_changes.outputs.files_changed }} / ${{ needs.protected_changes.outputs.lines_changed }} |
|
|
513
|
+
| Files / lines | ${{ needs.protected_changes.outputs.files_changed }} / ${{ needs.protected_changes.outputs.lines_changed }} counted, ${{ needs.protected_changes.outputs.files_total }} / ${{ needs.protected_changes.outputs.lines_total }} in the diff |
|
|
444
514
|
| Protected paths | ${{ needs.protected_changes.outputs.requires_review == 'true' && 'yes' || 'no' }} |
|
|
445
515
|
| Owner paths | ${{ needs.protected_changes.outputs.owner_hit == 'true' && 'yes' || 'no' }} |
|
|
446
516
|
${{ needs.validate_output.outputs.outcome == 'owner-review'
|
|
@@ -453,6 +523,7 @@ jobs:
|
|
|
453
523
|
```
|
|
454
524
|
|
|
455
525
|
Findings and verification on the linked issue: #${{ needs.subject.outputs.issue }}. [View this workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
|
526
|
+
${{ env.EVIDENCE_BEFORE_REVIEW == 'true' && contains(fromJson('["human-review","owner-review"]'), needs.validate_output.outputs.outcome) && 'Screenshots of this head follow in their own comment if it carries a verification plan. Approving the pull request merges it.' || '' }}
|
|
456
527
|
- name: Merge approved pull request
|
|
457
528
|
if: needs.validate_output.outputs.outcome == 'auto-merge'
|
|
458
529
|
env:
|
|
@@ -512,6 +583,20 @@ jobs:
|
|
|
512
583
|
token: ${{ steps.app-token.outputs.token }}
|
|
513
584
|
issue-number: ${{ needs.subject.outputs.issue }}
|
|
514
585
|
labels: ${{ env.WORKING_LABEL }}
|
|
586
|
+
# A person decides this one, so the screenshots come before the decision, in a router run of
|
|
587
|
+
# their own outside the belt. Never on auto-merge: that dispatch would race the merge.
|
|
588
|
+
- name: Replay the verification plan for the reviewer
|
|
589
|
+
if: env.EVIDENCE_BEFORE_REVIEW == 'true' && contains(fromJson('["human-review","owner-review"]'), needs.validate_output.outputs.outcome)
|
|
590
|
+
continue-on-error: true
|
|
591
|
+
env:
|
|
592
|
+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
|
593
|
+
REPO: ${{ github.repository }}
|
|
594
|
+
PR: ${{ needs.subject.outputs.pr }}
|
|
595
|
+
run: |
|
|
596
|
+
set -euo pipefail
|
|
597
|
+
branch=$(gh api "repos/$REPO" --jq .default_branch)
|
|
598
|
+
gh api "repos/$REPO/actions/workflows/work-router.yml/dispatches" --method POST \
|
|
599
|
+
-f ref="$branch" -f "inputs[operation]=evidence" -f "inputs[pr-number]=$PR"
|
|
515
600
|
- name: Clear merged issue labels
|
|
516
601
|
if: needs.validate_output.outputs.outcome == 'auto-merge'
|
|
517
602
|
uses: ./.github/actions/remove-issue-labels
|
|
@@ -817,6 +902,18 @@ timeout-minutes: 120
|
|
|
817
902
|
${{ needs.protected_changes.outputs.signals }}
|
|
818
903
|
```
|
|
819
904
|
|
|
905
|
+
**Comments and tests (`check-diff`): `${{ needs.code_rules.outputs.result }}`**
|
|
906
|
+
|
|
907
|
+
```
|
|
908
|
+
${{ needs.code_rules.outputs.report }}
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
When that is `fail`, repairing it is part of this run whatever CI concluded: delete the
|
|
912
|
+
comments and tests it lists, leave every file it names with no slop, run
|
|
913
|
+
`node .opencode/scripts/check-diff.mjs`
|
|
914
|
+
until it exits 0, then verify, push and report `remediated` as in step 6. An `assessed`
|
|
915
|
+
verdict while it fails blocks the pull request.
|
|
916
|
+
|
|
820
917
|
- **success** → step 4, then step 5 (review the change).
|
|
821
918
|
- **failure** → step 4, then step 6 (CI remediation).
|
|
822
919
|
- **action_required, cancelled, timed_out, or anything else** → CI did not produce a usable
|