"""Offline exact-parity gate for the frozen Batch01 band/channel oracle.""" from __future__ import annotations import csv import hashlib import json from pathlib import Path from typing import Any import numpy as np from .historical_band_channel import OBSERVED_BAND_CHANNEL_PARAMS, evaluate_band_channel from .parity_harness_v1 import ( ComparisonRecord, FeatureVersion, ParityStatus, compare_array, compare_float64_ulp, recompute_coverage, ) ROOT = Path(__file__).resolve().parents[3] BATCH01_REQUEST = ROOT / "batch01_oracle_request.json" BATCH01_RESULT = ROOT / "batch01_oracle_result.json" BATCH01_OUTPUTS = ROOT / "batch01_oracle_outputs.npz" CANONICAL_CSV = ROOT / "hs22_oracle_v1" / "binance_btcusdt_spot_2m_180d.csv" BOLLINGER_RESOLUTION = ROOT / "batch01_bollinger_parity_resolution_v1.json" BOLLINGER_ROOT_REPORT = ROOT / "batch01_native_mismatch_report.json" _DIGESTS = { "batch01_oracle_request.json": ( "7ca0c8578dd81c3ae60898d83e6e73f9bf8889a39a873b451c7cdaf036cbaf24" ), "batch01_oracle_result.json": ( "7c1d5dbdcb183aa2d872baa45c4d02fe2d59cccabe9022f8797237b3776c8e96" ), "batch01_oracle_outputs.npz": ( "e1f2268b634e50eb65b9b5175ea369e52bf0a2039b18049030849948a45fd149" ), "hs22_oracle_v1/binance_btcusdt_spot_2m_180d.csv": ( "7fb56bb05b0edc2348407765cd693efadf334307c25877dfb52acfe4221e5d00" ), } class FrozenBatch01ArtifactError(ValueError): """Raised when a parity input is not the pinned local oracle artifact.""" def _digest(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() def _canonical_bytes(value: object) -> bytes: return json.dumps(value, sort_keys=True, separators=(",", ":"), allow_nan=False).encode("utf-8") def _array_digest(values: np.ndarray) -> str: values = np.ascontiguousarray(values) header = _canonical_bytes({"dtype": values.dtype.str, "shape": values.shape}) return hashlib.sha256(header + b"\0" + values.tobytes()).hexdigest() def batch01_native_parity_manifest() -> dict[str, object]: """Return the reproducible exact-comparison contract for all 97 variants.""" return { "schema_version": 1, "artifact": "BATCH01_NATIVE_PARITY_MANIFEST_V1", "engine_revision": "code-5056feb", "frozen_inputs": { name: {"path": name, "sha256": digest} for name, digest in _DIGESTS.items() }, "input_columns": ["close", "high", "low", "volume"], "variant_count": 97, "comparison": {"dtype": "exact", "shape": "exact", "nan_mask": "exact", "values": "exact"}, "documented_exception": { "path": BOLLINGER_RESOLUTION.name, "scope": "float64 one-ULP cases listed for indicator IDs 17 and 18 only", "global_tolerance": "forbidden", }, "derived_state_transitions": { "indicator_ids": [19, 28], "state": "1 when close is greater than output, otherwise -1; warmup NaN is 0", "transitions": "state differs from the preceding bar", }, } def batch01_native_parity_manifest_bytes() -> bytes: return _canonical_bytes(batch01_native_parity_manifest()) + b"\n" def write_batch01_native_parity_manifest(path: Path) -> None: path.write_bytes(batch01_native_parity_manifest_bytes()) def _require_frozen_artifacts() -> tuple[dict[str, Any], dict[str, Any]]: paths = { "batch01_oracle_request.json": BATCH01_REQUEST, "batch01_oracle_result.json": BATCH01_RESULT, "batch01_oracle_outputs.npz": BATCH01_OUTPUTS, "hs22_oracle_v1/binance_btcusdt_spot_2m_180d.csv": CANONICAL_CSV, } for name, path in paths.items(): if _digest(path) != _DIGESTS[name]: raise FrozenBatch01ArtifactError(f"{name} digest does not match the frozen artifact") request = json.loads(BATCH01_REQUEST.read_text(encoding="utf-8")) result = json.loads(BATCH01_RESULT.read_text(encoding="utf-8")) if request.get("artifact") != "HISTORICAL_FEATURE_ORACLE_V1_REQUEST": raise FrozenBatch01ArtifactError("invalid Batch01 request artifact") if result.get("artifact") != "HISTORICAL_FEATURE_ORACLE_V1_RESULT": raise FrozenBatch01ArtifactError("invalid Batch01 result artifact") if result.get("request_sha256") != _DIGESTS["batch01_oracle_request.json"]: raise FrozenBatch01ArtifactError("result is not linked to the frozen request") csv_digest = _DIGESTS["hs22_oracle_v1/binance_btcusdt_spot_2m_180d.csv"] if result.get("input_csv_sha256") != csv_digest: raise FrozenBatch01ArtifactError("result is not linked to the canonical CSV") if result.get("outputs_npz", {}).get("sha256") != _DIGESTS["batch01_oracle_outputs.npz"]: raise FrozenBatch01ArtifactError("result is not linked to the frozen NPZ") return request, result def _bollinger_resolution() -> dict[str, tuple[dict[str, Any], ...]]: resolution = json.loads(BOLLINGER_RESOLUTION.read_text(encoding="utf-8")) report = json.loads(BOLLINGER_ROOT_REPORT.read_text(encoding="utf-8")) source = resolution.get("source_report", {}) exception = resolution.get("exception", {}) if ( resolution.get("artifact") != "BATCH01_BOLLINGER_PARITY_RESOLUTION_V1" or resolution.get("schema_version") != 1 or source.get("artifact") != report.get("artifact") or source.get("classification") != report.get("classification") or source.get("failed_value_count") != report.get("failed_value_count") or exception != { "indicator_ids": [17, 18], "dtype": "float64", "max_ulps": 1, "unlisted_mismatch_policy": "fail", "all_other_indicators_policy": "exact", "shape_policy": "exact", "nan_mask_policy": "exact", } ): raise FrozenBatch01ArtifactError("invalid Bollinger parity resolution") report_cases = { (item["request_id"], int(detail["index"])): { "indicator_id": item["indicator_id"], "signed_ulp": detail["ulp"]["signed"], "threshold_sensitivity": { key: detail["threshold_sensitivity"][key] for key in ( "oracle_close_above_band", "native_close_above_band", "decision_changed", "close_to_oracle_band_ulps", "close_to_native_band_ulps", ) }, } for item in report["variants"] for detail in item["mismatches"] } accepted = resolution.get("accepted_cases") if not isinstance(accepted, list) or len(accepted) != 8: raise FrozenBatch01ArtifactError("resolution must list all eight accepted cases") resolution_cases = { (item["request_id"], int(item["index"])): { "indicator_id": item["indicator_id"], "signed_ulp": item["signed_ulp"], "threshold_sensitivity": item["threshold_sensitivity"], } for item in accepted } if resolution_cases != report_cases or any( int(item["indicator_id"]) not in {17, 18} or item["threshold_sensitivity"]["decision_changed"] for item in accepted ): raise FrozenBatch01ArtifactError("resolution does not match the root-cause evidence") grouped: dict[str, list[dict[str, Any]]] = {} for item in accepted: grouped.setdefault(item["request_id"], []).append(item) return {request_id: tuple(cases) for request_id, cases in grouped.items()} def _load_ohlcv() -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: with CANONICAL_CSV.open(newline="", encoding="utf-8") as handle: rows = list(csv.DictReader(handle)) return tuple( np.asarray([float(row[name]) for row in rows], dtype=np.float64) for name in ("close", "high", "low", "volume") ) # type: ignore[return-value] def _state_and_transitions(close: np.ndarray, output: np.ndarray) -> tuple[np.ndarray, np.ndarray]: state = np.zeros(output.shape, dtype=np.int8) valid = ~np.isnan(output) state[valid] = np.where(close[valid] > output[valid], 1, -1) transitions = np.zeros(output.shape, dtype=np.bool_) transitions[1:] = state[1:] != state[:-1] return state, transitions def _record_artifact(record: ComparisonRecord) -> dict[str, object]: return record.artifact() def batch01_native_acceptance_manifest(report: dict[str, object]) -> dict[str, object]: """Summarize the resolved Batch01 gate and recompute its submitted coverage.""" variants = [item for item in report["records"] if ":" not in item["name"]] feature_versions = [ FeatureVersion( feature_version=item["name"], primitive_key=item["name"], engineering_family="band_channel", usage_slots=1, status=ParityStatus(item["status"]), ) for item in variants ] accepted = [ item for item in variants if item["reason"] == "accepted_documented_float64_ulp_drift" ] return { "schema_version": 1, "artifact": "BATCH01_NATIVE_ACCEPTANCE_MANIFEST_V1", "parity_manifest": batch01_native_parity_manifest(), "status": "accepted" if report["passed"] else "rejected", "accepted_documented_ulp_variant_count": len(accepted), "accepted_documented_ulp_value_count": sum(item["value_mismatches"] for item in accepted), "coverage": recompute_coverage(feature_versions), } def write_batch01_native_acceptance_manifest(path: Path) -> None: report = evaluate_batch01_native_parity() path.write_bytes(_canonical_bytes(batch01_native_acceptance_manifest(report)) + b"\n") def evaluate_batch01_native_parity() -> dict[str, object]: """Evaluate native Batch01 functions against the immutable oracle NPZ exactly.""" request, result = _require_frozen_artifacts() accepted_cases = _bollinger_resolution() requests = request["requests"] result_requests = {item["request_id"]: item for item in result["requests"]} requested_params = { (int(item["indicator_id"]), int(item["period"]), float(item["p1"])) for item in requests } if requested_params != OBSERVED_BAND_CHANNEL_PARAMS or len(requests) != 97: raise FrozenBatch01ArtifactError("request variants do not match the Batch01 native surface") if set(result_requests) != {item["request_id"] for item in requests}: raise FrozenBatch01ArtifactError("result request records do not match the frozen request") close, high, low, volume = _load_ohlcv() records: list[ComparisonRecord] = [] with np.load(BATCH01_OUTPUTS) as expected_outputs: if set(expected_outputs.files) != set(result_requests): raise FrozenBatch01ArtifactError("NPZ output keys do not match result request records") for item in requests: request_id = item["request_id"] expected = expected_outputs[request_id] metadata = result_requests[request_id] if expected.dtype.str != metadata["dtype"] or list(expected.shape) != metadata["shape"]: raise FrozenBatch01ArtifactError(f"NPZ metadata mismatch for {request_id}") if _array_digest(expected) != metadata["sha256"]: raise FrozenBatch01ArtifactError(f"NPZ value digest mismatch for {request_id}") actual = evaluate_band_channel( int(item["indicator_id"]), close, high, low, volume, int(item["period"]), float(item["p1"]), ) indicator_id = int(item["indicator_id"]) cases = accepted_cases.get(request_id, ()) records.append( compare_float64_ulp( request_id, expected, actual, max_ulps=1, allowed_indexes=frozenset(int(case["index"]) for case in cases), ) if indicator_id in {17, 18} else compare_array(request_id, expected, actual) ) if indicator_id in {19, 28}: expected_state, expected_transitions = _state_and_transitions(close, expected) actual_state, actual_transitions = _state_and_transitions(close, actual) records.append(compare_array(f"{request_id}:state", expected_state, actual_state)) records.append( compare_array( f"{request_id}:transitions", expected_transitions, actual_transitions ) ) failures = [record for record in records if not record.passed] report = { "manifest": batch01_native_parity_manifest(), "records": [_record_artifact(record) for record in records], "passed": not failures, "failure_count": len(failures), "failures": [_record_artifact(record) for record in failures], } report["acceptance_manifest"] = batch01_native_acceptance_manifest(report) return report