@plainconceptsplatform/workflows 0.28.15 → 0.28.18

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.
Files changed (30) hide show
  1. package/README.md +1 -1
  2. package/dist/catalog-installation.js +3 -3
  3. package/dist/catalog-listing.js +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/tui.js +3 -3
  6. package/loops/actions/housekeeping/action.yml +2 -2
  7. package/loops/actions/validate-triage-output/validate-triage-output.sh +1 -1
  8. package/loops/actions/verify-refine-output/verify-refine-output.sh +3 -3
  9. package/loops/actions/verify-route-matrix/verify-route-matrix.sh +33 -5
  10. package/loops/docs/diagrams.md +4 -4
  11. package/loops/scripts/compile-agent-workflows.mjs +2 -2
  12. package/loops/templates/agentics/agentics-app-errors.yml +1 -1
  13. package/loops/templates/agentics/agentics-checks.yml +3 -3
  14. package/loops/templates/agentics/agentics-error-report.yml +3 -3
  15. package/loops/templates/agentics/agentics-maintenance.yml +9 -9
  16. package/loops/templates/ci/app-ci-dotnet-next.yml +10 -10
  17. package/loops/templates/ci/app-ci-node-monorepo.yml +11 -11
  18. package/loops/templates/issues/bug_report.yml +3 -3
  19. package/loops/templates/issues/feature_request.yml +4 -4
  20. package/loops/workflows/agent-apply-review.md +9 -9
  21. package/loops/workflows/agent-audit.md +3 -3
  22. package/loops/workflows/agent-implement.md +11 -11
  23. package/loops/workflows/agent-merge-gate.md +19 -19
  24. package/loops/workflows/agent-refine.md +21 -12
  25. package/loops/workflows/agent-release.md +5 -5
  26. package/loops/workflows/agent-triage.md +21 -21
  27. package/loops/workflows/agent-visual-verify.md +3 -3
  28. package/loops/workflows/authorize-bot-work.yml +1 -1
  29. package/loops/workflows/work-router.yml +37 -37
  30. package/package.json +46 -45
@@ -6,7 +6,7 @@ env:
6
6
  REPO_RULES: "Apply only actionable outstanding reviewer feedback to the selected bot pull request. Make minimal changes that address each comment. Preserve architecture and do not weaken tests. Run full verification after changes."
7
7
  WORKING_LABEL: bot-working
8
8
  REVIEW_LABEL: review
9
- # Marks a park the machine caused — a crash, a timeout, an empty output — as opposed to one it
9
+ # Marks a park the machine caused a crash, a timeout, an empty output as opposed to one it
10
10
  # decided on. The janitor retries these after a while and never touches a decision park, because
11
11
  # re-running a decision produces the same decision. Created idempotently where it is applied.
12
12
  STALLED_LABEL: stalled
@@ -43,7 +43,7 @@ name: "Agent: Apply Review"
43
43
  # Router-only worker. The Work Router owns triggers, classification, and rung 1-2 checks.
44
44
  # This workflow receives the classified inputs and runs rung 3+.
45
45
  imports:
46
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
46
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.90.0
47
47
  - shared/platform-defaults.md
48
48
  - shared/opencode-ci.md
49
49
 
@@ -80,7 +80,7 @@ jobs:
80
80
  # `reserve` thirteen minutes later and refined a closed issue to completion. Read now, once,
81
81
  # and gate both the reservation and the agent on it.
82
82
  still_open:
83
- runs-on: RunnerLandingZone
83
+ runs-on: agents-arc
84
84
  timeout-minutes: 5
85
85
  permissions:
86
86
  contents: read
@@ -99,7 +99,7 @@ jobs:
99
99
  token: ${{ github.token }}
100
100
  issue-number: ${{ inputs.issue-number }}
101
101
  subject:
102
- runs-on: RunnerLandingZone
102
+ runs-on: agents-arc
103
103
  timeout-minutes: 5
104
104
  permissions:
105
105
  contents: read
@@ -169,7 +169,7 @@ jobs:
169
169
  reserve:
170
170
  needs: [subject, still_open]
171
171
  if: needs.subject.outputs.found == 'true' && needs.subject.outputs.issue != '' && needs.still_open.outputs.open == 'true'
172
- runs-on: RunnerLandingZone
172
+ runs-on: agents-arc
173
173
  timeout-minutes: 5
174
174
  permissions:
175
175
  contents: read
@@ -202,7 +202,7 @@ jobs:
202
202
  validate_output:
203
203
  needs: [activation, subject, agent, safe_outputs]
204
204
  if: always() && needs.agent.result == 'success' && needs.safe_outputs.result == 'success'
205
- runs-on: RunnerLandingZone
205
+ runs-on: agents-arc
206
206
  permissions:
