chore(audit): execute 2026-06-10 audit — CI path-filter parity, version pins, un-skip isolation test#158
Merged
Merged
Conversation
New lint-meta rule github-actions-paths-filter-parity: workflows pairing a push.paths trigger with an in-job dorny/paths-filter gate must keep the two path sets mutually glob-covered. Drift produces silent failure modes: a push-only path starts the workflow but every gated step no-ops (change lands unverified); a filter-only path never triggers on direct pushes to main. The rule surfaced and this commit fixes three drifted workflows: - apps-docs-linkcheck: wrangler.jsonc/bunfig.toml/osv-scanner.toml were in push.paths but missing from the docs filter — a config-only change skipped the rebuild the workflow's own comment promises. - apps-docs-security-deps: filter narrowed to dep files while push covered apps/docs/** (and osv-scanner.toml was gated out); now mirrors the broad api/ui sibling shape. - infra-compose-validate-compose: setup.sh was push-triggered but absent from every job filter (shellcheck on it never ran on setup.sh-only changes); yamllint lints all workflows but only triggered on edits to itself — push now covers .github/workflows/**. Audit: F001
yamllint was installed job-time via unpinned 'pip install --user yamllint', so the compose/workflow lint gate silently tracked the latest PyPI release — rule changes upstream could flip CI with no repo diff. Pin it to 1.38.0 via a YAMLLINT_VERSION env var, and have the local pre-push gate read that pin at runtime (same single-source idiom as GITLEAKS_VERSION) to warn when the brew-installed yamllint diverges. New lint-meta rule github-actions-pip-install-pinned blocks the class: any job-time pip install of a bare package name without an ==<version> pin. Audit: F003
All 23 workflows ran on floating ubuntu-latest while everything else in the repo is exact-pinned (deps, action SHAs, scanner versions, bun). The runner image migrates on GitHub's schedule, so preinstalled tool versions and OS packages change between runs of the same SHA with no commit to blame. New lint-meta rule github-actions-runner-pinned blocks the class: any runs-on label ending in -latest fails lint:meta (expression labels for matrix strategies are exempt). 26 instances pinned to ubuntu-24.04. Audit: F002
The skip predated the current assertion strategy: counts now use >= against awaited fixture inserts and isolation is asserted via per-user action prefixes, so fire-and-forget audit-log writes from the auth flow cannot flip the outcome — only a real userId-scoping regression can. Verified stable across 5 consecutive runs against the live local stack (postgres+valkey). Guardrail unchanged: skipped-tests-need-tracking already polices skip hygiene; this removes the last tracked skip in the API suite. Audit: F004
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Executes all 4 findings from today's
audit-monoreporun, guardrail-first: every class-of-defect fix ships with a lint-meta rule that surfaced the instances (RED) before the fix (GREEN), so the class is blocked for good.6c9fc66): new rulegithub-actions-paths-filter-parityrequires workflows pairing apush.pathstrigger with an in-job dorny/paths-filter gate to keep the two path sets mutually glob-covered. It surfaced 3 drifted workflows, all fixed:apps-docs-linkcheck(wrangler/bunfig/osv-scanner config changes skipped the rebuild the workflow's own comment promises),apps-docs-security-deps(filter gated outosv-scanner.tomlallowlist edits; now mirrors the broad api/ui sibling shape),infra-compose-validate-compose(setup.shshellcheck never ran on setup.sh-only changes; yamllint lints all workflows but only triggered on edits to itself).3935433): CI installed yamllint job-time with no version pin, so the compose/workflow lint gate tracked latest-PyPI. Pinned to 1.38.0 viaYAMLLINT_VERSION; the local infra pre-push reads that pin at runtime and warns on drift (same single-source idiom asGITLEAKS_VERSION). New rulegithub-actions-pip-install-pinnedblocks the class.669c329): all 23 workflows ran on floatingubuntu-latestwhile everything else in the repo is exact-pinned. 26runs-oninstances →ubuntu-24.04; new rulegithub-actions-runner-pinnedbans*-latestlabels (expression labels exempt).6f84588): the long-skipped HTTP-level user-isolation test is back, rewritten against the endpoint's actual contract. The first un-skip attempt failed in the gate and exposed two latent defects in the old test: it asserted a{success, data}envelope the route never returns (bareDashboardSummarySchema), and itsstartsWith("bob.")checks could never catch leakage because the feed humanizes actions (bob.event.1→ "Bob event 1"). New assertions match the real body shape and humanized titles, so a userId-scoping regression now actually fails the test.Three new lint-meta rules (31 → 34) with tests (100 → 106 lint-meta assertions),
RULES.mdand the docslint-meta-catalog.jsonregenerated.Test plan
cd apps/api && bun run check— typecheck + lint + lint:meta + knip greencd apps/api && bun test tests/lint-meta— 106 pass, incl. RED/GREEN coverage for all 3 new rulesyamllint(CI config) clean over.github/workflows/after the runner/paths editsshellcheck -x -S warning infra/compose/scripts/pre-push.shcleanConventions
any, no blindas, no!YAMLLINT_VERSIONis workflow-job env, not app config)Screenshots
n/a — CI/workflow, lint-meta, and API test changes only.