Compare commits
2 Commits
160cbffbd4
...
8b8fbec63f
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b8fbec63f | |||
| eec490b407 |
20
AGENTS.md
20
AGENTS.md
@ -409,3 +409,23 @@ not degrade into camera-only evidence.
|
|||||||
- [x] Run shell syntax checks, focused contract tests, and package checks.
|
- [x] Run shell syntax checks, focused contract tests, and package checks.
|
||||||
- [x] Push clean semver `0.17.19` for installed client/server testing.
|
- [x] Push clean semver `0.17.19` for installed client/server testing.
|
||||||
- [ ] Re-run only after `LESAVKA_MIC_SOURCE` is listed by the local audio stack.
|
- [ ] Re-run only after `LESAVKA_MIC_SOURCE` is listed by the local audio stack.
|
||||||
|
|
||||||
|
## 0.17.20 Provisional Adaptive Calibration Checklist
|
||||||
|
|
||||||
|
Context: the 0.17.19 adaptive run reached live media and produced browser-visible sync evidence,
|
||||||
|
but the probe still did not calibrate. Each segment either had only 3 coded pairs or an analyzer
|
||||||
|
failure, so the existing `calibration.ready=true` gate refused every adjustment. That was safe for
|
||||||
|
saved defaults, but wrong for the user-directed adaptive probe goal: live segments should be allowed
|
||||||
|
to make bounded provisional corrections from imperfect-but-usable evidence, then let the next segment
|
||||||
|
judge whether the correction helped.
|
||||||
|
|
||||||
|
- [x] Treat the 0.17.19 run as a measurement-only run, not a calibration run.
|
||||||
|
- [x] Keep permanent saved calibration gated by analyzer-ready evidence.
|
||||||
|
- [x] Add provisional adaptive calibration mode enabled by adaptive runs by default.
|
||||||
|
- [x] Allow provisional corrections from low-but-usable paired-pulse reports when p95 and drift are bounded.
|
||||||
|
- [x] Use median skew as the provisional correction source and default to video offset adjustment.
|
||||||
|
- [x] Clamp provisional correction gain and max step so one noisy segment cannot swing the site offset wildly.
|
||||||
|
- [x] Record decision mode and provisional recommendations in segment metrics.
|
||||||
|
- [x] Update manual probe contract tests for provisional calibration controls and output.
|
||||||
|
- [x] Run shell syntax checks, focused contract tests, and package checks.
|
||||||
|
- [x] Push clean semver `0.17.20` for installed client/server testing.
|
||||||
|
|||||||
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.17.19"
|
version = "0.17.20"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-stream",
|
"async-stream",
|
||||||
@ -1686,7 +1686,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.17.19"
|
version = "0.17.20"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
@ -1698,7 +1698,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.17.19"
|
version = "0.17.20"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
@ -4,7 +4,7 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.17.19"
|
version = "0.17.20"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.17.19"
|
version = "0.17.20"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,12 @@ LESAVKA_SYNC_CALIBRATION_SEGMENTS=${LESAVKA_SYNC_CALIBRATION_SEGMENTS:-1}
|
|||||||
LESAVKA_SYNC_CONTINUOUS_BROWSER=${LESAVKA_SYNC_CONTINUOUS_BROWSER:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}
|
LESAVKA_SYNC_CONTINUOUS_BROWSER=${LESAVKA_SYNC_CONTINUOUS_BROWSER:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}
|
||||||
LESAVKA_SYNC_CONTINUE_ON_ANALYSIS_FAILURE=${LESAVKA_SYNC_CONTINUE_ON_ANALYSIS_FAILURE:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}
|
LESAVKA_SYNC_CONTINUE_ON_ANALYSIS_FAILURE=${LESAVKA_SYNC_CONTINUE_ON_ANALYSIS_FAILURE:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}
|
||||||
LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS=${LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS:-3}
|
LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS=${LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS:-3}
|
||||||
|
LESAVKA_SYNC_PROVISIONAL_CALIBRATION=${LESAVKA_SYNC_PROVISIONAL_CALIBRATION:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}
|
||||||
|
LESAVKA_SYNC_PROVISIONAL_MIN_PAIRS=${LESAVKA_SYNC_PROVISIONAL_MIN_PAIRS:-3}
|
||||||
|
LESAVKA_SYNC_PROVISIONAL_MAX_P95_MS=${LESAVKA_SYNC_PROVISIONAL_MAX_P95_MS:-350}
|
||||||
|
LESAVKA_SYNC_PROVISIONAL_MAX_DRIFT_MS=${LESAVKA_SYNC_PROVISIONAL_MAX_DRIFT_MS:-250}
|
||||||
|
LESAVKA_SYNC_PROVISIONAL_GAIN=${LESAVKA_SYNC_PROVISIONAL_GAIN:-0.5}
|
||||||
|
LESAVKA_SYNC_PROVISIONAL_MAX_STEP_US=${LESAVKA_SYNC_PROVISIONAL_MAX_STEP_US:-150000}
|
||||||
STIMULUS_PORT=${STIMULUS_PORT:-18444}
|
STIMULUS_PORT=${STIMULUS_PORT:-18444}
|
||||||
STIMULUS_SETTLE_SECONDS=${STIMULUS_SETTLE_SECONDS:-10}
|
STIMULUS_SETTLE_SECONDS=${STIMULUS_SETTLE_SECONDS:-10}
|
||||||
LOCAL_OUTPUT_DIR=${LOCAL_OUTPUT_DIR:-"${REPO_ROOT}/tmp"}
|
LOCAL_OUTPUT_DIR=${LOCAL_OUTPUT_DIR:-"${REPO_ROOT}/tmp"}
|
||||||
@ -289,6 +295,8 @@ maybe_apply_probe_calibration() {
|
|||||||
local summary
|
local summary
|
||||||
if ! summary="$(python3 - "${report_json}" "${LESAVKA_SYNC_CALIBRATION_TARGET}" <<'PY'
|
if ! summary="$(python3 - "${report_json}" "${LESAVKA_SYNC_CALIBRATION_TARGET}" <<'PY'
|
||||||
import json
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -302,25 +310,115 @@ verdict = report.get("verdict", {})
|
|||||||
if target not in {"audio", "video"}:
|
if target not in {"audio", "video"}:
|
||||||
target = "video"
|
target = "video"
|
||||||
|
|
||||||
audio_recommendation = int(cal.get("recommended_audio_offset_adjust_us") or 0)
|
def env_bool(name, default=False):
|
||||||
video_recommendation = int(cal.get("recommended_video_offset_adjust_us") or 0)
|
raw = os.environ.get(name)
|
||||||
|
if raw is None:
|
||||||
|
return default
|
||||||
|
return raw.strip().lower() in {"1", "true", "yes", "on"}
|
||||||
|
|
||||||
|
def env_int(name, default):
|
||||||
|
try:
|
||||||
|
return int(os.environ.get(name, str(default)))
|
||||||
|
except ValueError:
|
||||||
|
return default
|
||||||
|
|
||||||
|
def env_float(name, default):
|
||||||
|
try:
|
||||||
|
return float(os.environ.get(name, str(default)))
|
||||||
|
except ValueError:
|
||||||
|
return default
|
||||||
|
|
||||||
|
def as_float(value, default=0.0):
|
||||||
|
try:
|
||||||
|
parsed = float(value)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return default
|
||||||
|
return parsed if math.isfinite(parsed) else default
|
||||||
|
|
||||||
|
def clamp(value, limit):
|
||||||
|
limit = abs(int(limit))
|
||||||
|
return max(-limit, min(limit, int(round(value))))
|
||||||
|
|
||||||
|
ready = bool(cal.get("ready"))
|
||||||
|
paired_pulses = int(report.get("paired_event_count", 0) or 0)
|
||||||
|
median_skew_ms = as_float(report.get("median_skew_ms", 0.0))
|
||||||
|
p95_abs_skew_ms = as_float(verdict.get("p95_abs_skew_ms", 0.0))
|
||||||
|
drift_ms = as_float(report.get("drift_ms", 0.0))
|
||||||
|
|
||||||
|
provisional_enabled = env_bool("LESAVKA_SYNC_PROVISIONAL_CALIBRATION", False)
|
||||||
|
provisional_min_pairs = env_int("LESAVKA_SYNC_PROVISIONAL_MIN_PAIRS", 3)
|
||||||
|
provisional_max_p95_ms = env_float("LESAVKA_SYNC_PROVISIONAL_MAX_P95_MS", 350.0)
|
||||||
|
provisional_max_drift_ms = env_float("LESAVKA_SYNC_PROVISIONAL_MAX_DRIFT_MS", 250.0)
|
||||||
|
provisional_gain = env_float("LESAVKA_SYNC_PROVISIONAL_GAIN", 0.5)
|
||||||
|
provisional_max_step_us = env_int("LESAVKA_SYNC_PROVISIONAL_MAX_STEP_US", 150000)
|
||||||
|
|
||||||
|
ready_audio_recommendation = int(cal.get("recommended_audio_offset_adjust_us") or 0)
|
||||||
|
ready_video_recommendation = int(cal.get("recommended_video_offset_adjust_us") or 0)
|
||||||
|
provisional_audio_recommendation = int(round(-median_skew_ms * 1000.0))
|
||||||
|
provisional_video_recommendation = int(round(median_skew_ms * 1000.0))
|
||||||
|
|
||||||
|
audio_recommendation = ready_audio_recommendation
|
||||||
|
video_recommendation = ready_video_recommendation
|
||||||
audio_delta = audio_recommendation if target == "audio" else 0
|
audio_delta = audio_recommendation if target == "audio" else 0
|
||||||
video_delta = video_recommendation if target == "video" else 0
|
video_delta = video_recommendation if target == "video" else 0
|
||||||
|
decision_mode = "ready" if ready else "refused"
|
||||||
|
decision_note = "analyzer marked this report calibration-ready" if ready else "analyzer did not mark this report calibration-ready"
|
||||||
|
|
||||||
|
if not ready and provisional_enabled:
|
||||||
|
refusal_reasons = []
|
||||||
|
if paired_pulses < provisional_min_pairs:
|
||||||
|
refusal_reasons.append(f"paired_pulses {paired_pulses} < {provisional_min_pairs}")
|
||||||
|
if p95_abs_skew_ms > provisional_max_p95_ms:
|
||||||
|
refusal_reasons.append(f"p95_abs_skew_ms {p95_abs_skew_ms:.1f} > {provisional_max_p95_ms:.1f}")
|
||||||
|
if abs(drift_ms) > provisional_max_drift_ms:
|
||||||
|
refusal_reasons.append(f"abs(drift_ms) {abs(drift_ms):.1f} > {provisional_max_drift_ms:.1f}")
|
||||||
|
|
||||||
|
if refusal_reasons:
|
||||||
|
decision_note = "provisional calibration refused: " + "; ".join(refusal_reasons)
|
||||||
|
else:
|
||||||
|
audio_recommendation = provisional_audio_recommendation
|
||||||
|
video_recommendation = provisional_video_recommendation
|
||||||
|
if target == "audio":
|
||||||
|
audio_delta = clamp(audio_recommendation * provisional_gain, provisional_max_step_us)
|
||||||
|
video_delta = 0
|
||||||
|
else:
|
||||||
|
audio_delta = 0
|
||||||
|
video_delta = clamp(video_recommendation * provisional_gain, provisional_max_step_us)
|
||||||
|
if audio_delta == 0 and video_delta == 0:
|
||||||
|
decision_note = "provisional calibration skipped: rounded correction was zero"
|
||||||
|
else:
|
||||||
|
decision_mode = "provisional"
|
||||||
|
decision_note = (
|
||||||
|
"bounded provisional correction from median skew; "
|
||||||
|
"not safe to save until a confirming ready report"
|
||||||
|
)
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
"report_json": report_path,
|
"report_json": report_path,
|
||||||
"calibration_ready": str(bool(cal.get("ready"))).lower(),
|
"calibration_ready": str(ready).lower(),
|
||||||
"calibration_target": target,
|
"calibration_target": target,
|
||||||
|
"calibration_decision_mode": decision_mode,
|
||||||
|
"calibration_decision_note": decision_note,
|
||||||
"calibration_audio_recommendation_us": audio_recommendation,
|
"calibration_audio_recommendation_us": audio_recommendation,
|
||||||
"calibration_video_recommendation_us": video_recommendation,
|
"calibration_video_recommendation_us": video_recommendation,
|
||||||
|
"calibration_ready_audio_recommendation_us": ready_audio_recommendation,
|
||||||
|
"calibration_ready_video_recommendation_us": ready_video_recommendation,
|
||||||
|
"calibration_provisional_audio_recommendation_us": provisional_audio_recommendation,
|
||||||
|
"calibration_provisional_video_recommendation_us": provisional_video_recommendation,
|
||||||
"calibration_apply_audio_delta_us": audio_delta,
|
"calibration_apply_audio_delta_us": audio_delta,
|
||||||
"calibration_apply_video_delta_us": video_delta,
|
"calibration_apply_video_delta_us": video_delta,
|
||||||
"calibration_note": cal.get("note", ""),
|
"calibration_note": cal.get("note", ""),
|
||||||
|
"provisional_calibration_enabled": str(provisional_enabled).lower(),
|
||||||
|
"provisional_min_pairs": provisional_min_pairs,
|
||||||
|
"provisional_max_p95_ms": f"{provisional_max_p95_ms:.1f}",
|
||||||
|
"provisional_max_drift_ms": f"{provisional_max_drift_ms:.1f}",
|
||||||
|
"provisional_gain": f"{provisional_gain:.3f}",
|
||||||
|
"provisional_max_step_us": provisional_max_step_us,
|
||||||
"verdict_status": verdict.get("status", ""),
|
"verdict_status": verdict.get("status", ""),
|
||||||
"paired_pulses": report.get("paired_event_count", 0),
|
"paired_pulses": paired_pulses,
|
||||||
"median_skew_ms": f"{float(report.get('median_skew_ms', 0.0)):+.1f}",
|
"median_skew_ms": f"{median_skew_ms:+.1f}",
|
||||||
"p95_abs_skew_ms": f"{float(verdict.get('p95_abs_skew_ms', 0.0)):.1f}",
|
"p95_abs_skew_ms": f"{p95_abs_skew_ms:.1f}",
|
||||||
"drift_ms": f"{float(report.get('drift_ms', 0.0)):+.1f}",
|
"drift_ms": f"{drift_ms:+.1f}",
|
||||||
}
|
}
|
||||||
for key, value in fields.items():
|
for key, value in fields.items():
|
||||||
print(f"{key}={shlex.quote(str(value))}")
|
print(f"{key}={shlex.quote(str(value))}")
|
||||||
@ -340,16 +438,28 @@ PY
|
|||||||
echo " ↪ drift_ms=${drift_ms}"
|
echo " ↪ drift_ms=${drift_ms}"
|
||||||
echo " ↪ calibration_ready=${calibration_ready}"
|
echo " ↪ calibration_ready=${calibration_ready}"
|
||||||
echo " ↪ calibration_target=${calibration_target}"
|
echo " ↪ calibration_target=${calibration_target}"
|
||||||
|
echo " ↪ calibration_decision_mode=${calibration_decision_mode}"
|
||||||
echo " ↪ recommended_audio_offset_adjust_us=${calibration_audio_recommendation_us}"
|
echo " ↪ recommended_audio_offset_adjust_us=${calibration_audio_recommendation_us}"
|
||||||
echo " ↪ recommended_video_offset_adjust_us=${calibration_video_recommendation_us}"
|
echo " ↪ recommended_video_offset_adjust_us=${calibration_video_recommendation_us}"
|
||||||
|
echo " ↪ ready_audio_offset_adjust_us=${calibration_ready_audio_recommendation_us}"
|
||||||
|
echo " ↪ ready_video_offset_adjust_us=${calibration_ready_video_recommendation_us}"
|
||||||
|
echo " ↪ provisional_audio_offset_adjust_us=${calibration_provisional_audio_recommendation_us}"
|
||||||
|
echo " ↪ provisional_video_offset_adjust_us=${calibration_provisional_video_recommendation_us}"
|
||||||
|
echo " ↪ provisional_calibration_enabled=${provisional_calibration_enabled}"
|
||||||
|
echo " ↪ provisional_min_pairs=${provisional_min_pairs}"
|
||||||
|
echo " ↪ provisional_max_p95_ms=${provisional_max_p95_ms}"
|
||||||
|
echo " ↪ provisional_max_drift_ms=${provisional_max_drift_ms}"
|
||||||
|
echo " ↪ provisional_gain=${provisional_gain}"
|
||||||
|
echo " ↪ provisional_max_step_us=${provisional_max_step_us}"
|
||||||
echo " ↪ calibration_note=${calibration_note}"
|
echo " ↪ calibration_note=${calibration_note}"
|
||||||
|
echo " ↪ calibration_decision_note=${calibration_decision_note}"
|
||||||
|
|
||||||
if [[ "${LESAVKA_SYNC_APPLY_CALIBRATION}" != "1" ]]; then
|
if [[ "${LESAVKA_SYNC_APPLY_CALIBRATION}" != "1" ]]; then
|
||||||
echo " ↪ calibration apply disabled; set LESAVKA_SYNC_APPLY_CALIBRATION=1 to apply a ready recommendation"
|
echo " ↪ calibration apply disabled; set LESAVKA_SYNC_APPLY_CALIBRATION=1 to apply ready or provisional recommendations"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
if [[ "${calibration_ready}" != "true" ]]; then
|
if [[ "${calibration_decision_mode}" == "refused" ]]; then
|
||||||
echo " ↪ calibration apply refused: analyzer did not mark this report calibration-ready"
|
echo " ↪ calibration apply refused: ${calibration_decision_note}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
if [[ "${calibration_apply_audio_delta_us}" == "0" && "${calibration_apply_video_delta_us}" == "0" ]]; then
|
if [[ "${calibration_apply_audio_delta_us}" == "0" && "${calibration_apply_video_delta_us}" == "0" ]]; then
|
||||||
@ -357,7 +467,7 @@ PY
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local note="mirrored probe ${STAMP} ${label}: target=${calibration_target}, median=${median_skew_ms}ms, p95=${p95_abs_skew_ms}ms, pairs=${paired_pulses}"
|
local note="mirrored probe ${STAMP} ${label}: mode=${calibration_decision_mode}, target=${calibration_target}, median=${median_skew_ms}ms, p95=${p95_abs_skew_ms}ms, pairs=${paired_pulses}"
|
||||||
echo " ↪ applying calibration: audio_delta_us=${calibration_apply_audio_delta_us}, video_delta_us=${calibration_apply_video_delta_us}"
|
echo " ↪ applying calibration: audio_delta_us=${calibration_apply_audio_delta_us}, video_delta_us=${calibration_apply_video_delta_us}"
|
||||||
LESAVKA_TLS_DOMAIN="${LESAVKA_TLS_DOMAIN}" \
|
LESAVKA_TLS_DOMAIN="${LESAVKA_TLS_DOMAIN}" \
|
||||||
"${REPO_ROOT}/target/debug/lesavka-relayctl" \
|
"${REPO_ROOT}/target/debug/lesavka-relayctl" \
|
||||||
@ -365,13 +475,15 @@ PY
|
|||||||
calibrate "${calibration_apply_audio_delta_us}" "${calibration_apply_video_delta_us}" "${note}" \
|
calibrate "${calibration_apply_audio_delta_us}" "${calibration_apply_video_delta_us}" "${note}" \
|
||||||
| sed 's/^/ ↪ /'
|
| sed 's/^/ ↪ /'
|
||||||
|
|
||||||
if [[ "${LESAVKA_SYNC_SAVE_CALIBRATION}" == "1" ]]; then
|
if [[ "${LESAVKA_SYNC_SAVE_CALIBRATION}" == "1" && "${calibration_decision_mode}" == "ready" ]]; then
|
||||||
echo " ↪ saving active calibration as site default"
|
echo " ↪ saving active calibration as site default"
|
||||||
LESAVKA_TLS_DOMAIN="${LESAVKA_TLS_DOMAIN}" \
|
LESAVKA_TLS_DOMAIN="${LESAVKA_TLS_DOMAIN}" \
|
||||||
"${REPO_ROOT}/target/debug/lesavka-relayctl" \
|
"${REPO_ROOT}/target/debug/lesavka-relayctl" \
|
||||||
--server "${RESOLVED_LESAVKA_SERVER_ADDR}" \
|
--server "${RESOLVED_LESAVKA_SERVER_ADDR}" \
|
||||||
calibration-save-default \
|
calibration-save-default \
|
||||||
| sed 's/^/ ↪ /'
|
| sed 's/^/ ↪ /'
|
||||||
|
elif [[ "${LESAVKA_SYNC_SAVE_CALIBRATION}" == "1" ]]; then
|
||||||
|
echo " ↪ provisional calibration not saved; require a confirming ready rerun before saving defaults"
|
||||||
else
|
else
|
||||||
echo " ↪ active calibration not saved; set LESAVKA_SYNC_SAVE_CALIBRATION=1 after a confirming rerun"
|
echo " ↪ active calibration not saved; set LESAVKA_SYNC_SAVE_CALIBRATION=1 after a confirming rerun"
|
||||||
fi
|
fi
|
||||||
@ -595,8 +707,12 @@ for segment in range(1, segment_count + 1):
|
|||||||
"analysis_raw_first_audio_activity_s": as_float(str(failure.get("raw_first_audio_activity_s", ""))),
|
"analysis_raw_first_audio_activity_s": as_float(str(failure.get("raw_first_audio_activity_s", ""))),
|
||||||
"calibration_ready": bool(calibration.get("ready", False)),
|
"calibration_ready": bool(calibration.get("ready", False)),
|
||||||
"calibration_note": calibration.get("note", ""),
|
"calibration_note": calibration.get("note", ""),
|
||||||
|
"decision_mode": decision.get("calibration_decision_mode", ""),
|
||||||
|
"decision_note": decision.get("calibration_decision_note", ""),
|
||||||
"decision_video_delta_us": as_float(decision.get("calibration_apply_video_delta_us")),
|
"decision_video_delta_us": as_float(decision.get("calibration_apply_video_delta_us")),
|
||||||
"decision_audio_delta_us": as_float(decision.get("calibration_apply_audio_delta_us")),
|
"decision_audio_delta_us": as_float(decision.get("calibration_apply_audio_delta_us")),
|
||||||
|
"decision_provisional_video_recommendation_us": as_float(decision.get("calibration_provisional_video_recommendation_us")),
|
||||||
|
"decision_provisional_audio_recommendation_us": as_float(decision.get("calibration_provisional_audio_recommendation_us")),
|
||||||
"planner_phase_before": planner_before.get("planner_phase", ""),
|
"planner_phase_before": planner_before.get("planner_phase", ""),
|
||||||
"planner_phase_after": planner_after.get("planner_phase", ""),
|
"planner_phase_after": planner_after.get("planner_phase", ""),
|
||||||
"planner_live_lag_ms_before": as_float(planner_before.get("planner_live_lag_ms")),
|
"planner_live_lag_ms_before": as_float(planner_before.get("planner_live_lag_ms")),
|
||||||
|
|||||||
@ -10,7 +10,7 @@ bench = false
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.17.19"
|
version = "0.17.20"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
autobins = false
|
autobins = false
|
||||||
|
|
||||||
|
|||||||
@ -127,6 +127,12 @@ fn mirrored_sync_script_uses_real_client_capture_path() {
|
|||||||
"LESAVKA_SYNC_CONTINUOUS_BROWSER=${LESAVKA_SYNC_CONTINUOUS_BROWSER:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}",
|
"LESAVKA_SYNC_CONTINUOUS_BROWSER=${LESAVKA_SYNC_CONTINUOUS_BROWSER:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}",
|
||||||
"LESAVKA_SYNC_CONTINUE_ON_ANALYSIS_FAILURE=${LESAVKA_SYNC_CONTINUE_ON_ANALYSIS_FAILURE:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}",
|
"LESAVKA_SYNC_CONTINUE_ON_ANALYSIS_FAILURE=${LESAVKA_SYNC_CONTINUE_ON_ANALYSIS_FAILURE:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}",
|
||||||
"LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS=${LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS:-3}",
|
"LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS=${LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS:-3}",
|
||||||
|
"LESAVKA_SYNC_PROVISIONAL_CALIBRATION=${LESAVKA_SYNC_PROVISIONAL_CALIBRATION:-${LESAVKA_SYNC_ADAPTIVE_CALIBRATION}}",
|
||||||
|
"LESAVKA_SYNC_PROVISIONAL_MIN_PAIRS=${LESAVKA_SYNC_PROVISIONAL_MIN_PAIRS:-3}",
|
||||||
|
"LESAVKA_SYNC_PROVISIONAL_MAX_P95_MS=${LESAVKA_SYNC_PROVISIONAL_MAX_P95_MS:-350}",
|
||||||
|
"LESAVKA_SYNC_PROVISIONAL_MAX_DRIFT_MS=${LESAVKA_SYNC_PROVISIONAL_MAX_DRIFT_MS:-250}",
|
||||||
|
"LESAVKA_SYNC_PROVISIONAL_GAIN=${LESAVKA_SYNC_PROVISIONAL_GAIN:-0.5}",
|
||||||
|
"LESAVKA_SYNC_PROVISIONAL_MAX_STEP_US=${LESAVKA_SYNC_PROVISIONAL_MAX_STEP_US:-150000}",
|
||||||
"LESAVKA_SYNC_ADAPTIVE_CALIBRATION",
|
"LESAVKA_SYNC_ADAPTIVE_CALIBRATION",
|
||||||
"LESAVKA_SYNC_CALIBRATION_SEGMENTS=4",
|
"LESAVKA_SYNC_CALIBRATION_SEGMENTS=4",
|
||||||
"browser_consumer_reuse_session=${reuse_browser_session}",
|
"browser_consumer_reuse_session=${reuse_browser_session}",
|
||||||
@ -147,13 +153,18 @@ fn mirrored_sync_script_uses_real_client_capture_path() {
|
|||||||
"probe_activity_start_delta_ms",
|
"probe_activity_start_delta_ms",
|
||||||
"blind-targets.json",
|
"blind-targets.json",
|
||||||
"no segment produced a passing probe verdict; refusing to invent blind targets",
|
"no segment produced a passing probe verdict; refusing to invent blind targets",
|
||||||
|
"decision_mode",
|
||||||
|
"decision_provisional_video_recommendation_us",
|
||||||
"planner_live_lag_ms_after",
|
"planner_live_lag_ms_after",
|
||||||
"probe_p95_abs_skew_ms",
|
"probe_p95_abs_skew_ms",
|
||||||
"settling ${LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS}s before next calibration segment",
|
"settling ${LESAVKA_SYNC_SEGMENT_SETTLE_SECONDS}s before next calibration segment",
|
||||||
"print_upstream_calibration_state \"before mirrored run\"",
|
"print_upstream_calibration_state \"before mirrored run\"",
|
||||||
"maybe_apply_probe_calibration",
|
"maybe_apply_probe_calibration",
|
||||||
"calibration_ready=${calibration_ready}",
|
"calibration_ready=${calibration_ready}",
|
||||||
"calibration apply refused: analyzer did not mark this report calibration-ready",
|
"calibration_decision_mode=${calibration_decision_mode}",
|
||||||
|
"bounded provisional correction from median skew",
|
||||||
|
"provisional calibration not saved",
|
||||||
|
"calibration apply refused: ${calibration_decision_note}",
|
||||||
"calibrate \"${calibration_apply_audio_delta_us}\" \"${calibration_apply_video_delta_us}\"",
|
"calibrate \"${calibration_apply_audio_delta_us}\" \"${calibration_apply_video_delta_us}\"",
|
||||||
"calibration-save-default",
|
"calibration-save-default",
|
||||||
"print_upstream_sync_state \"after mirrored run\"",
|
"print_upstream_sync_state \"after mirrored run\"",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user