207
207
  contents: read
208
208
  pull-requests: read
@@ -245,7 +245,7 @@ jobs:
245
245
  needs.agent.result == 'success' &&
246
246
  needs.safe_outputs.result == 'success' &&
247
247
  needs.validate_output.outputs.valid == 'true'
248
- runs-on: RunnerLandingZone
248
+ runs-on: agents-arc
249
249
  permissions:
250
250
  contents: write
251
251
  issues: write
@@ -286,7 +286,7 @@ jobs:
286
286
  # Only the reservation comes off. pr-pending says a pull request for this issue is open and
287
287
  # waiting, which is still true on both outcomes that reach here: already-satisfied and
288
288
  # needs-human both leave the pull request open. Stripping it made the board show issues
289
- # with open pull requests as having none — the exact bug the merge gate's own comment warns
289
+ # with open pull requests as having none the exact bug the merge gate's own comment warns
290
290
  # about, in the one file the route matrix was not checking.
291
291
  - name: Release review outcome
292
292
  if: needs.validate_output.outputs.outcome != 'implemented'
@@ -301,7 +301,7 @@ jobs:
301
301
  always() &&
302
302
  needs.subject.outputs.found == 'true' &&
303
303
  (needs.agent.result != 'success' || needs.safe_outputs.result != 'success' || needs.validate_output.outputs.valid != 'true')
304
- runs-on: RunnerLandingZone
304
+ runs-on: agents-arc
305
305
  permissions:
306
306
  contents: read
307
307
  issues: write
@@ -30,7 +30,7 @@ name: "Agent: Audit"
30
30
  # Shared: network policy only. This workflow owns its Safe Outputs and OpenCode configuration.
31
31
  # permissions, engine, model and runs-on cannot be shared , see shared/platform-defaults.md.
32
32
  imports:
33
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
33
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.90.0
34
34
  - shared/platform-defaults.md
35
35
  - shared/opencode-ci.md
36
36
 
@@ -89,7 +89,7 @@ jobs:
89
89
  needs.agent.result == 'success' &&
90
90
  needs.safe_outputs.result == 'success' &&
91
91
  needs.safe_outputs.outputs.process_safe_outputs_processed_count != '0'
92
- runs-on: RunnerLandingZone
92
+ runs-on: agents-arc
93
93
  permissions:
94
94
  contents: read
95
95
  issues: write
@@ -143,7 +143,7 @@ jobs:
143
143
  if: >
144
144
  needs.agent.result == 'success' &&
145
145
  needs.safe_outputs.outputs.process_safe_outputs_processed_count == '0'
146
- runs-on: RunnerLandingZone
146
+ runs-on: agents-arc
147
147
  permissions:
148
148
  contents: read
149
149
  steps:
@@ -11,7 +11,7 @@ env:
11
11
  IMPLEMENT_LABEL: implement
12
12
  WORKING_LABEL: bot-working
13
13
  REVIEW_LABEL: review
14
- # Marks a park the machine caused — a crash, a timeout, an empty output — as opposed to one it
14
+ # Marks a park the machine caused a crash, a timeout, an empty output as opposed to one it
15
15
  # decided on. The janitor retries these after a while and never touches a decision park, because
16
16
  # re-running a decision produces the same decision. Created idempotently where it is applied.
17
17
  STALLED_LABEL: stalled
@@ -79,7 +79,7 @@ name: "Agent: Implement Issue"
79
79
  # Shared: network policy only. This workflow owns its Safe Outputs and OpenCode configuration.
80
80
  # permissions, engine, model and runs-on cannot be shared , see shared/platform-defaults.md.
81
81
  imports:
82
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
82
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.90.0
83
83
  - shared/platform-defaults.md
84
84
  - shared/opencode-ci.md
85
85
 
@@ -109,7 +109,7 @@ jobs:
109
109
  # `reserve` thirteen minutes later and refined a closed issue to completion. Read now, once,
110
110
  # and gate both the reservation and the agent on it.
111
111
  still_open:
112
- runs-on: RunnerLandingZone
112
+ runs-on: agents-arc
113
113
  timeout-minutes: 5
114
114
  permissions:
115
115
  contents: read
@@ -128,7 +128,7 @@ jobs:
128
128
  token: ${{ github.token }}
129
129
  issue-number: ${{ inputs.issue-number }}
130
130
  eligibility:
131
- runs-on: RunnerLandingZone
131
+ runs-on: agents-arc
132
132
  timeout-minutes: 5
133
133
  permissions:
134
134
  issues: read
@@ -176,7 +176,7 @@ jobs:
176
176
  reserve:
177
177
  needs: [eligibility, still_open]
178
178
  if: needs.eligibility.outputs.eligible == 'true' && needs.still_open.outputs.open == 'true'
