mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 08:03:13 +00:00
GitHub Actions already owns SPA bytes, so the unused pointer scripts and the stale greenlight checklist should not stay in tree.
79 lines
7.1 KiB
Markdown
79 lines
7.1 KiB
Markdown
# 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`. Governance also runs the repository
|
||
gates: Terraform import-plan checker, Terraform formatting and validation, the
|
||
HCP run guard, CloudFront verify, workflow shell checks, and G13 (app/Terraform
|
||
isolation). 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 |
|
||
| Terraform import-plan contract | `npm run test:terraform-import-plan` → `scripts/test-terraform-import-plan-check.py` | `governance` + CI | Synthetic plan JSON + canonical maps |
|
||
| Terraform formatting/validation | `npm run test:terraform` → `scripts/terraform-validate.mjs` | `governance` + CI | `terraform/live/dev`, `terraform/live/staging` |
|
||
| HCP run guard | `npm run test:hcp-run-guard` → `scripts/test-hcp-run-guard.py` | `governance` + CI | Workspace invariants + apply reconcile |
|
||
| CloudFront release verify | `npm run test:cloudfront-release-verify` → `scripts/test-verify-cloudfront-release.sh` | `governance` + CI | Stubbed aws/curl |
|
||
| GitHub workflow shell | `npm run test:github-workflows` → `scripts/check-github-workflows.sh` | `governance` + CI | `bash -n` + actionlint |
|
||
| G13 App/Terraform isolation | `python3 scripts/check_app_terraform_isolation.py` vs `GOVERNANCE_BASE` | `governance` + CI | Deployable app files vs `terraform/` |
|
||
|
||
## 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.
|
||
- **Terraform gates never touch live state** — `terraform init -backend=false
|
||
-lockfile=readonly` and `validate` run offline; the plan checker is tested
|
||
against synthetic plan JSON. Real import and controlled-update plans from HCP
|
||
are migration evidence reviewed by a human before an approved apply
|
||
(`terraform/README.md`). G13 fails a diff that contains both `terraform/`
|
||
and deployable application files (`src/`, `public/`, `pages/`, `config/`,
|
||
`index.html`, Vite/tsconfig, or `.env*`). Workflow,
|
||
docs, and gate-script changes may travel with either side. Runtime isolation
|
||
stays: `deploy-web.yaml` ignores `terraform/**`, and app-only tags skip HCP
|
||
when workspace trigger patterns miss.
|
||
|
||
## 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` (with Terraform 1.16.0 installed) so the maintainability
|
||
ratchets and repository gates are guaranteed from this repository regardless
|
||
of the reusable workflow.
|
||
- **Terraform CI ([`.github/workflows/ci-terraform.yaml`](.github/workflows/ci-terraform.yaml)):**
|
||
fmt, `init -backend=false`, validate, import-plan unit tests, and G13
|
||
classifier unit tests on `terraform/**` changes for PRs to `main` or `dev`.
|
||
|
||
## 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`. Governance also needs
|
||
`terraform` (CI: 1.16.0; `versions.tf` accepts `>= 1.14.0, < 2.0.0`) and
|
||
`python3` (3.10+) on `PATH`.
|