# Beauty Design Compiler V2 browser-QA evidence
The browser-QA finalizer is a read-only evidence merger. Generated HTML, compiler scores, and the existence of a screenshot directory are never treated as proof that browser QA passed.
V2 design selection is intentionally two phase:
1. Static compilation emits `STATIC_SHORTLIST`, four to six candidate ordinals, and `shortlist-review-required`.
2. `materializeBeautyTournamentShortlistV2` renders those candidates.
3. An authorized structured visual-review workflow supplies review evidence; it may be direct Codex screenshot inspection or an explicitly enabled provider-backed critic.
4. `finalizeBeautyDesignV2VisualSelection` deterministically selects only from candidates that pass both static and supplied visual thresholds.
5. The resulting tournament is `VISUAL_REVIEW_ACCEPTED`; only that phase can be persisted as an accepted V2 selection.
The repository contains a gated, budget-limited Responses visual-critic implementation, but the
current release evidence does **not** contain a Responses critic result. The optional path was
unavailable under the configured account controls. Seven staged screenshot-review calls were
discarded atomically, and no partial result was accepted. The
authoritative visual evidence is the recorded direct Codex inspection; it is not a human-participant
study. Static QA generation never turns fixture labels or structural browser metrics into invented
human or model scores.
## Current post-migration evidence
The renderer-style migration is `COMMITTED` for 128/128 accepted fictional-fixture pages with zero
migration failures. Fresh Chrome capture then produced:
- 512/512 screenshots and 512/512 runtime measurements over mobile, tablet, desktop, and wide;
- both intended self-hosted font faces loaded in all 512 measurements;
- zero failed requests, resource errors, broken links, console errors, page errors, or horizontal
overflow;
- 52/52 planned direct inspections passing all six named checks over all four viewports; and
- 256/256 mobile/desktop axe-core runs accepted by the finalizer, with zero violations and all 221
nodes from 70 automated `incomplete` contrast findings independently resolved as passing.
This is local, fixture-only, non-indexed evidence. Lighthouse was not provided, field Core Web
Vitals were not measured, no human-participant study was performed, and no customer production
deployment or current public URL is claimed.
Run it only after browser capture and direct inspection are complete:
```text
pnpm beauty:qa:finalize:v2
```
It reads the generated QA site at `artifacts/beauty-design-compiler-v2/qa-site` by default and writes:
- `qa-summary-v2-final.json`
- `qa-summary-v2-final.html`
The exit codes are `0` for passed, `1` for failed, and `2` for incomplete or invalid evidence.
## Required source evidence
The finalizer verifies these renderer-owned files:
- `qa-summary-v2.json`
- `reports/render-records.json`
- `reports/direct-inspection-plan.json`
- `reports/renderer-style-migration-v1.json` when a committed renderer migration changed accepted
presentation HTML
The release contract is fixed at 128 fictional pages, 52 direct-inspection IDs, and these four viewports:
| ID | Width | Height |
| --------- | ----: | -----: |
| `mobile` | 390 | 844 |
| `tablet` | 768 | 1024 |
| `desktop` | 1440 | 1000 |
| `wide` | 1920 | 1080 |
The exact screenshot and browser-metric set is the Cartesian product of the 128 page IDs in `render-records.json` and those four viewports: 512 unique pairs.
## Browser evidence layout
Browser capture writes beneath:
```text
browser-qa/
screenshot-inventory.json
browser-metrics.json
axe-results.json
direct-inspection-ledger.json
post-migration-chrome-capture.json
post-migration-direct-inspection-decisions.json
screenshots/
...
lighthouse/
*.json
```
Screenshot paths in the inventory are relative to the QA root and must remain beneath `browser-qa/screenshots/`. The finalizer verifies containment, extension, file existence, path uniqueness, and the SHA-256 of every captured file.
When `reports/renderer-style-migration-v1.json` is present and `COMMITTED`, the finalizer first
verifies the complete 128-record migration. Each screenshot, runtime measurement, axe run, and
direct-inspection entry must then carry the exact migration-report SHA-256 and the matching
post-migration HTML SHA-256. Pre-migration evidence cannot silently satisfy the post-migration
gate.
### `screenshot-inventory.json`
```json
{
"schemaVersion": "beauty-browser-screenshot-inventory-v1",
"generatedAt": "2026-07-27T12:00:00.000Z",
"browser": {
"name": "Chrome",
"version": "138.0.0"
},
"viewports": [
{ "id": "mobile", "width": 390, "height": 844 },
{ "id": "tablet", "width": 768, "height": 1024 },
{ "id": "desktop", "width": 1440, "height": 1000 },
{ "id": "wide", "width": 1920, "height": 1080 }
],
"screenshots": [
{
"pageId": "atelier-split-portrait--rich-1",
"viewportId": "mobile",
"status": "captured",
"relativePath": "browser-qa/screenshots/atelier-split-portrait--rich-1--mobile.png",
"sha256": "64-lowercase-hex-characters",
"capturedAt": "2026-07-27T12:00:01.000Z"
}
]
}
```
A capture failure is represented explicitly:
```json
{
"pageId": "atelier-split-portrait--rich-1",
"viewportId": "mobile",
"status": "failed",
"error": "Timed out while waiting for fonts"
}
```
A failed capture is a known QA failure. A missing page/viewport record is incomplete evidence.
### `browser-metrics.json`
```json
{
"schemaVersion": "beauty-browser-metrics-v1",
"generatedAt": "2026-07-27T12:00:00.000Z",
"measurements": [
{
"pageId": "atelier-split-portrait--rich-1",
"viewportId": "mobile",
"consoleErrors": [],
"pageErrors": [],
"failedRequests": [],
"brokenLinks": [],
"horizontalOverflowPx": 0,
"cumulativeLayoutShift": 0.02,
"primaryActionVisible": true,
"primaryActionTarget": { "width": 146, "height": 48 },
"reducedMotionVerified": true,
"motionViolations": []
}
]
}
```
All 512 pairs are mandatory. The enforced limits are no browser errors, failed requests, broken links, or motion violations; horizontal overflow no greater than 1 CSS pixel; cumulative layout shift no greater than 0.1; a visible primary action with at least a 44-by-44 CSS-pixel target; and verified reduced-motion behavior.
### `axe-results.json`
```json
{
"schemaVersion": "beauty-axe-results-v1",
"generatedAt": "2026-07-27T12:00:00.000Z",
"axeVersion": "4.10.3",
"runs": [
{
"pageId": "atelier-split-portrait--rich-1",
"viewportId": "mobile",
"status": "completed",
"violations": [],
"incomplete": [],
"passes": 42,
"inapplicable": 31
}
]
}
```
Every page requires a completed `mobile` and `desktop` run: 256 unique runs. Violations,
unresolved `incomplete` nodes, and execution failures block a pass. An automated `incomplete`
contrast node may pass only when the evidence contains a matching independently computed
`RESOLVED_PASS` record that meets the applicable contrast threshold.
### `direct-inspection-ledger.json`
```json
{
"schemaVersion": "beauty-direct-inspection-ledger-v1",
"reviewedAt": "2026-07-27T13:00:00.000Z",
"reviewer": "authorized-reviewer-id",
"entries": [
{
"pageId": "atelier-split-portrait--rich-2",
"status": "pass",
"inspectedViewports": ["mobile", "tablet", "desktop", "wide"],
"checks": {
"firstViewportClarity": true,
"bookingVisibility": true,
"typographyAndWrapping": true,
"imageCropAndFallback": true,
"responsiveComposition": true,
"noOverflowOrOverlap": true
},
"notes": "Directly inspected all four captures.",
"screenshotRefs": ["browser-qa/screenshots/atelier-split-portrait--rich-2--mobile.png"]
}
]
}
```
All 52 IDs from the generated inspection plan are mandatory. Every viewport must be recorded, every named check must pass, and each screenshot reference must exist in the verified screenshot inventory. `needs-review` is a failure, not a pass.
## Optional Lighthouse evidence
Raw Lighthouse JSON can be placed beneath `browser-qa/lighthouse/`. Its absence is reported as `not-provided` and does not fabricate or imply a Lighthouse pass. If any Lighthouse JSON is supplied, every file must parse as a Lighthouse result and the finalizer enforces:
- Performance score at least 0.95.
- Accessibility score at least 0.95.
- SEO score at least 0.95.
- LCP no greater than 2,500 ms when the audit is present.
- CLS no greater than 0.1 when the audit is present.
- INP no greater than 200 ms when the audit is present.
Malformed supplied Lighthouse evidence makes the report incomplete. Valid supplied evidence below a threshold makes it failed.
## Status semantics
- `incomplete`: any mandatory source or browser evidence is absent, malformed, contradictory, outside the required ID set, missing a required pair, has an unverifiable screenshot path or hash, or otherwise cannot support a conclusion.
- `failed`: all mandatory evidence is complete and verifiable, but at least one capture, metric, accessibility run, direct inspection, or supplied Lighthouse threshold failed.
- `passed`: every mandatory item is complete and verifiable, and all enforced checks pass.
If failures and missing evidence coexist, the status remains `incomplete`; the known failures are still preserved in the final report.