179
- runs-on: RunnerLandingZone
179
+ runs-on: agents-arc
180
180
  timeout-minutes: 5
181
181
  permissions:
182
182
  contents: read
@@ -217,7 +217,7 @@ jobs:
217
217
  always() &&
218
218
  needs.agent.result == 'success' &&
219
219
  needs.safe_outputs.result == 'success'
220
- runs-on: RunnerLandingZone
220
+ runs-on: agents-arc
221
221
  permissions:
222
222
  contents: read
223
223
  issues: write
@@ -292,7 +292,7 @@ jobs:
292
292
  # finish successfully without producing one: safeoutputs/noop, or an output the validator
293
293
  # would have rejected if this worker had one. The old behaviour was to remove bot-working
294
294
  # and stop, leaving the issue carrying `implement` with no `review`, no `pr-pending`, no
295
- # comment, and no bot-working — which also hid it from the hourly stale-reservation sweep.
295
+ # comment, and no bot-working which also hid it from the hourly stale-reservation sweep.
296
296
  # Comments do not re-trigger implement, so nothing on any path would ever look at it again.
297
297
  # It was the only failure in the fleet that signalled nobody at all.
298
298
  #
@@ -433,7 +433,7 @@ jobs:
433
433
  needs.agent.result != 'success' ||
434
434
  needs.safe_outputs.result != 'success'
435
435
  )
436
- runs-on: RunnerLandingZone
436
+ runs-on: agents-arc
437
437
  permissions:
438
438
  contents: read
439
439
  issues: write
@@ -558,7 +558,7 @@ jobs:
558
558
  # which makes agent -> await_landing -> conclude -> agent a cycle and fails compilation.
559
559
  needs: [agent, safe_outputs, conclude]
560
560
  if: always() && needs.conclude.result == 'success'
561
- runs-on: ubuntu-latest
561
+ runs-on: agents-arc
562
562
  timeout-minutes: 95
563
563
  permissions:
564
564
  contents: read
@@ -694,7 +694,7 @@ timeout-minutes: 180
694
694
  a. Create a todo entry for each checklist item (`- [ ]`) found in the issue body.
695
695
 
696
696
  b. Implement each change one at a time, marking each todo complete before moving to the
697
- next. Keep changes minimal — touch only what the checklist describes. Never read outside
697
+ next. Keep changes minimal touch only what the checklist describes. Never read outside
698
698
  this repository root. Adhere to ${{ env.REPO_RULES }},
699
699
  ${{ env.ARCHITECTURE_RULES }} and ${{ env.TESTING_RULES }}.
700
700
 
@@ -728,7 +728,7 @@ timeout-minutes: 180
728
728
 
729
729
  **DECISIVE IMPLEMENTATION**, on both paths. When a design choice is ambiguous, pick the most
730
730
  standard interpretation and implement it immediately. Do not deliberate between options for
731
- more than one turn. Do not ask clarifying questions — the issue author expects you to use good
731
+ more than one turn. Do not ask clarifying questions the issue author expects you to use good
732
732
  judgment. If two approaches are equally valid, pick one and proceed. You can always iterate
733
733
  based on pull request feedback.
734
734
 
@@ -55,7 +55,7 @@ env:
55
55
  # than chose not to. The belt does not retry a blocked pull request.
56
56
  OWNER_REVIEW_LABEL: owner-review
57
57
  BLOCKED_LABEL: blocked
58
- # Marks a park the machine caused — a crash, a timeout, an empty output — as opposed to one it
58
+ # Marks a park the machine caused a crash, a timeout, an empty output as opposed to one it
59
59
  # decided on. The janitor retries these after a while and never touches a decision park, because
60
60
  # re-running a decision produces the same decision. Created idempotently where it is applied.
61
61
  STALLED_LABEL: stalled
@@ -98,7 +98,7 @@ name: "Agent: Merge Gate"
98
98
  # Router-only worker. The Work Router owns triggers, classification, and rung 1-2 checks.
99
99
  # This workflow receives the classified inputs and runs rung 3+.
100
100
  imports:
101
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
101
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.90.0
102
102
  - shared/platform-defaults.md
103
103
  - shared/opencode-ci.md
104
104
 
@@ -140,7 +140,7 @@ on:
140
140
  # values and `on.steps` outputs do not reach the agent job.
141
141
  jobs:
142
142
  subject:
143
- runs-on: RunnerLandingZone
143
+ runs-on: agents-arc
144
144
  timeout-minutes: 5
145
145
  permissions:
146
146
  contents: read
@@ -196,7 +196,7 @@ jobs:
196
196
  protected_changes:
197
197
  needs: subject
198
198
  if: needs.subject.outputs.found == 'true'
