executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
audit-gate-logicRead-only audit of CI gate logic: silent bypass, ratchet gaming, required-but-not, duplicate gates. Use when "can CI be bypassed" or "why did a regression pass CI". Cost → audit-cicd. Rule content → audit-doctrine.
Independent GitHub snapshot · Automated classification · Original documentation governs
Degree of freedom: MIXED — Phases 0–2.5 [HIGH freedom]; Phase 3
history/probe [LOW freedom — run exactly] (no scratch branch unless asked).
Read-only. audit-cicd asks "is the pipeline fast, cheap, and safe to run."
This asks "does the gate stop what it claims to stop." A green check is a
claim. The expensive failures are the ones where CI passed and shouldn't have.
Present findings. Do not edit workflows, branch protection, or baselines.
Consolidation of the archaeology map → housekeep-gates. Rule-to-mechanical
gaps → enhance-agent-guardrails. Whether the rule content is right
(remedy, named token, Tier-D practice) → audit-doctrine.
| Skill | Owns |
|---|---|
| audit-gate-logic (this) | Bypass, ratchet integrity, conflicts, required-vs-actual, archaeology map |
housekeep-gates | Executes the map — aggregator, delete losers, prove |
audit-cicd | Pipeline cost, speed, storage, runner safety |
workflow-quality-gate | Runs the pre-release sweep — does not audit its soundness |
enhance-agent-guardrails | Installs new gates; does not audit existing gate logic |
burndown-full / workflow-green-repo | Execute MATCH/DONE or green the repo — ratchet holes stay here |
audit-codemod-safety | Bulk-transform behavior; if CI waved a semantic bug through, that is also a finding here |
test-mutation | Assertion-strength gate this map should name if coverage is the only test metric |
Degrade honestly. Highest-value "is it actually required" checks need
branch-protection / rulesets via the repo settings API (gh api), not just
YAML. If settings are invisible, audit the workflow files and say so — you
can still catch continue-on-error and ratchet classes, but you cannot
confirm the required-check list.
if:, continue-on-error, required-check list, or historyObserve:
lintjob hascontinue-on-error: trueand is the only required status check named "Lint". Interpret: lint can fail and the required check still reports success. Classify: silent bypass (continue-on-error). Severity: critical — ships-broken-green. Finding: lint | continue-on-error | critical |.github/workflows/ci.yml:24
Inventory the full gating surface, not just the obvious jobs:
.github/workflows/*, or GitLab/CircleCI equivalent):
each job, its triggers (on:), its if: conditions, path/branch filters.workflow-green-repo
green baseline.For each gate record: what it checks, what happens on failure (block / warn / silently pass), and whether it is enforced server-side or only by convention.
continue-on-error / soft failure — continue-on-error: true, || true,
exit 0 swallowing, or if: always() masking a failure. The check runs,
"passes", and enforces nothing.
Required-in-name-only — Runs in CI but is not in the required list →
mergeable while failing. Or a required check whose job can be skipped
(if:) so it reports success-by-absence. A skipped required check often
counts as passed.
Path/branch filters that skip the wrong changes — paths: /
paths-ignore: that exclude a gate for the files that needed it (security
scan skips .github/, so a PR that disables the scan is not scanned).
Filters that never run on the default branch, or only on PRs and not on
direct pushes.
Condition conflicts — Two workflows whose if: / triggers both fire
on the same event (duplicate work, race on a shared resource, contradictory
status posts) or both skip (each assumes the other ran). Missing
concurrency groups so two runs race and the loser's failure is discarded.
Fork / permissions bypass — pull_request_target running privileged with
untrusted code, or gates that do not run on external-contributor PRs.
Event mismatch — Gate triggers on push but merges use squash/PR (or
vice versa), so the enforced commit was never the gated one.
One-way that isn't — Can the baseline be regenerated in the same PR that
regresses (--update-snapshot, coverage --update-baseline committed
alongside the drop), locking the regression in as the new floor? Baseline
moves should be a separate, reviewed act.
Exclusion gaming — Coverage/lint passes because the dropped files are in
.eslintignore, coveragePathIgnorePatterns, or // istanbul ignore. A
ratchet that measures a shrinking surface always passes.
Threshold vs reality — Floor so far below actual that a real drop still clears it (60% gate, 90% actual → 89% "passes"). Global thresholds hiding per-file collapse. Bundle budgets set above current so growth is free.
Baseline staleness / drift — Never regenerated (no longer reflects the codebase) or auto-regenerated every run (never actually ratchets).
Direction bugs — Comparison operator backwards (passes when worse), or
comparing against main after main already absorbed the regression.
Burndown ratchet integrity — Can MATCH/DONE mark an item DONE without
verification evidence? Can the count go down (work un-done) without failing?
Cross-check completion-judge / burndown-full.
Gates accumulate: each dev, agent session, or "let's add a check" iteration layers another workflow without removing the last. Audit the set:
Duplicate gates, different vintages — Two+ jobs checking the same
thing (two lint jobs with disagreeing configs, ESLint and Biome both
wired, an old test.yml and a newer ci.yml both running the suite).
For each pair: which actually blocks, whether configs disagree, which is
vestigial.
Competing baselines / ratchets — Multiple floors for one metric (jest threshold + codecov + a committed floor), updated at different times. The agent satisfies whichever loaded; the strictest one silently stopped being the real gate.
Hook-vs-CI divergence — Pre-commit / pre-push enforcing a different
ruleset than CI, so "passes locally" and "passes CI" are different claims
and people learn --no-verify.
Dead gates — Triggers that can no longer fire (renamed branches, removed paths, disabled but not deleted). Still cost comprehension: every reader must reason about a gate that does nothing.
Best-of selection — For each duplicate cluster, name the winner:
needs: all others) beats N scattered required checksmerge_group + matching check names) beats PR-onlyRecord winner + losers per cluster — this is the input housekeep-gates
executes.
Where CI history is inspectable, look for a merged PR that introduced a failure the gate should have caught. Each one is a proven hole, not a hypothetical.
Optional cheap probe on a scratch branch the user already has: introduce a deliberate violation the gate claims to catch and confirm it blocks. A gate never tested against a real violation has unknown efficacy. Do not create that branch or push it unless the user asked.
continue-on-error / soft-fail / always() masking foundpull_request_target / external-PR bypass assessedhousekeep-gatesgh api result, or merged PR — not "probably bypassable"housekeep-gates; cost → audit-cicdhousekeep-gates; pipeline-side → audit-cicd; rule-to-mechanical gaps → enhance-agent-guardrails. Present and stop.