@plainconceptsplatform/workflows 0.28.14 → 0.28.17
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/README.md +1 -1
- package/dist/catalog-installation.js +3 -3
- package/dist/catalog-listing.js +1 -1
- package/dist/index.js +1 -1
- package/dist/tui.js +3 -3
- package/loops/actions/housekeeping/action.yml +2 -2
- package/loops/actions/validate-triage-output/validate-triage-output.sh +1 -1
- package/loops/actions/verify-refine-output/verify-refine-output.sh +3 -3
- package/loops/actions/verify-route-matrix/verify-route-matrix.sh +33 -5
- package/loops/docs/diagrams.md +4 -4
- package/loops/scripts/compile-agent-workflows.mjs +2 -2
- package/loops/templates/agentics/agentics-app-errors.yml +1 -1
- package/loops/templates/agentics/agentics-checks.yml +3 -3
- package/loops/templates/agentics/agentics-error-report.yml +3 -3
- package/loops/templates/agentics/agentics-maintenance.yml +9 -9
- package/loops/templates/ci/app-ci-dotnet-next.yml +10 -10
- package/loops/templates/ci/app-ci-node-monorepo.yml +11 -11
- package/loops/templates/issues/bug_report.yml +3 -3
- package/loops/templates/issues/feature_request.yml +4 -4
- package/loops/workflows/agent-apply-review.md +3 -3
- package/loops/workflows/agent-audit.md +1 -1
- package/loops/workflows/agent-implement.md +6 -6
- package/loops/workflows/agent-merge-gate.md +13 -13
- package/loops/workflows/agent-refine.md +4 -4
- package/loops/workflows/agent-release.md +5 -5
- package/loops/workflows/agent-triage.md +16 -16
- package/loops/workflows/agent-visual-verify.md +2 -2
- package/loops/workflows/authorize-bot-work.yml +1 -1
- package/loops/workflows/work-router.yml +37 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ npx --yes --package @plainconceptsplatform/workflows@latest workflows search "ci
|
|
|
83
83
|
|
|
84
84
|
Install optional standalone templates with `add --template`. Available templates are `agentics-checks`, `agentics-error-report`, `agentics-maintenance`, `app-ci-dotnet-next`, `app-ci-node-monorepo`, `bug-report`, `feature-request`, `github-release`, and `opencode.ci.json`. CI templates are stack-specific copies, not a combined template. `github-release` publishes generated release notes when a `v*` tag is pushed. Edit their top-level `env:` values for repository paths, package names, and commands.
|
|
85
85
|
|
|
86
|
-
`agentics-error-report` is worth installing everywhere. Once a day it classifies how *this package's* workflows behaved in the repository and files what broke upstream, so the package gets fixed instead of every repository working around the same bug. It is deterministic
|
|
86
|
+
`agentics-error-report` is worth installing everywhere. Once a day it classifies how *this package's* workflows behaved in the repository and files what broke upstream, so the package gets fixed instead of every repository working around the same bug. It is deterministic no model runs, because a model asked to summarise a failure paraphrases whatever the log held and it sends only the names this package gives its own workflows, jobs and steps, a conclusion, a bucketed runner label, a count and a classification id. No log line, branch, title, path or issue number leaves the repository, the repository's own workflows are counted and never inspected, and a leak scanner withholds any report mentioning the repository or its owner and fails the run rather than filing it. Clear `UPSTREAM_NAME` in its `env:` to compute the report into the job summary and file nothing.
|
|
87
87
|
|
|
88
88
|
## Manual installation
|
|
89
89
|
|
|
@@ -403,18 +403,18 @@ function validateActionManifests(updates) {
|
|
|
403
403
|
manifest = parseYaml(content);
|
|
404
404
|
}
|
|
405
405
|
catch {
|
|
406
|
-
throw new Error(`${target}: invalid YAML
|
|
406
|
+
throw new Error(`${target}: invalid YAML failed to parse action manifest`);
|
|
407
407
|
}
|
|
408
408
|
if (manifest?.runs?.using !== "composite")
|
|
409
409
|
continue;
|
|
410
410
|
const steps = manifest.runs?.steps;
|
|
411
411
|
if (!Array.isArray(steps) || steps.length === 0) {
|
|
412
|
-
throw new Error(`${target}: composite action has no steps
|
|
412
|
+
throw new Error(`${target}: composite action has no steps file may be truncated`);
|
|
413
413
|
}
|
|
414
414
|
for (const [index, step] of steps.entries()) {
|
|
415
415
|
const label = step.name ?? step.id ?? `step ${index}`;
|
|
416
416
|
if (step.shell !== undefined && (typeof step.run !== "string" || step.run.trim() === "")) {
|
|
417
|
-
throw new Error(`${target}: step "${label}" has shell: but no run:
|
|
417
|
+
throw new Error(`${target}: step "${label}" has shell: but no run: manifest is invalid or truncated`);
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
420
|
}
|
package/dist/catalog-listing.js
CHANGED
|
@@ -50,7 +50,7 @@ export function formatCatalog(entries) {
|
|
|
50
50
|
}
|
|
51
51
|
function formatEntry(entry) {
|
|
52
52
|
const mark = entry.installed ? "[x]" : "[ ]";
|
|
53
|
-
return ` ${mark} ${entry.name}
|
|
53
|
+
return ` ${mark} ${entry.name} ${entry.description}`;
|
|
54
54
|
}
|
|
55
55
|
async function isFileInstalled(basePath, workerOrTemplateFile, explicitTarget) {
|
|
56
56
|
const installedPath = templateInstallPath(basePath, workerOrTemplateFile, explicitTarget);
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { routeNames, templateNames } from "./workflow-catalog.js";
|
|
|
7
7
|
import { runInteractive } from "./tui.js";
|
|
8
8
|
import { resolve } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
|
-
const HELP_TEXT = `Workflows CLI
|
|
10
|
+
const HELP_TEXT = `Workflows CLI install and update Plain Concepts Platform agentic workflows.
|
|
11
11
|
|
|
12
12
|
Run with no arguments to launch the interactive TUI, the primary way to select and install
|
|
13
13
|
workflows and templates:
|
package/dist/tui.js
CHANGED
|
@@ -93,17 +93,17 @@ function renderEntry(entry, highlighted, checked) {
|
|
|
93
93
|
if (checked) {
|
|
94
94
|
const checkbox = `${ANSI.green}[x]${ANSI.reset}`;
|
|
95
95
|
const name = highlighted ? `${ANSI.white}${ANSI.bold}${entry.name}${ANSI.reset}` : entry.name;
|
|
96
|
-
const desc = `${ANSI.dim}
|
|
96
|
+
const desc = `${ANSI.dim} ${entry.description}${ANSI.reset}`;
|
|
97
97
|
return `${indicator} ${checkbox} ${name}${desc}`;
|
|
98
98
|
}
|
|
99
99
|
const checkbox = `${ANSI.grey}[ ]${ANSI.reset}`;
|
|
100
100
|
const name = highlighted ? `${ANSI.white}${ANSI.bold}${entry.name}${ANSI.reset}` : entry.name;
|
|
101
|
-
const desc = `${ANSI.dim}
|
|
101
|
+
const desc = `${ANSI.dim} ${entry.description}${ANSI.reset}`;
|
|
102
102
|
return `${indicator} ${checkbox} ${name}${desc}`;
|
|
103
103
|
}
|
|
104
104
|
function render(state) {
|
|
105
105
|
const lines = [];
|
|
106
|
-
lines.push(`${ANSI.cyan}${ANSI.bold}Plain Concepts Platform
|
|
106
|
+
lines.push(`${ANSI.cyan}${ANSI.bold}Plain Concepts Platform Agentic Workflows${ANSI.reset}`);
|
|
107
107
|
lines.push(`${ANSI.dim}Select items to install. Already-installed items are pre-checked.${ANSI.reset}`);
|
|
108
108
|
lines.push("");
|
|
109
109
|
if (state.filter) {
|
|
@@ -67,7 +67,7 @@ runs:
|
|
|
67
67
|
const days = (ms) => Math.floor(ms / 86400000);
|
|
68
68
|
|
|
69
69
|
// 0. Cancel workflow runs stuck in "pending" for over an hour. The ARC fleet is two
|
|
70
|
-
// VMs, and when it saturates, jobs sit pending indefinitely
|
|
70
|
+
// VMs, and when it saturates, jobs sit pending indefinitely GitHub has no queue-time
|
|
71
71
|
// timeout. A stuck pending implement or refine run holds a fleet slot that the retry
|
|
72
72
|
// logic below can never free because the run never reaches a terminal state. This
|
|
73
73
|
// cancel runs on a GitHub-hosted runner, so it works even when the fleet is full.
|
|
@@ -103,7 +103,7 @@ runs:
|
|
|
103
103
|
if (issue.pull_request) continue;
|
|
104
104
|
const labels = names(issue);
|
|
105
105
|
if (!labels.includes('bot-working')) continue;
|
|
106
|
-
// Don't touch issues that already have stalled or review
|
|
106
|
+
// Don't touch issues that already have stalled or review those are handled below.
|
|
107
107
|
if (labels.includes('stalled') || labels.includes('review')) continue;
|
|
108
108
|
const work = WORK_LABELS.find((l) => labels.includes(l));
|
|
109
109
|
if (!work) continue;
|
|
@@ -18,7 +18,7 @@ fi
|
|
|
18
18
|
|
|
19
19
|
# The agent emits exactly one add_comment on the source issue. The comment body
|
|
20
20
|
# must contain a verdict line matching **Verdict:** pass|needs-info|needs-maintainer|block.
|
|
21
|
-
# capture() returns an object
|
|
21
|
+
# capture() returns an object use a named group (?<v>...) to extract the value.
|
|
22
22
|
# test() before capture() avoids jq errors on non-matching bodies.
|
|
23
23
|
jq -r --arg issue "$issue_number" '
|
|
24
24
|
def extract_verdict:
|
|
@@ -57,14 +57,14 @@ assert_output 'wrong issue output is invalid' invalid \
|
|
|
57
57
|
assert_output 'complete output cannot update another issue' invalid \
|
|
58
58
|
'{"items":[{"type":"update_issue","item_number":42,"body":"# User story"},{"type":"update_issue","item_number":7,"body":"# Other story"}]}'
|
|
59
59
|
assert_output 'draft update with questions comment is questions' questions \
|
|
60
|
-
'{"items":[{"type":"update_issue","item_number":42,"body":"<!-- agent-refine-draft -->\n### Proposal\n_pending
|
|
60
|
+
'{"items":[{"type":"update_issue","item_number":42,"body":"<!-- agent-refine-draft -->\n### Proposal\n_pending see questions below_"},{"type":"add_comment","item_number":42,"body":"<!-- agent-refine -->\nRefinement update\nI have some questions about this issue. Please reply in one comment and I''ll process your answers.\nWhich area owns this behavior?"}]}'
|
|
61
61
|
assert_output 'draft update alone is invalid' invalid \
|
|
62
|
-
'{"items":[{"type":"update_issue","item_number":42,"body":"<!-- agent-refine-draft -->\n### Proposal\n_pending
|
|
62
|
+
'{"items":[{"type":"update_issue","item_number":42,"body":"<!-- agent-refine-draft -->\n### Proposal\n_pending see questions below_"}]}'
|
|
63
63
|
|
|
64
64
|
# From a real run. The agent's first update_issue went out malformed, the bridge counted it
|
|
65
65
|
# as spent, the retry carrying the body was refused, and the "Refinement complete" comment
|
|
66
66
|
# went out regardless. Invalid is the only safe reading: the body was never replaced. Note
|
|
67
|
-
# what it must not be read as
|
|
67
|
+
# what it must not be read as a question. Nobody asked one, so "questions" would leave the
|
|
68
68
|
# issue waiting on an answer that is never coming.
|
|
69
69
|
assert_output 'a completion claim with no body is invalid' invalid \
|
|
70
70
|
'{"items":[{"type":"add_comment","item_number":42,"body":"<!-- agent-refine -->\nRefinement update\nRefinement complete. The implement label has been added and the implement workflow will start shortly."},{"type":"report_incomplete","reason":"update_issue limit reached"}]}'
|
|
@@ -530,7 +530,7 @@ if [ "$BOUNDARY_OK" -eq 1 ]; then PASS=$((PASS + 1)); else FAIL=$((FAIL + 1)); f
|
|
|
530
530
|
|
|
531
531
|
# `review` must not be a one-way door. It used to be: authorize-bot-work refused to fire on an
|
|
532
532
|
# issue carrying it, and the classifier refuses to route while it is set, so a person adding
|
|
533
|
-
# `refine` to a parked issue got nothing at all
|
|
533
|
+
# `refine` to a parked issue got nothing at all no run, no comment, no error. Triage's own
|
|
534
534
|
# needs-maintainer verdict tells the maintainer to do exactly that, so the bot was giving an
|
|
535
535
|
# instruction the machine ignored. authorize-bot-work now clears `review` before handing over,
|
|
536
536
|
# which is what makes the human's decision stick.
|
|
@@ -843,7 +843,7 @@ if worker_installed merge-gate; then
|
|
|
843
843
|
{ PENDING_OK=0; echo "FAIL: the only pr-pending removal must sit under the auto-merge disposition" >&2; }
|
|
844
844
|
|
|
845
845
|
# The invariant only ever looked at the merge gate, so apply-review quietly stripped the label
|
|
846
|
-
# on its already-satisfied and needs-human paths
|
|
846
|
+
# on its already-satisfied and needs-human paths both of which leave the pull request open.
|
|
847
847
|
# The one file the check ignored was the one breaking it. Look at every worker: implement adds
|
|
848
848
|
# the label, merge-gate removes it on merge, nobody else may touch it.
|
|
849
849
|
for worker in "${WORKFLOWS_DIR}"/agent-*.md; do
|
|
@@ -2201,6 +2201,9 @@ echo "── Runner pools ──────────────────
|
|
|
2201
2201
|
# agent jobs of every worker except release -> agents-arc (the Azure fleet in
|
|
2202
2202
|
# agentrunner-pro-rg-01,
|
|
2203
2203
|
# runner group `agentic`)
|
|
2204
|
+
# gate and post-processing jobs -> RunnerLandingZone (GitHub-hosted, no fleet
|
|
2205
|
+
# capacity consumed by
|
|
2206
|
+
# trivial checks)
|
|
2204
2207
|
# agent-release.md and work-router.yml -> RunnerLandingZone
|
|
2205
2208
|
# ubuntu-latest -> GitHub's own runner, chosen by nobody, left
|
|
2206
2209
|
# wherever the package already has it
|
|
@@ -2223,9 +2226,34 @@ for worker_md in "${WORKFLOWS_DIR}"/agent-*.md; do
|
|
|
2223
2226
|
want="$AGENT_POOL"
|
|
2224
2227
|
[ "$worker_name" = "agent-release" ] && want="$PLUMBING_POOL"
|
|
2225
2228
|
got="$(pools_named "$worker_md" | tr '\n' ' ' | sed 's/ $//')"
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
+
# Gate jobs and post-processing jobs run on RunnerLandingZone (GitHub-hosted) to avoid
|
|
2230
|
+
# consuming self-hosted fleet capacity for trivial checks. The agent job and safe_outputs
|
|
2231
|
+
# stay on agents-arc. So a worker may name both pools.
|
|
2232
|
+
allowed_pools="${want} ${PLUMBING_POOL}"
|
|
2233
|
+
if [ "$worker_name" = "agent-release" ]; then
|
|
2234
|
+
if [ "$got" != "$want" ]; then
|
|
2235
|
+
POOL_OK=0
|
|
2236
|
+
echo "FAIL: ${worker_name} names runner pool(s) '${got}' but must name only '${want}'" >&2
|
|
2237
|
+
fi
|
|
2238
|
+
else
|
|
2239
|
+
# Every pool named must be in the allowed set; agents-arc must be present (the agent job).
|
|
2240
|
+
ok=1
|
|
2241
|
+
for p in $got; do
|
|
2242
|
+
case " $allowed_pools " in *" $p "*) ;; *) ok=0 ;; esac
|
|
2243
|
+
done
|
|
2244
|
+
if ! echo "$got" | grep -qw "$AGENT_POOL"; then
|
|
2245
|
+
# visual-verify gets its agent runs-on from a shared import, not from the .md file,
|
|
2246
|
+
# so the pool check only sees the subject gate job on RunnerLandingZone.
|
|
2247
|
+
if [ "$worker_name" = "agent-visual-verify" ] && echo "$got" | grep -qw "$PLUMBING_POOL"; then
|
|
2248
|
+
:
|
|
2249
|
+
else
|
|
2250
|
+
ok=0
|
|
2251
|
+
fi
|
|
2252
|
+
fi
|
|
2253
|
+
if [ "$ok" -ne 1 ]; then
|
|
2254
|
+
POOL_OK=0
|
|
2255
|
+
echo "FAIL: ${worker_name} names runner pool(s) '${got}' but must name only '${AGENT_POOL}' and/or '${PLUMBING_POOL}' (with at least ${AGENT_POOL})" >&2
|
|
2256
|
+
fi
|
|
2229
2257
|
fi
|
|
2230
2258
|
done
|
|
2231
2259
|
|
package/loops/docs/diagrams.md
CHANGED
|
@@ -449,7 +449,7 @@ a file on disk, so a confused model cannot publish a release.
|
|
|
449
449
|
Not a worker: a deterministic job in the router, on its own six-hourly cron, with no model. It is
|
|
450
450
|
the answer to a specific measured problem. Across the four consumers, 58 of 237 issues closed since
|
|
451
451
|
1 August were closed by the bot; autonomy ran between 6% and 50%. The gap was not bad decisions, it
|
|
452
|
-
was silence
|
|
452
|
+
was silence work that stopped and told nobody, and state that nothing ever cleaned up.
|
|
453
453
|
|
|
454
454
|
The one rule that shapes it: **retry a failure, report a decision.** A crash, a timeout or an empty
|
|
455
455
|
output is a machine failure, and the worker marks it `stalled`; those are worth running again. A
|
|
@@ -490,7 +490,7 @@ Three things make it safe to leave running unattended. It uses the App token, be
|
|
|
490
490
|
no workflow run from an event raised with `GITHUB_TOKEN`, so with the default token every retry
|
|
491
491
|
would be a green no-op. Every write goes through one `act()` wrapper, which is the only place
|
|
492
492
|
`dry-run` is read, so there is no second path that forgets to check it. And it closes exactly two
|
|
493
|
-
kinds of issue
|
|
493
|
+
kinds of issue a split parent whose children are all done, and its own digest which the route
|
|
494
494
|
matrix asserts by counting.
|
|
495
495
|
|
|
496
496
|
---
|
|
@@ -571,7 +571,7 @@ the repository it runs in. Every consumer is private, so that is the whole desig
|
|
|
571
571
|
What crosses the boundary is a fixed, enumerable set of facts about workflows **this package ships**:
|
|
572
572
|
their file names, their job and step names, a conclusion, a runner label, a count, and the id of a
|
|
573
573
|
matched entry from a catalogue of sixteen known failure shapes. What never crosses it is free text
|
|
574
|
-
of any kind
|
|
574
|
+
of any kind no log line, no branch name, no issue title, no path, no URL, no number that could be
|
|
575
575
|
looked up. Hence no model: a model asked to summarise a failure paraphrases whatever the log held.
|
|
576
576
|
|
|
577
577
|
```mermaid
|
|
@@ -618,7 +618,7 @@ earlier versions of them passed against a deliberately broken guard and were rew
|
|
|
618
618
|
Runs after merge-gate decides to auto-merge, before the actual merge, and produces **evidence, not
|
|
619
619
|
code changes**: it writes a verification plan, drives a real browser through the app, and attaches
|
|
620
620
|
screenshots to the linked issue. It is called directly by merge-gate's `conclude` job, so it is not
|
|
621
|
-
a router route. Failures never block the merge
|
|
621
|
+
a router route. Failures never block the merge a browser that will not start or an app that never
|
|
622
622
|
comes up emits a warning comment and the merge proceeds.
|
|
623
623
|
|
|
624
624
|
```mermaid
|
|
@@ -147,7 +147,7 @@ for (const file of readdirSync(workflowDirectory)) {
|
|
|
147
147
|
//
|
|
148
148
|
// Install only when the pinned version is missing, and take a lock so two jobs starting at
|
|
149
149
|
// once cannot both write the global prefix.
|
|
150
|
-
// gh-aw pins opencode-ai 1.2.14 at every release checked, up to v0.
|
|
150
|
+
// gh-aw pins opencode-ai 1.2.14 at every release checked, up to v0.90.0. That version is
|
|
151
151
|
// from 2026-02-25. The harness expects 1.18.9 and this is the current release, so a gh-aw
|
|
152
152
|
// upgrade does not move it and the pin is ours to choose.
|
|
153
153
|
// gh-aw defaults NPM_CONFIG_MIN_RELEASE_AGE to 3 days, which blocks any package
|
|
@@ -224,7 +224,7 @@ for (const file of readdirSync(workflowDirectory)) {
|
|
|
224
224
|
/^([ \t]+)- name: Report failed jobs\n([ \t]*)id: report_failed_jobs\n[ \t]*if: always\(\)\n/m,
|
|
225
225
|
'$1- name: Report failed jobs\n$2id: report_failed_jobs\n$2if: false # never: failures surface in the run and the retry belt\n')
|
|
226
226
|
|
|
227
|
-
// v0.
|
|
227
|
+
// v0.90.0's arc-dind mode stages the engine CLI to a daemon-visible path but assumes the
|
|
228
228
|
// Copilot engine: command -v copilot is empty under engine: opencode and cp "" fails the
|
|
229
229
|
// job before the agent starts. OpenCode needs no staging, because npm -g installs it under
|
|
230
230
|
// the tool-cache prefix inside _work, which the dind daemon shares.
|
|
@@ -87,7 +87,7 @@ jobs:
|
|
|
87
87
|
collect:
|
|
88
88
|
# Fork of a consumer: not their Azure, not their issues.
|
|
89
89
|
if: "!github.event.repository.fork"
|
|
90
|
-
runs-on:
|
|
90
|
+
runs-on: agents-arc
|
|
91
91
|
timeout-minutes: 20
|
|
92
92
|
# Load bearing, not decoration. The federated credential on the deploy identity trusts the
|
|
93
93
|
# subject `repo:<org>/<repo>:environment:<name>`, so without this the OIDC token is issued
|
|
@@ -25,7 +25,7 @@ env:
|
|
|
25
25
|
# Must match the version the locks were compiled with (first line of every .lock.yml) and the
|
|
26
26
|
# `github/gh-aw/...@vX` import pin in every worker. A different compiler regenerates every lock
|
|
27
27
|
# and the freshness diff measures the version, not the change under review.
|
|
28
|
-
GH_AW_VERSION: v0.
|
|
28
|
+
GH_AW_VERSION: v0.90.0
|
|
29
29
|
ACTIONLINT_VERSION: 1.7.7
|
|
30
30
|
ACTIONLINT_SHA256: 023070a287cd8cccd71515fedc843f1985bf96c436b7effaecce67290e7e0757
|
|
31
31
|
SHELLCHECK_VERSION: 0.10.0
|
|
@@ -45,7 +45,7 @@ concurrency:
|
|
|
45
45
|
jobs:
|
|
46
46
|
verify-lockfiles:
|
|
47
47
|
name: Verify generated agent lockfiles
|
|
48
|
-
runs-on:
|
|
48
|
+
runs-on: agents-arc
|
|
49
49
|
timeout-minutes: 10
|
|
50
50
|
env:
|
|
51
51
|
# gh-aw resolves the `github/gh-aw/...` imports through the GitHub API on every compile,
|
|
@@ -126,7 +126,7 @@ jobs:
|
|
|
126
126
|
|
|
127
127
|
lint-workflows:
|
|
128
128
|
name: Lint authored workflows and shell
|
|
129
|
-
runs-on:
|
|
129
|
+
runs-on: agents-arc
|
|
130
130
|
timeout-minutes: 10
|
|
131
131
|
steps:
|
|
132
132
|
- name: Checkout repository
|
|
@@ -6,8 +6,8 @@ name: "Agentics: Error Report"
|
|
|
6
6
|
# same bug on its own.
|
|
7
7
|
#
|
|
8
8
|
# THIS REPOSITORY IS PRIVATE AND THE REPORT LEAVES IT. That is the whole design constraint. The
|
|
9
|
-
# job is deterministic
|
|
10
|
-
# whatever the log happened to contain
|
|
9
|
+
# job is deterministic no model runs, because a model summarising a log would paraphrase
|
|
10
|
+
# whatever the log happened to contain and it sends only:
|
|
11
11
|
#
|
|
12
12
|
# * the names this package gives its own workflows, jobs and steps
|
|
13
13
|
# * a conclusion, a runner label and a count
|
|
@@ -59,7 +59,7 @@ jobs:
|
|
|
59
59
|
report:
|
|
60
60
|
# Fork of a consumer: the fleet is not theirs and neither is the report.
|
|
61
61
|
if: "!github.event.repository.fork"
|
|
62
|
-
runs-on:
|
|
62
|
+
runs-on: agents-arc
|
|
63
63
|
timeout-minutes: 20
|
|
64
64
|
concurrency:
|
|
65
65
|
group: agentics-error-report
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Managed by @plainconceptsplatform/workflows. Source: loops/templates/agentics/agentics-maintenance.yml. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
2
|
-
# Derived from the gh-aw v0.
|
|
2
|
+
# Derived from the gh-aw v0.90.0 maintenance workflow.
|
|
3
3
|
# Copy provenance is documented in docs/ownership.md.
|
|
4
4
|
name: Agentic Maintenance
|
|
5
5
|
|
|
@@ -48,12 +48,12 @@ 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: agents-arc
|
|
52
52
|
permissions:
|
|
53
53
|
discussions: write
|
|
54
54
|
steps:
|
|
55
55
|
- name: Setup Scripts
|
|
56
|
-
uses: github/gh-aw-actions/setup@
|
|
56
|
+
uses: github/gh-aw-actions/setup@a65c3ae1e11016c37f426bb3847a6f5e1a7d58df # v0.90.0
|
|
57
57
|
with:
|
|
58
58
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
59
59
|
- name: Close expired discussions
|
|
@@ -66,12 +66,12 @@ 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: agents-arc
|
|
70
70
|
permissions:
|
|
71
71
|
issues: write
|
|
72
72
|
steps:
|
|
73
73
|
- name: Setup Scripts
|
|
74
|
-
uses: github/gh-aw-actions/setup@
|
|
74
|
+
uses: github/gh-aw-actions/setup@a65c3ae1e11016c37f426bb3847a6f5e1a7d58df # v0.90.0
|
|
75
75
|
with:
|
|
76
76
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
77
77
|
- name: Close expired issues
|
|
@@ -84,12 +84,12 @@ 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: agents-arc
|
|
88
88
|
permissions:
|
|
89
89
|
pull-requests: write
|
|
90
90
|
steps:
|
|
91
91
|
- name: Setup Scripts
|
|
92
|
-
uses: github/gh-aw-actions/setup@
|
|
92
|
+
uses: github/gh-aw-actions/setup@a65c3ae1e11016c37f426bb3847a6f5e1a7d58df # v0.90.0
|
|
93
93
|
with:
|
|
94
94
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
95
95
|
- name: Close expired pull requests
|
|
@@ -102,12 +102,12 @@ 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: agents-arc
|
|
106
106
|
permissions:
|
|
107
107
|
actions: write
|
|
108
108
|
steps:
|
|
109
109
|
- name: Setup Scripts
|
|
110
|
-
uses: github/gh-aw-actions/setup@
|
|
110
|
+
uses: github/gh-aw-actions/setup@a65c3ae1e11016c37f426bb3847a6f5e1a7d58df # v0.90.0
|
|
111
111
|
with:
|
|
112
112
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
113
113
|
- name: Cleanup outdated cache-memory entries
|
|
@@ -40,7 +40,7 @@ env:
|
|
|
40
40
|
# before any step runs, so a value generated in a step would arrive too late.
|
|
41
41
|
#
|
|
42
42
|
# The same expression is repeated inside the service's `options` above rather than read
|
|
43
|
-
# from here, because the `env` context is not available in `jobs.<id>.services`
|
|
43
|
+
# from here, because the `env` context is not available in `jobs.<id>.services` only
|
|
44
44
|
# inside that service's own `env:`. Written as ${{ env.SQL_SA_PASSWORD }} there, the health
|
|
45
45
|
# check probes with an empty password and the service never reports healthy.
|
|
46
46
|
SQL_SA_PASSWORD: "Aa1!${{ github.run_id }}"
|
|
@@ -62,7 +62,7 @@ jobs:
|
|
|
62
62
|
api:
|
|
63
63
|
name: API (.NET)
|
|
64
64
|
if: github.event_name != 'schedule'
|
|
65
|
-
runs-on:
|
|
65
|
+
runs-on: agents-arc
|
|
66
66
|
timeout-minutes: 30
|
|
67
67
|
services:
|
|
68
68
|
sqlserver:
|
|
@@ -123,7 +123,7 @@ jobs:
|
|
|
123
123
|
mutation-api:
|
|
124
124
|
name: Mutation (.NET, diff)
|
|
125
125
|
if: github.event_name == 'pull_request'
|
|
126
|
-
runs-on:
|
|
126
|
+
runs-on: agents-arc
|
|
127
127
|
timeout-minutes: 25
|
|
128
128
|
defaults:
|
|
129
129
|
run:
|
|
@@ -169,7 +169,7 @@ jobs:
|
|
|
169
169
|
web:
|
|
170
170
|
name: Web (Next.js)
|
|
171
171
|
if: github.event_name != 'schedule'
|
|
172
|
-
runs-on:
|
|
172
|
+
runs-on: agents-arc
|
|
173
173
|
timeout-minutes: 15
|
|
174
174
|
steps:
|
|
175
175
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
@@ -200,7 +200,7 @@ jobs:
|
|
|
200
200
|
mutation-web:
|
|
201
201
|
name: Mutation (web, diff)
|
|
202
202
|
if: github.event_name == 'pull_request'
|
|
203
|
-
runs-on:
|
|
203
|
+
runs-on: agents-arc
|
|
204
204
|
timeout-minutes: 25
|
|
205
205
|
steps:
|
|
206
206
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
@@ -241,14 +241,14 @@ jobs:
|
|
|
241
241
|
|
|
242
242
|
secret-scan:
|
|
243
243
|
name: Secret scan (TruffleHog)
|
|
244
|
-
runs-on:
|
|
244
|
+
runs-on: agents-arc
|
|
245
245
|
steps:
|
|
246
246
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
247
247
|
- run: docker run --rm -v "${{ github.workspace }}:/repo" "$TRUFFLEHOG_IMAGE" filesystem /repo --only-verified --fail --no-update
|
|
248
248
|
|
|
249
249
|
deps-and-iac-scan:
|
|
250
250
|
name: Dependencies and IaC (Trivy)
|
|
251
|
-
runs-on:
|
|
251
|
+
runs-on: agents-arc
|
|
252
252
|
steps:
|
|
253
253
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
254
254
|
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
|
|
@@ -262,14 +262,14 @@ jobs:
|
|
|
262
262
|
|
|
263
263
|
sast-scan:
|
|
264
264
|
name: SAST (Semgrep)
|
|
265
|
-
runs-on:
|
|
265
|
+
runs-on: agents-arc
|
|
266
266
|
steps:
|
|
267
267
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
268
268
|
- 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
|
|
269
269
|
|
|
270
270
|
sbom:
|
|
271
271
|
name: SBOM (CycloneDX)
|
|
272
|
-
runs-on:
|
|
272
|
+
runs-on: agents-arc
|
|
273
273
|
steps:
|
|
274
274
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
275
275
|
- uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0
|
|
@@ -296,7 +296,7 @@ jobs:
|
|
|
296
296
|
github.event.pull_request.head.repo.full_name == github.repository &&
|
|
297
297
|
github.event.pull_request.draft == false &&
|
|
298
298
|
github.event.pull_request.user.type == 'Bot'
|
|
299
|
-
runs-on:
|
|
299
|
+
runs-on: agents-arc
|
|
300
300
|
timeout-minutes: 5
|
|
301
301
|
permissions:
|
|
302
302
|
contents: read
|
|
@@ -38,7 +38,7 @@ jobs:
|
|
|
38
38
|
lint:
|
|
39
39
|
name: Lint (Biome)
|
|
40
40
|
if: github.event_name != 'schedule'
|
|
41
|
-
runs-on:
|
|
41
|
+
runs-on: agents-arc
|
|
42
42
|
steps:
|
|
43
43
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
44
44
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
@@ -51,7 +51,7 @@ jobs:
|
|
|
51
51
|
web:
|
|
52
52
|
name: Web (Next.js static export)
|
|
53
53
|
if: github.event_name != 'schedule'
|
|
54
|
-
runs-on:
|
|
54
|
+
runs-on: agents-arc
|
|
55
55
|
steps:
|
|
56
56
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
57
57
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
@@ -73,7 +73,7 @@ jobs:
|
|
|
73
73
|
mutation-web:
|
|
74
74
|
name: Mutation (web, diff)
|
|
75
75
|
if: github.event_name == 'pull_request'
|
|
76
|
-
runs-on:
|
|
76
|
+
runs-on: agents-arc
|
|
77
77
|
timeout-minutes: 25
|
|
78
78
|
steps:
|
|
79
79
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
@@ -103,7 +103,7 @@ jobs:
|
|
|
103
103
|
name: E2E (Playwright)
|
|
104
104
|
if: github.event_name != 'schedule'
|
|
105
105
|
needs: web
|
|
106
|
-
runs-on:
|
|
106
|
+
runs-on: agents-arc
|
|
107
107
|
steps:
|
|
108
108
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
109
109
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
@@ -128,7 +128,7 @@ jobs:
|
|
|
128
128
|
name: Desktop (Electron)
|
|
129
129
|
if: github.event_name != 'schedule'
|
|
130
130
|
needs: web
|
|
131
|
-
runs-on:
|
|
131
|
+
runs-on: agents-arc
|
|
132
132
|
steps:
|
|
133
133
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
134
134
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
@@ -152,7 +152,7 @@ jobs:
|
|
|
152
152
|
mobile:
|
|
153
153
|
name: Mobile (Capacitor)
|
|
154
154
|
if: github.event_name != 'schedule'
|
|
155
|
-
runs-on:
|
|
155
|
+
runs-on: agents-arc
|
|
156
156
|
steps:
|
|
157
157
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
158
158
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
@@ -171,14 +171,14 @@ jobs:
|
|
|
171
171
|
|
|
172
172
|
secret-scan:
|
|
173
173
|
name: Secret scan (TruffleHog)
|
|
174
|
-
runs-on:
|
|
174
|
+
runs-on: agents-arc
|
|
175
175
|
steps:
|
|
176
176
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
177
177
|
- run: docker run --rm -v "${{ github.workspace }}:/repo" "$TRUFFLEHOG_IMAGE" filesystem /repo --only-verified --fail --no-update
|
|
178
178
|
|
|
179
179
|
deps-and-iac-scan:
|
|
180
180
|
name: Dependencies and IaC (Trivy)
|
|
181
|
-
runs-on:
|
|
181
|
+
runs-on: agents-arc
|
|
182
182
|
steps:
|
|
183
183
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
184
184
|
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
|
|
@@ -192,14 +192,14 @@ jobs:
|
|
|
192
192
|
|
|
193
193
|
sast-scan:
|
|
194
194
|
name: SAST (Semgrep)
|
|
195
|
-
runs-on:
|
|
195
|
+
runs-on: agents-arc
|
|
196
196
|
steps:
|
|
197
197
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
198
198
|
- 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
|
|
199
199
|
|
|
200
200
|
sbom:
|
|
201
201
|
name: SBOM (CycloneDX)
|
|
202
|
-
runs-on:
|
|
202
|
+
runs-on: agents-arc
|
|
203
203
|
steps:
|
|
204
204
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
205
205
|
- uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0
|
|
@@ -226,7 +226,7 @@ jobs:
|
|
|
226
226
|
github.event.pull_request.head.repo.full_name == github.repository &&
|
|
227
227
|
github.event.pull_request.draft == false &&
|
|
228
228
|
github.event.pull_request.user.type == 'Bot'
|
|
229
|
-
runs-on:
|
|
229
|
+
runs-on: agents-arc
|
|
230
230
|
timeout-minutes: 5
|
|
231
231
|
permissions:
|
|
232
232
|
contents: read
|
|
@@ -5,7 +5,7 @@ body:
|
|
|
5
5
|
- type: markdown
|
|
6
6
|
attributes:
|
|
7
7
|
value: |
|
|
8
|
-
Thanks for reporting. Do **not** include real secrets or production data
|
|
8
|
+
Thanks for reporting. Do **not** include real secrets or production data use placeholders.
|
|
9
9
|
|
|
10
10
|
For security vulnerabilities, contact the team directly instead of filing a public issue.
|
|
11
11
|
- type: dropdown
|
|
@@ -14,8 +14,8 @@ body:
|
|
|
14
14
|
label: Severity
|
|
15
15
|
options:
|
|
16
16
|
- Production-down / data loss
|
|
17
|
-
- Major
|
|
18
|
-
- Minor
|
|
17
|
+
- Major broken core flow
|
|
18
|
+
- Minor broken edge case
|
|
19
19
|
- Cosmetic / polish
|
|
20
20
|
validations:
|
|
21
21
|
required: true
|
|
@@ -5,21 +5,21 @@ body:
|
|
|
5
5
|
- type: markdown
|
|
6
6
|
attributes:
|
|
7
7
|
value: |
|
|
8
|
-
This template is for small, well-scoped improvements
|
|
8
|
+
This template is for small, well-scoped improvements a focused
|
|
9
9
|
enhancement, a missing convenience, a quality-of-life fix.
|
|
10
10
|
|
|
11
11
|
For large features, architecture changes, or cross-cutting work,
|
|
12
12
|
open a planning issue or an ADR instead.
|
|
13
13
|
|
|
14
|
-
Do **not** include real secrets or production data
|
|
14
|
+
Do **not** include real secrets or production data use placeholders.
|
|
15
15
|
- type: dropdown
|
|
16
16
|
id: scope
|
|
17
17
|
attributes:
|
|
18
18
|
label: Scope
|
|
19
19
|
description: How big is this change? If it doesn't fit Small or Medium, use a planning issue instead.
|
|
20
20
|
options:
|
|
21
|
-
- Small
|
|
22
|
-
- Medium
|
|
21
|
+
- Small a single file or component, no refactoring
|
|
22
|
+
- Medium touches a few files or a feature area, may need minor refactoring
|
|
23
23
|
validations:
|
|
24
24
|
required: true
|
|
25
25
|
- type: textarea
|
|
@@ -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
|
|
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.
|
|
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
|
|
|
@@ -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
|
|
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'
|
|
@@ -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.
|
|
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
|
|
|
@@ -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
|
|
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.
|
|
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
|
|
|
@@ -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
|
|
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
|
#
|
|
@@ -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:
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
977
|
-
you cannot trace
|
|
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
|
|
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
|
|
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
|
|
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`**
|
|
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`**
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
|
@@ -832,10 +832,10 @@ timeout-minutes: 90
|
|
|
832
832
|
could not answer. Leave the partial work visible: first call `update_issue` with a
|
|
833
833
|
temporal draft, then call `add_comment` once with the questions.
|
|
834
834
|
|
|
835
|
-
The temporal draft is the replacement body your path would have written
|
|
835
|
+
The temporal draft is the replacement body your path would have written the story
|
|
836
836
|
body from the standard path, the marker, summary and checklist from the trivial path —
|
|
837
837
|
holding everything you already established, with every
|
|
838
|
-
part the questions leave open marked `_pending
|
|
838
|
+
part the questions leave open marked `_pending see questions below_`. Its very
|
|
839
839
|
first line is `${{ env.DRAFT_MARKER }}`; the next run replaces the draft wholesale
|
|
840
840
|
with the final body.
|
|
841
841
|
|
|
@@ -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.
|
|
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:
|
|
33
|
-
runs-on-slim:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
501
|
-
issues in `${{ env.OPEN_ISSUES_PATH }}`. Flag any that are semantically similar
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
|
@@ -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
|
|
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.
|
|
@@ -34,7 +34,7 @@ jobs:
|
|
|
34
34
|
github.event.label.name == 'refine') &&
|
|
35
35
|
!contains(github.event.issue.labels.*.name, 'bot-working') &&
|
|
36
36
|
!endsWith(github.actor, '[bot]')
|
|
37
|
-
runs-on:
|
|
37
|
+
runs-on: agents-arc
|
|
38
38
|
timeout-minutes: 5
|
|
39
39
|
concurrency:
|
|
40
40
|
group: authorize-${{ github.event.issue.number }}
|
|
@@ -10,38 +10,38 @@ name: "# Main Work Router"
|
|
|
10
10
|
run-name: >-
|
|
11
11
|
${{ github.event_name == 'issues'
|
|
12
12
|
&& github.event.action == 'opened'
|
|
13
|
-
&& format('Event: Issue opened
|
|
13
|
+
&& format('Event: Issue opened - #{0} {1} by {2}', github.event.issue.number, github.event.issue.title, github.actor)
|
|
14
14
|
|| github.event_name == 'issues'
|
|
15
15
|
&& github.event.label.name == 'bot-working'
|
|
16
16
|
&& contains(github.event.issue.labels.*.name, 'implement')
|
|
17
|
-
&& format('Agent: Implement
|
|
17
|
+
&& format('Agent: Implement - #{0} {1}', github.event.issue.number, github.event.issue.title)
|
|
18
18
|
|| github.event_name == 'issues'
|
|
19
19
|
&& github.event.label.name == 'bot-working'
|
|
20
20
|
&& contains(github.event.issue.labels.*.name, 'refine')
|
|
21
|
-
&& format('Agent: Refine
|
|
21
|
+
&& format('Agent: Refine - #{0} {1}', github.event.issue.number, github.event.issue.title)
|
|
22
22
|
|| github.event_name == 'issues'
|
|
23
23
|
&& github.event.label.name == 'bot-working'
|
|
24
24
|
&& contains(github.event.issue.labels.*.name, 'direct')
|
|
25
|
-
&& format('Working: Direct
|
|
25
|
+
&& format('Working: Direct - #{0} {1}', github.event.issue.number, github.event.issue.title)
|
|
26
26
|
|| github.event_name == 'issues'
|
|
27
27
|
&& github.event.label.name == 'bot-working'
|
|
28
28
|
&& contains(github.event.issue.labels.*.name, 'triage')
|
|
29
|
-
&& format('Agent: Triage
|
|
29
|
+
&& format('Agent: Triage - #{0} {1}', github.event.issue.number, github.event.issue.title)
|
|
30
30
|
|| github.event_name == 'issues'
|
|
31
31
|
&& github.event.label.name == 'bot-working'
|
|
32
32
|
&& format('Working: #{0} {1}', github.event.issue.number, github.event.issue.title)
|
|
33
33
|
|| github.event_name == 'issues'
|
|
34
34
|
&& github.event.label.name == 'implement'
|
|
35
35
|
&& endsWith(github.actor, '[bot]')
|
|
36
|
-
&& format('Agent: Implement
|
|
36
|
+
&& format('Agent: Implement - #{0} {1}', github.event.issue.number, github.event.issue.title)
|
|
37
37
|
|| github.event_name == 'issues'
|
|
38
38
|
&& github.event.label.name == 'refine'
|
|
39
39
|
&& endsWith(github.actor, '[bot]')
|
|
40
|
-
&& format('Agent: Refine
|
|
40
|
+
&& format('Agent: Refine - #{0} {1}', github.event.issue.number, github.event.issue.title)
|
|
41
41
|
|| github.event_name == 'issues'
|
|
42
42
|
&& github.event.label.name == 'direct'
|
|
43
43
|
&& endsWith(github.actor, '[bot]')
|
|
44
|
-
&& format('Working: Direct
|
|
44
|
+
&& format('Working: Direct - #{0} {1}', github.event.issue.number, github.event.issue.title)
|
|
45
45
|
|| github.event_name == 'issues'
|
|
46
46
|
&& format('Event: {0} on #{1} by {2}', github.event.label.name, github.event.issue.number, github.actor)
|
|
47
47
|
|| github.event_name == 'issue_comment'
|
|
@@ -56,25 +56,25 @@ run-name: >-
|
|
|
56
56
|
&& format('Event: CI {0} on {1}', github.event.workflow_run.conclusion, github.event.workflow_run.head_branch)
|
|
57
57
|
|| github.event_name == 'workflow_dispatch'
|
|
58
58
|
&& inputs.operation == 'triage'
|
|
59
|
-
&& format('Agent: Triage
|
|
59
|
+
&& format('Agent: Triage - #{0}', inputs.issue-number)
|
|
60
60
|
|| github.event_name == 'workflow_dispatch'
|
|
61
61
|
&& inputs.operation == 'refine'
|
|
62
|
-
&& format('Agent: Refine
|
|
62
|
+
&& format('Agent: Refine - #{0}', inputs.issue-number)
|
|
63
63
|
|| github.event_name == 'workflow_dispatch'
|
|
64
64
|
&& inputs.operation == 'implement'
|
|
65
|
-
&& format('Agent: Implement
|
|
65
|
+
&& format('Agent: Implement - #{0}', inputs.issue-number)
|
|
66
66
|
|| github.event_name == 'workflow_dispatch'
|
|
67
67
|
&& inputs.operation == 'merge-gate'
|
|
68
|
-
&& format('Agent: Merge Gate
|
|
68
|
+
&& format('Agent: Merge Gate - PR #{0}', inputs.pr-number)
|
|
69
69
|
|| github.event_name == 'workflow_dispatch'
|
|
70
70
|
&& inputs.operation == 'visual-verify'
|
|
71
|
-
&& format('Agent: Visual Verify
|
|
71
|
+
&& format('Agent: Visual Verify - PR #{0}', inputs.pr-number)
|
|
72
72
|
|| github.event_name == 'workflow_dispatch'
|
|
73
73
|
&& inputs.operation == 'batch'
|
|
74
|
-
&& format('Working: Batch
|
|
74
|
+
&& format('Working: Batch - #{0}', inputs.issue-number)
|
|
75
75
|
|| github.event_name == 'workflow_dispatch'
|
|
76
76
|
&& inputs.operation == 'audit'
|
|
77
|
-
&& format('Agent: Audit
|
|
77
|
+
&& format('Agent: Audit - manual{0}', '')
|
|
78
78
|
|| github.event_name == 'workflow_dispatch'
|
|
79
79
|
&& inputs.operation == 'release'
|
|
80
80
|
&& format('Agent: Release{0}', '')
|
|
@@ -82,19 +82,19 @@ run-name: >-
|
|
|
82
82
|
&& format('dispatch: {0}', inputs.operation)
|
|
83
83
|
|| github.event_name == 'schedule'
|
|
84
84
|
&& github.event.schedule == '17 1 * * 1'
|
|
85
|
-
&& format('Agent: Audit
|
|
85
|
+
&& format('Agent: Audit - weekly{0}', '')
|
|
86
86
|
|| github.event_name == 'schedule'
|
|
87
87
|
&& github.event.schedule == '43 3 * * *'
|
|
88
|
-
&& format('Agentics: Audit Close
|
|
88
|
+
&& format('Agentics: Audit Close - daily{0}', '')
|
|
89
89
|
|| github.event_name == 'schedule'
|
|
90
90
|
&& github.event.schedule == '0 6 * * *'
|
|
91
|
-
&& format('Agentics: Cleanup
|
|
91
|
+
&& format('Agentics: Cleanup - daily{0}', '')
|
|
92
92
|
|| github.event_name == 'schedule'
|
|
93
93
|
&& github.event.schedule == '17 * * * *'
|
|
94
|
-
&& format('Agentics: Reconcile
|
|
94
|
+
&& format('Agentics: Reconcile - hourly{0}', '')
|
|
95
95
|
|| github.event_name == 'schedule'
|
|
96
96
|
&& github.event.schedule == '23 */6 * * *'
|
|
97
|
-
&& format('Agentics: Maintenance
|
|
97
|
+
&& format('Agentics: Maintenance - 6h{0}', '')
|
|
98
98
|
|| github.event_name == 'schedule'
|
|
99
99
|
&& format('schedule {0}', github.event.schedule)
|
|
100
100
|
|| github.event_name }}
|
|
@@ -267,7 +267,7 @@ permissions:
|
|
|
267
267
|
jobs:
|
|
268
268
|
# Public repositories must check repository permission before an event can start a model.
|
|
269
269
|
authorize:
|
|
270
|
-
runs-on:
|
|
270
|
+
runs-on: agents-arc
|
|
271
271
|
timeout-minutes: 5
|
|
272
272
|
permissions:
|
|
273
273
|
contents: read
|
|
@@ -346,7 +346,7 @@ jobs:
|
|
|
346
346
|
# "unknown" counts as inside. Somebody with write or better whose membership
|
|
347
347
|
# cannot be established is far more likely to be a colleague than an outside
|
|
348
348
|
# collaborator, and treating them as outside starts a triage agent nobody asked
|
|
349
|
-
# for
|
|
349
|
+
# for - which, with a four-hour timeout, holds a runner for the afternoon.
|
|
350
350
|
if [ "$is_member" != "false" ]; then
|
|
351
351
|
echo "trusted=true" >> "$GITHUB_OUTPUT"
|
|
352
352
|
echo "is_outside_collaborator=false" >> "$GITHUB_OUTPUT"
|
|
@@ -370,7 +370,7 @@ jobs:
|
|
|
370
370
|
esac
|
|
371
371
|
|
|
372
372
|
classify:
|
|
373
|
-
runs-on:
|
|
373
|
+
runs-on: agents-arc
|
|
374
374
|
timeout-minutes: 5
|
|
375
375
|
permissions:
|
|
376
376
|
contents: read
|
|
@@ -423,12 +423,12 @@ jobs:
|
|
|
423
423
|
AGENTMEMORY_SECRET: ${{ secrets.AGENTMEMORY_SECRET }}
|
|
424
424
|
|
|
425
425
|
# Checks whether an open bot PR already exists for the issue. If it does, implement is
|
|
426
|
-
# skipped
|
|
426
|
+
# skipped - the merge-gate will handle fixing the existing PR. This prevents duplicate
|
|
427
427
|
# PRs when retries are triggered after a merge-gate failure.
|
|
428
428
|
check-implement-pr:
|
|
429
429
|
needs: [classify, authorize]
|
|
430
430
|
if: needs.classify.outputs.route == 'implement' && needs.authorize.outputs.trusted == 'true'
|
|
431
|
-
runs-on:
|
|
431
|
+
runs-on: agents-arc
|
|
432
432
|
timeout-minutes: 3
|
|
433
433
|
permissions:
|
|
434
434
|
contents: read
|
|
@@ -519,7 +519,7 @@ jobs:
|
|
|
519
519
|
dispatch-triage:
|
|
520
520
|
needs: [classify, authorize]
|
|
521
521
|
if: needs.classify.outputs.route == 'triage' && needs.authorize.outputs.is_outside_collaborator == 'true'
|
|
522
|
-
runs-on:
|
|
522
|
+
runs-on: agents-arc
|
|
523
523
|
timeout-minutes: 5
|
|
524
524
|
permissions:
|
|
525
525
|
actions: write
|
|
@@ -548,7 +548,7 @@ jobs:
|
|
|
548
548
|
call-triage:
|
|
549
549
|
needs: [classify, authorize]
|
|
550
550
|
# Triage on issue open is for outside collaborators only (handled by dispatch-triage).
|
|
551
|
-
# A trusted actor who opens an issue should not start triage
|
|
551
|
+
# A trusted actor who opens an issue should not start triage - they can add refine/implement/direct
|
|
552
552
|
# labels or manually dispatch triage. All other triage routes (labeled, comment, dispatch) are trusted.
|
|
553
553
|
if: needs.classify.outputs.route == 'triage' && needs.authorize.outputs.trusted == 'true' && !(github.event_name == 'issues' && github.event.action == 'opened')
|
|
554
554
|
uses: ./.github/workflows/agent-triage.lock.yml
|
|
@@ -669,7 +669,7 @@ jobs:
|
|
|
669
669
|
if: >
|
|
670
670
|
needs.classify.outputs.route == 'bot-approve' &&
|
|
671
671
|
(github.actor == 'app/github-actions' || github.actor == 'platform-devbox[bot]')
|
|
672
|
-
runs-on:
|
|
672
|
+
runs-on: agents-arc
|
|
673
673
|
timeout-minutes: 5
|
|
674
674
|
permissions:
|
|
675
675
|
actions: write
|
|
@@ -700,8 +700,8 @@ jobs:
|
|
|
700
700
|
# Conflict watcher for bot pull requests. Merge-conflict state is only available from the
|
|
701
701
|
# mergeability API, which the pure classifier cannot read, so this is an event-gated
|
|
702
702
|
# deterministic dispatcher rather than a classify route (it runs alongside bot-approve on
|
|
703
|
-
# the same pull_request_target event). It NEVER checks out or runs pull request code
|
|
704
|
-
# reads mergeability through the API and dispatches the Merge Gate
|
|
703
|
+
# the same pull_request_target event). It NEVER checks out or runs pull request code - it
|
|
704
|
+
# reads mergeability through the API and dispatches the Merge Gate - so it is safe on
|
|
705
705
|
# pull_request_target. Two entry points:
|
|
706
706
|
# opened / reopened / synchronize → check the pull request that changed. Gated to this
|
|
707
707
|
# repository's own branches so a fork PR never starts this App-token job.
|
|
@@ -726,7 +726,7 @@ jobs:
|
|
|
726
726
|
github.event.pull_request.head.repo.full_name == github.repository
|
|
727
727
|
)
|
|
728
728
|
)
|
|
729
|
-
runs-on:
|
|
729
|
+
runs-on: agents-arc
|
|
730
730
|
timeout-minutes: 10
|
|
731
731
|
permissions:
|
|
732
732
|
contents: read
|
|
@@ -754,7 +754,7 @@ jobs:
|
|
|
754
754
|
set -euo pipefail
|
|
755
755
|
|
|
756
756
|
# Dispatch the Merge Gate for one pull request when it is a red-CI open, non-draft
|
|
757
|
-
# pull request on this repository whose CI has concluded
|
|
757
|
+
# pull request on this repository whose CI has concluded - the
|
|
758
758
|
# conflict case is one arm of that, because a conflicting PR never gets a fresh
|
|
759
759
|
# CI run of its own; a merge conflict with red or concluded CI is the same
|
|
760
760
|
# "needs the gate" signal. A green non-conflicting PR is left for the merge belt
|
|
@@ -918,7 +918,7 @@ jobs:
|
|
|
918
918
|
reconcile-bot-pr-runs:
|
|
919
919
|
needs: classify
|
|
920
920
|
if: needs.classify.outputs.route == 'reconcile-bot-pr-runs'
|
|
921
|
-
runs-on:
|
|
921
|
+
runs-on: agents-arc
|
|
922
922
|
timeout-minutes: 5
|
|
923
923
|
permissions:
|
|
924
924
|
contents: read
|
|
@@ -1145,7 +1145,7 @@ jobs:
|
|
|
1145
1145
|
audit-close:
|
|
1146
1146
|
needs: classify
|
|
1147
1147
|
if: needs.classify.outputs.route == 'audit-close'
|
|
1148
|
-
runs-on:
|
|
1148
|
+
runs-on: agents-arc
|
|
1149
1149
|
timeout-minutes: 15
|
|
1150
1150
|
concurrency:
|
|
1151
1151
|
group: audit-close
|
|
@@ -1170,7 +1170,7 @@ jobs:
|
|
|
1170
1170
|
cleanup-artifacts:
|
|
1171
1171
|
needs: classify
|
|
1172
1172
|
if: needs.classify.outputs.route == 'cleanup-artifacts' && !github.event.repository.fork
|
|
1173
|
-
runs-on:
|
|
1173
|
+
runs-on: agents-arc
|
|
1174
1174
|
timeout-minutes: 15
|
|
1175
1175
|
concurrency:
|
|
1176
1176
|
group: cleanup-artifacts
|
|
@@ -1194,7 +1194,7 @@ jobs:
|
|
|
1194
1194
|
housekeeping:
|
|
1195
1195
|
needs: classify
|
|
1196
1196
|
if: needs.classify.outputs.route == 'housekeeping' && !github.event.repository.fork
|
|
1197
|
-
runs-on:
|
|
1197
|
+
runs-on: agents-arc
|
|
1198
1198
|
timeout-minutes: 15
|
|
1199
1199
|
concurrency:
|
|
1200
1200
|
group: housekeeping
|
|
@@ -1235,7 +1235,7 @@ jobs:
|
|
|
1235
1235
|
validate:
|
|
1236
1236
|
needs: classify
|
|
1237
1237
|
if: needs.classify.outputs.route == 'validate'
|
|
1238
|
-
runs-on:
|
|
1238
|
+
runs-on: agents-arc
|
|
1239
1239
|
timeout-minutes: 10
|
|
1240
1240
|
permissions:
|
|
1241
1241
|
contents: read
|