@plainconceptsplatform/workflows 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/catalog-installation.d.ts +12 -0
  2. package/dist/catalog-installation.js +81 -0
  3. package/dist/catalog-installation.test.d.ts +1 -0
  4. package/dist/catalog-installation.test.js +85 -0
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +57 -0
  7. package/dist/repository-inspection.d.ts +23 -0
  8. package/dist/repository-inspection.js +91 -0
  9. package/dist/repository-state.d.ts +18 -0
  10. package/dist/repository-state.js +77 -0
  11. package/dist/repository-state.test.d.ts +1 -0
  12. package/dist/repository-state.test.js +96 -0
  13. package/dist/workflow-catalog.d.ts +17 -0
  14. package/dist/workflow-catalog.js +39 -0
  15. package/dist/workflow-catalog.test.d.ts +1 -0
  16. package/dist/workflow-catalog.test.js +14 -0
  17. package/loops/actions/add-issue-labels/action.yml +29 -0
  18. package/loops/actions/agent-output.cjs +16 -0
  19. package/loops/actions/apply-agent-bundle/action.yml +23 -0
  20. package/loops/actions/apply-agent-bundle/apply-bundle.sh +45 -0
  21. package/loops/actions/apply-agent-comments/action.yml +41 -0
  22. package/loops/actions/apply-agent-labels/action.yml +54 -0
  23. package/loops/actions/apply-agent-output/action.yml +107 -0
  24. package/loops/actions/audit-close/action.yml +103 -0
  25. package/loops/actions/classify-route/action.yml +90 -0
  26. package/loops/actions/classify-route/classify-route.sh +172 -0
  27. package/loops/actions/cleanup-artifacts/action.yml +64 -0
  28. package/loops/actions/close-agent-issues/action.yml +42 -0
  29. package/loops/actions/create-agent-issues/action.yml +51 -0
  30. package/loops/actions/create-issue-comment/action.yml +28 -0
  31. package/loops/actions/download-agent-output/action.yml +52 -0
  32. package/loops/actions/identify-gate-subject/action.yml +96 -0
  33. package/loops/actions/link-pr-to-issue/action.yml +39 -0
  34. package/loops/actions/list-open-issues/action.yml +32 -0
  35. package/loops/actions/load-issue-context/action.yml +42 -0
  36. package/loops/actions/merge-agent-pr/action.yml +35 -0
  37. package/loops/actions/push-agent-branch/action.yml +44 -0
  38. package/loops/actions/remove-issue-labels/action.yml +34 -0
  39. package/loops/actions/stale-recovery/action.yml +287 -0
  40. package/loops/actions/update-agent-issues/action.yml +57 -0
  41. package/loops/actions/validate-refine-output/action.yml +43 -0
  42. package/loops/actions/validate-refine-output/validate-refine-output.sh +46 -0
  43. package/loops/actions/verify-composite-actions/action.yml +8 -0
  44. package/loops/actions/verify-composite-actions/verify-composite-actions.sh +50 -0
  45. package/loops/actions/verify-refine-output/action.yml +8 -0
  46. package/loops/actions/verify-refine-output/verify-refine-output.sh +65 -0
  47. package/loops/actions/verify-route-matrix/action.yml +8 -0
  48. package/loops/actions/verify-route-matrix/verify-route-matrix.sh +212 -0
  49. package/loops/aw/repo-config.md +12 -0
  50. package/loops/scripts/compile-agent-workflows.mjs +13 -0
  51. package/loops/workflows/agent-apply-review.md +372 -0
  52. package/loops/workflows/agent-audit.md +197 -0
  53. package/loops/workflows/agent-direct.md +362 -0
  54. package/loops/workflows/agent-implement.md +329 -0
  55. package/loops/workflows/agent-merge-gate.md +470 -0
  56. package/loops/workflows/agent-propose.md +342 -0
  57. package/loops/workflows/agent-refine.md +338 -0
  58. package/loops/workflows/shared/opencode-ci.md +26 -0
  59. package/loops/workflows/shared/platform-defaults.md +14 -0
  60. package/loops/workflows/work-router.yml +391 -0
  61. package/package.json +28 -0
