# Controlled sensitive-candidate review release

Use for health, finance, identity, or other sensitive workflows that project extracted candidates, show a preview, and transfer only an explicit operator-confirmed value into a canonical store.

## Mandatory preview binding

A preview digest is a security and data-integrity boundary, not display metadata.

- Bind it to candidate identity/type and revision, current match/comparison digest, target/catalog identity, value, operator/qualitative state, unit, explicit observation/event date, source-specific reference text, and source-review revision.
- Recompute it in the worker from current authoritative rows immediately before transfer and compare with `hmac.compare_digest`.
- Reject both a missing digest and a mismatch for every sensitive transfer/remap operation. `if digest: compare` is bypassable.
- Enforce the requirement in request validation and worker validation. The worker remains authoritative because queue payloads can be forged independently of the browser.
- Candidate revision alone is insufficient because match, reference, or source-review state can change without incrementing it.
- Bind the digest to the **submitted** edited value/unit as well as the extracted value. A valid digest over the extracted candidate must never authorize a different `corrected_confirmed` payload. If the product has no server round-trip that regenerates a preview for edits, reject corrected confirmation fail-closed and remove that action from the UI rather than accepting an unbound edit.
- Bind and recheck current source availability, not just historical review timestamps. An original that was reviewed and later became `missing`, `blocked`, replaced, or otherwise unavailable must fail both confirmation and final transfer.

## Projection and semantic boundaries

- Keep candidate projection read-only; write only through the existing authenticated submission, queue, worker, transaction, audit, and idempotency contracts.
- Deserialize staging JSON into nested allowlisted projections. Never return staging records verbatim.
- Omit numeric/internal document IDs, canonical row IDs, candidate internals, source-text revisions, storage paths, filenames, and raw engine strings. Map provenance engines to a bounded public enum and probe every endpoint that exposes the preview.
- Keep technical match confidence separate from review status; confidence never confirms.
- Require reviewed source/original and relevant page/section evidence before canonical transfer.
- Keep observation/event date, document date, import date, and confirmation date separate; never promote document/import date as a fallback.
- Preserve censored operators separately and exclude censored observations from exact chart/delta/baseline series.
- Permit qualitative values only through a bounded contract; never invent a number or unit.
- Validate signed reference bounds and reference-unit compatibility. Preserve source-specific raw reference text without creating a global normal range.
- Include source provenance in duplicate identity; equal values from different sources must not silently collapse.
- Use only explicit catalog grouping fields; otherwise display unclassified.

## Required synthetic counterexamples

1. Missing preview digest is rejected.
2. Old digest is rejected after changing only match/reference/source-review data while candidate revision stays unchanged.
3. Unreviewed source/original or page is rejected.
4. Missing explicit observation date is rejected.
5. Reference-unit mismatch and malformed range are rejected; signed bounds survive.
6. Qualitative confirmation remains qualitative and unitless in every confirmed-only consumer.
7. Censored values never enter chart/delta/baseline series.
8. Equal values from different sources retain distinct provenance or explicit conflict state.
9. Feature and generic-review APIs expose no internal IDs, staging fields, paths, or raw engine labels.
10. Replay remains idempotent and transfer is transactionally atomic.
11. A forged `corrected_confirmed` value/unit cannot reuse the digest of the extracted candidate; rejection leaves review events, staging, and canonical tables unchanged.
12. A previously reviewed original whose current status is `missing` or `blocked` is rejected at both confirmation and transfer.

## Baseline-first regression discipline

Before editing broad legacy tests to make a feature branch green, reproduce each broad-gate failure at the frozen base commit under the same dependencies, environment, fixture profile, and command. Classify it as feature regression, pre-existing baseline debt, environment mismatch, or intentionally superseded contract.

Only change unrelated legacy tests when the task explicitly accepts that scope. Otherwise report inherited debt separately and keep the feature diff narrow. Never weaken assertions merely to advance a matrix; replace obsolete assertions only with checks for the current documented contract while preserving safety/security evidence. A failure reproduced at base proves inheritance, not a green current suite.

## Release gate

No commit, push, or deployment while any P0/P1 remains, a required counterexample is missing, or the final exact tree differs from the reviewed tree. After late fixes, rerun affected focused tests, relevant browser groups, exact-tree review, deterministic build/byte comparison, protected-surface hashes, DB integrity/FK checks, secret scan, and private read-only runtime smoke.

Maintain a finding ledger keyed by reviewer dispatch time, reviewed tree/hash, finding, counterexample, fix, and closing test. Async results can arrive out of order: a late-delivered P1 from an older review remains open until its concrete counterexample is closed. A newer PASS does **not** supersede an older finding unless that PASS explicitly covered the finding on the post-fix exact tree. After the last code change, obtain one bounded exact-tree closure verdict covering every ledger item before committing.
