From 73b7b4b709e11328e009e7893659868e0cf6bbe4 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 9 Aug 2026 03:37:22 -0400 Subject: [PATCH 1/2] docs(ci): say why the skip-actors line must survive a re-pin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The comment explained where the exception lives and how #1766 widened it, but not why deleting the line is unsafe even when its value matches the upstream default of the moment. That is the property a re-pin reviewer needs: the four actors are ADR 0002's 2026-08-04 ratified baseline, and inheriting re-delegates that decision to whatever ci-workflows ships next. Records the asymmetry the ADR's own rationale turns on — a stale explicit list fails closed, a stale inherited default fails open — and names standards#308 as the residual gap, since runner-policy can reject an unexpected input but cannot require an expected one. Comment-only. The actor list is unchanged and stays at the ratified four. Salvaged from PR #1845, closed as superseded by the 2026-08-04 operator decision; this was the part of that branch worth keeping. Refs #1767 Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/claude-security-review.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/claude-security-review.yml b/.github/workflows/claude-security-review.yml index 65c80c1810..54e4612274 100644 --- a/.github/workflows/claude-security-review.yml +++ b/.github/workflows/claude-security-review.yml @@ -41,6 +41,23 @@ jobs: # rewrites the exception whenever ci-workflows changes it — which is how # `claude[bot]` and `melodic-ai[bot]` entered it (#1766 dropped this line # while re-pinning to a version whose default had widened). + # + # DO NOT delete this line at a re-pin, and do not "simplify" it away. + # Deleting it is not a no-op even when the value matches the upstream + # default of the moment: the four actors here are ADR 0002's 2026-08-04 + # ratified baseline, and inheriting instead re-delegates that decision to + # whatever ci-workflows ships next. Every actor in an inherited default + # satisfies this repo's REQUIRED `security-review / security-review` + # check with no review run, on security-sensitive paths. + # + # The failure directions are asymmetric, which is why explicit wins here + # and not everywhere: a stale explicit list fails CLOSED (an actor gets a + # review it may not have needed — visible, cheap), while a stale + # inherited default fails OPEN (an actor this repo never deliberated + # skips review silently — exactly what #1766 did). runner-policy rejects + # inputs outside the reviewed contract but cannot REQUIRE one, so + # dropping this line re-widens the exception with CI green and nothing + # said. That residual gap is standards#308. skip-actors: dependabot[bot],claude[bot],melodic-ai[bot],melodic-standards-sync[bot] # One named secret (least privilege), never `secrets: inherit`. secrets: From 16b0a8197fccbde74e13b7d0ab037a98e9dc3709 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 9 Aug 2026 03:55:06 -0400 Subject: [PATCH 2/2] docs(ci): correct the stale-explicit-list failure mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review caught a factual error in the previous commit. It described a stale explicit list as costing "an actor gets a review it may not have needed — visible, cheap." That is not what happens. For an actor the reusable's `allowed_bots` does not permit, the action throws and this lane's fail-closed mapping turns it into a RED required check no push can fix — a merge block, not an extra review. ADR 0002 records this directly ("skip-actors and the action's allowed_bots are different levers with different outcomes"), and it is why removing a name from this list is never a one-line change: un-skipping an actor for real means widening `allowed_bots` upstream. The asymmetry the comment exists to convey survives and is sharper stated correctly — loud-and-blocking versus silent-and-permissive, rather than a cheap extra review versus a silent skip. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/claude-security-review.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/claude-security-review.yml b/.github/workflows/claude-security-review.yml index 54e4612274..6478ba55a6 100644 --- a/.github/workflows/claude-security-review.yml +++ b/.github/workflows/claude-security-review.yml @@ -51,13 +51,19 @@ jobs: # check with no review run, on security-sensitive paths. # # The failure directions are asymmetric, which is why explicit wins here - # and not everywhere: a stale explicit list fails CLOSED (an actor gets a - # review it may not have needed — visible, cheap), while a stale - # inherited default fails OPEN (an actor this repo never deliberated - # skips review silently — exactly what #1766 did). runner-policy rejects - # inputs outside the reviewed contract but cannot REQUIRE one, so - # dropping this line re-widens the exception with CI green and nothing - # said. That residual gap is standards#308. + # and not everywhere. A stale explicit list fails CLOSED and LOUD: for an + # actor the reusable's `allowed_bots` does not permit, the action throws + # and this lane's fail-closed mapping turns that into a RED required + # check no push can fix — a merge block, not an extra review (ADR 0002, + # "skip-actors and the action's allowed_bots are different levers"). + # Un-skipping such an actor for real means widening `allowed_bots` + # upstream, which is why removing a name here is never a one-line change. + # A stale inherited default fails OPEN and SILENT: an actor this repo + # never deliberated skips review with CI green — exactly what #1766 did. + # Loud-and-blocking is the direction to fail in; silent-and-permissive is + # not. runner-policy rejects inputs outside the reviewed contract but + # cannot REQUIRE one, so dropping this line re-widens the exception with + # nothing said. That residual gap is standards#308. skip-actors: dependabot[bot],claude[bot],melodic-ai[bot],melodic-standards-sync[bot] # One named secret (least privilege), never `secrets: inherit`. secrets: