From 741291e657b019faa3b4eb19c63de2d2ed836741 Mon Sep 17 00:00:00 2001 From: don-petry <36422719+don-petry@users.noreply.github.com> Date: Sun, 18 Oct 2026 18:05:30 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20implement=20issue=20#635=20=E2=80=94=20?= =?UTF-8?q?Compliance:=20verbatim-stub-drift-initiative-driver.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/initiative-driver.yml | 109 ++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 8 deletions(-) diff --git a/.github/workflows/initiative-driver.yml b/.github/workflows/initiative-driver.yml index 8782e6cc..3b7b158d 100644 --- a/.github/workflows/initiative-driver.yml +++ b/.github/workflows/initiative-driver.yml @@ -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=), # 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. @@ -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 @@ -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" \ + --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}"