Repository navigation
chore: sync 5 org-standard workflow stub(s) from petry-projects/.github #529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b6024c6
38441e1
5327057
ec13777
027e726
e2e1cab
e29613e
4b4b5f0
7808380
c9d707b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 (petry-projects/.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 petry-projects/.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 petry-projects/.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 | ||
| # petry-projects/.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/petry-projects/.github/blob/main/standards/ci-standards.md | ||
| name: Initiative Driver — Dispatch Central | ||
|
|
@@ -76,11 +94,82 @@ 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 | ||
| # petry-projects/.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 petry-projects/.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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: The new PAT-bearing checkout and fail-open gate are not covered by CI; no guard tests this workflow’s security-sensitive dispatch contract. Add a fixture-driven test with negative cases for the private checkout/pin, missing-tooling fail-open behavior, and explicit (Based on your team's feedback about guarding reliability- and security-sensitive workflow invariants). Prompt for AI agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This finding requires adding CI fixture-driven tests for the security-sensitive PAT checkout and fail-open gate behavior. These test fixtures would need to be added to the workflow-tests job and scripts/test-initiative-driver-workflow.sh, which is outside the scope of syncing workflow stub changes from the upstream template. This would be a follow-up task in the test infrastructure. |
||
| with: | ||
| repository: petry-projects/.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" || { | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
| 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' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Exclude deferred runs from both history counters. Each deferred attempt still runs this workflow, so it can reset the cooldown and consume the daily budget without dispatching. Prompt for AI agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Excluding deferred runs from history counters requires changes to the gate script logic in petry-projects/.github/scripts/agent-rate-limit-gate.sh, not changes to this caller stub. The gate script is the authority for how runs are counted and how decisions are made. This is an upstream issue to be addressed in the central gate tooling, not in individual caller stubs. |
||
| env: | ||
| GH_TOKEN: ${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }} | ||
| run: | | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| # ───────────────────────────────────────────────────────────────────────────── | ||
| # SOURCE OF TRUTH: petry-projects/.github/standards/workflows/persona-mention.yml | ||
| # Standard: petry-projects/.github/standards/persona-standards.md (§4.1) | ||
| # Reusable: petry-projects/.github/.github/workflows/persona-mention-reusable.yml | ||
| # | ||
| # AGENTS — READ BEFORE EDITING: | ||
| # • This file is a THIN CALLER STUB. All routing logic lives in the reusable | ||
| # workflow above, and every per-persona decision lives in that persona's | ||
| # manifest — not here and not in the reusable. | ||
| # • You MUST NOT change: the `uses:` ref — it is pinned to the | ||
| # `persona-mention/v1-ring1` channel, a moving tag advanced centrally. | ||
| # Never repoint it to `@main`, a SHA, or a frozen `@vX.Y.Z` (see | ||
| # ci-standards.md → Reusable workflow versioning). Also do not change the | ||
| # trigger events or the job-level `permissions:` block — reusable workflows | ||
| # can be granted no more permissions than the calling job, so removing the | ||
| # stanza breaks the reusable's gh API calls. | ||
| # • Do NOT add a per-persona stub. ONE router serves every persona (§4.1); | ||
| # a stub per agent is the drift the manifest exists to prevent. | ||
| # • If you need different behaviour, open a PR against the reusable in the | ||
| # central repo. A new release is rolled out by moving the channel tag | ||
| # centrally — never by editing callers, so no fanout PR is needed. | ||
| # ───────────────────────────────────────────────────────────────────────────── | ||
| # | ||
| # Persona Mention Router — thin caller for the org-level reusable. | ||
| # | ||
| # Adopting this file makes every persona that enables the `mention` surface | ||
| # addressable in this repo as `@petry-projects/<role>` — e.g. | ||
| # | ||
| # @petry-projects/qa-lead please assess test risk on this PR | ||
| # | ||
| # The handle is an org TEAM, never a user account: '@qa-lead' is a real GitHub | ||
| # account owned by an unrelated person (§4.1). | ||
| # | ||
| # To adopt: copy this file to .github/workflows/persona-mention.yml in your repo. | ||
| # Requires: GH_PAT_WORKFLOWS org secret (already present in petry-projects org). | ||
| name: Persona — Mention Router | ||
|
|
||
| on: | ||
| # issue_comment covers BOTH issues and PR conversation comments. | ||
| issue_comment: | ||
| types: [created] | ||
| pull_request_review_comment: | ||
| types: [created] | ||
| # Discussions cannot run an agent inline (#571) — but this router only parses | ||
| # and dispatches, and the agent itself runs on the resulting | ||
| # repository_dispatch, which is exactly the bridge the manifest declares. | ||
| discussion_comment: | ||
| types: [created] | ||
| # NOTE: reviewer assignment (pull_request/review_requested) is NOT subscribed | ||
| # here yet, even though §4 says "Reviewer-assignment counts here too". The | ||
| # router has no path for it, and a trigger that fires into a router which | ||
| # ignores it is a dead trigger that only burns runs. Tracked as finding 10 in | ||
| # petry-projects/.github#755; the trigger lands with the routing, not before. | ||
|
|
||
| permissions: {} | ||
|
|
||
| jobs: | ||
| persona-mention: | ||
| permissions: | ||
| contents: read # the reusable checks out its tooling repo — required, | ||
| # or the call fails at startup (a reusable is granted | ||
| # no more than the caller; persona-standards.md §5) | ||
| issues: read | ||
| pull-requests: read | ||
| # NOSONAR(githubactions:S7637) first-party channel ref | ||
| uses: petry-projects/.github/.github/workflows/persona-mention-reusable.yml@persona-mention/v1-ring1 | ||
| # NOSONAR(githubactions:S7635) org secrets are scoped to first-party reusables | ||
| secrets: inherit |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
| # reusable workflow above. | ||
| # • You MAY change: the workflow name(s) in `workflow_run.workflows` to match | ||
| # your repository's CI workflow name(s). | ||
| # • You MUST NOT change: the `@pr-auto-review/v1-stable` channel in the `uses:` | ||
| # • You MUST NOT change: the `@pr-auto-review/v1-ring1` channel in the `uses:` | ||
| # line — this reusable is on the org-wide moving-channel model (rollout and | ||
| # rollback are a single central tag move; a frozen `@vN`/`@<sha>` pin is | ||
| # rejected by the compliance audit). Nor the trigger event types or the | ||
|
|
@@ -28,9 +28,7 @@ | |
| # workflow_run fires when a named GitHub Actions workflow completes. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: This PR introduces a multi-event concurrency/cancel invariant (per-trigger group selection with conditional Prompt for AI agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This finding requires adding test fixtures to guard the concurrency/cancel invariants. The regression guard infrastructure (workflow-tests job + fixture scripts) lives in the CI configuration, not in the workflow stubs themselves. This is outside the scope of syncing workflow stubs from the upstream template. Creating test fixtures for this would be a follow-up task in the test/CI infrastructure, not part of this sync.
don-petry marked this conversation as resolved.
Resolved
|
||
| # check_suite does NOT trigger for GitHub Actions runs, so this is required | ||
| # to catch CI turning green on a PR. | ||
| # Set to this repository's CI workflow name(s). TalkTerm's CI workflow is | ||
| # named "CI" (see .github/workflows/ci.yml `name: CI`), so the value below is | ||
| # already correct for this repo. | ||
| # TODO: replace "CI" with your repository's CI workflow name(s). | ||
|
Check warning on line 31 in .github/workflows/pr-auto-review.yml
|
||
| workflow_run: | ||
| workflows: ["CI"] | ||
| types: [completed] | ||
|
|
@@ -46,13 +44,33 @@ | |
|
|
||
| permissions: {} | ||
|
|
||
| # The concurrency group depends on the event context (issue #1126): | ||
| # • pull_request / pull_request_review — share one group per PR number and never | ||
| # cancel an in-progress run, because these run on the PR head and a cancelled | ||
| # run would leave a cancelled `pr-auto-review / check-and-dispatch` check there. | ||
| # • check_suite / workflow_run — use a unique group per github.run_id, so separate | ||
| # runs never collide. `cancel-in-progress` is enabled for them, but it only | ||
| # affects another attempt of the same run (reruns keep the same run ID). | ||
| # check_suite and workflow_run events may have multiple associated PRs | ||
| # (pull_requests[]), so no array indexing is used; events without a single PR | ||
| # context fall back to the unique-per-run group to avoid cross-PR interference | ||
| # (petry-projects/.github#1342). | ||
| concurrency: | ||
| group: >- | ||
| ${{ | ||
| (github.event_name == 'pull_request' || github.event_name == 'pull_request_review') | ||
| && format('pr-auto-review-ready-check-pr-{0}', github.event.pull_request.number) | ||
| || format('pr-auto-review-ready-check-unique-{0}', github.run_id) | ||
| }} | ||
| cancel-in-progress: ${{ github.event_name == 'check_suite' || github.event_name == 'workflow_run' }} | ||
|
|
||
| jobs: | ||
| pr-auto-review: | ||
| permissions: | ||
| pull-requests: read | ||
| checks: read | ||
| actions: read | ||
| uses: petry-projects/.github/.github/workflows/pr-auto-review-reusable.yml@pr-auto-review/v1-stable # NOSONAR(githubactions:S7637) first-party channel ref | ||
| uses: petry-projects/.github/.github/workflows/pr-auto-review-reusable.yml@pr-auto-review/v1-ring1 # NOSONAR(githubactions:S7637) first-party channel ref | ||
| secrets: | ||
| # Canonical-first fallback (.github-private#1326). The reusable resolves this | ||
| # secret BY NAME, so only the VALUE changes — the passed key stays named | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.