You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
hotato trust now measures cross-channel leakage and low signal level, two
input defects that previously passed silently as "safe to scan". A red-team
found that symmetric echo bleed at roughly -40 dB flips a downstream timing
verdict (talk-over 400 ms to 1050 ms in the reproduced case) while trust still
reported scorable: true, safe to scan, and no warning, because crosstalk was
judged only by whole-clip echo coherence -- a single best-lag cosine that
unrelated activity elsewhere in the call dilutes below the bar.
A new crosstalk_risk.leakage_db (with leakage_direction) reports the level
of a consistent, attenuated, delayed COPY of one channel found on the other.
It is measured from the per-frame level ratio of the copy, which a real leak
holds constant across every frame the source speaks, so it survives the leak
being loud enough to re-trigger the other channel's own detector -- exactly
the regime that breaks the verdict and the one coherence misses. At or above -40 dB (calibrated to the reproduced break point) the copy is flagged
(crosstalk_risk.suspected), a warning is raised, and the recommendation is
downgraded to scan with caution. The threshold was benchmarked against every
clean dual-channel fixture in the corpus (12 real recordings and 7 synthetic):
none carries a consistent copy above -50 dB, so none is flagged, and all
still read safe to scan.
A signal level very low warning is raised when even the loudest channel
peaks below -30 dBFS, the band where turn timing can be under-measured
downstream while every scorability gate still passes.
Both are additive and DISCLOSURE-ONLY: scorable, the not-scorable reason
chain, and the exit code are unchanged. trust adds signals and states its
limits; it never silently changes what passes. schema_version stays "1".
See docs/TRUST.md.
Changed
hotato fix trial's provenance guard now verifies identity, it does not
trust the envelope. An external red-team of 0.8.0 showed the guard trusted
the audio_provenance JSON: a digest string was compared for equality and
nothing else, so a hand-written envelope (valid-looking digests, no audio),
a non-hex or absurd-metadata block, a header-only byte flip (decoded audio
unchanged), a cherry-picked after set, or a frozen hold could all still reach improved. The guard is rebuilt around one rule: an improved verdict is
never reachable on unverifiable evidence.
Validate before trusting: every sha256 / pcm_sha256 must be 64-char
lowercase hex; each side's sample_rate / num_samples must be plausible;
the top-level digest must be consistent with the per-side digests it claims
to combine. A malformed block is UNKNOWN (inconclusive), never "a distinct
recording".
Recompute when the audio is present: the raw and decoded-PCM sha256 are
recomputed from the file next to the envelope at trial time; a digest that
disagrees with the bytes on disk is refused
(refusal_kind: recompute_mismatch).
Unverifiable is never improved: a well-formed identity hotato could
not recompute (the audio was not present) downgrades to inconclusive with
the reason that a fix claim requires provenance hotato can recompute. This
closes the decisive forgery -- hand-written envelopes with no files.
Compare DECODED PCM, not raw bytes: identical decoded audio before vs.
after is the same conversation re-scored (refused), so a header-only edit
or a trailing-byte append can no longer disguise a re-score as a recapture.
When a side records no pcm_sha256 the check falls back to the raw digest
AND marks the fixture unverified.
Completeness: every before target and hold must have an after
counterpart; a required only-before fixture is refused
(refusal_kind: incomplete_after) with the omitted list.
Holds get the same guard as targets: a still-passing hold with frozen
(re-scored) audio is now refused, not silently accepted.
--min-n is echoed in every surface (text, JSON, HTML) so a lowered
floor is always visible.
hotato verify's envelope rollup additively reports unpaired.only_before_required (before targets / holds dropped from the
after set); the flat only_before / only_after lists are unchanged.
Docs (docs/FIX-TRIAL.md, docs/RECAPTURE.md) updated to describe the
hardened guard exactly. No new claim is made about attacker-proofing an
offline tool a user fully controls; the guard makes the honest-but-motivated
failure modes impossible or loud, recomputes what can be recomputed, and the
report states exactly what was and was NOT verified.
The apply receipt now renders beside the verdict, and a nested CLAIM
can no longer read as a pass under a red parent. The same red-team found
two remaining honesty gaps in the rendered report itself, independent of
the provenance guard above:
Apply receipt: hotato fix trial never calls apply.create_clone,
so apply_dry_run is always True and apply_created / apply_applies_change are always False, on every verdict including improved -- but the rendered report never said so; a green trial from
an unapplied patch looked identical to one where the change was known to
be live. apply_dry_run / apply_created / apply_applies_change / apply_receipt_note are now top-level JSON fields (not just nested
inside apply), a text line right under the header, and pills plus a
header sentence in the HTML <header> block, on every run.
No positive claim under a failed parent: hotato verify's nested CLAIM line inside a fix-trial report could read CLAIM: ... This improvement COINCIDES with your change even when the outer fix-trial
verdict was inconclusive or refused (a provenance or completeness
issue downgraded the outer verdict, but the inner verify claim was
unaware of it) -- a cropped screenshot of just that block looked like a
clean pass. verify.render_text now takes an optional superseded_by
verdict; hotato fix trial passes its own verdict whenever it is not improved, and a claim that would read "supported" is tagged CLAIM (SUPERSEDED BY {VERDICT}) with a one-line restatement, in both text and
HTML.
Docs: docs/FIX-TRIAL.md and docs/RECAPTURE.md each gained a
"What this does not stop" section: fabricated-but-freshly-captured
stimuli, a repacked contract with a loosened policy (manifest integrity
is not authenticity), resample/codec/gain transforms of the same call
(a known PCM-identity residual), and that signatures are not
implemented. None of this is new attacker-proofing; it is stating
plainly what a green result does and does not establish.