diff --git a/apps/node-agent/packaging/build_deb.py b/apps/node-agent/packaging/build_deb.py index f20be49..92f05de 100644 --- a/apps/node-agent/packaging/build_deb.py +++ b/apps/node-agent/packaging/build_deb.py @@ -11,7 +11,7 @@ import sys ROOT = Path(__file__).resolve().parents[1] -VERSION = "0.8.5" +VERSION = "0.8.6" sys.path.insert(0, str(ROOT.parents[1] / "scripts/packaging")) from debian import package diff --git a/docs/audits/2026-09-07-k1-causal-diagnostics-r8.md b/docs/audits/2026-09-07-k1-causal-diagnostics-r8.md new file mode 100644 index 0000000..bb749ef --- /dev/null +++ b/docs/audits/2026-09-07-k1-causal-diagnostics-r8.md @@ -0,0 +1,44 @@ +# Onboard K1 causal diagnostics R8 + +The owner screenshot after R7 corresponds to a new network.provision operation, +not connection.verify. The operation failed at connect-failed in approximately +68 ms with BleakError, side_effect_status=none and network_not_applied. It did +not cross the Wi-Fi dispatch boundary. The service remained active without a +restart. This is distinct from the Linux route-probe TypeError corrected in R7. +The Bluetooth failure origin remains unproven; a missing BlueZ device object +is only a hypothesis and is not grounds for an automatic rescan or write retry. + +The existing journal logger only recorded PluginExecutionError and the facade +wrapper stack. The facade retains the native exception as __cause__, but the +logger did not follow it. The new bounded causal logger records exception class +and basename/function/line for up to six causes and ten frames per cause. It +respects suppressed context and terminates cycles. It never renders exception +messages, source lines, frame locals or payloads. Both journalled and outer +HTTP failure paths use it. Error responses and device admission are unchanged. + +A regression now passes through the actual NodeBridge and plugin facade with +only the service endpoint replaced. It verifies that the native BleakError +location survives the real PluginExecutionError wrapper, exactly one connect +is followed by state observation, and generated secret material is absent from +logs and the response. A second test covers cyclic and suppressed chains. +The earlier test substituted NodeBridge.invoke and therefore never exercised +the wrapper that obscured the installed failure. + +The existing wireless modal also distinguishes its two actions more clearly. +Check K1 state appears before the network fields; the provisioning action is +now labelled Apply Wi-Fi and check. No new controls, permissions, retries, +state machine, profiles or host-network changes are introduced. Final Connect +continues to require current device/session proof. + +Validation: 20 NodeBridge/package lifecycle tests, 23 focused frontend and +architecture checks, 794 full Core frontend tests, Core TypeScript/production +build and scoped Ruff passed. Node 0.8.6 and optional K1 0.1.5 are reserved for +this source. Package, installation and owner UI results will be recorded after +they are observed. This increment improves diagnosis and action clarity; it +does not claim to fix the physical Bluetooth failure. + +The owner screenshot and exact operation result are preserved with UTC and +monotonic collection timestamps and SHA-256 hashes under private/acceptance/ +k1-node085-20260907-bluetooth-1355. Browser cache clearing for that attempt has +not been confirmed. No hardware commands were issued by the agent. The next +physical check remains through the owner UI after clearing browser cache. diff --git a/plugins/xgrids-k1/frontend/src/sensors/DeviceEnrollmentWindow.tsx b/plugins/xgrids-k1/frontend/src/sensors/DeviceEnrollmentWindow.tsx index e5eb9ef..36165a7 100644 --- a/plugins/xgrids-k1/frontend/src/sensors/DeviceEnrollmentWindow.tsx +++ b/plugins/xgrids-k1/frontend/src/sensors/DeviceEnrollmentWindow.tsx @@ -133,10 +133,14 @@ export function DeviceEnrollmentWindow({transport,onChange,onClose,renderWindow} {bluetoothFailure&&
} {selected&&
:undefined} onClick={()=>void run('networks')}>{busy==='networks'?'Ищем сети':'Найти сети'}}> {!confirmed&&<> + {enrollmentAllowed(state,'verify')&& + }
{!!networks.length&&