#!/usr/bin/env bash set -uo pipefail # CASAN H6 — local-vs-provider telemetry reconciliation (D2). # Provider-API usage records are the billing ground truth; local metrics must # not under-report tokens (the cost-hiding attack: trim local metrics so a # runaway/exfil step looks cheap). Per step, local claimed tokens must cover # provider-reported tokens within a tolerance; a provider step entirely absent # from local metrics is also a discrepancy (hidden run). # # Usage: telemetry-reconcile.sh [tolerance_pct] # # Greppable outputs: TELEMETRY_RECONCILED | TELEMETRY_DISCREPANCY LOCAL_LOG="${1:-}" PROVIDER_LOG="${2:-}" TOLERANCE_PCT="${3:-10}" if [[ -z "$LOCAL_LOG" || -z "$PROVIDER_LOG" || ! -f "$PROVIDER_LOG" ]]; then echo "Usage: telemetry-reconcile.sh [tolerance_pct]" >&2 exit 64 fi python - "$LOCAL_LOG" "$PROVIDER_LOG" "$TOLERANCE_PCT" <<'PY' import json import sys local_path, provider_path, tol_pct = sys.argv[1], sys.argv[2], float(sys.argv[3]) def sums_by_step(path): totals = {} try: with open(path, encoding="utf-8") as fh: for line in fh: line = line.strip() if not line: continue rec = json.loads(line) step = rec.get("step") if step is None: continue totals[step] = totals.get(step, 0) + int(rec.get("total_tokens", 0)) except OSError: pass return totals local = sums_by_step(local_path) provider = sums_by_step(provider_path) if not provider: raise SystemExit("TELEMETRY_DISCREPANCY provider log empty — nothing to reconcile against") issues = [] for step, prov_tokens in sorted(provider.items()): loc_tokens = local.get(step) if loc_tokens is None: issues.append(f"step={step} local=MISSING provider={prov_tokens}") continue floor = prov_tokens * (1 - tol_pct / 100.0) if loc_tokens < floor: issues.append(f"step={step} local={loc_tokens} provider={prov_tokens} (under-reported beyond {tol_pct}%)") if issues: for issue in issues: print(f"TELEMETRY_DISCREPANCY {issue}", file=sys.stderr) raise SystemExit(1) print(f"TELEMETRY_RECONCILED steps={len(provider)} tolerance_pct={tol_pct}") PY exit $?