@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.
@@ -26,7 +26,7 @@ concurrency:
26
26
  jobs:
27
27
  verify-lockfiles:
28
28
  name: Verify generated agent lockfiles
29
- runs-on: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
172
+ runs-on: RunnerLandingZone
173
173
  steps:
174
174
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
175
175
  - uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0
@@ -12,7 +12,7 @@ permissions:
12
12
  jobs:
13
13
  publish:
14
14
  name: Publish release
15
- runs-on: ubuntu-latest
15
+ runs-on: RunnerLandingZone
16
16
  timeout-minutes: 10
17
17
  steps:
18
18
  - name: Create or update GitHub release
@@ -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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
216
- runs-on-slim: ubuntu-latest
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: ubuntu-latest
46
- runs-on-slim: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
182
- runs-on-slim: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
186
- runs-on-slim: ubuntu-latest
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. Execute every phase in order. Each phase loads its own sub-skill (`ob-plan-explore`,
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, merge phases,
244
- or replace the pipeline with your own ad-hoc checklist.
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
- c. The `apply` phase uses `ob-plan-apply` which delegates implementation to specialist
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
- d. Implement only what the issue asks for: a vague sentence is not licence to redesign
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
- e. Follow repository documentation and established conventions. Keep changes focused,
256
- protect secrets, do not bypass checks, and do not modify generated files unless the issue requires it.
257
- Adhere to ${{ env.REPO_RULES }}.
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
- 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. Flag security, schema, auth, or calculation changes for human review. Do not merge protected file changes."
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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
- Review the pull request before merging it manually.
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: ubuntu-latest
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: Mark the failed implementation issue as in progress
183
+ - name: Check for merge conflicts
181
184
  if: needs.subject.outputs.conclusion == 'failure'
182
- uses: ./.github/actions/add-issue-labels
183
- with:
184
- token: ${{ steps.app-token.outputs.token }}
185
- issue-number: ${{ needs.subject.outputs.issue }}
186
- labels: ${{ env.WORKING_LABEL }}
187
- - name: Clear the human-needed flag
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/remove-issue-labels
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
- labels: ${{ env.REVIEW_LABEL }}
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
283
- runs-on-slim: ubuntu-latest
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: ubuntu-latest
60
- runs-on-slim: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
221
- runs-on-slim: ubuntu-latest
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, and only if bot-working is NOT already present
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
- runs-on: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
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: ubuntu-latest
506
+ runs-on: RunnerLandingZone
507
507
  timeout-minutes: 10
508
508
  permissions:
509
509
  contents: read
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plainconceptsplatform/workflows",
3
- "version": "0.4.13",
3
+ "version": "0.4.19",
4
4
  "description": "Install and update Platform GitHub agentic workflows.",
5
5
  "keywords": [
6
6
  "github-actions",