199
- runs-on: RunnerLandingZone
199
+ runs-on: agents-arc
200
200
  timeout-minutes: 5
201
201
  permissions:
202
202
  contents: read
@@ -243,7 +243,7 @@ jobs:
243
243
  # gh-aw makes the agent depend on custom jobs. Keep this job successful when
244
244
  # there are no protected files instead of skipping it and blocking remediation.
245
245
  if: always() && needs.subject.outputs.found == 'true'
246
- runs-on: RunnerLandingZone
246
+ runs-on: agents-arc
247
247
  timeout-minutes: 5
248
248
  permissions:
249
249
  contents: read
@@ -303,7 +303,7 @@ jobs:
303
303
  reserve:
304
304
  needs: subject
305
305
  if: needs.subject.outputs.found == 'true'
306
- runs-on: RunnerLandingZone
306
+ runs-on: agents-arc
307
307
  timeout-minutes: 5
308
308
  permissions:
309
309
  contents: read
@@ -353,7 +353,7 @@ jobs:
353
353
  always() &&
354
354
  needs.agent.result == 'success' &&
355
355
  needs.safe_outputs.result == 'success'
356
- runs-on: RunnerLandingZone
356
+ runs-on: agents-arc
357
357
  permissions:
358
358
  contents: read
359
359
  outputs:
@@ -581,7 +581,7 @@ jobs:
581
581
  needs.safe_outputs.result != 'success' ||
582
582
  needs.validate_output.outputs.valid != 'true'
583
583
  )
584
- runs-on: RunnerLandingZone
584
+ runs-on: agents-arc
585
585
  permissions:
586
586
  contents: read
587
587
  issues: write
@@ -877,7 +877,7 @@ timeout-minutes: 120
877
877
  `/tmp/gh-aw/agent/pr.json` for the shape of the change. If CI failed, also read
878
878
  `/tmp/gh-aw/agent/failed-jobs.json` and `/tmp/gh-aw/agent/failed-logs.txt`.
879
879
 
880
- These files are the factual basis for everything below. Do not guess — cite what you read.
880
+ These files are the factual basis for everything below. Do not guess cite what you read.
881
881
 
882
882
  4b. **Merge conflict when CI is green.** If the conclusion is `success` and
883
883
  `has_conflicts` is `true` (current value: `${{ needs.reserve.outputs.has_conflicts }}`),
@@ -899,7 +899,7 @@ timeout-minutes: 120
899
899
  Push the merged branch using `push_to_pull_request_branch` (pr_number: ${{ needs.subject.outputs.pr }},
900
900
  branch: the current PR branch), then emit the `add_comment` with
901
901
  **Verdict:** remediated. CI will re-run on the updated branch and the merge gate
902
- will be triggered again — the next cycle will see a clean, conflict-free PR and can
902
+ will be triggered again the next cycle will see a clean, conflict-free PR and can
903
903
  reach a real disposition.
904
904
 
905
905
  If the merge cannot be completed or the conflicts are genuinely ambiguous, do not push.
@@ -959,7 +959,7 @@ timeout-minutes: 120
959
959
  per gap, with `category: correctness`, the file and line, and a `suggestedFix`.
960
960
 
961
961
  **Correctness remediation.** When `acceptanceCriteriaMet` is `false`, you may fix the
962
- gap and push the fix the same way you fix a failed CI run — this is the same
962
+ gap and push the fix the same way you fix a failed CI run this is the same
963
963
  `remediated` verdict the merge-conflict and CI-failure paths use, and it re-runs CI and
964
964
  the gate on the new head. To do it:
965
965
 
@@ -973,8 +973,8 @@ timeout-minutes: 120
973
973
  cycle validates the fix.
974
974
  - Do not rebase, reset, amend or otherwise rewrite history: the push is fast-forward only.
975
975
 
976
- If you cannot fix a criterion in one pass — it needs a decision, a question, or a code path
977
- you cannot trace — do not push. Report `assessed` with `acceptanceCriteriaMet: false` and no
976
+ If you cannot fix a criterion in one pass it needs a decision, a question, or a code path
977
+ you cannot trace do not push. Report `assessed` with `acceptanceCriteriaMet: false` and no
978
978
  push. The workflow sends the pull request to a human, which is the correct action when the
979
979
  gap is beyond a focused repair.
980
980
 
@@ -999,13 +999,13 @@ timeout-minutes: 120
999
999
  the pull request for a person, so it is the one judgement of yours that can hold up a merge on
1000
1000
  its own, and the same rule applies to it as to a finding: unevidenced, it does not count. A
1001
1001
  `low` with an empty `recoverabilitySignals` is read as `medium`. This is not an invitation to
1002
- pad the list — it is the difference between "this rewrites the plan rows in place" and a
1002
+ pad the list it is the difference between "this rewrites the plan rows in place" and a
1003
1003
  reflex.
