Skip to content

hotato 0.9.0

Choose a tag to compare

@quantumCF quantumCF released this 10 Jul 17:15

Added

  • 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.