@plainconceptsplatform/workflows 0.28.15 → 0.28.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +1 -1
  2. package/dist/catalog-installation.js +3 -3
  3. package/dist/catalog-listing.js +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/tui.js +3 -3
  6. package/loops/actions/housekeeping/action.yml +2 -2
  7. package/loops/actions/validate-triage-output/validate-triage-output.sh +1 -1
  8. package/loops/actions/verify-refine-output/verify-refine-output.sh +3 -3
  9. package/loops/actions/verify-route-matrix/verify-route-matrix.sh +33 -5
  10. package/loops/docs/diagrams.md +4 -4
  11. package/loops/scripts/compile-agent-workflows.mjs +2 -2
  12. package/loops/templates/agentics/agentics-app-errors.yml +1 -1
  13. package/loops/templates/agentics/agentics-checks.yml +3 -3
  14. package/loops/templates/agentics/agentics-error-report.yml +3 -3
  15. package/loops/templates/agentics/agentics-maintenance.yml +9 -9
  16. package/loops/templates/ci/app-ci-dotnet-next.yml +10 -10
  17. package/loops/templates/ci/app-ci-node-monorepo.yml +11 -11
  18. package/loops/templates/issues/bug_report.yml +3 -3
  19. package/loops/templates/issues/feature_request.yml +4 -4
  20. package/loops/workflows/agent-apply-review.md +9 -9
  21. package/loops/workflows/agent-audit.md +3 -3
  22. package/loops/workflows/agent-implement.md +11 -11
  23. package/loops/workflows/agent-merge-gate.md +19 -19
  24. package/loops/workflows/agent-refine.md +21 -12
  25. package/loops/workflows/agent-release.md +5 -5
  26. package/loops/workflows/agent-triage.md +21 -21
  27. package/loops/workflows/agent-visual-verify.md +3 -3
  28. package/loops/workflows/authorize-bot-work.yml +1 -1
  29. package/loops/workflows/work-router.yml +37 -37
  30. package/package.json +46 -45
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 — 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.
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 — failed to parse action manifest`);
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 — file may be truncated`);
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: — manifest is invalid or truncated`);
417
+ throw new Error(`${target}: step "${label}" has shell: but no run: manifest is invalid or truncated`);
418
418
  }
419
419
  }
420
420
  }
@@ -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} — ${entry.description}`;
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 — install and update Plain Concepts Platform agentic workflows.
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} — ${entry.description}${ANSI.reset}`;
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} — ${entry.description}${ANSI.reset}`;
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 — Agentic Workflows${ANSI.reset}`);
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 — GitHub has no queue-time
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 — those are handled below.
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 — use a named group (?<v>...) to extract the value.
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 — 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?"}]}'
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 — see questions below_"}]}'
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 — a question. Nobody asked one, so "questions" would leave the
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 — no run, no comment, no error. Triage's own
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 — both of which leave the pull request open.
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
- if [ "$got" != "$want" ]; then
2227
- POOL_OK=0
2228
- echo "FAIL: ${worker_name} names runner pool(s) '${got}' but must name only '${want}'" >&2
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
 
@@ -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 — work that stopped and told nobody, and state that nothing ever cleaned up.
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 — a split parent whose children are all done, and its own digest — which the route
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 — no log line, no branch name, no issue title, no path, no URL, no number that could be
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 — a browser that will not start or an app that never
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.87.5. That version is
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.87.5's arc-dind mode stages the engine CLI to a daemon-visible path but assumes the
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: ubuntu-latest
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.87.5
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: ubuntu-latest
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: ubuntu-latest
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 — no model runs, because a model summarising a log would paraphrase
10
- # whatever the log happened to contain — and it sends only:
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: ubuntu-latest
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.83.4 maintenance workflow.
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: ubuntu-latest
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@e89c65e17eb281bbd5ff2ff9e9199a03e96654c7 # v0.83.4
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: ubuntu-latest
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@e89c65e17eb281bbd5ff2ff9e9199a03e96654c7 # v0.83.4
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: ubuntu-latest
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@e89c65e17eb281bbd5ff2ff9e9199a03e96654c7 # v0.83.4
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: ubuntu-latest
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@e89c65e17eb281bbd5ff2ff9e9199a03e96654c7 # v0.83.4
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` — only
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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: RunnerLandingZone
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 — use placeholders.
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 — broken core flow
18
- - Minor — broken edge case
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 — a focused
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 — use placeholders.
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 — a single file or component, no refactoring
22
- - Medium — touches a few files or a feature area, may need minor refactoring
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