diff --git a/.github/workflows/factory-hygiene-audit-cadence.yml b/.github/workflows/factory-hygiene-audit-cadence.yml new file mode 100644 index 0000000000..30758c04e9 --- /dev/null +++ b/.github/workflows/factory-hygiene-audit-cadence.yml @@ -0,0 +1,108 @@ +name: factory-hygiene-audit-cadence + +# Daily cadence for the two factory-hygiene audit tools: +# +# - tools/hygiene/audit-rule-cross-refs.ts (.claude/rules/ cross-ref audit) +# - tools/hygiene/audit-user-scope-memory-index.ts (MEMORY.md bloat audit) +# +# Per the session's razor-cadence item 4 + item 5 mechanization work +# (PRs #3202 + #3208). Without an external trigger, the audits depend on +# agent-remembering-to-run-them, which `encoding-rules-without-mechanizing.md` +# explicitly flags as the failure mode this workflow prevents. +# +# Why daily: rule cross-refs drift slowly (~1 new rule per few days) but +# MEMORY.md bloat compounds with every memory-file landing. Daily is the +# coarsest cadence that still surfaces drift inside one work-window. +# +# What this workflow does: +# - Runs the rule-cross-refs audit + uploads report as workflow artifact +# - Runs the memory-index audit unit tests (the tool runs against user- +# scope memory, not available in CI) +# - Detect-only (exit 0 always); the maintainer / future-Otto reviews +# the artifacts. No auto-file backlog rows. +# +# Composes with: +# - tools/hygiene/audit-rule-cross-refs.ts (PR #3202) +# - tools/hygiene/audit-user-scope-memory-index.ts (PR #3208) +# - .github/workflows/razor-cadence.yml (the issue-tracker cadence) +# - .github/workflows/git-hotspot-cadence.yml (template shape) +# +# Safe-pattern compliance: SHA-pinned actions, explicit minimum +# permissions (contents: read only), concurrency group, pinned runs-on, +# path-filter for self-test trigger. This workflow uses only +# github.run_id and github.ref in template expressions — no untrusted +# user-authored inputs. + +on: + schedule: + # Daily 14:37 UTC — off-the-hour to avoid GHA cron thundering-herd. + - cron: "37 14 * * *" + workflow_dispatch: {} + pull_request: + paths: + - "tools/hygiene/audit-rule-cross-refs.ts" + - "tools/hygiene/audit-user-scope-memory-index.ts" + - ".github/workflows/factory-hygiene-audit-cadence.yml" + +permissions: + contents: read + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +concurrency: + group: factory-hygiene-audit-cadence-${{ github.ref }} + cancel-in-progress: false + +jobs: + rule-cross-refs-audit: + name: audit .claude/rules/ cross-references + runs-on: ubuntu-24.04 + timeout-minutes: 5 + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 1 + + - name: Setup Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: latest + + - name: Run rule-cross-refs audit + run: | + mkdir -p audit-reports + bun tools/hygiene/audit-rule-cross-refs.ts \ + --report audit-reports/rule-cross-refs.md + + - name: Upload audit report + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: rule-cross-refs-audit-${{ github.run_id }} + path: audit-reports/ + if-no-files-found: warn + retention-days: 90 + + memory-index-self-test: + name: self-test memory-index audit tool + runs-on: ubuntu-24.04 + timeout-minutes: 5 + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 1 + + - name: Setup Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: latest + + - name: Run memory-index audit tests + # Self-test only: MEMORY.md is user-scope and not available in CI. + # The unit-test suite verifies the tool itself hasn't regressed. + run: bun test tools/hygiene/audit-user-scope-memory-index.test.ts