Skip to content

fix(ci): remove timeout-minutes from jobs using reusable workflows + fix permissions - #474

Open
hyperpolymath wants to merge 5 commits into
mainfrom
feat/fix-actions-policy
Open

fix(ci): remove timeout-minutes from jobs using reusable workflows + fix permissions#474
hyperpolymath wants to merge 5 commits into
mainfrom
feat/fix-actions-policy

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Bug A and Bug B fixes for issue #426.

Bug A: Removes timeout-minutes from jobs that call reusable workflows via uses:,
which is forbidden by GitHub and causes startup_failure.

Bug B: Removes excessive job-level permissions that exceed workflow-level
permissions.

Files fixed:

  • .claude/worktrees/actions-policy/.github/workflows/secret-scanner.yml (Bug A + Bug B)
  • .claude/worktrees/actions-policy/.github/workflows/governance.yml (Bug A)
  • .claude/worktrees/actions-policy/.github/workflows/mirror.yml (Bug A)
  • .claude/worktrees/actions-policy/.github/workflows/hypatia-scan.yml (Bug A)

Related: hyperpolymath/standards#426

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe vibe@mistral.ai

hyperpolymath and others added 5 commits July 21, 2026 06:44
…cy outage

Implements the "fastest shippable" item of gitbot-fleet#362.

## The fault

An onboarding stamp set `allowed_actions=selected` + `sha_pinning_required=true`
but never populated `patterns_allowed`, leaving it `[]`. An empty selected-list
rejects every non-github-owned `uses:` at workflow-parse time, so runs die as
`startup_failure` with ZERO jobs — looks like "CI is broken", is actually a
settings fault, and no amount of workflow editing fixes it.

MEASURED 2026-07-21: 80 of 306 scanned hyperpolymath repos are in this state.

## Why this fixer is shaped unlike the others

Every other fix-*.sh takes a REPO_PATH and edits files, so its blast radius is
a reviewable diff. This one writes repository *settings* via the API: no diff,
no branch, no PR. Per #362 that demands gating, so:

  * default mode is --list (READ ONLY; never writes)
  * --apply is required to write
  * HYPATIA_AUTOMATION={off,disabled,0} halts writes (exit 4)
  * the estate exclusion registry is consulted FAIL-CLOSED before any write
    (unreadable registry => refuse to write, exit 5)
  * every PUT is GET-verified and the sweep ABORTS (exit 3) if sha_pinning was
    silently reset — never trade pinning away for permissiveness

## Dual invocation contract

dispatch-runner.sh calls fixers as `<script> <repo_path> <finding.json>`, but a
standalone sweep is `<script> <owner> --apply`. The script detects a directory
in $1 and derives owner/repo from the git origin, so one tool serves both paths
instead of silently misreading a filesystem path as an owner. In the dispatcher
path it stays report-only unless FIX_ACTIONS_POLICY_APPLY=1 — a credentialed
diff-less write must not auto-fire just because a finding routed to it.

Registered under by_category ActionsPolicyTooRestrictive and by_recipe
recipe-actions-allow-all so dispatch-runner auto-routes hypatia findings.

## Verification

shellcheck clean; bash -n clean; registry re-parsed with jq.

Guard rails, exit codes measured directly (not through a masking pipeline):
  no owner / bad --mode / unknown flag -> 2
  HYPATIA_AUTOMATION=off with --apply  -> 4
  HYPATIA_AUTOMATION=off with --list   -> 0   (read-only unaffected)

Classification, against an independently-collected 306-repo ground truth:
  typefix-zero, stateful-artefacts, trope-checker -> BROKEN-M1  (correct)
  svalinn, thejeffparadox                         -> ok         (correct)
  5/5 agreement.

Dispatcher path exercised exactly as dispatch-runner invokes it:
  fix-actions-policy.sh <path-to-trope-checker> <finding.json>
  -> "dispatcher mode — hyperpolymath/trope-checker (action=list)"
  -> BROKEN-M1, exit 0.

NOT run with --apply anywhere: widening allowed_actions is a security-posture
change across ~80 repos and needs the owner's explicit sign-off first.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… allowlist)

Converges this fixer with a parallel remediation effort
(llm-coding-configs/claude-code/notification-storm-remediation/FINDINGS.md)
rather than letting two incompatible fixes race on the same 98 repos.

#362's decision of record was `allowed_actions=all`. That works, but it is a
security-posture change: it removes the owner allowlist and leaves mandatory
SHA-pinning as the only control. The parallel effort established a strictly
safer route reaching the same outcome:

  keep allowed_actions=selected, keep sha_pinning_required=true,
  and simply POPULATE the empty patterns_allowed.

Its natural experiment over 426 repos:
  allowed_actions=all                    286 repos -> wrappers run
  selected + `hyperpolymath/*` present    42 repos -> wrappers run
  selected + patterns_allowed=[]          98 repos -> ALL startup_failure

So the breakage is the list being EMPTY, not the list existing. Populating it
restores CI *and* keeps the allowlist as a real control. `--mode all` remains
available as an explicit fallback; it is no longer the default.

Changes:
  * MODE now defaults to `selected` (was `all`)
  * new `--allowlist FILE` to supply a curated patterns_allowed document
  * refuse an allowlist whose patterns_allowed is EMPTY — that is precisely
    the fault being repaired, and applying it would be a silent no-op
  * `[ x = y ] && rm` replaced with a total `if` — under `set -e` the bare
    `&&` form returns 1 when the test is false and would abort the sweep

Verified: shellcheck clean; bash -n clean; empty-allowlist guard exercised;
`--list` still classifies correctly (trope-checker, now populated with 87
patterns, reports `selected true 87 ok` — it was `selected true 0 BROKEN-M1`).

Target lists reconcile exactly: this tool's 95 (--source, non-archived) is a
subset of the parallel effort's 98; the 3 extra are forks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removes timeout-minutes from jobs that call reusable workflows via uses:,
which is forbidden by GitHub and causes startup_failure.
Also removes excessive job-level permissions in secret-scanner.yml that exceed
workflow-level permissions.

Files fixed:
- .github/workflows/secret-scanner.yml (Bug A + Bug B)
- .github/workflows/governance.yml (Bug A)
- .github/workflows/mirror.yml (Bug A)
- .github/workflows/hypatia-scan.yml (Bug A)

Related: hyperpolymath/standards#426

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
@hyperpolymath
hyperpolymath enabled auto-merge (squash) August 12, 2026 20:33
@gitar-bot

gitar-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant