Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 101 additions & 8 deletions .github/workflows/initiative-driver.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# is pure-bash (no claude-code-action), so this stub dispatches the central
# workflow_dispatch DIRECTLY with `gh workflow run`. No LLM runs here.
# • You MUST NOT change: the dispatch target
# (-R combsmith/.github-private -f target_repo=${{ github.repository }}),
# (-R combsmith/.github-private -f target_repo=<this repo>),
# the `initiative:auto` label filter, or the PAT guard.
# • If you need different release behaviour, open a PR against the central
# driver in combsmith/.github-private — never by editing callers.
Expand All @@ -27,14 +27,32 @@
# sub-issues to dev-lead — so the central driver does not have to watch every
# enrolled repo's events.
#
# Rate-limit gate (#640): before dispatching, this stub asks the source-side
# agent-rate-limit gate (combsmith/.github/scripts/agent-rate-limit-gate.sh)
# whether `initiative-driver` may dispatch right now. initiative-driver is the
# canary that ENFORCES: the gate derives concurrency / cooldown / daily-budget /
# consecutive-failure counters from this stub's own run history (no state
# backend) and reads every threshold from standards/agent-rate-limits.json.
# It throttles dispatches that DO start (cooldown / daily budget / breaker); it
# does NOT pre-empt the cancel-in-progress concurrency group below — that group
# cancels a superseded run before any step (gate included) executes (#443/#402).
# A `defer` simply skips the dispatch step — never a cancel, never a job failure.
#
# Gate tooling is fetched at a pinned commit SHA of combsmith/.github (not
# a moving tag — the PAT is handed to that code). If the tooling is unavailable
# or the gate errors, the gate step FAILS LOUDLY (::error:: annotation + step
# summary, step marked failed) but the dispatch still runs (fail-open — an
# outage of the gate must never stop the fleet; standards/agent-rate-limits.md).
#
# To adopt:
# 1. Copy this file verbatim to .github/workflows/initiative-driver.yml in your repo.
# 2. Ensure the `initiative:auto` label exists on the repo.
# 3. Confirm the org-level secret GH_PAT_WORKFLOWS is accessible **and its
# owner has write access to combsmith/.github-private** (to dispatch
# the central workflow) **and to this repo** (the central driver applies the
# `dev-lead` label cross-repo with that PAT; a label applied with
# GITHUB_TOKEN would not trigger dev-lead).
# 3. Confirm the org-level secret GH_PAT_DON_PETRY (or the legacy fallback
# GH_PAT_WORKFLOWS) is accessible **and its owner has write access to
# combsmith/.github-private** (to dispatch the central workflow) **and
# to this repo** (the central driver applies the `dev-lead` label
# cross-repo with that PAT; a label applied with GITHUB_TOKEN would not
# trigger dev-lead).
#
# Standard: https://github.com/combsmith/.github/blob/main/standards/ci-standards.md
name: Initiative Driver — Dispatch Central
Expand Down Expand Up @@ -76,14 +94,89 @@ jobs:
GH_TOKEN: ${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}
run: |
if [ -z "${GH_TOKEN}" ]; then
echo "::error::GH_PAT_WORKFLOWS is required — a workflow_dispatch fired with GITHUB_TOKEN never starts a run."
echo "::error::GH_PAT_DON_PETRY (or legacy GH_PAT_WORKFLOWS) is required — a workflow_dispatch fired with GITHUB_TOKEN never starts a run."
exit 1
fi