1004
1004
 
1005
1005
  **5e. Raise the blast radius if the paths missed something.** The measured level came from
1006
- file paths and diff shape. If the change introduces something those rules cannot see — a new
1006
+ file paths and diff shape. If the change introduces something those rules cannot see a new
1007
1007
  authorization decision point, a new trust boundary, a write to shared state from a path that
1008
- never wrote before — set `blastRadiusRaise` with the level and the reason. You can only raise
1008
+ never wrote before set `blastRadiusRaise` with the level and the reason. You can only raise
1009
1009
  it. A lower value is ignored.
1010
1010
 
1011
1011
  **5f. State your confidence.** A number between 0 and 1, for the whole assessment, not for
@@ -1067,10 +1067,10 @@ timeout-minutes: 120
1067
1067
 
1068
1068
  7. Say which of two things you did, and nothing more.
1069
1069
 
1070
- - **`remediated`** — something was wrong (CI failed, the branch conflicted, or the diff did
1070
+ - **`remediated`** something was wrong (CI failed, the branch conflicted, or the diff did
1071
1071
  not satisfy the acceptance criteria), you fixed it, you verified the fix, and you are
1072
1072
  pushing it. Exactly one `push_to_pull_request_branch` goes with this word.
1073
- - **`assessed`** — you reviewed the change and are reporting what you found. No push.
1073
+ - **`assessed`** you reviewed the change and are reporting what you found. No push.
1074
1074
 
1075
1075
  These are the only two words the workflow accepts. You do not write `merge`, `review`,
1076
1076
  `auto-merge`, `blocked`, or any other outcome: the workflow computes the disposition from
@@ -1120,7 +1120,7 @@ timeout-minutes: 120
1120
1120
 
1121
1121
  When `acceptanceCriteriaMet` is `false` and you are pushing a fix, the verdict must be
1122
1122
  `remediated`, not `assessed`: the validator refuses an `assessed` verdict that carries a
1123
- push. Set `acceptanceCriteriaMet` to `false` in the report you push with the fix — it
1123
+ push. Set `acceptanceCriteriaMet` to `false` in the report you push with the fix it
1124
1124
  describes the code you reviewed, not the fix you just produced. The next gate cycle
1125
1125
  re-evaluates the updated diff and sets it to `true` (or finds another gap).
1126
1126
 
@@ -19,7 +19,7 @@ env:
19
19
  WORKING_LABEL: bot-working
20
20
  IMPLEMENT_LABEL: implement
21
21
  REVIEW_LABEL: review
22
- # Marks a park the machine caused — a crash, a timeout, an empty output — as opposed to one it
22
+ # Marks a park the machine caused a crash, a timeout, an empty output as opposed to one it
23
23
  # decided on. The janitor retries these after a while and never touches a decision park, because
24
24
  # re-running a decision produces the same decision. Created idempotently where it is applied.
25
25
  STALLED_LABEL: stalled
@@ -85,7 +85,7 @@ description: |
85
85
  name: "Agent: Refine Issue"
86
86
 
87
87
  imports:
88
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
88
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.90.0
89
89
  - shared/platform-defaults.md
90
90
  - shared/opencode-ci.md
91
91
 
@@ -116,7 +116,7 @@ jobs:
116
116
  # `reserve` thirteen minutes later and refined a closed issue to completion. Read now, once,
117
117
  # and gate both the reservation and the agent on it.
118
118
  still_open:
119
- runs-on: RunnerLandingZone
119
+ runs-on: agents-arc
120
120
  timeout-minutes: 5
121
121
  permissions:
122
122
  contents: read
@@ -141,7 +141,7 @@ jobs:
141
141
  eligibility:
142
142
  needs: [still_open]
143
143
  if: needs.still_open.outputs.open == 'true'
144
- runs-on: RunnerLandingZone
144
+ runs-on: agents-arc
145
145
  permissions:
146
146
  issues: read
147
147
  outputs:
@@ -171,7 +171,7 @@ jobs:
171
171
  size_guard:
172
172
  needs: [still_open, eligibility]
173
173
  if: needs.still_open.outputs.open == 'true' && needs.eligibility.outputs.eligible == 'true'
174
- runs-on: RunnerLandingZone
174
+ runs-on: agents-arc
175
175
  timeout-minutes: 5
176
176
  permissions:
177
177
  contents: read
@@ -214,7 +214,7 @@ jobs:
214
214
  refuse_big_issue:
215
215
  needs: [still_open, size_guard, eligibility]
216
216
  if: needs.still_open.outputs.open == 'true' && needs.eligibility.outputs.eligible == 'true' && needs.size_guard.outputs.too_big == 'true'
217
- runs-on: RunnerLandingZone
217
+ runs-on: agents-arc
218
218
  timeout-minutes: 5
219
219
  permissions:
220
220
  contents: read
@@ -267,7 +267,7 @@ jobs:
267
267
  reserve:
268
268
  needs: [still_open, size_guard, eligibility]
269
269
  if: needs.still_open.outputs.open == 'true' && needs.eligibility.outputs.eligible == 'true' && needs.size_guard.outputs.too_big != 'true'
270
- runs-on: RunnerLandingZone
270
+ runs-on: agents-arc
271
271
  timeout-minutes: 5
272
272
  permissions:
273
273
  contents: read
@@ -308,7 +308,7 @@ jobs:
308
308
  always() &&
309
309
  needs.agent.result == 'success' &&
310
310
  needs.safe_outputs.result == 'success'
311
- runs-on: RunnerLandingZone
311
+ runs-on: agents-arc
312
312
  permissions:
313
313
  contents: read
314
314
  outputs:
@@ -345,7 +345,7 @@ jobs:
345
345
  needs.agent.result == 'success' &&
346
346
  needs.safe_outputs.result == 'success' &&
347
347
  needs.validate_output.outputs.valid == 'true'
348
- runs-on: RunnerLandingZone
348
+ runs-on: agents-arc
349
349
  permissions:
350
350
  contents: read
351
351
  issues: write
@@ -532,7 +532,7 @@ jobs:
532
532
  needs.safe_outputs.result != 'success' ||
533
533
  needs.validate_output.outputs.valid != 'true'
534
534
  )
