fix(k1): record redacted acceptance failures

This commit is contained in:
DCCONSTRUCTIONS
2026-07-18 16:11:29 +03:00
parent eddc09008e
commit a29b38a0d7
6 changed files with 187 additions and 18 deletions
@@ -1,5 +1,6 @@
from __future__ import annotations
import hashlib
import math
import threading
import time
@@ -8,6 +9,7 @@ from dataclasses import dataclass
from typing import Literal, Protocol
from k1link.device_plugins.xgrids_k1.protocol.application_bootstrap import (
ApplicationBootstrapError,
LiveDeviceControlBinding,
ShadowApplicationBootstrapOrchestrator,
)
@@ -19,6 +21,7 @@ from k1link.device_plugins.xgrids_k1.protocol.application_publish import (
)
from k1link.device_plugins.xgrids_k1.protocol.modeling_control import (
ModelingAction,
ModelingProtocolError,
ModelingResponse,
correlate_modeling_response,
)
@@ -130,6 +133,8 @@ class PhysicalAcceptanceDialogueExecutor:
self._permit = permit
self._bootstrap_complete = False
self._command_complete = False
self._response_evidence: list[dict[str, object]] = []
self._correlation_failure: dict[str, object] | None = None
def run_bootstrap(
self,
@@ -151,10 +156,30 @@ class PhysicalAcceptanceDialogueExecutor:
)
for request in batch:
if request.response_required:
orchestrator.accept_response(
request.response_topic,
responses[request.response_topic],
payload = responses[request.response_topic]
self._record_response_evidence(
phase="bootstrap",
operation_key=(
f"bootstrap:{request.ordinal}:{request.message_type}"
),
response_topic=request.response_topic,
payload=payload,
)
try:
orchestrator.accept_response(request.response_topic, payload)
except ApplicationBootstrapError as exc:
self._record_correlation_failure(
phase="bootstrap",
operation_key=(
f"bootstrap:{request.ordinal}:{request.message_type}"
),
response_topic=request.response_topic,
reason=str(exc),
)
raise ApplicationAcceptanceError(
"bootstrap response correlation failed for "
f"ordinal {request.ordinal} ({request.message_type}): {exc}"
) from exc
binding = orchestrator.binding
if binding is None:
@@ -173,10 +198,25 @@ class PhysicalAcceptanceDialogueExecutor:
[OneShotPublishEnvelope.from_modeling_command(command)],
required_response_topics={MODELING_RESPONSE_TOPIC},
)
return correlate_modeling_response(
responses[MODELING_RESPONSE_TOPIC],
command.command,
payload = responses[MODELING_RESPONSE_TOPIC]
self._record_response_evidence(
phase="modeling",
operation_key=f"modeling:{command.action.name.casefold()}",
response_topic=MODELING_RESPONSE_TOPIC,
payload=payload,
)
try:
return correlate_modeling_response(payload, command.command)
except ModelingProtocolError as exc:
self._record_correlation_failure(
phase="modeling",
operation_key=f"modeling:{command.action.name.casefold()}",
response_topic=MODELING_RESPONSE_TOPIC,
reason=str(exc),
)
raise ApplicationAcceptanceError(
f"modeling response correlation failed for {command.action.name}: {exc}"
) from exc
def snapshot(self) -> dict[str, object]:
return {
@@ -184,5 +224,44 @@ class PhysicalAcceptanceDialogueExecutor:
"bootstrap_complete": self._bootstrap_complete,
"command_complete": self._command_complete,
"permit": self._permit.snapshot(),
"response_evidence": tuple(dict(item) for item in self._response_evidence),
"correlation_failure": (
dict(self._correlation_failure)
if self._correlation_failure is not None
else None
),
"automatic_retry": False,
}
def _record_response_evidence(
self,
*,
phase: Literal["bootstrap", "modeling"],
operation_key: str,
response_topic: str,
payload: bytes,
) -> None:
self._response_evidence.append(
{
"phase": phase,
"operation_key": operation_key,
"response_topic": response_topic,
"payload_bytes": len(payload),
"payload_sha256": hashlib.sha256(payload).hexdigest(),
}
)
def _record_correlation_failure(
self,
*,
phase: Literal["bootstrap", "modeling"],
operation_key: str,
response_topic: str,
reason: str,
) -> None:
self._correlation_failure = {
"phase": phase,
"operation_key": operation_key,
"response_topic": response_topic,
"reason": reason,
}