Unify K1 discovery ownership and verification across enrollment paths

This commit is contained in:
DCCONSTRUCTIONS
2026-09-07 20:04:46 +03:00
parent 9c4d70b0e9
commit 762d77ef95
27 changed files with 615 additions and 191 deletions
+57
View File
@@ -198,6 +198,33 @@ def test_failure_locations_respects_suppression_and_bounds_cyclic_chains():
assert failure_locations(first) == "RuntimeError[]"
def test_native_failure_facts_keep_stage_and_write_boundary_without_messages():
from bleak.exc import BleakDBusError
from k1link.device_plugins.xgrids_k1.node_bridge import failure_transport_facts
secret = secrets.token_hex(20)
native = BleakDBusError("org.bluez.Error.InProgress", [secret])
native.operation_stage = "resolution"
native.device_write_attempted = False
native.device_write_confirmed = False
wrapper = RuntimeError(secret)
wrapper.__cause__ = native
facts = failure_transport_facts(wrapper)
assert facts == (
"stage=resolution bluez=org.bluez.Error.InProgress "
"device_write_attempted=False device_write_confirmed=False"
)
assert secret not in facts
native = BleakDBusError(secret, [secret])
native.operation_stage = secret
wrapper.__cause__ = native
assert secret not in failure_transport_facts(wrapper)
wrapper.__suppress_context__ = True
wrapper.__cause__ = None
assert failure_transport_facts(wrapper) == "unavailable"
def test_node_scan_reaches_service_through_real_facade_with_runtime_fence():
"""Exercise the actual admission boundary, replacing only the BLE service."""
from k1link.device_plugins.xgrids_k1.facade import SnapshotRuntimeConflict
@@ -640,6 +667,9 @@ def test_recheck_uses_only_exact_admitted_durable_bridge_target():
assert result["source"] == "durable-configured-state"
assert result["device_id"] == current["selected_device_id"]
assert result["expected_mode_revision"] == current["desired_connection_mode_revision"]
assert "source" not in verification_parameters(
current, "synthetic-operation", requested_device_id="other-device",
)
for patch in [{"allowed": False}, {"requires_live_gatt_validation": True},
{"required_connection_mode": "quick-connect"},
{"required_transport_ref": "other"}]:
@@ -648,3 +678,30 @@ def test_recheck_uses_only_exact_admitted_durable_bridge_target():
decision.update(allowed=True, requires_live_gatt_validation=False,
required_transport_ref=current["selected_device_id"],
required_connection_mode="bridge")
@pytest.mark.parametrize("requires_gatt", [False, True])
def test_enrollment_verify_and_detail_share_durable_target_admission(requires_gatt):
async def run():
device = bridge()
current = device.facade.current
current["connection_policy"] = {"actions": {"observe-configured-device-network": {
"allowed": True, "requires_live_gatt_validation": requires_gatt,
"required_connection_mode": "bridge",
"required_transport_ref": current["selected_device_id"],
}}}
command = {
"operation_id": "op_" + "d" * 32, "action": "verify", "runtime_id": "runtime-one",
"deadline_at": (datetime.now(UTC) + timedelta(seconds=60)).isoformat(),
"parameters": {"device_id": current["selected_device_id"],
"discovery_generation": 1, "mode_revision": 0},
}
await device.execute(command)
actions = [(a, p) for a, p in device.facade.actions if a != "state.read"]
assert len(actions) == 1 and actions[0][0] == "connection.verify"
payload = actions[0][1]
assert (payload.get("source") == "durable-configured-state") is not requires_gatt
assert payload["device_id"] == current["selected_device_id"]
assert payload["expected_discovery_generation"] == 1
assert "password" not in payload
asyncio.run(run())