# Auth split-origin acceptance contract

Status: executable evidence contract; production/browser evidence is BLOCKED until a production-equivalent input bundle exists.

## Inputs

The harness writes a run to `quality/acceptance/auth-split-origin/input/<run_id>/` containing exactly:

- `environment.json`
- `cases.ndjson`
- `summary.json`
- `sink-inventory.json`
- `sink-search.ndjson`
- `db-assertions.ndjson`
- `crash-injection.ndjson`
- `artifact-manifest.json`
- `traces/` containing sanitized Playwright traces only
- `SHA256SUMS`

The separately signed source manifest is `quality/acceptance/auth-split-origin/input/<run_id>/auth-sensitive-data-flow.json`. `environment.json.redaction_manifest.sha256` is `sha256:` plus the SHA-256 of its exact bytes. `sink-inventory.json.manifest_sha256` is the same digest without the prefix and `sink-inventory.json.entries` must be an exact JSON value copy of the signed manifest's `entries`; the verifier rejects any projection, omission, reordering, or changed value.

The closed manifest uses exact production/mail hop-class enums, unique reciprocal graph edges, unique hop/probe IDs, and explicit disabled-hop semantics. Every enabled entry has exactly one probe and an Ed25519 owner signature; disabled entries have no probe and a nonempty reason. Owner signatures cover canonical UTF-8 JSON (object keys sorted, no insignificant whitespace, `ensure_ascii=false`) of the complete entry excluding `owner_signature`. The security-owner Ed25519 signature covers the same canonical encoding of the complete manifest excluding `security_signature`. Public keys and signatures are standard padded base64. Self-test fixture keys must be labelled visibly `NON-PRODUCTION TEST KEY`; production manifests may not use fixture keys. The verifier cryptographically verifies every signature and fails closed if Ed25519 support is absent. The sink inventory is an exact copy of entries, the graph is root-connected and reciprocal, and every enabled hop has exactly one matching retained probe.

## Command and outputs

From the repository root:

```sh
python3 quality/acceptance/auth-split-origin/verify.py \
  --input quality/acceptance/auth-split-origin/input/<run_id> \
  --manifest quality/acceptance/auth-split-origin/input/<run_id>/auth-sensitive-data-flow.json \
  --publication artifacts/platform-auth/<run_id>
```

Only a fully schema-valid, digest-valid, production-equivalent bundle whose summary and every record are PASS exits 0 and prints one sanitized `VERDICT=PASS` line. Missing input, validator support, fields, files, records, signatures, digest equality, exact manifest copy, production equivalence, or any FAIL/BLOCKED record exits 2 and prints `VERDICT=BLOCKED`; the verifier never manufactures a PASS or fills evidence defaults. Schema/data faults are evidence invalidity and therefore BLOCKED, not test FAIL.

Output remains in the input run directory; verification does not rewrite evidence. `SHA256SUMS` strictly lists every retained file except itself. To avoid digest recursion, `artifact-manifest.json.files` and `summary.json.artifacts` each list the exact same payload set: every retained file except `SHA256SUMS`, `artifact-manifest.json`, and `summary.json`. All paths are closed normalized relative POSIX paths; sets, byte counts, and digests must agree. The retained publication path is `artifacts/platform-auth/<run_id>/`, must be distinct, and is revalidated byte-for-byte by the same invocation before PASS. No raw cookie, CSRF, password, reset token, auth response body, HAR body, or secret may be retained.

## Schema/self-test only

```sh
python3 quality/acceptance/auth-split-origin/self_test.py
```

This checks every schema with a Draft 2020-12 metaschema validator and proves an absent production bundle returns BLOCKED/exit 2. It does not run or imply any production or browser case.