- name: Checkout agent-rate-limit gate tooling
# Phase-4 wiring (#640): the gate library + orchestrator live in
# combsmith/.github; an enrolled caller stub does not carry them, so
# fetch them read-only into a scratch path. Uses the same PAT as the
# dispatch — the workflow's GITHUB_TOKEN cannot read another repo — so the
# stub's `permissions:` block is unchanged.
# continue-on-error: a tooling-checkout outage must not stop the fleet —
# the gate step then finds no script, reports an ::error:: (fail loudly),
# emits no decision, and the dispatch step's `!= 'defer'` guard falls
# through to dispatching (fail-open).
# ref: pinned to an immutable commit SHA of combsmith/.github (#1232)
# — a moving tag silently lagged the gate script (v1 predates it) and
# would hand the PAT to whatever the tag next points at. Bump it in a
# reviewed PR (see standards/agent-rate-limits.md §3.1).
continue-on-error: true
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: combsmith/.github
ref: cd0b16751454d2eb3486ec04477d7ee9cc96c425 # main @ 2026-10-02 (#1232)
path: .arl-gate-tooling
fetch-depth: 1
persist-credentials: false
token: ${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}

- name: Agent rate-limit admission gate (enforcing)
# initiative-driver is the ONE canary agent type that ENFORCES (pure bash,
# no model spend, the direct #443 target — AC #5). Reads run history with
# the PAT (independent of the `permissions:` block) and emits
# decision=allow|defer to $GITHUB_OUTPUT; a defer is honoured by the `if:`
# on the dispatch step below. Fail loud, fail open: a missing gate script
# or a gate error marks THIS step failed with an ::error:: (visible in the
# run), but continue-on-error keeps the job — and the dispatch — going.
continue-on-error: true
id: arl_gate
env:
GH_TOKEN: ${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}
ARL_ACTOR: ${{ github.actor }}
ARL_TRACKING_REPO: ${{ github.repository }}
# For issue events use the event's issue number; for schedule/workflow_dispatch
# fall back to a configured repo variable so argate_escalate can post the
# breaker marker and apply the needs-human-review label (both are skipped when
# tracking_issue is empty). Set INITIATIVE_DRIVER_TRACKING_ISSUE to the epic
# or operations issue number for this repo to enable escalation on non-issue runs.
ARL_TRACKING_ISSUE: ${{ github.event.issue.number || vars.INITIATIVE_DRIVER_TRACKING_ISSUE || '' }}
run: |
set -euo pipefail
ARL_GATE_SCRIPT=.arl-gate-tooling/scripts/agent-rate-limit-gate.sh
if ! [ -f "$ARL_GATE_SCRIPT" ]; then
msg="Agent rate-limit gate NOT ENFORCED: ${ARL_GATE_SCRIPT} is missing (tooling checkout failed or the pinned ref lacks the script). Dispatching ungated (fail-open)."
echo "::error::${msg}"
echo "### :warning: ${msg}" >> "$GITHUB_STEP_SUMMARY"
exit 1
fi
bash "$ARL_GATE_SCRIPT" initiative-driver \
--repo "$ARL_TRACKING_REPO" \
--mode enforce \
--workflow initiative-driver.yml \
--actor "$ARL_ACTOR" \
Comment thread
coderabbitai[bot] marked this conversation as resolved.
--tracking-repo "$ARL_TRACKING_REPO" \
--tracking-issue "$ARL_TRACKING_ISSUE" || {
rc=$?
echo "::error::Agent rate-limit gate errored (exit ${rc}) — dispatching ungated (fail-open)."
echo "### :warning: Agent rate-limit gate errored (exit ${rc}) — dispatching ungated (fail-open)." >> "$GITHUB_STEP_SUMMARY"
exit "$rc"
}

- name: Dispatch central initiative-driver
# Skipped (clean no-op) ONLY on an explicit `defer` — never a cancel, never
# a job failure (#640, AC #1/#2). Fail-OPEN: an empty/missing decision (the
# gate step or its tooling checkout failed) still dispatches, because an
# outage of the gate must never stop the fleet (ADR §7 fail-safe direction).
if: steps.arl_gate.outputs.decision != 'defer'
env:
GH_TOKEN: ${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}
# Pass github.repository via env (not inline template expansion) to keep
# the workflow expression out of shell text (zizmor template-injection).
# The dispatch target value is unchanged — target_repo is still this repo.
TARGET_REPO: ${{ github.repository }}
run: |
gh workflow run initiative-driver.yml \
-R combsmith/.github-private \
-f target_repo=${{ github.repository }}
-f target_repo="${TARGET_REPO}"
54 changes: 34 additions & 20 deletions .github/workflows/pr-review.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
name: PR Review Agent