535
- runs-on: RunnerLandingZone
535
+ runs-on: agents-arc
536
536
  permissions:
537
537
  contents: read
538
538
  issues: write
@@ -824,6 +824,15 @@ timeout-minutes: 90
824
824
  size of a very long message, tighten the body; a shorter call that lands beats a longer one
825
825
  that is cut off.
826
826
 
827
+ **Pipe JSON via stdin and always pass `.` as the trailing argument.** The safeoutputs bridge
828
+ reads the JSON payload from stdin only when the final argument is `.`. Quote the issue-number
829
+ flags on the same line, never in place of the dot. Correct:
830
+ `printf '%s' "$JSON" | safeoutputs create_issue .`
831
+ `printf '%s' "$JSON" | safeoutputs update_issue --issue_number 685 .`
832
+ `printf '%s' "$JSON" | safeoutputs add_comment --item_number 685 .`
833
+ Wrong (stdin never read, body silently empty, bridge returns success):
834
+ `printf '%s' "$JSON" | safeoutputs update_issue --issue_number 685`
835
+
827
836
  8. Decide exactly one outcome:
828
837
 
829
838
  Labels are workflow-owned state. Do not call `add_labels` or `remove_labels`.
@@ -832,10 +841,10 @@ timeout-minutes: 90
832
841
  could not answer. Leave the partial work visible: first call `update_issue` with a
833
842
  temporal draft, then call `add_comment` once with the questions.
834
843
 
835
- The temporal draft is the replacement body your path would have written — the story
844
+ The temporal draft is the replacement body your path would have written the story
836
845
  body from the standard path, the marker, summary and checklist from the trivial path —
837
846
  holding everything you already established, with every
838
- part the questions leave open marked `_pending — see questions below_`. Its very
847
+ part the questions leave open marked `_pending see questions below_`. Its very
839
848
  first line is `${{ env.DRAFT_MARKER }}`; the next run replaces the draft wholesale
840
849
  with the final body.
841
850
 
@@ -16,7 +16,7 @@ description: |
16
16
  name: "Agent: Release"
17
17
 
18
18
  imports:
19
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
19
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.90.0
20
20
  - shared/platform-defaults.md
21
21
  - shared/opencode-ci.md
22
22
 
@@ -29,8 +29,8 @@ on:
29
29
  type: string
30
30
  default: "auto"
31
31
 
32
- runs-on: RunnerLandingZone
33
- runs-on-slim: RunnerLandingZone
32
+ runs-on: agents-arc
33
+ runs-on-slim: agents-arc
34
34
 
35
35
  secrets:
36
36
  OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
@@ -98,7 +98,7 @@ jobs:
98
98
  always() &&
99
99
  needs.agent.result == 'success' &&
100
100
  needs.safe_outputs.result == 'success'
101
- runs-on: RunnerLandingZone
101
+ runs-on: agents-arc
102
102
  permissions:
103
103
  contents: write
104
104
  steps:
@@ -205,7 +205,7 @@ jobs:
205
205
  if: >
206
206
  always() &&
207
207
  (needs.agent.result != 'success' || needs.safe_outputs.result != 'success')
208
- runs-on: RunnerLandingZone
208
+ runs-on: agents-arc
209
209
  permissions:
