# Product quality gates Functional correctness is necessary, not sufficient. A build can compile, pass tests and produce a screenshot while still being too slow, visually incoherent or unpleasant to use. Do not let `pass` on technical acceptance stand in for product acceptance. ## Prototype vs product Choose the quality profile with the user before dispatch: | Profile | Use when | Mandatory gates | |---|---|---| | **Prototype** | the user explicitly wants a rough idea, spike or throwaway demo | runnable artifact, honest limits, no performance promise | | **Product** | the artifact will be used, shipped, demoed to others or compared with an existing version | functional + performance + UX/visual + baseline + human acceptance | Do not silently treat a prototype as a product. Do not demand product polish for a disposable spike. State the profile in the brief. ## Gates ### 1. Functional - acceptance commands and edge cases pass; - the artifact runs, not just compiles; - the verifier can reproduce the checks; - no known crash/data-loss path. ### 2. Performance Performance is part of correctness for interactive products. Define a budget in the brief before code, measure it on a **release/optimized** build, and record the environment. Suggested starting points (adjust to the product, do not treat as universal): - p95 frame time at the target window size: **≤16.7 ms** for 60 FPS, or a documented lower target; - input-to-visible response: **≤50 ms** for click/selection, **≤100 ms** for heavier actions; - startup to usable UI: **≤2 s** for a local desktop editor; - idle CPU and memory recorded; no runaway process when idle; - test with a realistic scene, not only an empty one (e.g. 100/1 000 entities). Measure with a frame-time diagnostic/overlay, a scripted interaction, or an external profiler. Record p50/p95, resolution, GPU/CPU, build profile and commit. **Debug builds are not evidence of release performance**; if only debug is available, report the numbers as provisional and do not claim the budget is met. If the budget is not met: reduce scope or fix the hot path before adding features. Do not hide a frame-time regression behind more UI. ### 3. UX / visual For GUI and visual work: - run a real 5-minute task, not just a screenshot; - check hierarchy, typography, spacing, contrast, focus, hover/active/disabled states; - check default, minimum and error/empty states; - check that the viewport is not blocked by panels and that resizing does not clip controls; - compare with the existing version/baseline on the same scenarios; - capture artifacts and record the exact commands. “Looks fine” is not a verdict. Name what is readable, reachable, clipped or missing. ### 4. Baseline If a previous version exists, define the scenarios where the new version must be **no worse**: startup, time to first edit, selection, drag, save, visual density. A regression against the baseline is a failure even if the new implementation has more features. ### 5. Human acceptance A verifier can check evidence; it cannot decide that the product feels usable. After each milestone or vertical slice: 1. the lead gives the user a short runnable artifact and a 3–5 step scenario; 2. the user runs it and answers: usable / usable with issues / not usable; 3. issues become the next milestone, not a footnote in a report; 4. **do not start the next milestone until the current one is accepted** (or explicitly waived). Record the verdict in `state.json`/`final-report.md`. A detached verifier `pass` is not a substitute. ### 6. Scope One milestone per session. Do not implement M1/M2 while M0 is still unpleasant. If the current slice is not usable, adding assets, play mode or export will not fix it. ## Stop rules Stop and re-plan when any of these is true: - functional acceptance passes but the product is visibly slower or worse than the baseline; - performance was not measured on an optimized build for a product task; - the user says “not usable” and the next step is more features instead of fixing the current slice; - the work has consumed half the milestone budget/time without a runnable artifact; - a UI slice has multiple parallel writers and the visual language is drifting; - the verifier can only produce a `pass` by ignoring performance/UX. ## Minimal product gate > Release build, measured p95 frame time and input latency, 5-minute real scenario, baseline > comparison, explicit user verdict. If any is missing, the product gate is `not_run`, not `pass`.