# Quality Gates

Mechanica is intended to feel like a professional engineering viewer, so each milestone should pass objective quality gates before it is considered complete.

## Repository gates

Run these commands after installing dependencies:

```bash
npm install
npm run lint
npm run typecheck
npm run build
npm run preview
```

The maintainer should generate the package lockfile locally with `npm install`. A lockfile is not hand-authored in this repository foundation.

## TypeScript gates

- `strict` TypeScript stays enabled.
- No local import may reference a file or export that does not exist.
- Registry data must satisfy `MachineDefinition`.
- Animation modules must satisfy `MachineAnimationModule`.
- Scene adapters must satisfy `MachineSceneAdapter`.
- URL parsing must tolerate missing, malformed, and older query parameters.

## Registry gates

The machine registry must remain data-driven.

A change fails review if it:

- hardcodes machine IDs inside catalogue cards
- adds machine-specific conditionals to generic viewer controls
- references a guided-tour part ID that is not in the machine
- references an animation-driven part ID that is not in the machine
- ships a GLB asset descriptor without a URL
- renames a released machine or part ID without URL migration

Recommended validation hook:

```ts
import { assertValidMachineRegistry } from './src/modules/machines/validation';

assertValidMachineRegistry();
```

## Accessibility gates

Every interactive control must meet these requirements:

- keyboard reachable
- visible focus style
- accessible name through text, `aria-label`, or `aria-labelledby`
- disabled state communicated to assistive tech
- no color-only status communication
- reduced-motion alternative for camera fly-throughs and animated tours

Canvas-specific gates:

- selected part details must be readable outside the canvas
- guided tour captions must be DOM text
- keyboard users must be able to change camera presets, reset view, play/pause animation, and step animation
- pointer hover information must also be available after keyboard focus or selection

## Visual gates

- No white flash during route transitions or loading.
- Skeletons reserve final layout dimensions.
- Panels use the shared dark theme tokens.
- Numeric engineering readouts use tabular numerals.
- Text contrast targets WCAG AA.
- Hit states are visible for hover, active, selected, and focus-visible.

## Performance gates

Target budgets:

| Area | Desktop target | Mobile target |
| --- | ---: | ---: |
| Viewer FPS | 60 fps | 30 fps minimum |
| Initial route JS | under 250 KB gzip before 3D chunks | under 250 KB gzip before 3D chunks |
| Per-machine 3D chunk | under 300 KB gzip code, assets streamed separately | under 250 KB gzip code |
| GLB geometry | under 150k triangles per detailed machine LOD | under 60k triangles per mobile LOD |
| Texture memory | under 64 MB per machine | under 24 MB per machine |
| Draw calls | under 180 | under 90 |

Implementation expectations:

- lazy-load machine scene modules
- instance repeated elements such as bolts, balls, blades, gear teeth, and cylinders
- cap device pixel ratio by quality tier
- use Draco for geometry-heavy GLB assets
- use KTX2/Basis for production textures
- pause non-essential animation when tab visibility changes
- honor reduced motion

## Documentation gates

Any new architecture-level system must include:

- purpose
- public API or data shape
- file ownership
- extension path
- failure modes
- example usage
- performance and accessibility considerations

## Dependency gates

Before introducing a dependency:

1. Confirm it is declared in `package.json`.
2. Prefer stable APIs over fast-moving experimental APIs.
3. Avoid exact version pins unless required for a security or compatibility reason.
4. Document any SDK/API calls that should be checked after dependency resolution.
5. Do not commit generated lockfiles unless the project maintainers decide to standardize on one package manager.

## Release gates for future milestones

A future production milestone should not be marked complete until:

- all declared scripts pass on a clean checkout
- Vercel preview deploy succeeds
- the catalogue primary path is tested at desktop, tablet, and mobile widths
- keyboard-only viewer operation is tested
- screen reader labels are sampled on major panels
- at least one machine exercises the complete path: catalogue card → viewer → part selection → animation playback → exploded view → share URL
