From 0bab7060370ba99eed731d2454bb6bec095f23be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Wed, 9 Sep 2026 21:48:15 +0800 Subject: [PATCH] fix(collab): derive heartbeat repository head --- .../HB-MPC-0001/EVENT-CONTRACT.json | 1 + .../heartbeat-multipath-console/courier.py | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/eternal-lake-heart/heartbeat-core/office-building-current/control-center/HB-MPC-0001/EVENT-CONTRACT.json b/eternal-lake-heart/heartbeat-core/office-building-current/control-center/HB-MPC-0001/EVENT-CONTRACT.json index 9ac6ab5..e372558 100644 --- a/eternal-lake-heart/heartbeat-core/office-building-current/control-center/HB-MPC-0001/EVENT-CONTRACT.json +++ b/eternal-lake-heart/heartbeat-core/office-building-current/control-center/HB-MPC-0001/EVENT-CONTRACT.json @@ -21,6 +21,7 @@ "ONE_HOST_MAY_NOT_PAUSE_EXIT_OR_RESUME_ANOTHER_HOST", "NO_QUOTA_OR_UNRESPONSIVE_MODEL_MUST_NOT_BE_REPORTED_AS_ONLINE", "COURIER_HEARTBEAT_PROVES_ONLY_DELIVERY_ORGAN_PRESENCE_NOT_MODEL_COGNITION", + "HEARTBEAT_REPO012_HEAD_IS_DETERMINISTICALLY_READ_AND_CALLER_SUPPLIED_MISMATCH_IS_REJECTED", "HUMAN_ABSENCE_ROUTES_FINAL_DECISIONS_TO_WAITING_HUMAN_FINAL_AID_WITHOUT_BLOCKING_SAFE_INDEPENDENT_WORK", "MESSAGE_OR_MODEL_ADVICE_NEVER_GRANTS_REALITY_AUTHORITY" ], diff --git a/server-tools/heartbeat-multipath-console/courier.py b/server-tools/heartbeat-multipath-console/courier.py index 6d0c150..a2e4946 100644 --- a/server-tools/heartbeat-multipath-console/courier.py +++ b/server-tools/heartbeat-multipath-console/courier.py @@ -116,6 +116,19 @@ def prepare_decision_payload(host: str, event_type: str, payload: dict[str, Any] return {**payload, "brain_state": brain_snapshot(host)} +def enrich_heartbeat_payload(event_type: str, payload: dict[str, Any]) -> dict[str, Any]: + if event_type != "HEARTBEAT": + return payload + result = subprocess.run(["git", "-C", str(ROOT), "rev-parse", "HEAD"], text=True, capture_output=True, timeout=10) + if result.returncode or not re.fullmatch(r"[a-f0-9]{40}", result.stdout.strip()): + raise ValueError("REPO012_HEAD_READBACK_FAILED") + observed = result.stdout.strip() + supplied = payload.get("repo012_head") + if supplied is not None and supplied != observed: + raise ValueError(f"REPO012_HEAD_PAYLOAD_MISMATCH:supplied={supplied}:observed={observed}") + return {**payload, "observed_repo012_head": observed} + + def emit(host: str, event_type: str, mentions: list[str], task_id: str | None, payload: dict[str, Any], evidence: list[str]) -> dict[str, Any]: record = host_record(host) endpoint = Path(record["endpoint"]) @@ -126,7 +139,7 @@ def emit(host: str, event_type: str, mentions: list[str], task_id: str | None, p raise ValueError("ENDPOINT_REALPATH_MISMATCH") stamp = datetime.now().astimezone().strftime("%Y%m%dT%H%M%S%f%z") event_id = f"HB-MPC-{record['development_id']}-{stamp}-{uuid.uuid4().hex[:8]}" - payload = prepare_decision_payload(host, event_type, payload) + payload = enrich_heartbeat_payload(event_type, prepare_decision_payload(host, event_type, payload)) event = { "schema": "guanghu.heartbeat-multipath-event/v1", "event_id": event_id,