Skip to content
Back to skills

Pre Push Parity

ASecurity

Run the CI gates locally before pushing, so failures surface in seconds instead of one CI cycle at a time. Enumerates the checks in .github/workflows/, runs the locally-runnable subset in CI's order, and pins the local-vs-CI delta as a memory the first time you work in a repo. Use before `git push` / opening a PR, or when CI just failed on something your local gate missed. Triggers on "pre-push", "before push", "ci parity", "will ci pass", "local gate", "prepush", "pre-push check".

  • 19 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 3, 2026
toolsgobashdockergitapisecuritydocumentation

Works with

  • api

Security analysis

A100/100

Scanned September 21, 2026

npx -y skills add nexus-substrate/nexus-agents --skill pre-push-parity --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pre Push Parity?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Pre Push Parity
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nexus-substrate-pre-push-parity/badge)](https://www.skillsdirectory.com/skills/nexus-substrate-pre-push-parity)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: pre-push-parity
description: |
  Run the CI gates locally before pushing, so failures surface in seconds
  instead of one CI cycle at a time. Enumerates the checks in
  .github/workflows/, runs the locally-runnable subset in CI's order, and
  pins the local-vs-CI delta as a memory the first time you work in a repo.
  Use before `git push` / opening a PR, or when CI just failed on something
  your local gate missed.
  Triggers on "pre-push", "before push", "ci parity", "will ci pass",
  "local gate", "prepush", "pre-push check".
allowed-tools: Read, Bash, Grep, Glob
---

# Pre-Push Parity Skill

<!--
  CANONICAL SOURCES:
  - .github/workflows/ci.yml (the gate list this mirrors)
  - Motivating incident: #3073 (agents rediscover CI-only checks one failure at a time)
-->

## Why

CI runs a **strict superset** of any local quality gate. When the local gate
(`pnpm test`, a `make verify`, etc.) is green but CI is red, the agent burns a
full ~3-minute cycle per discovery — push, wait, parse logs, fix, push — for a
check it could have run locally in seconds. On a multi-PR session that's hours.
The fix is to run the superset locally **before** `git push`.

Real failures that motivated this (#3073): `ruff format --check` (local gate
only ran `ruff check`) and a `gitleaks` false-positive on a `*-Key-N` test
fixture — neither was in the local gate, both cost CI cycles.

## Principle

> Whatever CI can fail you on, run it locally first. For the checks you _can't_
> run locally (SaaS / GitHub-native), know they exist and that they're the
> residual risk — don't be surprised by them.

## Step 1 — Enumerate the repo's CI checks (do this first time in a repo)

```bash
# Job names + the commands each step runs:
grep -rEn 'name:|run:' .github/workflows/*.yml | grep -iv 'uses:'
```

Compare that list to your local gate. Anything CI runs that you don't is a
parity gap. **Write a memory** pinning the delta so the next session starts
informed (don't rediscover it):

> `ci-vs-local-gate-<repo>` — CI runs these checks the local gate doesn't: X, Y, Z.
> Run them via `<commands>` before push. Z (CodeQL/Scorecard/Socket) can't run
> locally — residual risk.

## Step 2 — Run the locally-runnable gates (nexus-agents)

In CI's order, fastest-feedback-first. Stop at the first failure, fix, restart.

| CI gate                    | Local command                                                   |
| -------------------------- | --------------------------------------------------------------- |
| Type Check                 | `pnpm typecheck`                                                |
| Lint                       | `pnpm lint`                                                     |
| Test                       | `pnpm test` (CI uses `pnpm test:coverage`)                      |
| Build                      | `pnpm build`                                                    |
| Changeset Presence         | `pnpm exec tsx scripts/check-changeset.ts origin/main`          |
| Producer/Consumer (#3024)  | `pnpm exec tsx scripts/check-new-unused-exports.ts origin/main` |
| Model String Drift         | `pnpm check:model-drift`                                        |
| Commit Messages            | `npx commitlint --from origin/main --to HEAD`                   |
| Working-tree clean (#2872) | `git status --porcelain` (must be empty)                        |
| Secret scan                | `gitleaks detect --no-banner` (runs in the pre-commit hook too) |

One-shot (mirrors CI, fails fast):

```bash
pnpm typecheck && pnpm lint && pnpm test && pnpm build \
  && pnpm exec tsx scripts/check-changeset.ts origin/main \
  && pnpm exec tsx scripts/check-new-unused-exports.ts origin/main \
  && pnpm check:model-drift \
  && npx commitlint --from origin/main --to HEAD \
  && test -z "$(git status --porcelain)" \
  && br="$(git branch --show-current)" && [ -n "$br" ] && [ "$br" != "main" ] && [ "$br" != "master" ] \
  && echo "PARITY OK ($br)"
```

> The pre-commit hook already runs `gitleaks` + lint-staged `eslint --fix` +
> `prettier`, so a successful commit covers formatting/secrets. This skill adds
> the gates the hook does **not** cover (typecheck, full test, build, changeset,
> unused-exports, model-drift, commitlint, clean-tree).

## Branch safety (before push)

The harness can silently switch the working branch mid-session (#3072): a long
run can end up on `main` carrying another branch's uncommitted edits — risking
lost work or an accidental push to `main`. Before every push, confirm you are
on the branch you intend (the one-shot above already gates on this):

```bash
git branch --show-current   # must be your feature branch — never empty (detached) or main/master
```

If it is `main`/`master` or empty (detached HEAD), **STOP — do not push.** Find
your work (`git reflog`, `git stash list`), check out / re-create the intended
feature branch, then re-run the gates before pushing.

## Step 3 — Checks you can NOT run locally (residual risk)

These are GitHub-native or third-party SaaS — note them, don't be surprised:

- **CodeQL** (`codeql.yml`), **OpenSSF Scorecard** (`scorecard.yml`),
  **Semgrep** (`semgrep.yml`), **Socket Security** — security scanners.
- **Consolidation E2E** (`docker compose ...`) — needs Docker; run it locally
  only if you touched the data-dir / consolidation path.
- **Link Check**, **Documentation Gate / DocOps Skill Sync** — run
  `pnpm link-check` and `pnpm governance:check` if you touched docs/skills.

## Step 4 — gitleaks fixture hygiene

The `generic-api-key` rule false-positives on test fixtures containing the
literal word `key` with entropy (e.g. `Idempotency-Key-1`). When the test
doesn't need the literal word, use a neutral fixture (`dash-shaped-value-7`).
If a real fixture must trip it, add a scoped `.gitleaksignore` entry — never a
blanket disable.

## Done when

- The Step-2 one-shot prints `PARITY OK`, **or** every failure it surfaced is
  fixed and re-run green.
- For a first-time repo: a `ci-vs-local-gate-*` memory records the delta.
- You've consciously accepted the Step-3 residual (can't-run-locally) checks.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.