@@ -0,0 +1,470 @@
1
+ ---
2
+ env:
3
+ WORKING_LABEL: bot-working
4
+ IMPLEMENT_LABEL: implement
5
+ REVIEW_LABEL: review
6
+ GATE_MARKER: "<!-- agent-merge-gate -->"
7
+ INCOMPLETE_COMMENT: "Automated CI failure remediation ended without an outcome. The issue remains for a retry."
8
+ ISSUE_CONTEXT_PATH: /tmp/gh-aw/agent/issue-context.json
9
+ GIT_AUTHOR_NAME: "github-actions[bot]"
10
+ GIT_AUTHOR_EMAIL: "github-actions[bot]@users.noreply.github.com"
11
+ GIT_COMMITTER_NAME: "github-actions[bot]"
12
+ GIT_COMMITTER_EMAIL: "github-actions[bot]@users.noreply.github.com"
13
+ description: |
14
+ Decides what happens to a bot-authored pull request once CI has reported: merge when the
15
+ risk assessment is clean, hand to a human when it is not, fix CI when it failed. Called by
16
+ the Work Router; does not trigger on public events.
17
+
18
+ The router supplies the CI conclusion and run ID as facts, so there is no polling and no
19
+ timeout branch. The conclusion is read from the inputs instead of filtered at the trigger.
20
+
21
+ name: "Agent: Merge Gate"
22
+
23
+ # Router-only worker. The Work Router owns triggers, classification, and rung 1-2 checks.
24
+ # This workflow receives the classified inputs and runs rung 3+.
25
+ imports:
26
+ - shared/platform-defaults.md
27
+ - shared/opencode-ci.md
28
+ - shared/repo-config.md
29
+
30
+ on:
31
+ workflow_call:
32
+ inputs:
33
+ pr-number:
34
+ description: Pull request number to gate.
35
+ required: true
36
+ type: string
37
+ linked-issue:
38
+ description: Issue number the pull request closes. May be empty.
39
+ required: false
40
+ type: string
41
+ ci-conclusion:
42
+ description: CI conclusion (success, failure, action_required, cancelled, etc.).
43
+ required: true
44
+ type: string
45
+ ci-run-id:
46
+ description: CI workflow run ID for fetching failing logs.
47
+ required: false
48
+ type: string
49
+
50
+ # Rung 4. Router has classified the event; identify-gate-subject validates PR ownership,
51
+ # resolves the closing issue, and confirms the CI verdict.
52
+ # A custom job, not `on.steps`, because the prompt and the precompute step need these
53
+ # values and `on.steps` outputs do not reach the agent job.
54
+ jobs:
55
+ subject:
56
+ runs-on: ubuntu-latest
57
+ permissions:
58
+ contents: read
59
+ issues: read
60
+ pull-requests: read
61
+ actions: read
62
+ outputs:
63
+ found: ${{ steps.subject.outputs.found }}
64
+ pr: ${{ steps.subject.outputs.pr }}
65
+ issue: ${{ steps.subject.outputs.issue }}
66
+ conclusion: ${{ steps.subject.outputs.conclusion }}
67
+ steps:
68
+ - name: Checkout workflow actions
69
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
70
+ with:
71
+ persist-credentials: false
72
+ - name: Identify the pull request, its issue, and the CI verdict
73
+ id: subject
74
+ uses: ./.github/actions/identify-gate-subject
75
+ with:
76
+ token: ${{ github.token }}
77
+ pr-number: ${{ inputs.pr-number }}
78
+ ci-conclusion: ${{ inputs.ci-conclusion }}
79
+ linked-issue: ${{ inputs.linked-issue }}
80
+ require-label: ${{ env.IMPLEMENT_LABEL }}
81
+
82
+ protected_changes:
83
+ needs: subject
84
+ if: needs.subject.outputs.found == 'true'
85
+ runs-on: ubuntu-latest
86
+ permissions:
87
+ pull-requests: read
88
+ outputs:
89
+ requires_review: ${{ steps.files.outputs.requires_review }}
90
+ files: ${{ steps.files.outputs.files }}
91
+ steps:
92
+ - name: Require review for protected pull request files
93
+ id: files
94
+ env:
95
+ GH_TOKEN: ${{ github.token }}
96
+ REPO: ${{ github.repository }}
97
+ PR: ${{ needs.subject.outputs.pr }}
98
+ run: |
99
+ set -euo pipefail
100
+ files=$(gh api --paginate "repos/$REPO/pulls/$PR/files?per_page=100" --jq '.[].filename')
101
+ protected=$(printf '%s\n' "$files" | grep -E '^(\.|AGENTS\.md$|ARCHITECTURE\.md$|DESIGN\.md$|opencode\.jsonc$|package\.json$|pnpm-lock\.yaml$|Directory\.Packages\.props$|global\.json$)' || true)
102
+
103
+ if [ -n "$protected" ]; then
104
+ echo "requires_review=true" >> "$GITHUB_OUTPUT"
105
+ {
106
+ echo 'files<<EOF'
107
+ printf '%s\n' "$protected"
108
+ echo EOF
109
+ } >> "$GITHUB_OUTPUT"
110
+ else
111
+ echo "requires_review=false" >> "$GITHUB_OUTPUT"
112
+ echo "files=" >> "$GITHUB_OUTPUT"
113
+ fi
114
+
115
+ review_required:
116
+ needs: [subject, protected_changes]
117
+ if: needs.subject.outputs.found == 'true' && needs.protected_changes.outputs.requires_review == 'true'
118
+ runs-on: ubuntu-latest
119
+ permissions:
120
+ contents: read
121
+ issues: write
122
+ steps:
123
+ - name: Checkout workflow actions
124
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
125
+ with:
126
+ persist-credentials: false
127
+ - name: Create bot token
128
+ id: app-token
129
+ uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
130
+ with:
131
+ client-id: ${{ secrets.BOT_APP_ID }}
132
+ private-key: ${{ secrets.BOT_PRIVATE_KEY }}
133
+ - name: Release the issue
134
+ uses: ./.github/actions/remove-issue-labels
135
+ with:
136
+ token: ${{ steps.app-token.outputs.token }}
137
+ issue-number: ${{ needs.subject.outputs.issue }}
138
+ labels: ${{ env.WORKING_LABEL }}
139
+ - name: Flag human review
140
+ uses: ./.github/actions/add-issue-labels
141
+ with:
142
+ token: ${{ steps.app-token.outputs.token }}
143
+ issue-number: ${{ needs.subject.outputs.issue }}
144
+ labels: ${{ env.REVIEW_LABEL }}
145
+ - name: Explain the merge hold
146
+ uses: ./.github/actions/create-issue-comment
147
+ with:
148
+ token: ${{ steps.app-token.outputs.token }}
149
+ issue-number: ${{ needs.subject.outputs.issue }}
150
+ body: |
151
+ ${{ env.GATE_MARKER }}
152
+ PR #${{ needs.subject.outputs.pr }} changes protected files and cannot be auto-merged.
153
+ Review the pull request before merging it manually.
154
+
155
+ Protected files:
156
+ ${{ needs.protected_changes.outputs.files }}
157
+
158
+ reserve:
159
+ needs: subject
160
+ if: needs.subject.outputs.found == 'true'
161
+ runs-on: ubuntu-latest
162
+ permissions:
163
+ contents: read
164
+ issues: write
165
+ steps:
166
+ - name: Checkout workflow actions
167
+ if: needs.subject.outputs.conclusion == 'failure'
168
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
169
+ with:
170
+ persist-credentials: false
171
+ - name: Create bot token
172
+ if: needs.subject.outputs.conclusion == 'failure'
173
+ id: app-token
174
+ uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
175
+ with:
176
+ client-id: ${{ secrets.BOT_APP_ID }}
177
+ private-key: ${{ secrets.BOT_PRIVATE_KEY }}
178
+ - name: Mark the failed implementation issue as in progress
179
+ if: needs.subject.outputs.conclusion == 'failure'
180
+ uses: ./.github/actions/add-issue-labels
181
+ with:
182
+ token: ${{ steps.app-token.outputs.token }}
183
+ issue-number: ${{ needs.subject.outputs.issue }}
184
+ labels: ${{ env.WORKING_LABEL }}
185
+ - name: Clear the human-needed flag
186
+ if: needs.subject.outputs.conclusion == 'failure'
187
+ uses: ./.github/actions/remove-issue-labels
188
+ with:
189
+ token: ${{ steps.app-token.outputs.token }}
190
+ issue-number: ${{ needs.subject.outputs.issue }}
191
+ labels: ${{ env.REVIEW_LABEL }}
192
+ conclude:
193
+ needs: [activation, subject, protected_changes, agent, safe_outputs]
194
+ if: >
195
+ needs.agent.result == 'success' &&
196
+ needs.safe_outputs.result == 'success' &&
197
+ needs.protected_changes.outputs.requires_review != 'true'
198
+ runs-on: ubuntu-latest
199
+ permissions:
200
+ contents: write
201
+ issues: write
202
+ pull-requests: write
203
+ steps:
204
+ - name: Create bot token
205
+ id: app-token
206
+ uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
207
+ with:
208
+ client-id: ${{ secrets.BOT_APP_ID }}
209
+ private-key: ${{ secrets.BOT_PRIVATE_KEY }}
210
+ - name: Checkout repository
211
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
212
+ with:
213
+ token: ${{ steps.app-token.outputs.token }}
214
+ fetch-depth: 0
215
+ - name: Verify pull request closes the source issue
216
+ continue-on-error: true
217
+ uses: ./.github/actions/link-pr-to-issue
218
+ with:
219
+ token: ${{ steps.app-token.outputs.token }}
220
+ pr-number: ${{ needs.subject.outputs.pr }}
221
+ issue-number: ${{ needs.subject.outputs.issue }}
222
+ - name: Apply agent output
223
+ uses: ./.github/actions/apply-agent-output
224
+ with:
225
+ artifact-name: ${{ needs.activation.outputs.artifact_prefix }}agent
226
+ token: ${{ steps.app-token.outputs.token }}
227
+ merge-pull-request: 'true'
228
+ push-to-branch: 'true'
229
+ close-issues: 'true'
230
+ incomplete:
231
+ needs: [subject, protected_changes, agent, safe_outputs]
232
+ if: >
233
+ always() &&
234
+ needs.subject.outputs.found == 'true' &&
235
+ needs.protected_changes.outputs.requires_review != 'true' &&
236
+ needs.agent.result != 'success'
237
+ runs-on: ubuntu-latest
238
+ permissions:
239
+ contents: read
240
+ issues: write
241
+ steps:
242
+ - name: Checkout workflow actions
243
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
244
+ with:
245
+ persist-credentials: false
246
+ - name: Create bot token
247
+ id: app-token
248
+ uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
249
+ with:
250
+ client-id: ${{ secrets.BOT_APP_ID }}
251
+ private-key: ${{ secrets.BOT_PRIVATE_KEY }}
252
+ - name: Release the issue
253
+ uses: ./.github/actions/remove-issue-labels
254
+ with:
255
+ token: ${{ steps.app-token.outputs.token }}
256
+ issue-number: ${{ needs.subject.outputs.issue }}
257
+ labels: ${{ env.WORKING_LABEL }}
258
+ - name: Flag for human review
259
+ uses: ./.github/actions/add-issue-labels
260
+ with:
261
+ token: ${{ steps.app-token.outputs.token }}
262
+ issue-number: ${{ needs.subject.outputs.issue }}
263
+ labels: ${{ env.REVIEW_LABEL }}
264
+ - name: Report missing remediation outcome
265
+ uses: ./.github/actions/create-issue-comment
266
+ with:
267
+ token: ${{ steps.app-token.outputs.token }}
268
+ issue-number: ${{ needs.subject.outputs.issue }}
269
+ body: |
270
+ ${{ env.GATE_MARKER }}
271
+ ${{ env.INCOMPLETE_COMMENT }}
272
+ [View this workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
273
+
274
+ agent:
275
+ needs: protected_changes
276
+ if: needs.protected_changes.outputs.requires_review != 'true'
277
+
278
+ if: needs.subject.outputs.found == 'true' && needs.protected_changes.outputs.requires_review != 'true'
279
+
280
+ runs-on: ubuntu-latest
281
+ runs-on-slim: ubuntu-latest
282
+
283
+ secrets:
284
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
285
+
286
+ engine:
287
+ id: opencode
288
+ version: "1.2.14"
289
+ env:
290
+ OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
291
+
292
+ model: openai/glm-5-2
293
+
294
+ max-turns: 300
295
+ max-turn-cache-misses: 3000
296
+ max-ai-credits: 5000
297
+
298
+ permissions: read-all
299
+
300
+ # push-to-pull-request-branch with target "*" cannot reach a branch the shallow clone
301
+ # does not have.
302
+ checkout:
303
+ fetch: ["*"]
304
+ fetch-depth: 0
305
+
306
+ # Rung 3. The diff is what the risk assessment reads, and the failing logs are what a fix
307
+ # starts from. Both are known from the inputs, so neither costs the agent a turn.
308
+ steps:
309
+ - name: Load the issue context
310
+ uses: ./.github/actions/load-issue-context
311
+ with:
312
+ token: ${{ github.token }}
313
+ issue-number: ${{ needs.subject.outputs.issue }}
314
+ output-path: ${{ env.ISSUE_CONTEXT_PATH }}
315
+ - name: Fetch the diff and any failing job logs
316
+ env:
317
+ GH_TOKEN: ${{ github.token }}
318
+ REPO: ${{ github.repository }}
319
+ PR: ${{ needs.subject.outputs.pr }}
320
+ RUN_ID: ${{ inputs.ci-run-id }}
321
+ CONCLUSION: ${{ needs.subject.outputs.conclusion }}
322
+ run: |
323
+ set -euo pipefail
324
+ mkdir -p /tmp/gh-aw/agent
325
+ gh pr diff "$PR" --repo "$REPO" > /tmp/gh-aw/agent/diff.patch
326
+ gh pr view "$PR" --repo "$REPO" --json title,body,files,additions,deletions \
327
+ > /tmp/gh-aw/agent/pr.json
328
+ if [ "$CONCLUSION" = "failure" ]; then
329
+ gh run view "$RUN_ID" --repo "$REPO" --log-failed \
330
+ > /tmp/gh-aw/agent/failed-logs.txt 2>/dev/null || \
331
+ echo "logs unavailable" > /tmp/gh-aw/agent/failed-logs.txt
332
+ gh run view "$RUN_ID" --repo "$REPO" --json jobs \
333
+ --jq '[.jobs[] | select(.conclusion == "failure") | {name, conclusion}]' \
334
+ > /tmp/gh-aw/agent/failed-jobs.json
335
+ fi
336
+
337
+ safe-outputs:
338
+ staged: true
339
+ threat-detection: false
340
+ merge-pull-request:
341
+ push-to-pull-request-branch:
342
+ close-issue:
343
+ add-comment:
344
+ add-labels:
345
+ remove-labels:
346
+
347
+ timeout-minutes: 60
348
+ ---
349
+
350
+ 1. You are gating pull request **#${{ needs.subject.outputs.pr }}**, which closes issue
351
+ **#${{ needs.subject.outputs.issue }}**. CI concluded
352
+ **${{ needs.subject.outputs.conclusion }}**.
353
+
354
+ It has already been confirmed that this is an open pull request we authored, that it closes
355
+ an issue, and that the issue carries `implement`. Do not re-check any of that, and do not
356
+ poll for checks: the conclusion above is the answer.
357
+
358
+ 2. Read `${{ env.ISSUE_CONTEXT_PATH }}`. It contains the issue body and its discussion. When
359
+ running `/repo-verify`, the acceptance criteria there define what the implementation must
360
+ satisfy.
361
+
362
+ 3. Branch on the conclusion.
363
+
364
+ - **success** → step 4.
365
+ - **action_required** → CI did not run because the workflow needs approval.
366
+ Call `remove_labels` to remove `bot-working` (item_number:
367
+ ${{ needs.subject.outputs.issue }}), then `add_labels` to add `review`
368
+ (item_number: ${{ needs.subject.outputs.issue }}), and `add_comment`
369
+ (item_number: ${{ needs.subject.outputs.issue }}) saying CI requires
370
+ workflow approval before it can run, and a maintainer must approve the
371
+ pending run. Then stop , do not attempt to merge or fix.
372
+ - **failure** → step 7.
373
+ - **cancelled, timed_out, or anything else** → call `add_comment` with
374
+ `item_number: ${{ needs.subject.outputs.issue }}` saying CI did not produce a verdict,
375
+ then `add_labels` to add `review` (item_number: the issue), and stop.
376
+ A cancelled or unknown run is not evidence of anything.
377
+
378
+ Apply these repository-specific rules when assessing or remediating the pull request:
379
+
380
+ ```
381
+ $${{ env.REPO_RULES }}
382
+ ```
383
+
384
+ 4. Assess the risk of merging, as a reviewer would. Read `/tmp/gh-aw/agent/diff.patch` in full
385
+ and `/tmp/gh-aw/agent/pr.json` for the shape of the change. Flag it as risky when any of
386
+ these hold, and say which:
387
+
388
+ - It touches authentication, authorization, secrets, credentials, or security boundaries.
389
+ - It changes a repository-defined integration or cross-platform boundary.
390
+ - It changes a public API or a published package's contract.
391
+ - It deletes or weakens a test, or lowers a threshold.
392
+ - It changes CI, CD or a workflow file.
393
+ - It changes a protected file. This is normally handled before you run, but never merge one
394
+ if it reaches this gate.
395
+ - The diff is materially larger than the issue implied.
396
+ - You are simply not confident. Low confidence is itself a flag.
397
+
398
+ 5. **Clean assessment** → call `merge_pull_request` (pr_number:
399
+ ${{ needs.subject.outputs.pr }}), then `close_issue` (item_number:
400
+ ${{ needs.subject.outputs.issue }}), then `remove_labels` (item_number:
401
+ ${{ needs.subject.outputs.issue }}) to remove `implement`, `bot-working`, and `review`.
402
+ Call `add_comment` (item_number: ${{ needs.subject.outputs.issue }}):
403
+ `Auto-merged. PR #${{ needs.subject.outputs.pr }} closed.`
404
+
405
+ 6. **Flagged** → do not merge. Call `remove_labels` to remove `bot-working`
406
+ (item_number: ${{ needs.subject.outputs.issue }}), then `add_labels` to add `review`
407
+ (item_number: ${{ needs.subject.outputs.issue }}), and `add_comment`
408
+ (item_number: ${{ needs.subject.outputs.issue }}) explaining exactly which criterion
409
+ tripped and what a reviewer should look at. Then `add_comment`
410
+ (item_number: ${{ needs.subject.outputs.pr }}) on the PR with the same message.
411
+ Leave `implement` in place: the work is not finished until a human merges it.
412
+
413
+ 7. **CI failed** → read `/tmp/gh-aw/agent/failed-jobs.json` and
414
+ `/tmp/gh-aw/agent/failed-logs.txt`, which are already on disk. Load only skills required to
415
+ fix the actual cause. Run these verification commands before a push. Do not weaken a test,
416
+ disable a check, or push an unverified guess.
417
+
418
+ ```
419
+ $${{ env.VERIFY_COMMANDS }}
420
+ ```
421
+
422
+ Call `push_to_pull_request_branch` (pr_number: ${{ needs.subject.outputs.pr }}) to push
423
+ the fix, then `remove_labels` (item_number: ${{ needs.subject.outputs.issue }}) to remove
424
+ `bot-working`. CI will run again and trigger you again with the new result.
425
+
426
+ If you cannot fix it, or the logs show you have already tried on this same head commit,
427
+ stop looping: `remove_labels` (item_number: ${{ needs.subject.outputs.issue }}) to remove
428
+ `implement` and `bot-working`, `add_labels` (item_number:
429
+ ${{ needs.subject.outputs.issue }}) to add `review`, and `add_comment` (item_number:
430
+ ${{ needs.subject.outputs.issue }}) with the failure and what you tried. Per #167
431
+ decision 2, a human decides from there.
432
+
433
+ 8. Never merge with administrator privileges and never bypass a required check. If the merge
434
+ is refused, that refusal is the answer: `add_labels` to add `review`
435
+ (item_number: ${{ needs.subject.outputs.issue }}), `add_comment`
436
+ (item_number: ${{ needs.subject.outputs.issue }}) with the refusal, and leave it for a human.
437
+
438
+ ## Diagram
439
+
440
+ ```mermaid
441
+ flowchart TD
442
+ gateStart("Work Router<br/>merge-gate route<br/>(CI completed)") --> gateSubject
443
+ gateSubject["Subject (rung 4)<br/>Our PR? Closes an implement issue?"] -->|✓| gateFacts
444
+ gateSubject -.->|✗| gateIdle
445
+ gateFacts("Facts (rung 3)<br/>Diff, PR shape, failing logs") --> gateCi
446
+ gateCi["CI<br/>What did it conclude?"] -->|success| gateRisk
447
+ gateCi -.->|failure| gateFix
448
+ gateCi -.->|no verdict| gateHuman
449
+ gateRisk["Risk<br/>Auth, schema, API, tests, CI, size, doubt"] -->|clean| gateMerge
450
+ gateRisk -.->|flagged| gateHuman
451
+ gateFix("Fix<br/>Read logs, fix the cause, /repo-verify") -->|pushed| gateWait
452
+ gateFix -.->|cannot fix| gateHuman
453
+ gateMerge(("Merged<br/>Issue closed, review+labels removed"))
454
+ gateWait(("Pushed<br/>CI will re-run and re-trigger via Router"))
455
+ gateHuman(("Review<br/>review label, reason explained"))
456
+ gateIdle(("Idle<br/>Not our pull request"))
457
+
458
+ classDef start fill:#ffffff,stroke:#172033,stroke-width:2px,color:#172033
459
+ classDef action fill:#eef0ff,stroke:#554cff,stroke-width:2px,color:#172033
460
+ classDef decision fill:#fff8e8,stroke:#c75b00,stroke-width:2px,color:#172033
461
+ classDef idle fill:#202c40,stroke:#738198,stroke-width:2px,color:#ffffff
462
+ classDef failure fill:#fff0f0,stroke:#ef2929,stroke-width:2px,color:#8b1a1a
463
+ classDef success fill:#e8f8ec,stroke:#18883c,stroke-width:2px,color:#145a32
464
+ class gateStart start
465
+ class gateFacts,gateFix action
466
+ class gateSubject,gateCi,gateRisk decision
467
+ class gateIdle,gateWait idle
468
+ class gateHuman failure
469
+ class gateMerge success
470
+ ```