# Pre-Push Checks (MANDATORY)

## Rule

**NEVER push to any remote without first running and confirming ALL checks pass for every changed language stack.**

This rule exists because CI failures break the deploy pipeline for everyone and waste ~5 minutes per failed build. A 60-second local check prevents that.

---

## Quick Reference by Stack

### Python (backend-compliance, ai-compliance-sdk, compliance-tts-service)

```bash
cd <service-dir>
ruff check . && mypy . --ignore-missing-imports --no-error-summary && pytest tests/ -x -q --no-header
```

Blocks on: syntax errors, type errors, failing tests.

### Go (ai-compliance-sdk Go path)

```bash
cd <service-dir>
gofmt -l . | grep -q . && exit 1; go vet ./... && golangci-lint run --timeout=5m && go test -race ./... && go build ./...
```

Blocks on: formatting, vet findings, lint violations, test failures, build errors.

### TypeScript/Next.js (admin-compliance, developer-portal)

```bash
cd <nextjs-app-dir>
npx tsc --noEmit && npm run lint && npm run build
```

Blocks on: type errors, lint violations, **build failures**.

> `npm run build` is mandatory — `tsc` passes but `next build` fails more often than you'd expect (server/client boundary violations, env var issues, JSX syntax errors).

---

## What Claude Must Do Before Every Push

1. Identify which services/apps were changed in this task
2. Run the appropriate gate command(s) from the table above
3. If any check fails: fix it, re-run, confirm green
4. Only then run `git push origin main`

**No exceptions.** A push that skips pre-push checks and breaks CI is worse than a delayed push.

---

## CI vs Local Checks

| Stage | Where | What |
|-------|-------|------|
| Pre-push (local) | Claude runs | Lint + type check + unit tests + build |
| CI (Gitea Actions) | Automatic on push | Same + integration tests + contract tests |
| Deploy (Orca) | Automatic after CI | Docker build + health check |

Local checks catch 90% of CI failures in seconds. CI is the safety net, not the first line of defense.

---

## Failures That Were Caused by Skipping Pre-Push Checks

- `ChatFAB.tsx`: `const textLang` inside fetch object literal — caught by `tsc --noEmit` and `npm run build`
- `nodemailer` webpack error: server-only import in client component — caught by `npm run build`
- `jose` Edge Runtime error: full package import — caught by `npm run build`
- `main.py` `<en>` tags spoken: missing `import re` — caught by `python -c "import main"`

These all caused a broken deploy. Each would have been caught in <60 seconds locally.
