shoc-frontend-new/QUALITY_GATES.md
Alexandre Brandizzi 4337cc662b
Some checks are pending
CI / ci (push) Waiting to run
CI / governance (push) Waiting to run
Deploy / deploy (push) Waiting to run
chore(governance): enforce frontend quality system (#53)
* chore(governance): make React/TS conventions mandatory via executable gates

Add AGENTS.md, QUALITY_GATES.md, ARCHITECTURE_AND_CODE_QUALITY.md, and
REVIEW_AND_PR_FRAMEWORK.md as the binding conventions and PR review
contract for humans and all coding/review agents.

Add a single 'npm run verify' command (format + lint + build + test +
governance) and 'npm run governance', which runs a dependency-free godfile
ratchet (whole-repo, baseline in scripts/governance-baseline.json) and a
changed-file maintainability gate (complexity<=20, function<=150, params<=4,
depth<=4) via ESLint. Legacy is handled by ratchets, not relaxation: 5
godfiles over 500 lines are grandfathered debt; maintainability thresholds
apply to changed TS/TSX (72 legacy violations across ~51 files otherwise).

Add a repo-owned 'governance' CI job that runs 'npm run verify' so every
gate is guaranteed from this repository, independent of the org reusable
workflow.

* fix(governance): make frontend ratchets fail closed
2026-07-24 16:47:34 -03:00

54 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# QUALITY_GATES.md — executable frontend gates
The single command that runs **every** gate, locally and in CI:
```bash
npm run verify
```
`verify` chains: `format:check` → `lint` → `build` (`tsc -b && vite build`) →
`test` (`vitest run`) → `governance`. A task is not done until this is green.
## Gate matrix
| Gate | Command / rule source | Enforced by | Scope |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------- | ------------------------------------ |
| Formatting | `npm run format:check` (Prettier) | `verify` + lint-staged | Whole repo |
| Lint, zero warnings | `npm run lint` → `eslint . --max-warnings=0` | `verify` + CI | Governed TS/TSX (`eslint.config.js`) |
| Type-check + production build | `npm run build` → `tsc -b && vite build` | `verify` + CI | Whole app |
| Unit tests | `npm test` → `vitest run` | `verify` + CI | `src/test/**`, `config/**/*.test.ts` |
| Conditional rendering (no `: null`) | `no-restricted-syntax` in `eslint.config.js` | lint | Governed TSX |
| Boolean-only JSX `&&` | `seahaven/no-non-boolean-jsx-and` (type-aware) in `eslint-rules/` | lint | Governed TSX |
| Shared `Text` typography | `no-restricted-syntax` (raw `p`/`h1`–`h6`) + `seahaven/no-vp-error-outside-text` | lint | Governed TSX |
| Hooks correctness | `eslint-plugin-react-hooks` recommended (incl. `exhaustive-deps`) under zero-warnings | lint | Governed TS/TSX |
| Godfile ratchet (file length) | `scripts/governance-check.mjs` + `scripts/governance-baseline.json` | `governance` | `src/**`, `config/**` (non-test) |
| Changed-file maintainability | `scripts/governance-check.mjs` → ESLint (`complexity`, `max-lines-per-function`, `max-params`, `max-depth`) | `governance` | Changed TS/TSX vs base ref |
## No-false-pass guarantees
- **`--max-warnings=0`** — a warning is a failure. There is no "warning-only"
backlog; rules ship green (see AGENTS.md → How to add a convention).
- **Type-aware rules fail closed** — `seahaven/no-non-boolean-jsx-and` reports
when type services are unavailable rather than silently claiming safety.
- **Godfile ratchet is monotonic** — any new file over the cap, new baseline
entry, global cap increase, per-file cap increase, or growth beyond a frozen
legacy cap fails. Only cap reductions and entry removals are allowed.
- **Changed-file maintainability fails closed without a valid base** — in CI the
base ref is derived from `GITHUB_BASE_REF` (PR) or `github.event.before`
(push). An absent or unresolvable base is a failure, not a pass.
## Where the gates run
- **Locally:** `npm run verify`. `lint-staged` (via Husky) re-runs ESLint +
Prettier on staged files at commit; commitlint enforces Conventional Commits.
- **CI ([`.github/workflows/ci.yaml`](.github/workflows/ci.yaml)):** the org
reusable workflow (`ci-typescript-frontend.yaml`, Node 24) runs
format/lint/build/tests, **and** a repo-owned `governance` job runs
`npm run verify` so the maintainability ratchets are guaranteed from this
repository regardless of the reusable workflow.
## Toolchain pin
Node ≥ 22.22.1 (CI uses Node 24); npm 11.16.0 via `packageManager` (use
`corepack npm …` if your default `npm` is older). The lockfile is
`package-lock.json` v3; install with `npm ci`.