ci: harden reusable workflow execution - #92
Conversation
|
Claude finished @kyle-sexton's task in 3m 28s —— View job PR Review: ci: harden reusable workflow execution
This is a well-structured hardening PR. The core ideas are sound: job-scoped install paths, bounded retry/timeout for all network calls, output buffering to prevent partial-response corruption, and GA-verified object fetch. Here are the findings, most-severe first. Findings1.
|
|
Claude finished @kyle-sexton's task in 3m 2s —— View job PR Review: ci: harden reusable workflow execution
What changed in the fixup commit (
|
ad319b5 to
30dd861
Compare
|
Claude finished @kyle-sexton's task in 3m 31s —— View job PR Review: ci: harden reusable workflow execution (commit
|
|
Claude finished @kyle-sexton's task in 2m 11s —— View job PR Review: ci: harden reusable workflow execution (commit
|
|
Claude finished @kyle-sexton's task in 2m 24s —— View job PR Review: ci: harden reusable workflow execution (commits
|
|
Claude finished @kyle-sexton's task in 4m 6s —— View job PR Review: ci: harden reusable workflow execution (final — merged at
|
…contract Lockstep repin: #95 made the cross-environment cache proofs environment-invariant and #92 hardened the reusable execution, so the canonical callers pin the merged commit 9eb22ac carrying both. Part of melodic-software/github-iac#88. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D5wqdo4adEZmWgjpY9ZjVx
…224) Closes #217 ## Related - #209 / #212 (github-script port pattern this issue's fix depends on for consumers) - medley#1628 report Theme 1 (the exit-127 defect class that motivates never routing a gh-CLI-dependent job self-hosted without porting it first) - medley#1632 (comment-review-gate.yml github-script port -- the reviewed no-checkout consumer this change enables) ## Summary - Adds `admits-comment-events` (workflow_call input, default `false`) to `select-runner.yml`. When a caller sets it `true`, `issue_comment`, `pull_request_review`, and `pull_request_review_comment` jobs become eligible for local (self-hosted) routing, subject to every existing policy/private-repo/fork gate. - Fixes a second, independent event enumeration in the "Mint read-only observer token" step (`prefer-self-hosted` policy path) that had its own hardcoded event list and was otherwise unreachable for comment/review events even with the flag set. ## Why (and the design this landed on) Org GitHub Actions spending is capped at $0. The governed policy is `self-hosted-only`, so private-repo required checks already run on the fleet -- but comment/review-event jobs were categorically excluded from local routing and fell back to GitHub-hosted runners, which now fail at startup on a billing-limit error whenever free minutes are exhausted (observed on medley's `comment-review-gate.yml`). **Original-rationale finding:** `LOCAL_EVENT_ALLOWLIST` (git blame/log through #92, #103, #123, #135) is a plain default-deny allowlist -- "only explicitly reviewed caller event classes may route locally" -- not a comment-specific security ban. Comment/review events were simply never reviewed, not deliberately blocked. **Checkout-bearing consumer found, scoped out:** Auditing fleet consumers surfaced medley's `claude-assistant.yml`, which triggers on `issue_comment`/`pull_request_review_comment`, checks out the repository, and runs Claude with `contents: write` and commit signing via the same selector. Under the current `self-hosted-only` policy that job is dormant (comment events route hosted, so its `route == 'self-hosted'` gate never passes). A blanket "admit these event classes" change -- the originally scoped approach -- would have made that dormant job self-hosted-eligible as a side effect: comment-triggered checkout + code execution + write perms on the fleet, without a security review of that specific exposure. Landed on a **per-caller opt-in** instead: `admits-comment-events` defaults `false`, so `claude-assistant.yml` is untouched by this PR and stays exactly as dormant as it is today. Its dormant assist job would only ever go live by **its own deliberate future opt-in** -- a separate decision requiring its own security review of checkout+write-on-fleet exposure, not a side effect of this change. Recording this explicitly here per the review discussion; will also leave a comment on #217 for anyone who revisits `claude-assistant.yml`'s routing later. `comment-review-gate.yml` (medley#1632) is the reviewed consumer this opt-in is for: verified pure `gh api`/now `github-script` calls, zero checkout anywhere in that workflow. ## Consumer follow-up (not in this PR) medley pins `select-runner.yml` by full commit SHA (currently `90f1c54935203fa31b5b3d1f41531228be2c2b7f # v0.6.1`). Once this merges and cuts a tag, medley's normal repin process picks up the new SHA; only *after* that repin can `comment-review-gate.yml` add `admits-comment-events: true` to its `select-runner` call (the pinned-SHA reusable doesn't know the input yet, so adding it any earlier would be rejected as an unexpected input). ## Verification - `node --test .github/scripts/select-runner.test.cjs` -- 112/112 passing, including new coverage: `admits-comment-events` true/false x the three comment/review events x `self-hosted-only`/`prefer-self-hosted`, plus a regression test proving the flag does not widen an unrelated blocked event class (`workflow_run`) - `node --test .github/scripts/*.test.cjs` -- 247/247 passing repo-wide - `actionlint .github/workflows/select-runner.yml` -- clean - `node .github/scripts/render-select-runner-workflow.cjs --check` -- generated block in sync with `select-runner.cjs` 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Summary
Caller contract
working-directorydefaults to.andgo-version-filedefaults togo.mod. Tool versions, checksums, runners, package scope, and blocking posture are deliberately not caller-configurable.ci-runner PR #35 remains the downstream consumer and will adopt the final immutable SHA after Standards materializes its managed config path. This branch does not edit ci-runner.
Verification
Authoritative references