210
210
  contents: read
211
211
  steps:
@@ -11,7 +11,7 @@ env:
11
11
  TRIAGE_LABEL: triage
12
12
  WORKING_LABEL: bot-working
13
13
  REVIEW_LABEL: review
14
- # Marks a park the machine caused — a crash, a timeout, an empty output — as opposed to one it
14
+ # Marks a park the machine caused a crash, a timeout, an empty output as opposed to one it
15
15
  # decided on. The janitor retries these after a while and never touches a decision park, because
16
16
  # re-running a decision produces the same decision. Created idempotently where it is applied.
17
17
  STALLED_LABEL: stalled
@@ -56,7 +56,7 @@ description: |
56
56
 
57
57
  The gate is organisation membership, not permission level. The authorize job sets
58
58
  is_outside_collaborator for read permission, and also for write or better when the
59
- author association is COLLABORATOR — repository access without being one of the
59
+ author association is COLLABORATOR repository access without being one of the
60
60
  organisation's own. An org member with write skips triage; an outside collaborator
61
61
  with write does not.
62
62
 
@@ -66,7 +66,7 @@ description: |
66
66
  name: "Agent: Triage Issue"
67
67
 
68
68
  imports:
69
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
69
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.90.0
70
70
  - shared/platform-defaults.md
71
71
  - shared/opencode-ci.md
72
72
 
@@ -102,7 +102,7 @@ jobs:
102
102
  # `reserve` thirteen minutes later and refined a closed issue to completion. Read now, once,
103
103
  # and gate both the reservation and the agent on it.
104
104
  still_open:
105
- runs-on: RunnerLandingZone
105
+ runs-on: agents-arc
106
106
  timeout-minutes: 5
107
107
  permissions:
108
108
  contents: read
@@ -123,7 +123,7 @@ jobs:
123
123
  reserve:
124
124
  needs: [still_open]
125
125
  if: needs.still_open.outputs.open == 'true'
126
- runs-on: RunnerLandingZone
126
+ runs-on: agents-arc
127
127
  timeout-minutes: 5
128
128
  permissions:
129
129
  contents: read
@@ -170,7 +170,7 @@ jobs:
170
170
  always() &&
171
171
  needs.agent.result == 'success' &&
172
172
  needs.safe_outputs.result == 'success'
173
- runs-on: RunnerLandingZone
173
+ runs-on: agents-arc
174
174
  permissions:
175
175
  contents: read
176
176
  outputs:
@@ -198,7 +198,7 @@ jobs:
198
198
  needs.agent.result == 'success' &&
199
199
  needs.safe_outputs.result == 'success' &&
200
200
  needs.validate_output.outputs.valid == 'true'
201
- runs-on: RunnerLandingZone
201
+ runs-on: agents-arc
202
202
  permissions:
203
203
  contents: read
204
204
  issues: write
@@ -310,7 +310,7 @@ jobs:
310
310
  needs.safe_outputs.result != 'success' ||
311
311
  needs.validate_output.outputs.valid != 'true'
312
312
  )
313
- runs-on: RunnerLandingZone
313
+ runs-on: agents-arc
314
314
  permissions:
315
315
  contents: read
316
316
  issues: write
@@ -463,7 +463,7 @@ timeout-minutes: 45
463
463
 
464
464
  - On a **first** pass, triage from scratch.
465
465
  - On a **retriage** pass, incorporate the author's latest replies from comments. Previous
466
- triage comments are your own past work — read them to understand what was already asked
466
+ triage comments are your own past work read them to understand what was already asked
467
467
  and what the author addressed.
468
468
 
469
469
  3. Read `${{ env.OPEN_ISSUES_PATH }}`. It contains all open issues for duplicate detection.
@@ -479,45 +479,45 @@ timeout-minutes: 45
479
479
 
480
480
  5. Run each of these 10 checks. For each, emit a status and a short detail line.
481
481
 
482
- **Check 1 — Template completeness.** Does the issue body have the required fields from
482
+ **Check 1 Template completeness.** Does the issue body have the required fields from
483
483
  the bug report or feature request template? Are placeholder texts still present? Is the
484
484
  title clear and descriptive? Flag missing or incomplete fields.
485
485
 
486
- **Check 2 — Security risk scan.** Does the issue mention secrets, credentials, tokens,
486
+ **Check 2 Security risk scan.** Does the issue mention secrets, credentials, tokens,
487
487
  production data, PII, or destructive operations? Flag any mention of keys, passwords,
488
488
  connection strings, customer data, or `DROP`/`DELETE`/`TRUNCATE` statements. These need
489
489
  security review before any work begins.
490
490
 
