# Validation from a clean checkout

[Release guide](../RELEASING.md)

Run the usual command from a complete DanceMoves checkout:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\validate.ps1 -Mode Unit
if ($LASTEXITCODE -ne 0) { throw "Validation failed; do not release" }
```

The coordinator now prepares the ignored unit HTML before any adapter test
tries to read it. No external song workspace, `Z:` drive, browser, network
request, audio download, native compiler or WordPress installation is required for
that preparation. Node, PHP and Python are still required by the test suite.

## Inputs and outputs

| Harness | Tracked input | Generated unit output |
| --- | --- | --- |
| California | `tests/fixtures/california-screamin-unit.html` (synthetic DOM contract) | `qa/california-screamin-unit-candidate.html` |
| Clay | `qa/prelive/clay-stars/canonical-live-2.3.2.html` (existing pinned signed-out snapshot) | `qa/clay-stars-unit-candidate.html` |

The Clay source must match SHA-256
`2F3EC40E763E712CCFD5F94C818E0D651F9F98EF8CA925FEB05A9F39D464B038`.
The builder checks its title, single release root, single player, five chapter
controls and absence of the WordPress admin bar. It removes old plugin assets
and injects current local assets, including the effects and rudiments modules.
The current PHP header and `DANCE_MOVES_VERSION` must agree. Existing production
asset hashes in the harness manifests are still checked, not regenerated to
make tests pass.

California's fixture tests the expected adapter DOM and local asset wiring. It
is explicitly **not** the production page's layout, imagery, audio or complete
motion stack. Tests of native sensor mapping and lifecycle continue to run
against the actual production JavaScript elsewhere in the existing suite.

The generator writes only `*-unit-candidate.html`; existing
`*-harness-candidate.html` full-page QA files are not overwritten. Repeat runs
leave identical generated bytes and timestamps alone. Unit HTML is already
ignored by `qa/*.html` and remains excluded from the WordPress ZIP.

Preparation can also be invoked separately for diagnosis:

```powershell
node .\tools\prepare-test-harnesses.cjs
node .\tests\california-adapter.test.cjs
node .\tests\clay-adapter.test.cjs
```

Both adapter tests prepare their own unit input when invoked directly. Do not
create an empty missing HTML file or comment out a failing assertion.

## Why the old command failed

The old California adapter test unconditionally opened an ignored generated
file, but the Unit coordinator never generated it. The old preview builder
also assumed a private path under `Z:\My Songs\Releases\California Screamin'`.
Clay's test had the same unprepared-output dependency. Those private/generated
prerequisites are now outside the normal Unit path.

The historical preview builders are not called by Unit and have not been
silently repurposed as production evidence. Their full-page workflows still
need a verified source payload and appropriate live/browser review.

## Unit versus pre-live acceptance

The coordinator supplies `--candidate-file` to the existing Python scaffold
validator. It changes the candidate input for **that invocation only**, not the
manifest or its full-page path. All existing manifest, production-hash, CSS-risk
and encoding checks continue to run. A failure in either unit scaffold is fatal;
the California unit audit is no longer hidden behind a broad warning.

The generated HTML has:

```html
<meta name="dance-moves-fixture" content="unit-only">
```

The Python validator reports this limitation during scaffold checks and rejects
it in `--mode prelive`. Pre-live mode also rejects `--candidate-file`, even when
called as a Python function instead of through the CLI. It still uses the
manifest's full-page candidate and requires the existing browser, screenshot and
physical-device evidence. A passing Unit run does not approve deployment.

## Missing or changed tracked input

A missing Clay source, wrong source hash, missing runtime asset, invalid release
identity or mismatched plugin version is a hard error before candidate writes.
Check `git status` and restore only the affected tracked input from the intended
revision after preserving deliberate local edits. Do not automatically update
hashes, copy an unrelated EPK or recreate a private drive to get past the error.

Regression checks added for this setup:

```powershell
node .\tests\harness-preparation.test.cjs
python .\tests\test-harness-candidate-selection.py
```

No plugin runtime, page metadata, release version or packaging behavior changes
as part of this validation-setup repair.
