Skip to content

fix(governance): actions-lock-verify as its own context; advisory jobs cannot fail silently (step 2a) - #718

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/governance-reusable-repairs-2a
Sep 2, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
feat/governance-reusable-repairs-2a

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Behaviour-only repairs to governance-reusable.yml. No job name or
caller id changes: every live ruleset types " / ",
so a rename would turn a required context into a phantom estate-wide.
tests/test_governance_reusable_shape.sh freezes the 15 names.

  • New job Actions lockfile verify (actions-lock-verify). It fetches
    scripts/check-actions-lock-gate.sh + update-actions-lock.sh from
    standards at job.workflow_sha (the reusable's own pin, one speed
    of propagation) instead of running them from the consumer's cwd,
    which is why "Workflow security linter" died with exit 127
    ("scripts/update-actions-lock.sh: No such file") on every consumer.
    Lock present -> gh actions-lock --verify-local, rc propagated.
    Lock absent + unpinned uses -> fail. Lock absent + all SHA-pinned ->
    warning until ENFORCE_ACTIONS_LOCK_FROM (2026-10-01), error after.
    11 fixture cases incl. a planted positive (stub verifier exit 1 ->
    gate exit 1).
  • workflow-lint no longer carries the lock check (one context, one
    cause).
  • Every job honours inputs.runs-on (two were hardcoded).
  • Live Actions policy: "not evaluated" is a ::warning, not a ::notice.
  • Security policy: weak-crypto and http findings say ADVISORY in the
    message; hardcoded secrets say they FAIL the job.
  • gates.json: "Live Actions policy (credentialed advisory)" and
    "Code quality + docs" join never_required_contexts; match rule and
    context-freeze note recorded.
  • Spec §14: fold table for the estate policy files (step 2f).

Known: actionlint reports job.workflow_sha as undefined; it is
undocumented but populated with the called reusable's SHA (verified on
consumer runs pinned at 571cc73). scripts/tests/wave3-scorecards-test.sh
fails 2/9 on unmodified main too (pre-existing, not touched here).

…s cannot fail silently (step 2a)

Behaviour-only repairs to governance-reusable.yml. No job name or
caller id changes: every live ruleset types "<job id> / <job name>",
so a rename would turn a required context into a phantom estate-wide.
tests/test_governance_reusable_shape.sh freezes the 15 names.

- New job `Actions lockfile verify` (actions-lock-verify). It fetches
  scripts/check-actions-lock-gate.sh + update-actions-lock.sh from
  standards at `job.workflow_sha` (the reusable's own pin, one speed
  of propagation) instead of running them from the consumer's cwd,
  which is why "Workflow security linter" died with exit 127
  ("scripts/update-actions-lock.sh: No such file") on every consumer.
  Lock present -> `gh actions-lock --verify-local`, rc propagated.
  Lock absent + unpinned uses -> fail. Lock absent + all SHA-pinned ->
  warning until ENFORCE_ACTIONS_LOCK_FROM (2026-10-01), error after.
  11 fixture cases incl. a planted positive (stub verifier exit 1 ->
  gate exit 1).
- workflow-lint no longer carries the lock check (one context, one
  cause).
- Every job honours inputs.runs-on (two were hardcoded).
- Live Actions policy: "not evaluated" is a ::warning, not a ::notice.
- Security policy: weak-crypto and http findings say ADVISORY in the
  message; hardcoded secrets say they FAIL the job.
- gates.json: "Live Actions policy (credentialed advisory)" and
  "Code quality + docs" join never_required_contexts; match rule and
  context-freeze note recorded.
- Spec §14: fold table for the estate policy files (step 2f).

Known: actionlint reports `job.workflow_sha` as undefined; it is
undocumented but populated with the called reusable's SHA (verified on
consumer runs pinned at 571cc73). scripts/tests/wave3-scorecards-test.sh
fails 2/9 on unmodified main too (pre-existing, not touched here).
@hyperpolymath
hyperpolymath merged commit c59f24f into main Sep 2, 2026
41 of 44 checks passed
@hyperpolymath
hyperpolymath deleted the feat/governance-reusable-repairs-2a branch September 2, 2026 12:17
@sonarqubecloud

sonarqubecloud Bot commented Sep 2, 2026

Copy link
Copy Markdown

@coderabbitai

coderabbitai Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: 0bb48e7c-edc7-4cce-b249-11d7e42538d4

📥 Commits

Reviewing files that changed from the base of the PR and between 5dda327 and 5dbc008.

📒 Files selected for processing (6)
  • .github/workflows/governance-reusable.yml
  • config/rulesets/gates.json
  • docs/superpowers/specs/2026-09-02-cicd-regularisation-design.md
  • scripts/check-actions-lock-gate.sh
  • scripts/tests/check-actions-lock-gate-test.sh
  • tests/test_governance_reusable_shape.sh

📝 Summary

Summary by CodeRabbit

  • New Features

    • Added dedicated validation for GitHub Actions lockfiles and SHA-pinned workflow references.
    • Added grace-period handling for repositories transitioning to enforced action locking.
    • Standardised reusable governance jobs to use the caller-provided runner configuration.
    • Added clearer warnings and errors for advisory policy and security findings.
  • Documentation

    • Documented how governance checks are grouped, treated as advisory or required, and excluded from mandatory status requirements.
  • Tests

    • Added coverage for action-lock validation and governance workflow structure.

Walkthrough

The reusable governance workflow now uses caller-selected runners, explicit advisory annotations, and a dedicated action-lock verification job. New policy documentation, a lock-gate script, and structural Bash tests define and validate the updated governance behaviour.

Changes

Governance workflow regularisation

Layer / File(s) Summary
Policy and workflow contracts
.github/workflows/governance-reusable.yml, config/rulesets/gates.json, docs/superpowers/specs/...
The workflow uses inputs.runs-on, emits warning or error annotations, and separates Hypatia baseline validation from advisory findings. Policy configuration and design documentation define frozen and never-required contexts.
Action-lock gate behaviour
scripts/check-actions-lock-gate.sh, scripts/tests/check-actions-lock-gate-test.sh
The gate verifies existing lockfiles, rejects unpinned references, and applies the configured grace-window date. Tests cover verifier, date, lockfile, and missing-directory outcomes.
Dedicated lock verification job
.github/workflows/governance-reusable.yml
workflow-lint no longer performs lock verification. actions-lock-verify checks out pinned standards scripts, installs gh-actions-lock, and runs the gate.
Governance and gate validation
tests/test_governance_reusable_shape.sh
Structural tests freeze reusable job names, enforce caller runners, validate the dedicated lock job, restrict advisory jobs, and check policy context entries.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CallerRepository
  participant governance-reusable
  participant check-actions-lock-gate.sh
  participant update-actions-lock.sh
  CallerRepository->>governance-reusable: invoke reusable workflow
  governance-reusable->>CallerRepository: checkout repository and pinned standards scripts
  governance-reusable->>check-actions-lock-gate.sh: run action-lock gate
  check-actions-lock-gate.sh->>update-actions-lock.sh: verify existing actions.lock
  update-actions-lock.sh-->>check-actions-lock-gate.sh: return verification result
  check-actions-lock-gate.sh-->>governance-reusable: return gate status
Loading

Poem

A rabbit checks the workflow run,
Pins each action beneath the sun.
Warnings glow and errors speak,
Locked paths guard the checks they seek.
Tests hop through every gate.

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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