# Thin caller for the org PR Review agent (combsmith/.github-private),
# pinned to the known-good `pr-review/stable` channel. Adopted from the validated
# `.github-private/pr-review-trigger.yml` template (#536 consumer fan-out).
# ─────────────────────────────────────────────────────────────────────────────
# SOURCE OF TRUTH: combsmith/.github/standards/workflows/pr-review.yml
# Standard: combsmith/.github/standards/ci-standards.md
# Reusable: combsmith/.github-private/.github/workflows/pr-review.yml
# (the pr-review ENGINE — grandfathered name, not *-reusable.yml)
#
# - Version selection is the moving `pr-review/stable` tag — this file never
# changes on promotion; a release is rolled out by moving the tag centrally.
# - `agent_ref: pr-review/stable` pins the agent's own scripts to the same
# channel (#506), so the review logic AND scripts run the known-good version.
# - `secrets: inherit` forwards the org secrets, including
# `DON_PETRY_BOT_GH_PAT_CLASSIC` (classic PAT — required for approvals, since
# fine-grained PATs cannot `addPullRequestReview`).
# AGENTS — READ BEFORE EDITING:
# • This file is a THIN CALLER STUB. All review logic lives in the engine
# above, including concurrency (per PR + head SHA, never cancelling an
# in-flight review), the check_suite-without-a-PR skip, and reading
# `client_payload.pr_url` from repository_dispatch.
# • You MUST NOT change: the `@pr-review/v1-stable` channel in the `uses:`
# line or the matching `agent_ref` — both are re-pinned in lockstep to this
# repo's canary-ring tier by the standards sweep. Nor the workflow `name:`,
# the job id `review` (check names depend on both), the trigger event types,
# the Dependabot skip guard, or the job-level `permissions:` block. Do not
# add a stub-level `concurrency:` block.
# • The standards sweep only REPLACES an existing caller with this file; it
# never adds it to a repo that has none, and never touches
# combsmith/.github-private (whose pr-review.yml is the engine).
# • If you need different behaviour, open a PR against the engine in
# combsmith/.github-private. It reaches every repo when the channel
# tag is promoted.
# ─────────────────────────────────────────────────────────────────────────────

name: PR Review Agent

on:
check_suite:
Expand All @@ -22,18 +35,18 @@ on:
workflow_dispatch:
inputs:
pr_url:
description: 'Optional: review a single PR URL instead of enumerating'
description: "Optional: review a single PR URL instead of enumerating"
required: false
type: string
dry_run:
description: 'If true, never submit reviews or comments'
description: "If true, never submit reviews or comments"
required: false
default: 'false'
default: "false"
type: string
force_review:
description: 'If true, bypass idempotency and re-review at the same head SHA'
description: "If true, bypass idempotency and re-review at the same head SHA"
required: false
default: 'false'
default: "false"
type: string
repository_dispatch:
types: [pr-review-mention]
Expand All @@ -42,14 +55,15 @@ permissions: {}

jobs:
review:
uses: combsmith/.github-private/.github/workflows/pr-review.yml@pr-review/stable # NOSONAR(githubactions:S7637) first-party channel ref
if: ${{ github.actor != 'dependabot[bot]' }}
permissions:
contents: read
pull-requests: write
checks: read
uses: combsmith/.github-private/.github/workflows/pr-review.yml@pr-review/v1-stable # NOSONAR(githubactions:S7637) first-party channel ref
with:
agent_ref: pr-review/stable
agent_ref: pr-review/v1-stable
pr_url: ${{ inputs.pr_url || '' }}
dry_run: ${{ inputs.dry_run || '' }}
force_review: ${{ inputs.force_review || '' }}
secrets: inherit
secrets: inherit # NOSONAR(githubactions:S7635) first-party trusted reusable
Loading