core: Add evidence/veto roles to the liveness policy
Liveness checks now declare a `CheckRole`: positive **evidence** of life,
or a spoof **veto**. The policy composes them differently:
evidence = noisy_or(evidence check scores) // raises confidence
combined = evidence × ∏(veto check scores) // veto caps it
This is needed because some signals are evidence of an *attack*, not of
life, and noisy-OR (which ignores low scores) would render them inert. A
veto check still outputs "confidence the subject is live" in 0..1, but
*low* when it detects an attack signature; multiplying caps the final
score, so a confident veto (≈0, "this is a screen") overrides even
strong evidence. An inapplicable veto isn't in the product and caps
nothing, preserving additivity for veto checks too.
`role()` defaults to `Evidence`, so existing checks are unaffected;
spoof detectors override it. `LivenessAssessment` gains `evidence`
(pre-cap) alongside `combined` (post-cap) for diagnostics. The old
`combine` is renamed `noisy_or` to name what it actually does now that
it's only the evidence half.
Proptested: noisy-OR bounded/monotonic/single-identity as before, plus
the defining veto property — adding a veto never raises the final score
— and the combined score stays in [0,1] for any evidence/veto mix.
(The first real checks land next: the micro-motion check is being
removed as a proven dead end — magnitude-of-change is anti-correlated
with liveness, per both measurement and the PAD literature — and
replaced by a NIR-reflectance veto gate.)