Validate finer speech passages independently before Google ranking

This commit is contained in:
karl committed 2026-10-13 18:14:31 +02:00
1 parent 6353d02c04
commit fede6ce3bb
3 files changed
+274

No files matched your search

+66
View File
@@ -13,6 +13,7 @@ use std::{
const FIXTURE_SHA: &str = "b4e465a0eb9582b826eebd2a20797e1680e4907e336d02d0ef2194e2ba0af393";
const ASSETS: [&str; 5] = ["clip04", "music01", "music02", "sound01", "sound02"];
mod alignment;
mod gated;
const POLICY: &str = "primary-audio-range-v3;aresample16000-before-atrim;samplecoverage-1ms;nonoverlapping30s;independent-process-per-window;auto-language;segment-times";
@@ -105,6 +106,7 @@ fn eligible(asr: &Value, fixture: &Value) -> Result<(Vec<Value>, Vec<Value>)> {
] {
ensure!(asr[field].as_str().is_some_and(|hash| hash.len() == 64 && hash.bytes().all(|b| b.is_ascii_hexdigit())), "Missing ASR provenance");
}
let token_alignment = alignment::enabled(asr)?;
let vad = gated::verified_report(asr)?;
let rows = asr["rows"].as_array().context("Missing ASR rows")?;
ensure!(rows.len() == 5, "All five competing assets required");
@@ -187,6 +189,31 @@ fn eligible(asr: &Value, fixture: &Value) -> Result<(Vec<Value>, Vec<Value>)> {
window["segments"] == json!(actual),
"Normalized ASR segments differ from actual output"
);
let actual = if token_alignment {
let rebuilt =
alignment::reconstruct(&window["actual_whisper_json"], offset, duration);
if let Some(error) = window.get("alignment_validation_error") {
ensure!(
error.as_str().is_some_and(|e| !e.is_empty()) && rebuilt.is_err(),
"Valid aligned text must not be excluded"
);
excluded.push(json!({"asset":asset_id,"window_index":window_index,"offset_ms":offset,"duration_ms":duration,"eligible":false,"reason":error}));
continue;
}
let rebuilt = rebuilt?;
ensure!(
window["aligned_segments"] == json!(rebuilt),
"Normalized token passages differ from actual output"
);
rebuilt
} else {
ensure!(
window.get("aligned_segments").is_none()
&& window.get("alignment_validation_error").is_none(),
"Alignment without provenance"
);
actual
};
let title = Path::new(asset["path"].as_str().context("Missing source filename")?)
.file_name()
.context("Missing filename")?
@@ -319,6 +346,12 @@ fn main() -> Result<()> {
report["excluded_window_count"] = json!(excluded.len());
report["quality_score_eligible"] = json!(excluded.is_empty());
report["scope"] = json!("Diagnostic ASR segment text retrieval; all five sources compete, original filename titles, exact cosine, max across token windows, no labels in ranking. Source millisecond segment approximation, not word alignment or production integration.");
if alignment::enabled(&asr)? {
report["scope"] = json!("Diagnostic ordinary token-time sentence retrieval; all five sources compete, original exact recognized text, independently reconstructed approximate token intervals, no labels in ranking; not production integration.");
report["alignment_policy"] = json!(alignment::POLICY);
report["alignment_policy_sha256"] = json!(alignment::POLICY_SHA);
report["alignment_contract_sha256"] = json!(alignment::CONTRACT_SHA);
}
report["phase"] = json!("document_encoding");
checkpoint(&output, &report)?;
let start = Instant::now();
@@ -431,6 +464,39 @@ mod tests {
.is_err());
}
#[test]
fn aligned_pool_preserves_all_competitors_and_marks_real_failures_ineligible() {
let hash = "a".repeat(64);
let assets: Vec<_> = ASSETS
.iter()
.map(|id| json!({"id":id,"sha256":hash,"path":format!("{id}.wav")}))
.collect();
let raw = json!({"transcription":[{"text":" First. Second!","offsets":{"from":0,"to":1000},"tokens":[
{"id":100,"text":" First.","offsets":{"from":100,"to":400}},
{"id":101,"text":" Second!","offsets":{"from":600,"to":900}}]}]});
let rows:Vec<_> = ASSETS.iter().map(|id|json!({"asset":id,"source_sha256":hash,"audio_start_ms":1000,"audio_end_ms":2000,"duration_ms":1000,"windows":[{"offset_ms":1000,"duration_ms":1000,"decoded_frames":16000,"actual_whisper_json":raw,"segments":parsed_segments(&raw,1000,1000).unwrap(),"aligned_segments":alignment::reconstruct(&raw,1000,1000).unwrap()}]})).collect();
let mut report = json!({"version":1,"complete":true,"fixture_sha256":FIXTURE_SHA,"policy":POLICY,"backend":"forced CPU","threads":1,"upstream_commit":"d1be6fde11ac6e0407606b4e42fe72d34add8037","candidate":"base","model_sha256":"60ed5bc3dd14eea856493d334349b405782ddcaf0028d4b5df4088345fba2efe","worker_sha256":"12c681b4bcd9c7679b647b9a041e121a2f9e72cb2a9c6f189f529ec8b79c36f8","harness_sha256":hash,"ffmpeg_sha256":hash,"ffprobe_sha256":hash,"quality_failed":false,"validation_failures":[],"rows":rows,"alignment_policy":alignment::POLICY,"alignment_policy_sha256":alignment::POLICY_SHA,"alignment_contract_sha256":alignment::CONTRACT_SHA});
let fixture = json!({"assets":assets});
assert_eq!(eligible(&report, &fixture).unwrap().0.len(), 10);
let mut forged = report.clone();
forged["rows"][0]["windows"][0]["aligned_segments"][0]["start_ms"] = json!(1500);
assert!(eligible(&forged, &fixture).is_err());
let window = &mut report["rows"][0]["windows"][0];
window["actual_whisper_json"]["transcription"][0]["tokens"][0]
.as_object_mut()
.unwrap()
.remove("offsets");
window["alignment_validation_error"] = json!("Missing token time");
window.as_object_mut().unwrap().remove("aligned_segments");
report["quality_failed"] = json!(true);
report["validation_failures"] = json!([{"error":"Missing token time"}]);
let (pool, excluded) = eligible(&report, &fixture).unwrap();
assert_eq!(pool.len(), 8);
assert_eq!(excluded.len(), 1);
// Main derives quality_score_eligible solely from excluded.is_empty().
assert!(!excluded.is_empty());
}
#[test]
fn source_identity_coverage_and_recognized_text_cannot_be_forged() {
let hash = "a".repeat(64);