diff --git a/.github/workflows/ci-cache-paths-lint.yml b/.github/workflows/ci-cache-paths-lint.yml new file mode 100644 index 000000000..9aaff144b --- /dev/null +++ b/.github/workflows/ci-cache-paths-lint.yml @@ -0,0 +1,77 @@ +name: ci-cache-paths-lint + +# Flags any actions/cache `path:` in `.github/workflows/*.yml` +# overlapping with `git ls-files`. The discipline rule: +# +# actions/cache paths are mutually exclusive with git ls-files — +# cache only DERIVED files (downloaded jars, built artefacts, +# user-home tool state), never source-controlled content. +# +# Failure mode this prevents (silent + invisible): cache hit +# OVERWRITES freshly-checked-out source files with cached versions. +# PR edits to tracked files silently revert; CI tests the OLD +# content but reports the result as the PR's new state. Discovery- +# by-luck class — only surfaced via empirical bug in a recent +# CircuitRegistration test failure. +# +# Composes with: +# - tools/hygiene/audit-ci-cache-paths.ts (the audit tool itself) +# - .github/workflows/gate.yml (uses the narrowed cache pattern) +# - .github/workflows/low-memory.yml (same pattern) +# +# Safe-pattern compliance (per FACTORY-HYGIENE row #43): +# - SHA-pinned actions/checkout +# - Explicit minimum permissions: contents: read +# - No user-authored context; purely repo-file reads +# - Concurrency group + pinned runs-on +# - Path-filter narrows trigger surface + +on: + pull_request: + paths: + - ".github/workflows/**" + - "tools/hygiene/audit-ci-cache-paths.ts" + push: + branches: [main] + paths: + - ".github/workflows/**" + - "tools/hygiene/audit-ci-cache-paths.ts" + workflow_dispatch: {} + +permissions: + contents: read + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +concurrency: + group: ci-cache-paths-lint-${{ github.ref }} + cancel-in-progress: false + +jobs: + audit: + name: audit actions/cache paths vs git ls-files + runs-on: ubuntu-24.04 + timeout-minutes: 5 + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install toolchain via three-way-parity script (GOVERNANCE §24) + # Provides bun via mise's pin in .mise.toml. Same pattern as + # memory-index-duplicate-lint.yml. shellenv.sh wires + # BASH_ENV so subsequent run: steps auto-source the managed + # shellenv with bun on PATH. + run: ./tools/setup/install.sh + + - name: Run audit-ci-cache-paths + # Exits 0 if all cache paths are mutually exclusive with + # git ls-files; non-zero if any path overlaps with a tracked + # file. Detailed violation reports to stderr include the + # workflow + step name + the offending tracked file + + # "Why this is a bug" + "How to fix" output. + shell: bash + run: | + set -euo pipefail + bun tools/hygiene/audit-ci-cache-paths.ts