491
- **Check 3 — Change size assessment.** Is the request appropriately scoped for a single
491
+ **Check 3 Change size assessment.** Is the request appropriately scoped for a single
492
492
  issue? Check the scope dropdown if present. Does the description imply changes across
493
493
  multiple components, modules, or services? Flag if it is too large for single-issue
494
494
  implementation.
495
495
 
496
- **Check 4 — Danger level.** Does the request touch authentication, authorization, IAM,
496
+ **Check 4 Danger level.** Does the request touch authentication, authorization, IAM,
497
497
  infrastructure, migrations, data model changes, or other high-risk areas? These need
498
498
  maintainer eyes before the pipeline starts.
499
499
 
500
- **Check 5 — Duplicate detection.** Compare the issue title and body against the open
501
- issues in `${{ env.OPEN_ISSUES_PATH }}`. Flag any that are semantically similar — same
500
+ **Check 5 Duplicate detection.** Compare the issue title and body against the open
501
+ issues in `${{ env.OPEN_ISSUES_PATH }}`. Flag any that are semantically similar same
502
502
  problem described differently, or the same feature requested with different wording.
503
503
 
504
- **Check 6 — Clarity / actionability.** Is the issue clear enough to act on? A vague
504
+ **Check 6 Clarity / actionability.** Is the issue clear enough to act on? A vague
505
505
  request like "make it better" or "it doesn't work" needs clarification. At least one
506
506
  concrete, actionable item must be identifiable.
507
507
 
508
- **Check 7 — Reproducibility (bugs).** If this is a bug report, are the reproduction steps
508
+ **Check 7 Reproducibility (bugs).** If this is a bug report, are the reproduction steps
509
509
  detailed enough? Specific inputs, expected vs actual outputs, or just "it broke"? If not
510
510
  a bug report, mark as N/A.
511
511
 
512
- **Check 8 — Acceptance criteria quality.** Are the acceptance criteria concrete and
512
+ **Check 8 Acceptance criteria quality.** Are the acceptance criteria concrete and
513
513
  testable, or just "it should work"? At least one verifiable checkbox or
514
514
  Given/When/Then scenario should be present.
515
515
 
516
- **Check 9 — Cross-cutting impact.** Does the request imply changes to shared libraries,
516
+ **Check 9 Cross-cutting impact.** Does the request imply changes to shared libraries,
517
517
  API contracts, database schemas, or other repositories? Flag any mention of shared
518
518
  dependencies, contracts, or schemas that multiple teams depend on.
519
519
 
520
- **Check 10 — Product-owner eligibility.** Judge the issue against this repository's
520
+ **Check 10 Product-owner eligibility.** Judge the issue against this repository's
521
521
  intake scope: ${{ env.PRODUCT_SCOPE }}
522
522
 
523
523
  An out-of-scope request is **not** a block. Out of scope means the wrong door, not a bad
@@ -543,7 +543,7 @@ timeout-minutes: 45
543
543
  **block.** The issue cannot be done, is a security risk, is too dangerous to automate, or
544
544
  is still too ambiguous after ${{ env.MAX_TRIAGE_ROUNDS }} rounds of triage. State the
545
545
  reason clearly. The issue will be closed. Do not use this for work that is merely outside
546
- product-owner scope — that is `needs-maintainer`.
546
+ product-owner scope that is `needs-maintainer`.
547
547
 
548
548
  7. Emit exactly one `add_comment` targeting issue `${{ inputs.issue-number }}` with:
549
549
  1. `${{ env.TRIAGE_MARKER }}`
@@ -28,7 +28,7 @@ name: "Agent: Visual Verify"
28
28
 
29
29
  # Standalone worker called directly from merge-gate's conclude job. Not a router route.
30
30
  imports:
31
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
31
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.90.0
32
32
  - shared/platform-defaults.md
33
33
  - shared/opencode-ci.md
34
34
 
@@ -52,7 +52,7 @@ on:
52
52
  # shell step runs agent-browser to capture screenshots outside the awf sandbox.
53
53
  jobs:
54
54
  subject:
55
- runs-on: RunnerLandingZone
55
+ runs-on: agents-arc
56
56
  timeout-minutes: 5
57
57
  permissions:
58
58
  contents: read
@@ -304,7 +304,7 @@ max-ai-credits: 5000
304
304
  directory with a journey of agent-browser waypoints (open/find/wait/capture/expect). Each
305
305
  waypoint names a URL, a selector to wait for, and what to observe.
306
306
 
307
- If the plan says `not-applicable` (no UI surface is reachable for this change — a backend-
307
+ If the plan says `not-applicable` (no UI surface is reachable for this change a backend-
308
308
  only change to an API or a migration, for example), that is a valid, expected outcome. Write
309
309
  a summary comment saying the change has no UI surface and stop. Do not attempt to start a
310
310
  browser.