Files
local-transcriber/tests/test_streaming_sortformer_experiment.py
T
Dmitry Dementiev e71b2d1668 feat(experiment): добавлен gate принятия опоры владельцем
Зачем:
- не допустить загрузку W0 и Sortformer без отдельного принятия трёх референсов владельцем
- связать manifest с точными байтами listening package и owner-authored record

Что:
- добавлены строгие схемы трёх reference rows и четырёх решений Step 3
- все внешние файлы проверяются через held fd без symlink и TOCTOU
- добавлены negative tests для подмен, неточных JSON-типов и небезопасных путей

Проверка:
- uv run pytest -q (532 passed, 2 skipped)
- uv run ruff check src/local_transcriber/streaming_sortformer_experiment.py tests/test_streaming_sortformer_experiment.py
- git diff --check
2026-09-02 03:20:42 +03:00

2473 lines
84 KiB
Python

import copy
import ctypes
import hashlib
import json
import os
import tomllib
from datetime import UTC, datetime
from pathlib import Path
from types import SimpleNamespace
import numpy as np
import pytest
from local_transcriber import streaming_sortformer_experiment as experiment
def test_experiment_module_is_excluded_from_production_wheel():
project = tomllib.loads(
(Path(__file__).parents[1] / "pyproject.toml").read_text(encoding="utf-8")
)
excluded = project["tool"]["hatch"]["build"]["targets"]["wheel"]["exclude"]
assert "src/local_transcriber/streaming_sortformer_experiment.py" in excluded
def _write(root: Path, name: str, payload: bytes) -> dict[str, object]:
path = root / name
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(payload)
return {
"path": name,
"sha256": hashlib.sha256(payload).hexdigest(),
"size_bytes": len(payload),
}
def _write_json(root: Path, name: str, value: object) -> dict[str, object]:
return _write(
root,
name,
(json.dumps(value, ensure_ascii=True, sort_keys=True) + "\n").encode(),
)
def _record(
root: Path, prefix: str, *, duration: float, reference: bool
) -> dict[str, object]:
media = _write(root, f"media/{prefix}.wav", f"audio-{prefix}".encode())
sidecar = _write(root, f"sidecars/{prefix}.json", f"words-{prefix}".encode())
result = {
**media,
"duration_seconds": duration,
"sidecar_path": sidecar["path"],
"sidecar_sha256": sidecar["sha256"],
"expected_cluster_count": 2,
}
if reference:
reference_record = _write(
root, f"references/{prefix}.json", f"ref-{prefix}".encode()
)
result.update(
reference_path=reference_record["path"],
reference_sha256=reference_record["sha256"],
)
return result
def _manifest(root: Path) -> dict[str, object]:
inputs = []
for index in range(3):
source = _write(root, f"sources/{index}.wav", f"source-{index}".encode())
inputs.append(
{
"neutral_alias": f"control-{index + 1}",
"source_path": source["path"],
"source_sha256": source["sha256"],
"source_size_bytes": source["size_bytes"],
"fragment": _record(
root, f"fragment-{index}", duration=300.0, reference=True
),
"full_recording": _record(
root, f"full-{index}", duration=900.0, reference=False
),
}
)
package_generated_at = "2026-09-01T08:00:00+00:00"
package_rows = [
{
"neutral_alias": item["neutral_alias"],
"canonical_fragment_audio_sha256": item["fragment"]["sha256"],
"final_reference_sha256": item["fragment"]["reference_sha256"],
"full_recording_sha256": item["full_recording"]["sha256"],
}
for item in inputs
]
package = _write_json(
root,
"owner/listening-package.json",
{
"schema": "local-transcriber.owner-listening-package.v1",
"generated_at": package_generated_at,
"references": package_rows,
},
)
approval_timestamp = "2026-09-01T09:00:00+00:00"
acceptance = {
"schema": "local-transcriber.reference-owner-acceptance.v1",
"actor": "owner",
"status": "approved",
"decision": "approved",
"timestamp": approval_timestamp,
"owner_package_sha256": package["sha256"],
"references": [
{
**package_row,
"fragment_expected_cluster_count": item["fragment"][
"expected_cluster_count"
],
"full_recording_expected_cluster_count": item["full_recording"][
"expected_cluster_count"
],
"fragment_review_complete": True,
"full_recording_count_review_complete": True,
"reference_accepted": True,
}
for item, package_row in zip(inputs, package_rows, strict=True)
],
"step3": {
"recording_use_approved": True,
"inputs_and_counts_approved": True,
"full_recordings_available": True,
"final_hearing_gate_committed": True,
},
}
acceptance_file = _write_json(
root, "owner/reference-acceptance.json", acceptance
)
return {
"schema": "local-transcriber.streaming-sortformer-experiment.v1",
"fresh_basis": {
"marker": "issue-46-fresh-owner-reviewed-basis",
"owner_package": {
"path": package["path"],
"sha256": package["sha256"],
"generated_at": package_generated_at,
},
"approval": {
"path": acceptance_file["path"],
"sha256": acceptance_file["sha256"],
"actor": "owner",
"status": "approved",
"decision": "approved",
"timestamp": approval_timestamp,
},
},
"source": {"commit": "a" * 40},
"machine": _machine(),
"inputs": inputs,
"recipes": _recipes(),
"schedule": experiment.build_fragment_schedule(
[item["fragment"]["sha256"] for item in inputs],
[item["fragment"]["sidecar_sha256"] for item in inputs],
),
"rss_sample_interval_ms": 10,
}
def _machine() -> dict[str, object]:
return {
"machine_sha256": "1" * 64,
"physical_cores": 8,
"logical_cores": 16,
"affinity": list(range(8)),
"cpuid_isa_sha256": "2" * 64,
"ram_bytes": 16 * 1024**3,
"os_sha256": "3" * 64,
"compiler_sha256": "4" * 64,
"runtime_versions_sha256": "5" * 64,
"power_mode": "balanced",
"governor": "powersave",
"turbo": True,
}
def _recipes() -> dict[str, object]:
return {
"W0-FRESH": {
"sherpa_onnx_version": "1.13.6",
"sherpa_onnx_core_version": "1.13.6",
"segmentation_model_sha256": "220ad67ca923bef2fa91f2390c786097bf305bceb5e261d4af67b38e938e1079",
"embedding_model_sha256": "e9848563da86f263117134dfd7ad63c92355b37de492b55e325400c9d9c39012",
"window_shift_ratio": 0.1,
"clustering": {
"algorithm": "FastClustering",
"mode": "auto",
"threshold": 0.89,
},
"segmentation_provider": "cpu",
"embedding_provider": "cpu",
"segmentation_debug": True,
"embedding_debug": True,
"min_duration_on": 0.3,
"min_duration_off": 0.5,
"workers": 1,
"sessions": 1,
"intra_op_threads": 8,
"inter_op_threads": 1,
"batch_size": 1,
"process_variant": "upstream-unpatched",
},
"SORTFORMER-V2-Q8": {
"runtime_repo": "NVIDIA/NeMo-Speech.cpp",
"runtime_commit": "4f9676226f667d14608487df744f375db87127f8",
"runtime_license": "Apache-2.0",
"model_repo": "nvidia/diar_streaming_sortformer_4spk-v2",
"model_revision": "5240a64075176943f677d30fa2171c780229f341",
"model_name": "diar_streaming_sortformer_4spk-v2.q8_0.gguf",
"model_size_bytes": 147075776,
"model_sha256": "0679cfeb1ce356d0dea9470b31274f4bfc7eb927497d82005483770666da998a",
"model_license": "CC-BY-4.0",
"quantization": "Q8_0",
"preset": "cpu-diar",
"diarization_preset": "streaming",
"backend": "cpu",
"gpu": -1,
"processes": 1,
"streams": 1,
"internal_cpu_threads": 4,
"submodule_command": "git submodule update --init ggml",
"configure_command": "scripts/configure.sh cpu-diar",
"build_command": "cmake --build --preset cpu-diar",
"cmake_options": {
"build_type": "Release",
"generator": "Ninja",
"diarization_only": True,
"patched_ggml": False,
},
"geometry": {
"chunk_frames": 340,
"right_context_frames": 40,
"left_context_frames": 0,
"fifo_frames": 40,
"spkcache_frames": 188,
"update_period_frames": 300,
},
"post_processing": {
"onset": 0.641,
"offset": 0.561,
"pad_onset_sec": 0.229,
"pad_offset_sec": 0.079,
"min_duration_sec": 0.511,
"min_gap_sec": 0.296,
},
"num_speakers": 4,
"seconds_per_frame": 0.08,
"submodule_commits": {"ggml": "6" * 40},
"compiler": "pinned-compiler",
"cmake_version": "pinned-cmake",
"executable_sha256": "7" * 64,
"library_sha256": "8" * 64,
},
}
def _environment() -> dict[str, object]:
return {"commit": "a" * 40, "clean": True}
def _read_linked_json(root: Path, link: dict[str, object]) -> dict[str, object]:
return json.loads((root / str(link["path"])).read_text(encoding="utf-8"))
def _rewrite_linked_json(
root: Path, link: dict[str, object], value: object
) -> None:
payload = (json.dumps(value, ensure_ascii=True, sort_keys=True) + "\n").encode()
(root / str(link["path"])).write_bytes(payload)
link["sha256"] = hashlib.sha256(payload).hexdigest()
def _rewrite_linked_bytes(
root: Path, link: dict[str, object], payload: bytes
) -> None:
(root / str(link["path"])).write_bytes(payload)
link["sha256"] = hashlib.sha256(payload).hexdigest()
def _media_path(manifest: dict[str, object], binding: str) -> str:
item = manifest["inputs"][0]
paths = {
"source": item["source_path"],
"fragment": item["fragment"]["path"],
"fragment-sidecar": item["fragment"]["sidecar_path"],
"reference": item["fragment"]["reference_path"],
"full-recording": item["full_recording"]["path"],
"full-sidecar": item["full_recording"]["sidecar_path"],
}
return str(paths[binding])
def _set_binding_path(
manifest: dict[str, object], binding: str, value: str
) -> None:
if binding in {"owner-package", "owner-acceptance"}:
link = "owner_package" if binding == "owner-package" else "approval"
manifest["fresh_basis"][link]["path"] = value
return
item = manifest["inputs"][0]
if binding == "source":
item["source_path"] = value
elif binding == "fragment":
item["fragment"]["path"] = value
elif binding == "fragment-sidecar":
item["fragment"]["sidecar_path"] = value
elif binding == "reference":
item["fragment"]["reference_path"] = value
elif binding == "full-recording":
item["full_recording"]["path"] = value
elif binding == "full-sidecar":
item["full_recording"]["sidecar_path"] = value
else:
raise AssertionError(f"unknown binding: {binding}")
def _mutate_owner_acceptance(
manifest: dict[str, object], root: Path, case: str
) -> None:
basis = manifest["fresh_basis"]
approval_link = basis["approval"]
package_link = basis["owner_package"]
acceptance = _read_linked_json(root, approval_link)
package = _read_linked_json(root, package_link)
def write_acceptance() -> None:
_rewrite_linked_json(root, approval_link, acceptance)
def write_package(*, sync_acceptance: bool = True) -> None:
_rewrite_linked_json(root, package_link, package)
if sync_acceptance:
acceptance["owner_package_sha256"] = package_link["sha256"]
write_acceptance()
if case == "approval-missing":
del basis["approval"]
elif case == "approval-null":
basis["approval"] = None
elif case == "approval-link-unknown":
approval_link["count_review_status"] = "approved"
elif case == "record-missing":
(root / str(approval_link["path"])).unlink()
elif case == "record-path-missing":
approval_link["path"] = "owner/missing-acceptance.json"
elif case == "record-hash-mismatch":
approval_link["sha256"] = "f" * 64
elif case == "record-json-invalid":
payload = b"{\n"
(root / str(approval_link["path"])).write_bytes(payload)
approval_link["sha256"] = hashlib.sha256(payload).hexdigest()
elif case == "record-unknown-key":
acceptance["count_review_status"] = "approved"
write_acceptance()
elif case == "record-count-review-schema":
acceptance = {
"schema": "local-transcriber.reference-count-review.v1",
"status": "approved",
}
write_acceptance()
elif case in {"actor", "status", "decision"}:
replacement = {
"actor": "automation",
"status": "draft",
"decision": "rejected",
}[case]
approval_link[case] = replacement
acceptance[case] = replacement
write_acceptance()
elif case == "timestamp-naive":
approval_link["timestamp"] = "2026-09-01T09:00:00"
acceptance["timestamp"] = approval_link["timestamp"]
write_acceptance()
elif case == "timestamp-early":
approval_link["timestamp"] = package_link["generated_at"]
acceptance["timestamp"] = approval_link["timestamp"]
write_acceptance()
elif case == "timestamp-link-mismatch":
acceptance["timestamp"] = "2026-09-01T10:00:00+00:00"
write_acceptance()
elif case == "package-missing":
del basis["owner_package"]
elif case == "package-link-unknown":
package_link["status"] = "approved"
elif case == "package-file-missing":
(root / str(package_link["path"])).unlink()
elif case == "package-hash-mismatch":
package_link["sha256"] = "e" * 64
elif case == "package-timestamp-mismatch":
package_link["generated_at"] = "2026-09-01T07:00:00+00:00"
elif case == "package-unknown-key":
package["status"] = "approved"
write_package()
elif case == "package-row-binding":
package["references"][0]["final_reference_sha256"] = "d" * 64
write_package()
elif case == "package-row-omitted":
package["references"].pop()
write_package()
elif case == "package-row-duplicate":
package["references"][2] = copy.deepcopy(package["references"][1])
write_package()
elif case == "acceptance-row-omitted":
acceptance["references"].pop()
write_acceptance()
elif case == "acceptance-row-duplicate":
acceptance["references"][2] = copy.deepcopy(acceptance["references"][1])
write_acceptance()
elif case in {
"neutral_alias",
"canonical_fragment_audio_sha256",
"final_reference_sha256",
"full_recording_sha256",
}:
acceptance["references"][0][case] = (
"different-control" if case == "neutral_alias" else "c" * 64
)
write_acceptance()
elif case in {
"fragment_expected_cluster_count",
"full_recording_expected_cluster_count",
}:
acceptance["references"][0][case] = 4
write_acceptance()
elif case == "fragment-count-float":
acceptance["references"][0]["fragment_expected_cluster_count"] = 2.0
write_acceptance()
elif case == "fragment-count-bool":
acceptance["references"][0]["fragment_expected_cluster_count"] = True
write_acceptance()
elif case == "fragment-count-string":
acceptance["references"][0]["fragment_expected_cluster_count"] = "2"
write_acceptance()
elif case == "full-count-float":
acceptance["references"][0][
"full_recording_expected_cluster_count"
] = 2.0
write_acceptance()
elif case == "package-alias-type":
package["references"][0]["neutral_alias"] = 1
write_package()
elif case == "package-hash-type":
package["references"][0]["canonical_fragment_audio_sha256"] = 1
write_package()
elif case == "acceptance-hash-type":
acceptance["references"][0]["canonical_fragment_audio_sha256"] = 1
write_acceptance()
elif case in {
"fragment_review_complete",
"full_recording_count_review_complete",
"reference_accepted",
}:
acceptance["references"][0][case] = False
write_acceptance()
elif case == "fragment-review-int":
acceptance["references"][0]["fragment_review_complete"] = 1
write_acceptance()
elif case == "full-review-int":
acceptance["references"][0][
"full_recording_count_review_complete"
] = 1
write_acceptance()
elif case == "reference-accepted-int":
acceptance["references"][0]["reference_accepted"] = 1
write_acceptance()
elif case == "acceptance-row-unknown":
acceptance["references"][0]["status"] = "approved"
write_acceptance()
elif case == "owner-package-binding":
acceptance["owner_package_sha256"] = "b" * 64
write_acceptance()
elif case == "step3-int":
acceptance["step3"]["recording_use_approved"] = 1
write_acceptance()
elif case.startswith("step3-"):
acceptance["step3"][case.removeprefix("step3-")] = False
write_acceptance()
elif case == "step3-missing":
del acceptance["step3"]["recording_use_approved"]
write_acceptance()
elif case == "step3-unknown":
acceptance["step3"]["count_review_approved"] = True
write_acceptance()
else:
raise AssertionError(f"unknown case: {case}")
def test_preflight_validates_fresh_exact_schema_before_loading(tmp_path):
manifest = _manifest(tmp_path)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
validate_only=True,
)
assert outcome.state == "valid"
assert outcome.fragment_count == 3
assert outcome.full_recording_count == 3
assert calls == []
def test_complete_reference_owner_acceptance_is_required_before_loading(tmp_path):
manifest = _manifest(tmp_path)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert outcome.state == "valid"
assert calls == ["w0", "candidate"]
@pytest.mark.parametrize(
"case",
[
"approval-missing",
"approval-null",
"approval-link-unknown",
"record-missing",
"record-path-missing",
"record-hash-mismatch",
"record-json-invalid",
"record-unknown-key",
"record-count-review-schema",
"actor",
"status",
"decision",
"timestamp-naive",
"timestamp-early",
"timestamp-link-mismatch",
"package-missing",
"package-link-unknown",
"package-file-missing",
"package-hash-mismatch",
"package-timestamp-mismatch",
"package-unknown-key",
"package-row-binding",
"package-row-omitted",
"package-row-duplicate",
"acceptance-row-omitted",
"acceptance-row-duplicate",
"neutral_alias",
"canonical_fragment_audio_sha256",
"final_reference_sha256",
"full_recording_sha256",
"fragment_expected_cluster_count",
"full_recording_expected_cluster_count",
"fragment-count-float",
"fragment-count-bool",
"fragment-count-string",
"full-count-float",
"package-alias-type",
"package-hash-type",
"acceptance-hash-type",
"fragment_review_complete",
"full_recording_count_review_complete",
"reference_accepted",
"fragment-review-int",
"full-review-int",
"reference-accepted-int",
"acceptance-row-unknown",
"owner-package-binding",
"step3-recording_use_approved",
"step3-inputs_and_counts_approved",
"step3-full_recordings_available",
"step3-final_hearing_gate_committed",
"step3-int",
"step3-missing",
"step3-unknown",
],
)
def test_reference_owner_acceptance_failures_need_user_before_loaders(
tmp_path, case
):
manifest = _manifest(tmp_path)
_mutate_owner_acceptance(manifest, tmp_path, case)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
assert calls == []
@pytest.mark.parametrize(
("record", "original", "replacement"),
[
(
"approval",
b'"status": "approved"',
b'"status": "draft", "status": "approved"',
),
(
"approval",
b'"reference_accepted": true',
b'"reference_accepted": false, "reference_accepted": true',
),
(
"approval",
b'"recording_use_approved": true',
b'"recording_use_approved": false, "recording_use_approved": true',
),
(
"owner_package",
b'"neutral_alias": "control-1"',
b'"neutral_alias": "other", "neutral_alias": "control-1"',
),
(
"approval",
b'"fragment_expected_cluster_count": 2',
b'"fragment_expected_cluster_count": NaN',
),
],
)
def test_bound_owner_json_rejects_ambiguous_json_before_loaders(
tmp_path, record, original, replacement
):
manifest = _manifest(tmp_path)
link = manifest["fresh_basis"][record]
path = tmp_path / str(link["path"])
payload = path.read_bytes().replace(original, replacement, 1)
assert payload != path.read_bytes()
_rewrite_linked_bytes(tmp_path, link, payload)
if record == "owner_package":
acceptance_link = manifest["fresh_basis"]["approval"]
acceptance = _read_linked_json(tmp_path, acceptance_link)
acceptance["owner_package_sha256"] = link["sha256"]
_rewrite_linked_json(tmp_path, acceptance_link, acceptance)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
assert calls == []
@pytest.mark.parametrize("symlink_kind", ["final", "intermediate"])
def test_bound_owner_json_rejects_symlinks_before_loaders(
tmp_path, symlink_kind
):
manifest = _manifest(tmp_path)
if symlink_kind == "final":
link = manifest["fresh_basis"]["approval"]
path = tmp_path / str(link["path"])
target = path.with_name("acceptance-target.json")
path.rename(target)
path.symlink_to(target.name)
else:
owner = tmp_path / "owner"
target = tmp_path / "owner-target"
owner.rename(target)
owner.symlink_to(target.name, target_is_directory=True)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
assert calls == []
def test_bound_owner_json_cannot_hash_one_version_and_parse_another(
tmp_path, monkeypatch
):
manifest = _manifest(tmp_path)
link = manifest["fresh_basis"]["approval"]
path = tmp_path / str(link["path"])
approved_payload = path.read_bytes()
rejected_payload = approved_payload.replace(
b'"status": "approved"', b'"status": "draft"', 1
)
path.write_bytes(rejected_payload)
link["sha256"] = hashlib.sha256(rejected_payload).hexdigest()
original_file_sha256 = experiment.file_sha256
replaced = False
def replace_after_hash(candidate):
nonlocal replaced
digest = original_file_sha256(candidate)
if candidate == path and not replaced:
path.write_bytes(approved_payload)
replaced = True
return digest
monkeypatch.setattr(experiment, "file_sha256", replace_after_hash)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
assert calls == []
def test_bound_owner_json_rejects_path_replacement_during_held_read(
tmp_path, monkeypatch
):
manifest = _manifest(tmp_path)
link = manifest["fresh_basis"]["approval"]
path = tmp_path / str(link["path"])
target_inode = path.stat().st_ino
replacement = path.with_name("replacement.json")
payload = path.read_bytes()
original_read = os.read
replaced = False
def replace_path_after_read(file_descriptor, count):
nonlocal replaced
chunk = original_read(file_descriptor, count)
if os.fstat(file_descriptor).st_ino == target_inode and not replaced:
replacement.write_bytes(payload)
os.replace(replacement, path)
replaced = True
return chunk
monkeypatch.setattr(experiment.os, "read", replace_path_after_read)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert replaced is True
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
assert calls == []
def test_bound_owner_json_rejects_in_place_mutation_during_held_read(
tmp_path, monkeypatch
):
manifest = _manifest(tmp_path)
link = manifest["fresh_basis"]["approval"]
path = tmp_path / str(link["path"])
json_size = len(path.read_bytes().rstrip(b"\n"))
payload = path.read_bytes().rstrip(b"\n") + (b" " * 70_000) + b"\n"
_rewrite_linked_bytes(tmp_path, link, payload)
target_inode = path.stat().st_ino
original_read = os.read
mutated = False
def mutate_after_first_chunk(file_descriptor, count):
nonlocal mutated
chunk = original_read(file_descriptor, count)
if os.fstat(file_descriptor).st_ino == target_inode and not mutated:
writer = os.open(path, os.O_WRONLY)
try:
os.pwrite(writer, b"\t", json_size + 66_000)
os.fsync(writer)
finally:
os.close(writer)
mutated = True
return chunk
monkeypatch.setattr(experiment.os, "read", mutate_after_first_chunk)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert mutated is True
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
assert calls == []
def test_bound_owner_json_rejects_intermediate_directory_swap_during_read(
tmp_path, monkeypatch
):
manifest = _manifest(tmp_path)
link = manifest["fresh_basis"]["owner_package"]
path = tmp_path / str(link["path"])
target_inode = path.stat().st_ino
parent = path.parent
moved_parent = parent.with_name("owner-original")
original_read = os.read
swapped = False
def swap_directory_after_read(file_descriptor, count):
nonlocal swapped
chunk = original_read(file_descriptor, count)
if os.fstat(file_descriptor).st_ino == target_inode and not swapped:
parent.rename(moved_parent)
parent.mkdir()
(parent / path.name).write_bytes(b"{}\n")
swapped = True
return chunk
monkeypatch.setattr(experiment.os, "read", swap_directory_after_read)
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert swapped is True
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
assert calls == []
@pytest.mark.parametrize(
"binding",
[
"source",
"fragment",
"fragment-sidecar",
"reference",
"full-recording",
"full-sidecar",
],
)
@pytest.mark.parametrize("symlink_kind", ["final", "intermediate"])
def test_manifest_file_bindings_reject_internal_symlinks_before_loaders(
tmp_path, binding, symlink_kind
):
manifest = _manifest(tmp_path)
path = tmp_path / _media_path(manifest, binding)
if symlink_kind == "final":
target = path.with_name(f"{path.name}.target")
path.rename(target)
path.symlink_to(target.name)
else:
parent = path.parent
target = parent.with_name(f"{parent.name}-target")
parent.rename(target)
parent.symlink_to(target.name, target_is_directory=True)
calls = []
with pytest.raises(experiment.PreflightError) as raised:
experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert str(tmp_path) not in str(raised.value)
assert calls == []
def test_manifest_file_binding_rejects_final_replacement_during_read(
tmp_path, monkeypatch
):
manifest = _manifest(tmp_path)
path = tmp_path / _media_path(manifest, "fragment")
target_inode = path.stat().st_ino
replacement = path.with_name("replacement.wav")
original_read = os.read
replaced = False
def replace_path_after_read(file_descriptor, count):
nonlocal replaced
chunk = original_read(file_descriptor, count)
if os.fstat(file_descriptor).st_ino == target_inode and not replaced:
replacement.write_bytes(b"different-fragment-bytes")
os.replace(replacement, path)
replaced = True
return chunk
monkeypatch.setattr(experiment.os, "read", replace_path_after_read)
calls = []
with pytest.raises(experiment.PreflightError):
experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert replaced is True
assert path.read_bytes() == b"different-fragment-bytes"
assert hashlib.sha256(path.read_bytes()).hexdigest() != manifest["inputs"][0][
"fragment"
]["sha256"]
assert calls == []
def test_manifest_file_binding_rejects_intermediate_directory_swap_during_read(
tmp_path, monkeypatch
):
manifest = _manifest(tmp_path)
path = tmp_path / _media_path(manifest, "fragment")
target_inode = path.stat().st_ino
parent = path.parent
moved_parent = parent.with_name("media-original")
original_read = os.read
swapped = False
def swap_directory_after_read(file_descriptor, count):
nonlocal swapped
chunk = original_read(file_descriptor, count)
if os.fstat(file_descriptor).st_ino == target_inode and not swapped:
parent.rename(moved_parent)
parent.mkdir()
(parent / path.name).write_bytes(b"replacement-fragment")
swapped = True
return chunk
monkeypatch.setattr(experiment.os, "read", swap_directory_after_read)
calls = []
with pytest.raises(experiment.PreflightError):
experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert swapped is True
assert calls == []
def test_manifest_file_binding_rejects_in_place_mutation_during_read(
tmp_path, monkeypatch
):
manifest = _manifest(tmp_path)
path = tmp_path / _media_path(manifest, "fragment")
target_inode = path.stat().st_ino
original_read = os.read
mutated = False
def mutate_file_after_read(file_descriptor, count):
nonlocal mutated
chunk = original_read(file_descriptor, count)
if os.fstat(file_descriptor).st_ino == target_inode and not mutated:
path.write_bytes(b"mutated-fragment-with-different-size")
mutated = True
return chunk
monkeypatch.setattr(experiment.os, "read", mutate_file_after_read)
calls = []
with pytest.raises(experiment.PreflightError):
experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert mutated is True
assert calls == []
def test_bound_file_verification_closes_descriptors_on_success_and_failure(
tmp_path
):
proc_fds = Path("/proc/self/fd")
if not proc_fds.is_dir():
pytest.skip("fd accounting requires procfs")
manifest = _manifest(tmp_path)
before_success = len(list(proc_fds.iterdir()))
for _ in range(20):
assert experiment.validate_manifest(
manifest, root=tmp_path, environment=_environment()
).state == "valid"
assert len(list(proc_fds.iterdir())) == before_success
failed_root = tmp_path / "failed"
failed_manifest = _manifest(failed_root)
path = failed_root / _media_path(failed_manifest, "fragment")
target = path.with_name("fragment-target.wav")
path.rename(target)
path.symlink_to(target.name)
before_failure = len(list(proc_fds.iterdir()))
for _ in range(20):
with pytest.raises(experiment.PreflightError):
experiment.validate_manifest(
failed_manifest,
root=failed_root,
environment=_environment(),
)
assert len(list(proc_fds.iterdir())) == before_failure
@pytest.mark.parametrize(
"binding",
[
"source",
"fragment",
"fragment-sidecar",
"reference",
"full-recording",
"full-sidecar",
"owner-package",
"owner-acceptance",
],
)
def test_manifest_file_bindings_reject_nul_paths_before_loaders(
tmp_path, binding
):
manifest = _manifest(tmp_path)
_set_binding_path(manifest, binding, "private\x00binding")
calls = []
if binding.startswith("owner-"):
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
else:
with pytest.raises(experiment.PreflightError, match="path-escape"):
experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert calls == []
def test_manifest_file_binding_redacts_path_layer_value_error(
tmp_path, monkeypatch
):
manifest = _manifest(tmp_path)
original_open = os.open
def reject_component(path, flags, *, dir_fd=None):
if path == "sources":
raise ValueError("private path detail")
if dir_fd is None:
return original_open(path, flags)
return original_open(path, flags, dir_fd=dir_fd)
monkeypatch.setattr(experiment.os, "open", reject_component)
calls = []
with pytest.raises(experiment.PreflightError) as raised:
experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert str(raised.value) == "path-escape"
assert "private" not in str(raised.value)
assert calls == []
def test_missing_owner_approval_is_needs_user_and_never_loads(tmp_path):
manifest = _manifest(tmp_path)
manifest["fresh_basis"]["approval"] = None
calls = []
outcome = experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert outcome.state == "needs-user"
assert outcome.reason == "reference-owner-acceptance"
assert calls == []
@pytest.mark.parametrize(
"mutation",
[
lambda value: value.update(schema="3"),
lambda value: value.update(legacy_manifest="issue-41"),
lambda value: value["inputs"].__setitem__(
1,
{**value["inputs"][1], "source_sha256": value["inputs"][0]["source_sha256"]},
),
lambda value: value["inputs"][0]["fragment"].update(duration_seconds=299.9),
lambda value: value["inputs"][0]["full_recording"].update(
expected_cluster_count=5
),
lambda value: value["inputs"][0].update(neutral_alias=""),
lambda value: value["inputs"][1].update(
neutral_alias=value["inputs"][0]["neutral_alias"]
),
lambda value: value["source"].update(commit="b" * 40),
],
)
def test_preflight_rejects_schema_basis_counts_and_source_before_load(
tmp_path, mutation
):
manifest = _manifest(tmp_path)
mutation(manifest)
calls = []
with pytest.raises(experiment.PreflightError):
experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert calls == []
def test_preflight_rejects_hash_path_and_symlink_escape_without_leaking_path(tmp_path):
manifest = _manifest(tmp_path)
manifest["inputs"][0]["fragment"]["sha256"] = "f" * 64
calls = []
with pytest.raises(experiment.PreflightError) as raised:
experiment.preflight_and_load(
manifest,
root=tmp_path,
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
assert str(tmp_path) not in str(raised.value)
assert calls == []
outside = tmp_path.parent / f"outside-{datetime.now(UTC).timestamp()}"
outside.mkdir()
(outside / "escape.wav").write_bytes(b"escape")
(tmp_path / "link").symlink_to(outside, target_is_directory=True)
manifest = _manifest(tmp_path)
manifest["inputs"][0]["fragment"]["path"] = "link/escape.wav"
with pytest.raises(experiment.PreflightError, match="path-escape"):
experiment.validate_manifest(manifest, root=tmp_path, environment=_environment())
def test_preflight_rejects_legacy_cell_names_roots_and_recipe_pin_mismatch(tmp_path):
manifest = _manifest(tmp_path)
manifest["schedule"][0]["semantic_id"] = "41-W0"
with pytest.raises(experiment.PreflightError, match="legacy-identity"):
experiment.validate_manifest(manifest, root=tmp_path, environment=_environment())
manifest = _manifest(tmp_path)
manifest["schedule"][0]["semantic_id"] = "W0-FRESH"
with pytest.raises(experiment.PreflightError, match="schedule-mismatch"):
experiment.validate_manifest(manifest, root=tmp_path, environment=_environment())
manifest = _manifest(tmp_path)
manifest["inputs"][0]["fragment"]["path"] = "issue-42-store/audio.wav"
with pytest.raises(experiment.PreflightError, match="legacy-root"):
experiment.validate_manifest(manifest, root=tmp_path, environment=_environment())
manifest = _manifest(tmp_path)
manifest["recipes"]["W0-FRESH"]["intra_op_threads"] = 4
with pytest.raises(experiment.PreflightError, match="w0-pin-mismatch"):
experiment.validate_manifest(manifest, root=tmp_path, environment=_environment())
manifest = _manifest(tmp_path)
manifest["recipes"]["SORTFORMER-V2-Q8"]["geometry"]["chunk_frames"] = 320
with pytest.raises(experiment.PreflightError, match="candidate-pin-mismatch"):
experiment.validate_manifest(manifest, root=tmp_path, environment=_environment())
manifest = _manifest(tmp_path)
manifest["recipes"]["SORTFORMER-V2-Q8"]["submodule_commits"]["extra"] = "9" * 40
with pytest.raises(experiment.PreflightError, match="candidate-build-provenance"):
experiment.validate_manifest(manifest, root=tmp_path, environment=_environment())
def test_schedule_has_exact_primary_five_final_and_three_gated_full_pairs(tmp_path):
manifest = _manifest(tmp_path)
schedule = manifest["schedule"]
assert [(cell["pair_id"], cell["recipe"]) for cell in schedule] == [
("primary", "W0-FRESH"),
("primary", "SORTFORMER-V2-Q8"),
("final-1", "SORTFORMER-V2-Q8"),
("final-1", "W0-FRESH"),
("final-2", "W0-FRESH"),
("final-2", "SORTFORMER-V2-Q8"),
("final-3", "SORTFORMER-V2-Q8"),
("final-3", "W0-FRESH"),
("final-4", "W0-FRESH"),
("final-4", "SORTFORMER-V2-Q8"),
("final-5", "SORTFORMER-V2-Q8"),
("final-5", "W0-FRESH"),
]
assert len({cell["semantic_id"] for cell in schedule}) == 12
assert all(cell["fresh_process"] for cell in schedule)
for left, right in zip(schedule[::2], schedule[1::2], strict=True):
assert left["input_sha256"] == right["input_sha256"]
assert left["sidecar_sha256"] == right["sidecar_sha256"]
full_hashes = [item["full_recording"]["sha256"] for item in manifest["inputs"]]
sidecars = [
item["full_recording"]["sidecar_sha256"] for item in manifest["inputs"]
]
assert experiment.build_full_recording_schedule(
full_hashes,
sidecars,
final_median_speedup_percent=29.999,
experiment_state=None,
) == []
full = experiment.build_full_recording_schedule(
full_hashes,
sidecars,
final_median_speedup_percent=30.0,
experiment_state=None,
)
assert len(full) == 6
assert [cell["pair_id"] for cell in full] == [
"full-1", "full-1", "full-2", "full-2", "full-3", "full-3"
]
def test_fragment_state_machine_applies_primary_stop_before_final_cells(tmp_path):
manifest = _manifest(tmp_path)
store = experiment.ExperimentState(tmp_path / "primary-stop.json")
calls = []
def runner(cell):
calls.append(cell["pair_id"])
walls = [10.0, 10.0, 10.0]
if cell["recipe"] == "SORTFORMER-V2-Q8":
walls = [9.7, 9.7, 9.7]
return {"mandatory_passed": True, "input_wall_seconds": walls}
result = experiment.run_fragment_state_machine(
manifest, runner=runner, store=store
)
assert result["state"] == "stop"
assert result["first_reason"] == "equal-speed"
assert calls == ["primary", "primary"]
with pytest.raises(experiment.PreflightError, match="already-stopped"):
experiment.build_full_recording_schedule(
[item["full_recording"]["sha256"] for item in manifest["inputs"]],
[
item["full_recording"]["sidecar_sha256"]
for item in manifest["inputs"]
],
final_median_speedup_percent=40.0,
experiment_state=store.current,
)
def test_fragment_state_machine_aggregates_three_walls_and_opens_full_stage(tmp_path):
manifest = _manifest(tmp_path)
store = experiment.ExperimentState(tmp_path / "full-open.json")
calls = []
def runner(cell):
calls.append((cell["pair_id"], cell["recipe"]))
wall = 10.0 if cell["recipe"] == "W0-FRESH" else 6.0
return {
"mandatory_passed": True,
"input_wall_seconds": [wall, wall, wall],
}
result = experiment.run_fragment_state_machine(
manifest, runner=runner, store=store
)
assert len(calls) == 12
assert result["state"] == "full-recordings"
assert result["median_speedup_percent"] == pytest.approx(40.0)
assert len(result["full_schedule"]) == 6
@pytest.mark.parametrize(
("speedup", "state", "reason"),
[
(-5.0, "stop", "equal-speed"),
(5.0, "stop", "equal-speed"),
(5.0001, "stop", "below-continuation"),
(9.9999, "stop", "below-continuation"),
(10.0, "continue", None),
],
)
def test_primary_decision_preserves_five_and_ten_percent_boundaries(
speedup, state, reason
):
assert experiment.primary_decision(speedup, mandatory_gates_passed=True) == {
"state": state,
"reason": reason,
}
def test_final_statistics_use_exactly_five_values_and_thirty_percent_boundary():
values = [28.0, 29.0, 30.0, 31.0, 80.0]
assert experiment.final_statistics(values) == {
"median_speedup_percent": 30.0,
"mad_percentage_points": 1.0,
}
assert experiment.final_decision([28.0, 29.0, 29.999, 31.0, 80.0]) == {
"state": "stop",
"reason": "below-final-threshold",
"median_speedup_percent": 29.999,
"mad_percentage_points": pytest.approx(1.001),
}
assert experiment.final_decision(values)["state"] == "full-recordings"
with pytest.raises(ValueError, match="five-final-speedups"):
experiment.final_statistics([30.0] * 4)
def test_first_stop_is_atomic_and_later_cells_are_not_scheduled(tmp_path):
store = experiment.ExperimentState(tmp_path / "public-state.json")
calls = []
cells = [
{"semantic_id": "cell-a", "recipe": "W0-FRESH"},
{"semantic_id": "cell-b", "recipe": "SORTFORMER-V2-Q8"},
{"semantic_id": "cell-c", "recipe": "W0-FRESH"},
]
state = experiment.execute_until_stop(
cells,
lambda cell: calls.append(cell["semantic_id"])
or ({"mandatory_passed": cell["semantic_id"] != "cell-b"}),
store=store,
)
assert calls == ["cell-a", "cell-b"]
assert state["state"] == "stop"
assert state["first_reason"] == "mandatory-gate-failed"
assert experiment.SHA256_RE.fullmatch(state["result_sha256"])
persisted = json.loads((tmp_path / "public-state.json").read_text())
assert persisted == state
assert store.stop("later-reason", {"ignored": True}) == state
reloaded = experiment.ExperimentState(tmp_path / "public-state.json")
assert reloaded.stop("process-restarted", {"ignored": "again"}) == state
def _word(start, end, text, speaker):
return {"start": start, "end": end, "text": text, "speaker": speaker}
def _sidecar_word(start, end, text):
return {"start": start, "end": end, "text": text}
def test_quality_gate_checks_text_order_intervals_counts_and_canonical_labels():
sidecar = [
_sidecar_word(0.0, 0.5, "один"),
_sidecar_word(0.5, 1.0, "два"),
]
output = [_word(0.0, 0.5, "один", 9), _word(0.5, 1.0, "два", 4)]
intervals = [
{"start": 0.0, "end": 0.5, "speaker": 9},
{"start": 0.5, "end": 1.0, "speaker": 4},
]
verdict = experiment.quality_gate(
expected_cluster_count=2,
observed_cluster_count=2,
sidecar_words=sidecar,
output_words=output,
intervals=intervals,
audio_duration_seconds=1.0,
permitted_padding_seconds=0.0,
)
assert verdict == {"passed": True, "reason": None, "canonical_labels": [1, 2]}
reordered = [output[1], output[0]]
assert experiment.quality_gate(
expected_cluster_count=2,
observed_cluster_count=2,
sidecar_words=sidecar,
output_words=reordered,
intervals=intervals,
audio_duration_seconds=1.0,
permitted_padding_seconds=0.0,
)["reason"] == "word-order-mismatch"
invalid = copy.deepcopy(intervals)
invalid[1]["start"] = float("nan")
assert experiment.quality_gate(
expected_cluster_count=2,
observed_cluster_count=2,
sidecar_words=sidecar,
output_words=output,
intervals=invalid,
audio_duration_seconds=1.0,
permitted_padding_seconds=0.0,
)["reason"] == "invalid-intervals"
def test_quality_gate_normalizes_text_and_canonicalizes_tied_intervals():
sidecar = [
_sidecar_word(0.0, 0.5, " один "),
_sidecar_word(0.5, 1.0, " два "),
]
output = [_word(0.0, 0.5, "один", "z"), _word(0.5, 1.0, "два", "a")]
intervals = [
{"start": 0.0, "end": 0.5, "speaker": "z"},
{"start": 0.0, "end": 1.0, "speaker": "a"},
]
first = experiment.quality_gate(
expected_cluster_count=2,
observed_cluster_count=2,
sidecar_words=sidecar,
output_words=output,
intervals=intervals,
audio_duration_seconds=1.0,
permitted_padding_seconds=0.0,
)
second = experiment.quality_gate(
expected_cluster_count=2,
observed_cluster_count=2,
sidecar_words=sidecar,
output_words=output,
intervals=list(reversed(intervals)),
audio_duration_seconds=1.0,
permitted_padding_seconds=0.0,
)
assert first == second == {
"passed": True,
"reason": None,
"canonical_labels": [1, 2],
}
duplicate_cluster = [
{"start": 0.0, "end": 0.5, "speaker": "z"},
{"start": 0.5, "end": 1.0, "speaker": "z"},
]
assert experiment.quality_gate(
expected_cluster_count=2,
observed_cluster_count=2,
sidecar_words=sidecar,
output_words=output,
intervals=duplicate_cluster,
audio_duration_seconds=1.0,
permitted_padding_seconds=0.0,
)["reason"] == "cluster-count-mismatch"
def test_diagnostics_only_add_safe_listening_locations_and_hearing_needs_user():
diagnostics = experiment.diagnostic_listening_locations(
baseline={
"purity": 0.8,
"unmatched_words": 2,
"channel_stability": 0.9,
"short_turns": 4,
"overlap": 0.1,
"residual_clusters": 0,
},
candidate={
"purity": 0.7,
"unmatched_words": 3,
"channel_stability": 0.8,
"short_turns": 5,
"overlap": 0.2,
"residual_clusters": 1,
},
location_sha256=["9" * 64],
)
assert diagnostics == {"mandatory_passed": True, "location_sha256": ["9" * 64]}
assert experiment.hearing_gate({}) == {
"state": "needs-user",
"reason": "hearing-decisions-required",
}
categories = {category: "pass" for category in experiment.HEARING_CATEGORIES}
assert experiment.hearing_gate(categories) == {"state": "go", "reason": None}
categories[experiment.HEARING_CATEGORIES[2]] = "fail"
assert experiment.hearing_gate(categories) == {
"state": "stop",
"reason": "hearing-gate-failed",
}
def test_blinded_review_material_is_seeded_categorized_and_procedural():
diagnostic = {
category: [hashlib.sha256(f"diagnostic-{category}".encode()).hexdigest()]
for category in experiment.HEARING_CATEGORIES
}
matching = {
category: [
hashlib.sha256(f"match-a-{category}".encode()).hexdigest(),
hashlib.sha256(f"match-b-{category}".encode()).hexdigest(),
]
for category in experiment.HEARING_CATEGORIES
}
blinded, reveal = experiment.build_blinded_review_material(
diagnostic_locations=diagnostic,
matching_locations=matching,
private_seed_sha256="a" * 64,
matching_sample_size=1,
)
repeated, repeated_reveal = experiment.build_blinded_review_material(
diagnostic_locations=diagnostic,
matching_locations=matching,
private_seed_sha256="a" * 64,
matching_sample_size=1,
)
assert blinded == repeated
assert reveal == repeated_reveal
assert set(blinded["categories"]) == set(experiment.HEARING_CATEGORIES)
assert all(len(items) == 2 for items in blinded["categories"].values())
assert set(reveal["pair_order"].values()) <= {
("W0-FRESH", "SORTFORMER-V2-Q8"),
("SORTFORMER-V2-Q8", "W0-FRESH"),
}
serialized = experiment.serialize_public(blinded)
assert "W0-FRESH" not in serialized
assert "SORTFORMER-V2-Q8" not in serialized
assert blinded["reveal_sha256"] == experiment.canonical_sha256(reveal)
assert "процедурного ослепления" in (
experiment.build_blinded_review_material.__doc__ or ""
)
assert "может восстановить порядок" in (
experiment.build_blinded_review_material.__doc__ or ""
)
def test_memory_gate_uses_frozen_plateau_and_linear_growth_policy_boundaries():
mib = 1024**2
passing = experiment.memory_gate(
stage="fragment",
oom=False,
swap_before_bytes=0,
swap_after_bytes=0,
peak_rss_bytes=300 * mib,
rss_after_inputs=[100 * mib, 170 * mib, 234 * mib],
machine_ram_bytes=16 * 1024**3,
)
assert passing == {
"state": "pass",
"reason": None,
"plateau_policy": "fragment-only:last-delta<=max(64MiB,5%-of-max-post-input-rss);linear=all-deltas>same-tolerance",
}
assert experiment.memory_gate(
stage="fragment",
oom=False,
swap_before_bytes=0,
swap_after_bytes=0,
peak_rss_bytes=300 * mib,
rss_after_inputs=[100 * mib, 170 * mib, 235 * mib],
machine_ram_bytes=16 * 1024**3,
)["reason"] == "rss-linear-growth"
assert experiment.memory_gate(
stage="fragment",
oom=False,
swap_before_bytes=0,
swap_after_bytes=1,
peak_rss_bytes=300 * mib,
rss_after_inputs=[100 * mib, 120 * mib, 121 * mib],
machine_ram_bytes=16 * 1024**3,
)["reason"] == "active-swap"
assert experiment.memory_gate(
stage="fragment",
oom=True,
swap_before_bytes=0,
swap_after_bytes=0,
peak_rss_bytes=0,
rss_after_inputs=[0, 0, 0],
machine_ram_bytes=16 * 1024**3,
)["reason"] == "oom"
def test_memory_gate_marks_two_gibibyte_review_as_needs_user():
result = experiment.memory_gate(
stage="fragment",
oom=False,
swap_before_bytes=0,
swap_after_bytes=0,
peak_rss_bytes=2 * 1024**3 + 1,
rss_after_inputs=[2 * 1024**3, 2 * 1024**3, 2 * 1024**3],
machine_ram_bytes=16 * 1024**3,
)
assert result["state"] == "needs-user"
assert result["reason"] == "peak-rss-review"
reserved_ram = experiment.memory_gate(
stage="fragment",
oom=False,
swap_before_bytes=0,
swap_after_bytes=0,
peak_rss_bytes=3 * 1024**3,
rss_after_inputs=[1024**3, 1024**3, 1024**3],
machine_ram_bytes=16_601_477_120,
)
assert reserved_ram["state"] == "needs-user"
def test_memory_gate_skips_unsupported_plateau_in_single_full_recording_cell():
result = experiment.memory_gate(
stage="full",
oom=False,
swap_before_bytes=0,
swap_after_bytes=0,
peak_rss_bytes=1024**3,
rss_after_inputs=[900 * 1024**2],
machine_ram_bytes=16 * 1024**3,
)
assert result == {
"state": "pass",
"reason": None,
"plateau_policy": "fragment-only:last-delta<=max(64MiB,5%-of-max-post-input-rss);linear=all-deltas>same-tolerance",
}
gib = 1024**3
divergent = experiment.memory_gate(
stage="fragment",
oom=False,
swap_before_bytes=0,
swap_after_bytes=0,
peak_rss_bytes=4 * gib,
rss_after_inputs=[gib, int(1.1 * gib), int(1.18 * gib)],
machine_ram_bytes=32 * gib,
)
assert divergent["reason"] == "rss-linear-growth"
def _sortformer_gate(**changes):
recipe = _recipes()["SORTFORMER-V2-Q8"]
values = {
"effective_recipe": recipe,
"probabilities": [[0.0, 0.25, 0.5, 1.0], [0.1, 0.2, 0.3, 0.4]],
"labels": [1, 4],
"frame_count": 2,
"frame_probs_start": 0,
"segments": [
{"start": 0.0, "end": 0.08, "speaker": 1},
{"start": 0.08, "end": 0.16, "speaker": 4},
],
"channel_interval_counts": {1: 1, 2: 0, 3: 0, 4: 1},
"channel_durations_seconds": {1: 0.08, 2: 0.0, 3: 0.0, 4: 0.08},
"inference_wall_seconds": 1.0,
"post_processing_wall_seconds": 0.1,
}
values.update(changes)
return experiment.sortformer_gate(**values)
def test_sortformer_gate_checks_effective_config_shape_values_labels_and_metrics():
assert _sortformer_gate() == {"passed": True, "reason": None}
assert _sortformer_gate(probabilities=[[0.1, 0.2, 0.3]])["reason"] == (
"probability-shape"
)
assert _sortformer_gate(probabilities=[[0.1, 0.2, float("nan"), 0.4]])[
"reason"
] == "probability-value"
assert _sortformer_gate(labels=[0, 4])["reason"] == "speaker-label"
changed = _recipes()["SORTFORMER-V2-Q8"]
changed["seconds_per_frame"] = 0.1
assert _sortformer_gate(effective_recipe=changed)["reason"] == (
"effective-config-mismatch"
)
assert _sortformer_gate(inference_wall_seconds=-1)["reason"] == (
"invalid-stage-wall"
)
assert _sortformer_gate(
frame_count=5,
frame_probs_start=3,
) == {"passed": True, "reason": None}
assert _sortformer_gate(channel_interval_counts={1: 2, 2: 0, 3: 0, 4: 0})[
"reason"
] == "channel-counts"
class _Measurement:
def __init__(self, trace):
self.trace = trace
self.walls = {
"w0-process": 10.0,
"candidate-inference": 5.5,
"candidate-post-processing": 0.5,
}
def measure(self, label, operation):
self.trace.append(f"timer-start:{label}")
value = operation()
self.trace.append(f"timer-stop:{label}")
return value, {
"wall_seconds": self.walls[label],
"user_cpu_seconds": 1.0,
"system_cpu_seconds": 0.1,
"peak_rss_bytes": 100,
}
def test_measurement_boundary_times_only_exact_w0_and_candidate_operations():
trace = []
samples = np.asarray([0.0, 0.25], dtype=np.float32)
class W0:
def process(self, actual):
assert actual is samples
trace.append("w0-process")
return "w0-result"
class Runtime:
def prepare_samples(self, actual):
assert actual is samples
trace.append("prepare-samples")
return "prepared-buffer"
def stream_open(self):
trace.append("stream-open")
return "stream"
def stream_push(self, stream, actual):
assert stream == "stream" and actual == "prepared-buffer"
trace.append("stream-push")
def stream_finish(self, stream):
assert stream == "stream"
trace.append("stream-finish")
return "raw-segments"
def stream_close(self, stream):
assert stream == "stream"
trace.append("stream-close")
measurement = _Measurement(trace)
w0 = experiment.measure_w0(W0(), samples, measurement)
candidate = experiment.measure_candidate(
Runtime(),
samples,
lambda raw: trace.append("post-processing") or [raw],
measurement,
)
assert w0["result"] == "w0-result"
assert w0["metrics"]["wall_seconds"] == 10.0
assert candidate["result"] == ["raw-segments"]
assert candidate["metrics"]["wall_seconds"] == 6.0
assert candidate["inference_wall_seconds"] == 5.5
assert candidate["post_processing_wall_seconds"] == 0.5
assert trace == [
"timer-start:w0-process",
"w0-process",
"timer-stop:w0-process",
"prepare-samples",
"timer-start:candidate-inference",
"stream-open",
"stream-push",
"stream-finish",
"timer-stop:candidate-inference",
"timer-start:candidate-post-processing",
"post-processing",
"stream-close",
"timer-stop:candidate-post-processing",
]
def _guard(recipe="W0-FRESH", **changes):
result = {
"machine_sha256": "1" * 64,
"affinity": list(range(8)),
"logical_cores": 16,
"physical_cores": 8,
"cpuid_isa_sha256": "2" * 64,
"ram_bytes": 16 * 1024**3,
"os_sha256": "3" * 64,
"compiler_sha256": "4" * 64,
"runtime_versions_sha256": "5" * 64,
"recipe": recipe,
"effective_threads": 8 if recipe == "W0-FRESH" else 4,
"power_mode": "balanced",
"governor": "powersave",
"turbo": True,
"throttling": False,
"throttle_count": 10,
"swap_used_bytes": 0,
"swap_sin_bytes": 0,
"swap_sout_bytes": 0,
}
result.update(changes)
return result
def test_pair_guards_require_same_machine_affinity_and_frozen_thread_counts():
assert experiment.validate_pair_guards(
_guard(),
_guard(),
_guard("SORTFORMER-V2-Q8"),
_guard("SORTFORMER-V2-Q8"),
expected_machine=_machine(),
) == []
affinity_reasons = experiment.validate_pair_guards(
_guard(),
_guard(),
_guard("SORTFORMER-V2-Q8", affinity=list(range(1, 9))),
_guard("SORTFORMER-V2-Q8", affinity=list(range(1, 9))),
expected_machine=_machine(),
)
assert set(affinity_reasons) == {
"manifest-machine-mismatch",
"pair-affinity-mismatch",
}
assert "effective-threads-mismatch" in experiment.validate_pair_guards(
_guard(effective_threads=4),
_guard(effective_threads=4),
_guard("SORTFORMER-V2-Q8"),
_guard("SORTFORMER-V2-Q8"),
expected_machine=_machine(),
)
assert "pair-power-mismatch" in experiment.validate_pair_guards(
_guard(),
_guard(),
_guard("SORTFORMER-V2-Q8", governor="performance"),
_guard("SORTFORMER-V2-Q8", governor="performance"),
expected_machine=_machine(),
)
wrong = _guard(affinity=list(range(8, 16)))
assert "manifest-machine-mismatch" in experiment.validate_pair_guards(
wrong,
wrong,
_guard("SORTFORMER-V2-Q8", affinity=list(range(8, 16))),
_guard("SORTFORMER-V2-Q8", affinity=list(range(8, 16))),
expected_machine=_machine(),
)
def test_guarded_cell_excludes_invalid_wall_and_retries_once_after_stabilization():
snapshots = iter(
[
_guard(),
_guard(power_mode="performance"),
_guard(),
_guard(),
]
)
walls = iter([100.0, 50.0])
stabilizations = []
result = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: {"wall_seconds": next(walls)},
guard_reader=lambda: next(snapshots),
stabilize=lambda: stabilizations.append("stabilized"),
expected_machine=_machine(),
)
assert result["state"] == "accepted"
assert result["result"] == {"wall_seconds": 50.0}
assert stabilizations == ["stabilized"]
assert result["attempts"][0]["valid"] is False
assert "result" not in result["attempts"][0]
assert result["attempts"][1]["valid"] is True
def test_guarded_cell_accepts_stable_manifest_declared_performance_mode():
machine = _machine()
machine["power_mode"] = "performance"
result = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: {"wall_seconds": 1.0},
guard_reader=lambda: _guard(power_mode="performance"),
stabilize=lambda: pytest.fail("stable mode must not retry"),
expected_machine=machine,
)
assert result["state"] == "accepted"
assert len(result["attempts"]) == 1
def test_second_guard_invalidation_stops_with_first_reason_and_active_swap_never_retries():
throttled = iter(
[
_guard(),
_guard(throttling=True, throttle_count=11),
_guard(),
_guard(throttling=True, throttle_count=11),
]
)
second = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: {"wall_seconds": 99.0},
guard_reader=lambda: next(throttled),
stabilize=lambda: None,
expected_machine=_machine(),
)
assert second["state"] == "stop"
assert second["reason"] == "new-throttling"
assert len(second["attempts"]) == 2
calls = []
swapped = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: calls.append("run") or {"wall_seconds": 1.0},
guard_reader=lambda: _guard(swap_used_bytes=1),
stabilize=lambda: calls.append("stabilize"),
expected_machine=_machine(),
)
assert swapped["state"] == "stop"
assert swapped["reason"] == "active-swap"
assert calls == []
def test_oom_stops_without_retry_and_private_result_is_written_atomically(tmp_path):
calls = []
result = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: (_ for _ in ()).throw(MemoryError("private")),
guard_reader=lambda: _guard(),
stabilize=lambda: calls.append("stabilize"),
expected_machine=_machine(),
)
assert result["state"] == "stop"
assert result["reason"] == "oom"
assert calls == []
assert "private" not in json.dumps(result)
private_path = tmp_path / "closed" / "raw-result.json"
digest = experiment.persist_private_result(
private_path, {"raw_rows": [1, 2, 3], "secret": "allowed-here"}
)
assert digest == experiment.file_sha256(private_path)
assert sorted(path.name for path in private_path.parent.iterdir()) == [
"raw-result.json"
]
failed_path = tmp_path / "failed" / "raw-result.json"
with pytest.raises(ValueError):
experiment.persist_private_result(
failed_path, {"probability": float("nan"), "words": ["private"]}
)
assert list(failed_path.parent.iterdir()) == []
def test_guarded_cell_does_not_retry_hard_mismatch_and_sanitizes_exceptions():
snapshots = iter([_guard(), _guard(governor="performance")])
stabilizations = []
hard = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: {"wall_seconds": 1.0},
guard_reader=lambda: next(snapshots),
stabilize=lambda: stabilizations.append("unexpected"),
expected_machine=_machine(),
)
assert hard["state"] == "stop"
assert hard["reason"] == "runtime-power-setting-changed"
assert len(hard["attempts"]) == 1
assert stabilizations == []
failed = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: (_ for _ in ()).throw(RuntimeError("/private/path")),
guard_reader=lambda: _guard(),
stabilize=lambda: None,
expected_machine=_machine(),
)
assert failed["state"] == "stop"
assert failed["reason"] == "runtime-error"
assert "/private/path" not in json.dumps(failed)
unreadable = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: {"wall_seconds": 1.0},
guard_reader=lambda: (_ for _ in ()).throw(OSError("/private/guard")),
stabilize=lambda: None,
expected_machine=_machine(),
)
assert unreadable["state"] == "stop"
assert unreadable["reason"] == "runtime-guard-unavailable"
assert "/private/guard" not in json.dumps(unreadable)
calls = []
wrong_recipe = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "SORTFORMER-V2-Q8"},
runner=lambda _request: calls.append("run") or {"wall_seconds": 1.0},
guard_reader=lambda: _guard("W0-FRESH"),
stabilize=lambda: None,
expected_machine=_machine(),
)
assert wrong_recipe["reason"] == "runtime-recipe-mismatch"
assert calls == []
def test_guarded_cell_hashes_result_rejected_by_after_run_swap():
snapshots = iter([_guard(), _guard(swap_sin_bytes=1)])
raw_result = {"wall_seconds": 1.0, "private": "not-published"}
result = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: raw_result,
guard_reader=lambda: next(snapshots),
stabilize=lambda: None,
expected_machine=_machine(),
)
assert result["state"] == "stop"
assert result["reason"] == "active-swap"
assert result["attempts"][0]["invalid_result_sha256"] == (
experiment.canonical_sha256(raw_result)
)
assert "result" not in result["attempts"][0]
def test_non_finite_private_result_becomes_sanitized_first_stop(tmp_path):
guarded = experiment.run_guarded_cell(
{"semantic_id": "safe-cell", "recipe": "W0-FRESH"},
runner=lambda _request: {"wall_seconds": float("nan")},
guard_reader=lambda: _guard(),
stabilize=lambda: None,
expected_machine=_machine(),
)
assert guarded["state"] == "stop"
assert guarded["reason"] == "invalid-result-value"
assert "nan" not in json.dumps(guarded)
store = experiment.ExperimentState(tmp_path / "public-state.json")
state = store.stop("mandatory-gate-failed", {"probability": float("nan")})
assert state["first_reason"] == "invalid-result-value"
assert experiment.SHA256_RE.fullmatch(state["result_sha256"])
def test_public_plan_and_result_are_redacted_and_privacy_scanned(tmp_path):
manifest = _manifest(tmp_path)
outcome = experiment.validate_manifest(
manifest, root=tmp_path, environment=_environment()
)
plan = experiment.safe_public_plan(manifest, outcome)
serialized = experiment.serialize_public(plan)
assert plan["state"] == "valid"
assert plan["recipes"] == ["W0-FRESH", "SORTFORMER-V2-Q8"]
assert plan["fragment_count"] == 3
assert plan["scheduled_cell_count"] == 12
assert str(tmp_path) not in serialized
assert "fragment-0" not in serialized
assert "words-fragment" not in serialized
experiment.privacy_scan(plan)
report = experiment.safe_public_result(
source_commit="a" * 40,
result_sha256="b" * 64,
aggregate_timings={"w0_wall_seconds": 100.0, "candidate_wall_seconds": 60.0},
deltas={"speedup_percent": 40.0},
statistics_values={
"median_speedup_percent": 40.0,
"mad_percentage_points": 1.0,
},
gate_verdicts={"quality": "pass", "hearing": "needs-user"},
limitations=["four-speaker-output-limit", "non-english-domain-risk"],
first_stop_reason=None,
)
experiment.privacy_scan(report)
assert report["state"] == "needs-user"
assert report["limitations"][-1] == "procedural-blinding"
with pytest.raises(experiment.PrivacyError):
experiment.privacy_scan({"intervals": [{"start": 1.0}]})
with pytest.raises(experiment.PrivacyError):
experiment.privacy_scan({"note": str(tmp_path / "secret.wav")})
with pytest.raises(experiment.PrivacyError):
experiment.privacy_scan({"source_path": "relative-but-private.wav"})
with pytest.raises(experiment.PrivacyError):
experiment.privacy_scan({"note": "/opt/private/model.bin"})
with pytest.raises(experiment.PrivacyError):
experiment.privacy_scan({"note": "failure at /opt/private/model.bin"})
with pytest.raises(experiment.PreflightError, match="public-numeric-value"):
experiment.safe_public_result(
source_commit="a" * 40,
result_sha256="b" * 64,
aggregate_timings={"note": "private transcript"},
deltas={},
statistics_values={},
gate_verdicts={},
limitations=[],
first_stop_reason=None,
)
def test_public_result_requires_all_gates_and_final_speed_threshold_for_go():
common = {
"source_commit": "a" * 40,
"result_sha256": "b" * 64,
"aggregate_timings": {"candidate_wall_seconds": 60.0},
"deltas": {"speedup_percent": 40.0},
"limitations": ["four-speaker-output-limit"],
"first_stop_reason": None,
}
automatic = {
"quality": "pass",
"sortformer": "pass",
"memory": "pass",
"measurement": "pass",
"hearing": "pass",
}
below = experiment.safe_public_result(
**common,
statistics_values={"median_speedup_percent": 29.999},
gate_verdicts=automatic,
)
assert below["state"] == "stop"
assert below["first_stop_reason"] == "below-final-threshold"
incomplete = experiment.safe_public_result(
**common,
statistics_values={"median_speedup_percent": 40.0},
gate_verdicts={**automatic, "quality": "needs-user"},
)
assert incomplete["state"] == "needs-user"
go = experiment.safe_public_result(
**common,
statistics_values={"median_speedup_percent": 30.0},
gate_verdicts=automatic,
)
assert go["state"] == "go"
assert go["limitations"] == [
"four-speaker-output-limit",
"procedural-blinding",
]
deduplicated = experiment.safe_public_result(
**{**common, "limitations": ["procedural-blinding"]},
statistics_values={"median_speedup_percent": 30.0},
gate_verdicts=automatic,
)
assert deduplicated["limitations"] == ["procedural-blinding"]
def test_validate_only_cli_is_useful_redacted_and_never_calls_loader(
tmp_path, capsys
):
manifest = _manifest(tmp_path)
manifest_path = tmp_path / "manifest.json"
manifest_path.write_text(json.dumps(manifest), encoding="utf-8")
calls = []
exit_code = experiment.run_cli(
SimpleNamespace(manifest=manifest_path, validate_only=True),
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
)
output = capsys.readouterr().out
assert exit_code == 0
assert calls == []
assert '"schema_status": "pass"' in output
assert '"pin_status": "pass"' in output
assert '"schedule_status": "pass"' in output
assert str(tmp_path) not in output
manifest["fresh_basis"]["approval"] = None
manifest_path.write_text(json.dumps(manifest), encoding="utf-8")
assert experiment.run_cli(
SimpleNamespace(manifest=manifest_path, validate_only=True),
environment_probe=_environment,
w0_loader=lambda: calls.append("w0"),
candidate_loader=lambda: calls.append("candidate"),
) == 0
assert json.loads(capsys.readouterr().out)["state"] == "needs-user"
def test_invalid_cli_output_has_one_trailing_newline(tmp_path, capsys):
manifest_path = tmp_path / "invalid.json"
manifest_path.write_text("{}", encoding="utf-8")
with pytest.raises(SystemExit) as raised:
experiment.main(["--manifest", str(manifest_path), "--validate-only"])
assert raised.value.code == 2
output = capsys.readouterr().out
assert output.endswith("\n")
assert not output.endswith("\n\n")
def test_validate_only_cli_redacts_nul_path_failure(
tmp_path, capsys, monkeypatch
):
manifest = _manifest(tmp_path)
manifest["inputs"][0]["source_path"] = "private\x00source.wav"
manifest_path = tmp_path / "manifest.json"
manifest_path.write_text(json.dumps(manifest), encoding="utf-8")
monkeypatch.setattr(
experiment,
"git_environment_probe",
lambda _repository_root: _environment(),
)
with pytest.raises(SystemExit) as raised:
experiment.main(["--manifest", str(manifest_path), "--validate-only"])
captured = capsys.readouterr()
assert raised.value.code == 2
assert json.loads(captured.out) == {
"reason": "path-escape",
"state": "invalid",
}
assert captured.err == ""
assert "Traceback" not in captured.out
assert "\x00" not in captured.out
assert "private" not in captured.out
assert str(tmp_path) not in captured.out
def test_child_process_request_result_seam_uses_atomic_private_files(tmp_path):
request = {
"semantic_id": "cell-safe",
"recipe": "W0-FRESH",
"input_sha256": ["1" * 64, "2" * 64, "3" * 64],
"sidecar_sha256": ["4" * 64, "5" * 64, "6" * 64],
}
commands = []
def fake_process(command):
commands.append(command)
request_path = Path(command[-1])
payload = json.loads(request_path.read_text())
response = {
"worker_schema": experiment.WORKER_SCHEMA,
"semantic_id": payload["semantic_id"],
"status": "complete",
"result": {"wall_seconds": 1.0},
"result_sha256": experiment.canonical_sha256({"wall_seconds": 1.0}),
}
Path(payload["response_path"]).write_text(json.dumps(response))
return SimpleNamespace(returncode=0, stdout="private log", stderr="")
result = experiment.run_child_process(
request, work_dir=tmp_path, process_runner=fake_process
)
assert result["result"] == {"wall_seconds": 1.0}
assert len(commands) == 1
assert (tmp_path / "logs" / "cell-safe.stdout.log").read_text() == "private log"
stale_runner = lambda _command: SimpleNamespace(
returncode=0, stdout="", stderr=""
)
with pytest.raises(RuntimeError, match="child-process-failed"):
experiment.run_child_process(
request, work_dir=tmp_path, process_runner=stale_runner
)
def test_child_process_requires_an_explicit_worker_runner(tmp_path):
request = {
"semantic_id": "cell-safe",
"recipe": "W0-FRESH",
"input_sha256": ["1" * 64],
"sidecar_sha256": ["2" * 64],
}
with pytest.raises(experiment.PreflightError, match="worker-runner-required"):
experiment.run_child_process(request, work_dir=tmp_path)
class _FakeFunction:
def __init__(self, function):
self.function = function
self.argtypes = None
self.restype = None
def __call__(self, *args):
return self.function(*args)
class _FakeCAbi:
def __init__(
self,
*,
speakers=4,
seconds_per_frame=0.08,
create_status=0,
grown_segment_count=False,
):
self.speakers = speakers
self.seconds = seconds_per_frame
self.create_status = create_status
self.grown_segment_count = grown_segment_count
self.seen = None
self.pushed = None
self.closed = False
for name in dir(self):
if name.startswith("nemo_speech_"):
setattr(self, name, _FakeFunction(getattr(self, name)))
def nemo_speech_diar_create(self, config, output):
self.seen = config.contents
output._obj.value = 101
return self.create_status
def nemo_speech_diar_destroy(self, _model):
return None
def nemo_speech_diar_num_speakers(self, _model):
return self.speakers
def nemo_speech_diar_seconds_per_frame(self, _model):
return self.seconds
def nemo_speech_diar_stream_open(self, _model, output):
self.closed = False
output._obj.value = 202
return 0
def nemo_speech_diar_stream_push_f32(self, _stream, samples, count, sample_rate):
self.pushed = ([samples[index] for index in range(count)], sample_rate)
return 0
def nemo_speech_diar_stream_finish(self, _stream):
return 0
def nemo_speech_diar_stream_close(self, _stream):
self.closed = True
def nemo_speech_diar_frame_count(self, _stream):
assert not self.closed
return 2
def nemo_speech_diar_frame_probs_start(self, _stream):
assert not self.closed
return 0
def nemo_speech_diar_frame_probs(self, _stream, output, capacity):
assert not self.closed
assert capacity == 8
for index, value in enumerate((0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8)):
output[index] = value
return 0
def nemo_speech_diar_segments(self, _stream, config, output, capacity, count):
assert not self.closed
assert config.contents.onset == pytest.approx(0.641)
if not output:
count._obj.value = 2
return 0
assert capacity == 2
if self.grown_segment_count:
count._obj.value = 3
return 0
output[0].start_time = 0.0
output[0].end_time = 0.8
output[0].speaker = 1
output[1].start_time = 0.8
output[1].end_time = 1.6
output[1].speaker = 4
return 0
def test_fake_c_abi_validates_layout_cpu_selection_and_effective_config():
library = _FakeCAbi()
adapter = experiment.SortformerCAbi(library)
result = adapter.synthetic_check()
model = adapter.create_model("synthetic-model.gguf")
with pytest.raises(experiment.CAbiError, match="model-already-created"):
adapter.create_model("second-model.gguf")
stream = adapter.stream_open(model)
samples = np.asarray([0.0, 0.25], dtype=np.float32)
prepared = adapter.prepare_samples(samples)
assert prepared.owner is samples
assert ctypes.addressof(prepared.pointer.contents) == samples.ctypes.data
adapter.stream_push(stream, prepared, sample_rate=16_000)
adapter.stream_finish(stream)
output = adapter.collect_result(stream, model)
adapter.stream_close(stream)
adapter.destroy_model(model)
assert result == {
"model_config_size": 56,
"segmentation_config_size": 48,
"segment_size": 24,
"gpu": -1,
"num_speakers": 4,
"seconds_per_frame": pytest.approx(0.08),
"chunk_frames": 340,
"right_context_frames": 40,
}
assert library.seen.gpu == -1
assert library.seen.preset == b"streaming"
assert library.seen.update_period_frames == 300
assert library.pushed[0] == pytest.approx([0.0, 0.25])
assert library.pushed[1] == 16_000
assert output["frame_count"] == 2
assert output["frame_probs_start"] == 0
assert output["probabilities"][1] == pytest.approx([0.5, 0.6, 0.7, 0.8])
assert output["segments"] == [
{"start": 0.0, "end": 0.8, "speaker": 1},
{"start": 0.8, "end": 1.6, "speaker": 4},
]
def test_fake_c_abi_rejects_layout_and_runtime_config_mismatches():
with pytest.raises(experiment.CAbiError, match="layout"):
experiment.SortformerCAbi(_FakeCAbi(), expected_layout={"size": 999})
with pytest.raises(experiment.CAbiError, match="num-speakers"):
experiment.SortformerCAbi(_FakeCAbi(speakers=3)).synthetic_check()
with pytest.raises(experiment.CAbiError, match="seconds-per-frame"):
experiment.SortformerCAbi(_FakeCAbi(seconds_per_frame=0.1)).synthetic_check()
with pytest.raises(experiment.CAbiError, match="effective-config"):
experiment.SortformerCAbi(_FakeCAbi(create_status=1)).synthetic_check()
def test_fake_c_abi_load_boundary_configures_and_returns_adapter():
calls = []
library = _FakeCAbi()
adapter = experiment.SortformerCAbi.load(
Path("closed/libnemo_speech.so"),
loader=lambda path: calls.append(path) or library,
)
assert calls == ["closed/libnemo_speech.so"]
assert library.nemo_speech_diar_seconds_per_frame.restype is ctypes.c_double
assert library.nemo_speech_diar_frame_count.restype is ctypes.c_int64
assert adapter.synthetic_check()["num_speakers"] == 4
def test_fake_c_abi_rejects_segment_count_growth_beyond_owned_buffer():
adapter = experiment.SortformerCAbi(_FakeCAbi(grown_segment_count=True))
model = adapter.create_model("synthetic-model.gguf")
stream = adapter.stream_open(model)
with pytest.raises(experiment.CAbiError, match="segment-count-changed"):
adapter.collect_result(stream, model)
def test_candidate_measurement_collects_c_abi_result_before_stream_close():
trace = []
library = _FakeCAbi()
adapter = experiment.SortformerCAbi(library)
model = adapter.create_model("synthetic-model.gguf")
measured = experiment.measure_candidate(
adapter,
np.asarray([0.0, 0.25], dtype=np.float32),
lambda stream: adapter.collect_result(stream, model),
_Measurement(trace),
)
assert measured["result"]["frame_count"] == 2
assert library.closed is True