@plainconceptsplatform/workflows 0.4.13 → 0.4.19
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/loops/templates/agentics/agentics-checks.yml +2 -2
- package/loops/templates/agentics/agentics-maintenance.yml +4 -4
- package/loops/templates/ci/app-ci-dotnet-next.yml +6 -6
- package/loops/templates/ci/app-ci-node-monorepo.yml +9 -9
- package/loops/templates/release/github-release.yml +1 -1
- package/loops/workflows/agent-apply-review.md +7 -6
- package/loops/workflows/agent-audit.md +3 -3
- package/loops/workflows/agent-direct.md +7 -6
- package/loops/workflows/agent-implement.md +21 -14
- package/loops/workflows/agent-merge-gate.md +34 -19
- package/loops/workflows/agent-propose.md +5 -5
- package/loops/workflows/agent-refine.md +7 -6
- package/loops/workflows/authorize-bot-work.yml +8 -10
- package/loops/workflows/work-router.yml +8 -8
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@ concurrency:
|
|
|
26
26
|
jobs:
|
|
27
27
|
verify-lockfiles:
|
|
28
28
|
name: Verify generated agent lockfiles
|
|
29
|
-
runs-on:
|
|
29
|
+
runs-on: RunnerLandingZone
|
|
30
30
|
timeout-minutes: 10
|
|
31
31
|
steps:
|
|
32
32
|
- name: Checkout repository
|
|
@@ -56,7 +56,7 @@ jobs:
|
|
|
56
56
|
|
|
57
57
|
lint-workflows:
|
|
58
58
|
name: Lint authored workflows and shell
|
|
59
|
-
runs-on:
|
|
59
|
+
runs-on: RunnerLandingZone
|
|
60
60
|
timeout-minutes: 10
|
|
61
61
|
steps:
|
|
62
62
|
- name: Checkout repository
|
|
@@ -48,7 +48,7 @@ permissions: {}
|
|
|
48
48
|
jobs:
|
|
49
49
|
close-expired-discussions:
|
|
50
50
|
if: ${{ !(github.event.repository.fork) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
|
|
51
|
-
runs-on:
|
|
51
|
+
runs-on: RunnerLandingZone
|
|
52
52
|
permissions:
|
|
53
53
|
discussions: write
|
|
54
54
|
steps:
|
|
@@ -66,7 +66,7 @@ jobs:
|
|
|
66
66
|
await main();
|
|
67
67
|
close-expired-issues:
|
|
68
68
|
if: ${{ !(github.event.repository.fork) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
|
|
69
|
-
runs-on:
|
|
69
|
+
runs-on: RunnerLandingZone
|
|
70
70
|
permissions:
|
|
71
71
|
issues: write
|
|
72
72
|
steps:
|
|
@@ -84,7 +84,7 @@ jobs:
|
|
|
84
84
|
await main();
|
|
85
85
|
close-expired-pull-requests:
|
|
86
86
|
if: ${{ !(github.event.repository.fork) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
|
|
87
|
-
runs-on:
|
|
87
|
+
runs-on: RunnerLandingZone
|
|
88
88
|
permissions:
|
|
89
89
|
pull-requests: write
|
|
90
90
|
steps:
|
|
@@ -102,7 +102,7 @@ jobs:
|
|
|
102
102
|
await main();
|
|
103
103
|
cleanup-cache-memory:
|
|
104
104
|
if: ${{ !(github.event.repository.fork) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'clean_cache_memories') }}
|
|
105
|
-
runs-on:
|
|
105
|
+
runs-on: RunnerLandingZone
|
|
106
106
|
permissions:
|
|
107
107
|
actions: write
|
|
108
108
|
steps:
|
|
@@ -47,7 +47,7 @@ jobs:
|
|
|
47
47
|
api:
|
|
48
48
|
name: API (.NET)
|
|
49
49
|
if: github.event_name != 'schedule'
|
|
50
|
-
runs-on:
|
|
50
|
+
runs-on: RunnerLandingZone
|
|
51
51
|
timeout-minutes: 30
|
|
52
52
|
services:
|
|
53
53
|
sqlserver:
|
|
@@ -104,7 +104,7 @@ jobs:
|
|
|
104
104
|
web:
|
|
105
105
|
name: Web (Next.js)
|
|
106
106
|
if: github.event_name != 'schedule'
|
|
107
|
-
runs-on:
|
|
107
|
+
runs-on: RunnerLandingZone
|
|
108
108
|
timeout-minutes: 15
|
|
109
109
|
steps:
|
|
110
110
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
@@ -134,14 +134,14 @@ jobs:
|
|
|
134
134
|
|
|
135
135
|
secret-scan:
|
|
136
136
|
name: Secret scan (TruffleHog)
|
|
137
|
-
runs-on:
|
|
137
|
+
runs-on: RunnerLandingZone
|
|
138
138
|
steps:
|
|
139
139
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
140
140
|
- run: docker run --rm -v "${{ github.workspace }}:/repo" "$TRUFFLEHOG_IMAGE" filesystem /repo --only-verified --fail --no-update
|
|
141
141
|
|
|
142
142
|
deps-and-iac-scan:
|
|
143
143
|
name: Dependencies and IaC (Trivy)
|
|
144
|
-
runs-on:
|
|
144
|
+
runs-on: RunnerLandingZone
|
|
145
145
|
steps:
|
|
146
146
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
147
147
|
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
|
|
@@ -155,14 +155,14 @@ jobs:
|
|
|
155
155
|
|
|
156
156
|
sast-scan:
|
|
157
157
|
name: SAST (Semgrep)
|
|
158
|
-
runs-on:
|
|
158
|
+
runs-on: RunnerLandingZone
|
|
159
159
|
steps:
|
|
160
160
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
161
161
|
- run: docker run --rm -v "${{ github.workspace }}:/src" -w /src "$SEMGREP_IMAGE" semgrep scan --error --metrics=off --oss-only --disable-version-check --config p/default --config p/security-audit --config p/secrets --config p/csharp --config p/typescript --config p/react --exclude-rule yaml.github-actions.security.github-actions-mutable-action-tag.github-actions-mutable-action-tag
|
|
162
162
|
|
|
163
163
|
sbom:
|
|
164
164
|
name: SBOM (CycloneDX)
|
|
165
|
-
runs-on:
|
|
165
|
+
runs-on: RunnerLandingZone
|
|
166
166
|
steps:
|
|
167
167
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
168
168
|
- uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0
|
|
@@ -37,7 +37,7 @@ jobs:
|
|
|
37
37
|
lint:
|
|
38
38
|
name: Lint (Biome)
|
|
39
39
|
if: github.event_name != 'schedule'
|
|
40
|
-
runs-on:
|
|
40
|
+
runs-on: RunnerLandingZone
|
|
41
41
|
steps:
|
|
42
42
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
43
43
|
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
|
|
@@ -50,7 +50,7 @@ jobs:
|
|
|
50
50
|
web:
|
|
51
51
|
name: Web (Next.js static export)
|
|
52
52
|
if: github.event_name != 'schedule'
|
|
53
|
-
runs-on:
|
|
53
|
+
runs-on: RunnerLandingZone
|
|
54
54
|
steps:
|
|
55
55
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
56
56
|
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
|
|
@@ -73,7 +73,7 @@ jobs:
|
|
|
73
73
|
name: E2E (Playwright)
|
|
74
74
|
if: github.event_name != 'schedule'
|
|
75
75
|
needs: web
|
|
76
|
-
runs-on:
|
|
76
|
+
runs-on: RunnerLandingZone
|
|
77
77
|
steps:
|
|
78
78
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
79
79
|
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
|
|
@@ -98,7 +98,7 @@ jobs:
|
|
|
98
98
|
name: Desktop (Electron)
|
|
99
99
|
if: github.event_name != 'schedule'
|
|
100
100
|
needs: web
|
|
101
|
-
runs-on:
|
|
101
|
+
runs-on: RunnerLandingZone
|
|
102
102
|
steps:
|
|
103
103
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
104
104
|
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
|
|
@@ -122,7 +122,7 @@ jobs:
|
|
|
122
122
|
mobile:
|
|
123
123
|
name: Mobile (Capacitor)
|
|
124
124
|
if: github.event_name != 'schedule'
|
|
125
|
-
runs-on:
|
|
125
|
+
runs-on: RunnerLandingZone
|
|
126
126
|
steps:
|
|
127
127
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
128
128
|
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
|
|
@@ -141,14 +141,14 @@ jobs:
|
|
|
141
141
|
|
|
142
142
|
secret-scan:
|
|
143
143
|
name: Secret scan (TruffleHog)
|
|
144
|
-
runs-on:
|
|
144
|
+
runs-on: RunnerLandingZone
|
|
145
145
|
steps:
|
|
146
146
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
147
147
|
- run: docker run --rm -v "${{ github.workspace }}:/repo" "$TRUFFLEHOG_IMAGE" filesystem /repo --only-verified --fail --no-update
|
|
148
148
|
|
|
149
149
|
deps-and-iac-scan:
|
|
150
150
|
name: Dependencies and IaC (Trivy)
|
|
151
|
-
runs-on:
|
|
151
|
+
runs-on: RunnerLandingZone
|
|
152
152
|
steps:
|
|
153
153
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
154
154
|
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
|
|
@@ -162,14 +162,14 @@ jobs:
|
|
|
162
162
|
|
|
163
163
|
sast-scan:
|
|
164
164
|
name: SAST (Semgrep)
|
|
165
|
-
runs-on:
|
|
165
|
+
runs-on: RunnerLandingZone
|
|
166
166
|
steps:
|
|
167
167
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
168
168
|
- run: docker run --rm -v "${{ github.workspace }}:/src" -w /src "$SEMGREP_IMAGE" semgrep scan --error --metrics=off --oss-only --disable-version-check --config p/default --config p/security-audit --config p/secrets --config p/typescript --config p/react --exclude-rule yaml.github-actions.security.github-actions-mutable-action-tag.github-actions-mutable-action-tag
|
|
169
169
|
|
|
170
170
|
sbom:
|
|
171
171
|
name: SBOM (CycloneDX)
|
|
172
|
-
runs-on:
|
|
172
|
+
runs-on: RunnerLandingZone
|
|
173
173
|
steps:
|
|
174
174
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
175
175
|
- uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0
|
|
@@ -7,6 +7,7 @@ env:
|
|
|
7
7
|
REVIEW_MARKER: "<!-- agent-apply-review -->"
|
|
8
8
|
INCOMPLETE_COMMENT: "Automated review feedback ended without an outcome. The issue remains for a retry."
|
|
9
9
|
ISSUE_CONTEXT_PATH: /tmp/gh-aw/agent/issue-context.json
|
|
10
|
+
GH_AW_ALLOWED_BOTS: "platform-devbox[bot],github-actions[bot]"
|
|
10
11
|
GIT_AUTHOR_NAME: "github-actions[bot]"
|
|
11
12
|
GIT_AUTHOR_EMAIL: "github-actions[bot]@users.noreply.github.com"
|
|
12
13
|
GIT_COMMITTER_NAME: "github-actions[bot]"
|
|
@@ -43,7 +44,7 @@ on:
|
|
|
43
44
|
# substantive feedback. A custom job, not `on.steps`, because the prompt needs these values.
|
|
44
45
|
jobs:
|
|
45
46
|
subject:
|
|
46
|
-
runs-on:
|
|
47
|
+
runs-on: RunnerLandingZone
|
|
47
48
|
permissions:
|
|
48
49
|
contents: read
|
|
49
50
|
issues: read
|
|
@@ -112,7 +113,7 @@ jobs:
|
|
|
112
113
|
reserve:
|
|
113
114
|
needs: subject
|
|
114
115
|
if: needs.subject.outputs.found == 'true' && needs.subject.outputs.issue != ''
|
|
115
|
-
runs-on:
|
|
116
|
+
runs-on: RunnerLandingZone
|
|
116
117
|
permissions:
|
|
117
118
|
contents: read
|
|
118
119
|
issues: write
|
|
@@ -144,7 +145,7 @@ jobs:
|
|
|
144
145
|
if: >
|
|
145
146
|
needs.agent.result == 'success' &&
|
|
146
147
|
needs.safe_outputs.result == 'success'
|
|
147
|
-
runs-on:
|
|
148
|
+
runs-on: RunnerLandingZone
|
|
148
149
|
permissions:
|
|
149
150
|
contents: write
|
|
150
151
|
issues: write
|
|
@@ -173,7 +174,7 @@ jobs:
|
|
|
173
174
|
always() &&
|
|
174
175
|
needs.subject.outputs.found == 'true' &&
|
|
175
176
|
needs.agent.result != 'success'
|
|
176
|
-
runs-on:
|
|
177
|
+
runs-on: RunnerLandingZone
|
|
177
178
|
permissions:
|
|
178
179
|
contents: read
|
|
179
180
|
issues: write
|
|
@@ -212,8 +213,8 @@ jobs:
|
|
|
212
213
|
|
|
213
214
|
if: needs.subject.outputs.found == 'true'
|
|
214
215
|
|
|
215
|
-
runs-on:
|
|
216
|
-
runs-on-slim:
|
|
216
|
+
runs-on: RunnerLandingZone
|
|
217
|
+
runs-on-slim: RunnerLandingZone
|
|
217
218
|
|
|
218
219
|
secrets:
|
|
219
220
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
@@ -42,8 +42,8 @@ on:
|
|
|
42
42
|
query: "is:issue is:open label:audit"
|
|
43
43
|
max: 3
|
|
44
44
|
|
|
45
|
-
runs-on:
|
|
46
|
-
runs-on-slim:
|
|
45
|
+
runs-on: RunnerLandingZone
|
|
46
|
+
runs-on-slim: RunnerLandingZone
|
|
47
47
|
|
|
48
48
|
secrets:
|
|
49
49
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
@@ -76,7 +76,7 @@ jobs:
|
|
|
76
76
|
needs.agent.result == 'success' &&
|
|
77
77
|
needs.safe_outputs.result == 'success' &&
|
|
78
78
|
needs.safe_outputs.outputs.process_safe_outputs_processed_count != '0'
|
|
79
|
-
runs-on:
|
|
79
|
+
runs-on: RunnerLandingZone
|
|
80
80
|
permissions:
|
|
81
81
|
contents: read
|
|
82
82
|
issues: write
|
|
@@ -8,6 +8,7 @@ env:
|
|
|
8
8
|
DIRECT_MARKER: "<!-- agent-direct -->"
|
|
9
9
|
INCOMPLETE_COMMENT: "Automated direct execution ended without an outcome. The direct label remains for a retry."
|
|
10
10
|
ISSUE_CONTEXT_PATH: /tmp/gh-aw/agent/issue-context.json
|
|
11
|
+
GH_AW_ALLOWED_BOTS: "platform-devbox[bot],github-actions[bot]"
|
|
11
12
|
description: |
|
|
12
13
|
Executes a free-form instruction from an issue body and posts the results back on the same
|
|
13
14
|
issue. The issue body IS the prompt — the agent does whatever the maintainer asked for and
|
|
@@ -44,7 +45,7 @@ on:
|
|
|
44
45
|
|
|
45
46
|
jobs:
|
|
46
47
|
eligibility:
|
|
47
|
-
runs-on:
|
|
48
|
+
runs-on: RunnerLandingZone
|
|
48
49
|
permissions:
|
|
49
50
|
issues: read
|
|
50
51
|
outputs:
|
|
@@ -71,7 +72,7 @@ jobs:
|
|
|
71
72
|
reserve:
|
|
72
73
|
needs: eligibility
|
|
73
74
|
if: needs.eligibility.outputs.eligible == 'true'
|
|
74
|
-
runs-on:
|
|
75
|
+
runs-on: RunnerLandingZone
|
|
75
76
|
permissions:
|
|
76
77
|
contents: read
|
|
77
78
|
issues: write
|
|
@@ -103,7 +104,7 @@ jobs:
|
|
|
103
104
|
if: >
|
|
104
105
|
needs.agent.result == 'success' &&
|
|
105
106
|
needs.safe_outputs.result == 'success'
|
|
106
|
-
runs-on:
|
|
107
|
+
runs-on: RunnerLandingZone
|
|
107
108
|
permissions:
|
|
108
109
|
contents: read
|
|
109
110
|
issues: write
|
|
@@ -139,7 +140,7 @@ jobs:
|
|
|
139
140
|
always() &&
|
|
140
141
|
needs.eligibility.outputs.eligible == 'true' &&
|
|
141
142
|
needs.agent.result != 'success'
|
|
142
|
-
runs-on:
|
|
143
|
+
runs-on: RunnerLandingZone
|
|
143
144
|
permissions:
|
|
144
145
|
contents: read
|
|
145
146
|
issues: write
|
|
@@ -178,8 +179,8 @@ jobs:
|
|
|
178
179
|
|
|
179
180
|
if: inputs.issue-number != '' && needs.eligibility.outputs.eligible == 'true'
|
|
180
181
|
|
|
181
|
-
runs-on:
|
|
182
|
-
runs-on-slim:
|
|
182
|
+
runs-on: RunnerLandingZone
|
|
183
|
+
runs-on-slim: RunnerLandingZone
|
|
183
184
|
|
|
184
185
|
secrets:
|
|
185
186
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
@@ -12,6 +12,7 @@ env:
|
|
|
12
12
|
IMPLEMENT_MARKER: "<!-- agent-implement -->"
|
|
13
13
|
INCOMPLETE_COMMENT: "Automated implementation ended without an outcome. The implement label remains for a retry."
|
|
14
14
|
ISSUE_CONTEXT_PATH: /tmp/gh-aw/agent/implementation-context.json
|
|
15
|
+
GH_AW_ALLOWED_BOTS: "platform-devbox[bot],github-actions[bot]"
|
|
15
16
|
description: |
|
|
16
17
|
Implements an issue and opens a pull request. Stops there: the merge decision belongs to
|
|
17
18
|
`agent-merge-gate.md`, which runs once CI has reported. Replaces the `impl-*` chain in
|
|
@@ -42,7 +43,7 @@ on:
|
|
|
42
43
|
|
|
43
44
|
jobs:
|
|
44
45
|
eligibility:
|
|
45
|
-
runs-on:
|
|
46
|
+
runs-on: RunnerLandingZone
|
|
46
47
|
permissions:
|
|
47
48
|
issues: read
|
|
48
49
|
outputs:
|
|
@@ -69,7 +70,7 @@ jobs:
|
|
|
69
70
|
reserve:
|
|
70
71
|
needs: eligibility
|
|
71
72
|
if: needs.eligibility.outputs.eligible == 'true'
|
|
72
|
-
runs-on:
|
|
73
|
+
runs-on: RunnerLandingZone
|
|
73
74
|
permissions:
|
|
74
75
|
contents: read
|
|
75
76
|
issues: write
|
|
@@ -107,7 +108,7 @@ jobs:
|
|
|
107
108
|
if: >
|
|
108
109
|
needs.agent.result == 'success' &&
|
|
109
110
|
needs.safe_outputs.result == 'success'
|
|
110
|
-
runs-on:
|
|
111
|
+
runs-on: RunnerLandingZone
|
|
111
112
|
permissions:
|
|
112
113
|
contents: read
|
|
113
114
|
issues: write
|
|
@@ -143,7 +144,7 @@ jobs:
|
|
|
143
144
|
always() &&
|
|
144
145
|
needs.eligibility.outputs.eligible == 'true' &&
|
|
145
146
|
needs.agent.result != 'success'
|
|
146
|
-
runs-on:
|
|
147
|
+
runs-on: RunnerLandingZone
|
|
147
148
|
permissions:
|
|
148
149
|
contents: read
|
|
149
150
|
issues: write
|
|
@@ -182,8 +183,8 @@ jobs:
|
|
|
182
183
|
|
|
183
184
|
if: inputs.issue-number != '' && needs.eligibility.outputs.eligible == 'true'
|
|
184
185
|
|
|
185
|
-
runs-on:
|
|
186
|
-
runs-on-slim:
|
|
186
|
+
runs-on: RunnerLandingZone
|
|
187
|
+
runs-on-slim: RunnerLandingZone
|
|
187
188
|
|
|
188
189
|
secrets:
|
|
189
190
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
@@ -238,23 +239,29 @@ timeout-minutes: 90
|
|
|
238
239
|
a. Load the `ob-plan-goal` skill. It defines a mandatory, gate-sequenced pipeline:
|
|
239
240
|
`explore · propose · apply · verify · archive · evidence · output · report`
|
|
240
241
|
|
|
241
|
-
b.
|
|
242
|
+
b. **Refined-issue fast path:** If the issue context at `${{ env.ISSUE_CONTEXT_PATH }}`
|
|
243
|
+
already contains structured acceptance criteria (e.g. "## Acceptance criteria",
|
|
244
|
+
"### Scenario:", Gherkin blocks), affected artifacts, and design decisions, the
|
|
245
|
+
`ob-plan-goal` skill will skip the explore and propose phases and go directly to
|
|
246
|
+
apply. Do not override this: re-exploring a pre-refined issue wastes tokens.
|
|
247
|
+
|
|
248
|
+
c. Execute every phase in order. Each phase loads its own sub-skill (`ob-plan-explore`,
|
|
242
249
|
`ob-plan-propose`, `ob-plan-apply`, `ob-repo-verify`, `ob-plan-archive`,
|
|
243
|
-
`ob-ops-evidence`) and owns its procedure. You must not skip a phase
|
|
244
|
-
|
|
250
|
+
`ob-ops-evidence`) and owns its procedure. You must not skip a phase unless the
|
|
251
|
+
pipeline's refined-issue detection says to.
|
|
245
252
|
|
|
246
|
-
|
|
253
|
+
d. The `apply` phase uses `ob-plan-apply` which delegates implementation to specialist
|
|
247
254
|
subagent waves. Let it own worker resolution, concurrency, and retry , do not
|
|
248
255
|
implement the tasks yourself unless `ob-plan-apply` instructs you to.
|
|
249
256
|
|
|
250
|
-
|
|
257
|
+
e. Implement only what the issue asks for: a vague sentence is not licence to redesign
|
|
251
258
|
a module. Never read outside this repository root. The issue context at
|
|
252
259
|
`${{ env.ISSUE_CONTEXT_PATH }}` defines acceptance criteria that the pipeline must
|
|
253
260
|
satisfy.
|
|
254
261
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
262
|
+
f. Follow repository documentation and established conventions. Keep changes focused,
|
|
263
|
+
protect secrets, do not bypass checks, and do not modify generated files unless the issue requires it.
|
|
264
|
+
Adhere to ${{ env.REPO_RULES }}.
|
|
258
265
|
|
|
259
266
|
4. Verify before you conclude. From the repository root:
|
|
260
267
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-merge-gate.md. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
3
3
|
env:
|
|
4
|
-
|
|
4
|
+
VERIFY_COMMANDS: "dotnet restore apps/api/Numa.slnx && dotnet build apps/api/Numa.slnx -c Release --no-restore && dotnet test apps/api/tests/Numa.UnitTests/Numa.UnitTests.csproj -c Release --no-build && dotnet test apps/api/tests/Numa.ParityTests/Numa.ParityTests.csproj -c Release --no-build"
|
|
5
|
+
REPO_RULES: "Make a risk-based merge decision for the selected bot pull request. Merge only when CI is green and no risk indicators are present. Risk indicators for Numa: changes to QuoteCalculator or calculation waterfall, audit appender or hash chain, JWT issuance or permission checks, EF migrations or entity configurations, decimal precision or money handling, quote lifecycle transitions. Any of these require human review. Do not merge protected file changes."
|
|
5
6
|
WORKING_LABEL: bot-working
|
|
6
7
|
IMPLEMENT_LABEL: implement
|
|
7
8
|
REVIEW_LABEL: review
|
|
8
9
|
GATE_MARKER: "<!-- agent-merge-gate -->"
|
|
9
10
|
INCOMPLETE_COMMENT: "Automated CI failure remediation ended without an outcome. The issue remains for a retry."
|
|
10
11
|
ISSUE_CONTEXT_PATH: /tmp/gh-aw/agent/issue-context.json
|
|
12
|
+
GH_AW_ALLOWED_BOTS: "platform-devbox[bot],github-actions[bot]"
|
|
11
13
|
GIT_AUTHOR_NAME: "github-actions[bot]"
|
|
12
14
|
GIT_AUTHOR_EMAIL: "github-actions[bot]@users.noreply.github.com"
|
|
13
15
|
GIT_COMMITTER_NAME: "github-actions[bot]"
|
|
@@ -55,7 +57,7 @@ on:
|
|
|
55
57
|
# values and `on.steps` outputs do not reach the agent job.
|
|
56
58
|
jobs:
|
|
57
59
|
subject:
|
|
58
|
-
runs-on:
|
|
60
|
+
runs-on: RunnerLandingZone
|
|
59
61
|
permissions:
|
|
60
62
|
contents: read
|
|
61
63
|
issues: read
|
|
@@ -84,7 +86,7 @@ jobs:
|
|
|
84
86
|
protected_changes:
|
|
85
87
|
needs: subject
|
|
86
88
|
if: needs.subject.outputs.found == 'true'
|
|
87
|
-
runs-on:
|
|
89
|
+
runs-on: RunnerLandingZone
|
|
88
90
|
permissions:
|
|
89
91
|
pull-requests: read
|
|
90
92
|
outputs:
|
|
@@ -117,7 +119,7 @@ jobs:
|
|
|
117
119
|
review_required:
|
|
118
120
|
needs: [subject, protected_changes]
|
|
119
121
|
if: needs.subject.outputs.found == 'true' && needs.protected_changes.outputs.requires_review == 'true'
|
|
120
|
-
runs-on:
|
|
122
|
+
runs-on: RunnerLandingZone
|
|
121
123
|
permissions:
|
|
122
124
|
contents: read
|
|
123
125
|
issues: write
|
|
@@ -152,7 +154,7 @@ jobs:
|
|
|
152
154
|
body: |
|
|
153
155
|
${{ env.GATE_MARKER }}
|
|
154
156
|
PR #${{ needs.subject.outputs.pr }} changes protected files and cannot be auto-merged.
|
|
155
|
-
|
|
157
|
+
The `review` label is set: a human must merge this PR manually.
|
|
156
158
|
|
|
157
159
|
Protected files:
|
|
158
160
|
${{ needs.protected_changes.outputs.files }}
|
|
@@ -160,10 +162,11 @@ jobs:
|
|
|
160
162
|
reserve:
|
|
161
163
|
needs: subject
|
|
162
164
|
if: needs.subject.outputs.found == 'true'
|
|
163
|
-
runs-on:
|
|
165
|
+
runs-on: RunnerLandingZone
|
|
164
166
|
permissions:
|
|
165
167
|
contents: read
|
|
166
168
|
issues: write
|
|
169
|
+
pull-requests: read
|
|
167
170
|
steps:
|
|
168
171
|
- name: Checkout workflow actions
|
|
169
172
|
if: needs.subject.outputs.conclusion == 'failure'
|
|
@@ -177,27 +180,38 @@ jobs:
|
|
|
177
180
|
with:
|
|
178
181
|
client-id: ${{ secrets.BOT_APP_ID }}
|
|
179
182
|
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
|
|
180
|
-
- name:
|
|
183
|
+
- name: Check for merge conflicts
|
|
181
184
|
if: needs.subject.outputs.conclusion == 'failure'
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
185
|
+
id: conflicts
|
|
186
|
+
env:
|
|
187
|
+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
|
188
|
+
REPO: ${{ github.repository }}
|
|
189
|
+
PR: ${{ needs.subject.outputs.pr }}
|
|
190
|
+
run: |
|
|
191
|
+
set -euo pipefail
|
|
192
|
+
mergeable=$(gh pr view "$PR" --repo "$REPO" --json mergeable --jq '.mergeable')
|
|
193
|
+
if [ "$mergeable" = "CONFLICTING" ]; then
|
|
194
|
+
echo "has_conflicts=true" >> "$GITHUB_OUTPUT"
|
|
195
|
+
else
|
|
196
|
+
echo "has_conflicts=false" >> "$GITHUB_OUTPUT"
|
|
197
|
+
fi
|
|
198
|
+
- name: Comment on issue - problems found, solving them
|
|
188
199
|
if: needs.subject.outputs.conclusion == 'failure'
|
|
189
|
-
uses: ./.github/actions/
|
|
200
|
+
uses: ./.github/actions/create-issue-comment
|
|
190
201
|
with:
|
|
191
202
|
token: ${{ steps.app-token.outputs.token }}
|
|
192
203
|
issue-number: ${{ needs.subject.outputs.issue }}
|
|
193
|
-
|
|
204
|
+
body: |
|
|
205
|
+
${{ env.GATE_MARKER }}
|
|
206
|
+
Problems found in PR #${{ needs.subject.outputs.pr }}. ${{ steps.conflicts.outputs.has_conflicts == 'true' && 'Merge conflicts detected.' || 'CI failed.' }}
|
|
207
|
+
Bot is working on fixing it.
|
|
194
208
|
conclude:
|
|
195
209
|
needs: [activation, subject, protected_changes, agent, safe_outputs]
|
|
196
210
|
if: >
|
|
197
211
|
needs.agent.result == 'success' &&
|
|
198
212
|
needs.safe_outputs.result == 'success' &&
|
|
199
213
|
needs.protected_changes.outputs.requires_review != 'true'
|
|
200
|
-
runs-on:
|
|
214
|
+
runs-on: RunnerLandingZone
|
|
201
215
|
permissions:
|
|
202
216
|
contents: write
|
|
203
217
|
issues: write
|
|
@@ -236,7 +250,7 @@ jobs:
|
|
|
236
250
|
needs.subject.outputs.found == 'true' &&
|
|
237
251
|
needs.protected_changes.outputs.requires_review != 'true' &&
|
|
238
252
|
needs.agent.result != 'success'
|
|
239
|
-
runs-on:
|
|
253
|
+
runs-on: RunnerLandingZone
|
|
240
254
|
permissions:
|
|
241
255
|
contents: read
|
|
242
256
|
issues: write
|
|
@@ -270,6 +284,7 @@ jobs:
|
|
|
270
284
|
issue-number: ${{ needs.subject.outputs.issue }}
|
|
271
285
|
body: |
|
|
272
286
|
${{ env.GATE_MARKER }}
|
|
287
|
+
Bot could not resolve PR #${{ needs.subject.outputs.pr }} automatically. The `review` label is set: a human must take over.
|
|
273
288
|
${{ env.INCOMPLETE_COMMENT }}
|
|
274
289
|
[View this workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
|
275
290
|
|
|
@@ -279,8 +294,8 @@ jobs:
|
|
|
279
294
|
|
|
280
295
|
if: needs.subject.outputs.found == 'true' && needs.protected_changes.outputs.requires_review != 'true'
|
|
281
296
|
|
|
282
|
-
runs-on:
|
|
283
|
-
runs-on-slim:
|
|
297
|
+
runs-on: RunnerLandingZone
|
|
298
|
+
runs-on-slim: RunnerLandingZone
|
|
284
299
|
|
|
285
300
|
secrets:
|
|
286
301
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
@@ -56,8 +56,8 @@ on:
|
|
|
56
56
|
query: "is:issue is:open label:proposed -label:refine -label:implement"
|
|
57
57
|
max: 1
|
|
58
58
|
|
|
59
|
-
runs-on:
|
|
60
|
-
runs-on-slim:
|
|
59
|
+
runs-on: RunnerLandingZone
|
|
60
|
+
runs-on-slim: RunnerLandingZone
|
|
61
61
|
|
|
62
62
|
secrets:
|
|
63
63
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
@@ -156,7 +156,7 @@ jobs:
|
|
|
156
156
|
# Circuit breaker. A guard job that only reports; the agent's own `if:` is what stops the
|
|
157
157
|
# run, because a `needs` job succeeding with a false output does not gate its dependents.
|
|
158
158
|
capacity:
|
|
159
|
-
runs-on:
|
|
159
|
+
runs-on: RunnerLandingZone
|
|
160
160
|
permissions:
|
|
161
161
|
issues: read
|
|
162
162
|
outputs:
|
|
@@ -185,7 +185,7 @@ jobs:
|
|
|
185
185
|
needs.agent.result == 'success' &&
|
|
186
186
|
needs.safe_outputs.result == 'success' &&
|
|
187
187
|
needs.safe_outputs.outputs.process_safe_outputs_processed_count != '0'
|
|
188
|
-
runs-on:
|
|
188
|
+
runs-on: RunnerLandingZone
|
|
189
189
|
permissions:
|
|
190
190
|
contents: read
|
|
191
191
|
issues: write
|
|
@@ -225,7 +225,7 @@ safe-outputs:
|
|
|
225
225
|
# (release notes) and then files an issue, so it is the only one where a prompt-injection
|
|
226
226
|
# attempt has somewhere to go.
|
|
227
227
|
threat-detection:
|
|
228
|
-
runs-on:
|
|
228
|
+
runs-on: RunnerLandingZone
|
|
229
229
|
create-issue:
|
|
230
230
|
max: 1
|
|
231
231
|
|
|
@@ -13,6 +13,7 @@ env:
|
|
|
13
13
|
INCOMPLETE_COMMENT: "Automated refinement ended without an outcome. The refine label remains for a retry."
|
|
14
14
|
SAFE_OUTPUT_COMMENT_PREFIX: "Refinement update"
|
|
15
15
|
ISSUE_CONTEXT_PATH: /tmp/gh-aw/agent/issue-context.json
|
|
16
|
+
GH_AW_ALLOWED_BOTS: "platform-devbox[bot],github-actions[bot]"
|
|
16
17
|
REFINE_ISSUE_PATH: /tmp/gh-aw/refine-issue.json
|
|
17
18
|
REFINE_COMMENTS_PATH: /tmp/gh-aw/refine-comments.json
|
|
18
19
|
GIT_AUTHOR_NAME: "github-actions[bot]"
|
|
@@ -52,7 +53,7 @@ on:
|
|
|
52
53
|
|
|
53
54
|
jobs:
|
|
54
55
|
reserve:
|
|
55
|
-
runs-on:
|
|
56
|
+
runs-on: RunnerLandingZone
|
|
56
57
|
permissions:
|
|
57
58
|
contents: read
|
|
58
59
|
issues: write
|
|
@@ -85,7 +86,7 @@ jobs:
|
|
|
85
86
|
always() &&
|
|
86
87
|
needs.agent.result == 'success' &&
|
|
87
88
|
needs.safe_outputs.result == 'success'
|
|
88
|
-
runs-on:
|
|
89
|
+
runs-on: RunnerLandingZone
|
|
89
90
|
permissions:
|
|
90
91
|
contents: read
|
|
91
92
|
outputs:
|
|
@@ -115,7 +116,7 @@ jobs:
|
|
|
115
116
|
needs.agent.result == 'success' &&
|
|
116
117
|
needs.safe_outputs.result == 'success' &&
|
|
117
118
|
needs.validate_output.outputs.valid == 'true'
|
|
118
|
-
runs-on:
|
|
119
|
+
runs-on: RunnerLandingZone
|
|
119
120
|
permissions:
|
|
120
121
|
contents: read
|
|
121
122
|
issues: write
|
|
@@ -180,7 +181,7 @@ jobs:
|
|
|
180
181
|
needs.safe_outputs.result != 'success' ||
|
|
181
182
|
needs.validate_output.outputs.valid != 'true'
|
|
182
183
|
)
|
|
183
|
-
runs-on:
|
|
184
|
+
runs-on: RunnerLandingZone
|
|
184
185
|
permissions:
|
|
185
186
|
contents: read
|
|
186
187
|
issues: write
|
|
@@ -217,8 +218,8 @@ jobs:
|
|
|
217
218
|
|
|
218
219
|
if: inputs.issue-number != ''
|
|
219
220
|
|
|
220
|
-
runs-on:
|
|
221
|
-
runs-on-slim:
|
|
221
|
+
runs-on: RunnerLandingZone
|
|
222
|
+
runs-on-slim: RunnerLandingZone
|
|
222
223
|
|
|
223
224
|
secrets:
|
|
224
225
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Human adds implement/refine/direct label → validates permission → bot adds bot-working
|
|
2
2
|
# This ensures the bot is the actor for all agentic workflows.
|
|
3
|
+
#
|
|
4
|
+
# IMPORTANT: Only triggers for HUMAN actors. When the bot transitions refine→implement,
|
|
5
|
+
# it adds bot-working itself, so authorize-bot-work must not fire again.
|
|
3
6
|
name: "Authorize Bot Work"
|
|
4
7
|
|
|
5
8
|
on:
|
|
@@ -11,13 +14,15 @@ permissions:
|
|
|
11
14
|
|
|
12
15
|
jobs:
|
|
13
16
|
authorize:
|
|
14
|
-
# Only trigger for implement/refine/direct labels
|
|
17
|
+
# Only trigger for implement/refine/direct labels from HUMANS (not bots),
|
|
18
|
+
# and only if bot-working is NOT already present
|
|
15
19
|
if: >
|
|
16
20
|
(github.event.label.name == 'implement' ||
|
|
17
21
|
github.event.label.name == 'refine' ||
|
|
18
22
|
github.event.label.name == 'direct') &&
|
|
19
|
-
!contains(github.event.issue.labels.*.name, 'bot-working')
|
|
20
|
-
|
|
23
|
+
!contains(github.event.issue.labels.*.name, 'bot-working') &&
|
|
24
|
+
!endsWith(github.actor, '[bot]')
|
|
25
|
+
runs-on: RunnerLandingZone
|
|
21
26
|
timeout-minutes: 5
|
|
22
27
|
permissions:
|
|
23
28
|
contents: read
|
|
@@ -31,13 +36,6 @@ jobs:
|
|
|
31
36
|
run: |
|
|
32
37
|
set -euo pipefail
|
|
33
38
|
|
|
34
|
-
# Bots don't need validation - they're already authorized
|
|
35
|
-
if [[ "$ACTOR" == *"[bot]"* ]]; then
|
|
36
|
-
echo "authorized=true" >> "$GITHUB_OUTPUT"
|
|
37
|
-
echo "::notice::Bot actor ($ACTOR) - skipping permission check"
|
|
38
|
-
exit 0
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
39
|
permission=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$ACTOR/permission" \
|
|
42
40
|
--jq '.permission' 2>/dev/null || echo "none")
|
|
43
41
|
|
|
@@ -118,7 +118,7 @@ permissions:
|
|
|
118
118
|
jobs:
|
|
119
119
|
# Public repositories must check repository permission before an event can start a model.
|
|
120
120
|
authorize:
|
|
121
|
-
runs-on:
|
|
121
|
+
runs-on: RunnerLandingZone
|
|
122
122
|
timeout-minutes: 5
|
|
123
123
|
permissions:
|
|
124
124
|
contents: read
|
|
@@ -167,7 +167,7 @@ jobs:
|
|
|
167
167
|
esac
|
|
168
168
|
|
|
169
169
|
classify:
|
|
170
|
-
runs-on:
|
|
170
|
+
runs-on: RunnerLandingZone
|
|
171
171
|
timeout-minutes: 5
|
|
172
172
|
permissions:
|
|
173
173
|
contents: read
|
|
@@ -322,7 +322,7 @@ jobs:
|
|
|
322
322
|
if: >
|
|
323
323
|
needs.classify.outputs.route == 'bot-approve' &&
|
|
324
324
|
(github.actor == 'app/github-actions' || github.actor == 'platform-devbox[bot]')
|
|
325
|
-
runs-on:
|
|
325
|
+
runs-on: RunnerLandingZone
|
|
326
326
|
timeout-minutes: 5
|
|
327
327
|
permissions:
|
|
328
328
|
actions: write
|
|
@@ -353,7 +353,7 @@ jobs:
|
|
|
353
353
|
reconcile-bot-pr-runs:
|
|
354
354
|
needs: classify
|
|
355
355
|
if: needs.classify.outputs.route == 'reconcile-bot-pr-runs'
|
|
356
|
-
runs-on:
|
|
356
|
+
runs-on: RunnerLandingZone
|
|
357
357
|
timeout-minutes: 5
|
|
358
358
|
permissions:
|
|
359
359
|
contents: read
|
|
@@ -439,7 +439,7 @@ jobs:
|
|
|
439
439
|
audit-close:
|
|
440
440
|
needs: classify
|
|
441
441
|
if: needs.classify.outputs.route == 'audit-close'
|
|
442
|
-
runs-on:
|
|
442
|
+
runs-on: RunnerLandingZone
|
|
443
443
|
timeout-minutes: 15
|
|
444
444
|
concurrency:
|
|
445
445
|
group: audit-close
|
|
@@ -459,7 +459,7 @@ jobs:
|
|
|
459
459
|
cleanup-artifacts:
|
|
460
460
|
needs: classify
|
|
461
461
|
if: needs.classify.outputs.route == 'cleanup-artifacts' && !github.event.repository.fork
|
|
462
|
-
runs-on:
|
|
462
|
+
runs-on: RunnerLandingZone
|
|
463
463
|
timeout-minutes: 15
|
|
464
464
|
concurrency:
|
|
465
465
|
group: cleanup-artifacts
|
|
@@ -480,7 +480,7 @@ jobs:
|
|
|
480
480
|
stale-recovery:
|
|
481
481
|
needs: classify
|
|
482
482
|
if: needs.classify.outputs.route == 'stale-recovery'
|
|
483
|
-
runs-on:
|
|
483
|
+
runs-on: RunnerLandingZone
|
|
484
484
|
timeout-minutes: 15
|
|
485
485
|
concurrency:
|
|
486
486
|
group: stale-recovery
|
|
@@ -503,7 +503,7 @@ jobs:
|
|
|
503
503
|
validate:
|
|
504
504
|
needs: classify
|
|
505
505
|
if: needs.classify.outputs.route == 'validate'
|
|
506
|
-
runs-on:
|
|
506
|
+
runs-on: RunnerLandingZone
|
|
507
507
|
timeout-minutes: 10
|
|
508
508
|
permissions:
|
|
509
509
|
contents: read
|