Files
NODEDC_MISSION_CORE/apps/control-station/test/k1SupervisorPresentation.test.mjs
T
DCCONSTRUCTIONS 1c7dd29d8a chore(node): preserve pre-canonicalization experiment snapshot
Historical working copy retained for audit before consolidation into main. The canonicalized plugin architecture and later fixes already live in main; this snapshot is not a release or a request to restore obsolete source layout.
2026-09-21 08:45:34 +03:00

7771 lines
271 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { after, before, test } from "node:test";
import React, { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { createServer } from "vite";
let server;
let normalizeXgridsK1MissionState;
let xgridsK1Manifest;
let workspaces;
let connectionModeOptions;
let K1Metrics;
let K1ConnectionPipelines;
let physicalRecoveryConnectionDetail;
let shouldRenderK1OperationalPanels;
let K1ProvisioningPipeline;
let RuntimeActionFenceTestContext;
let LOCAL_OPERATION_PROGRESS_DELAY_MILLISECONDS;
let emptySearchPresentation;
let emptyProvisioningAttemptPresentation;
let emptyReadOnlyReconnectPresentation;
let provisioningAttemptViewState;
let unavailablePhysicalRetirementAuthority;
let connectionAttemptOwnsAppliedNetworkRecovery;
let connectionRecoveryObservationTargetMatches;
let connectionRecoveryEscapeKey;
let connectionRecoveryEscapeAfterScan;
let connectionRecoveryIsRequired;
let clearConnectionFailureAfterSuccessfulRefresh;
let dispatchConnectionRecoveryObservationForCurrentRuntime;
let dispatchUnavailablePhysicalRetirementForCurrentRuntime;
let dispatchRetiredPhysicalReconciliationForCurrentRuntime;
let retiredPhysicalReopenVerificationContext;
let admitPhysicalReopenPresentation;
let physicalReopenClickAuthority;
let physicalReopenPresentationIsCurrent;
let physicalReopenSettlementIsCurrent;
let scenarioResetPresentationBoundary;
let localScenarioActionEpochIsCurrent;
let explicitProvisioningDraftMatches;
let localProvisioningDraftFenceKey;
let exactChangeNetworkCandidate;
let connectionActionAuthorityMatches;
let reconfigurationContinuationAuthority;
let observedConnectionAuthorityAllowsTarget;
let connectContinuationAuthority;
let runtimeActionFenceMatches;
let currentRuntimeActionRequest;
let connectedReconfigurationActionApplicable;
let K1AcquisitionPipeline;
let K1Diagnostics;
let K1SpatialControlsView;
let k1SpatialAuthorityState;
let k1SpatialPhasePresentation;
let contourRuntimeAuthorityPresentation;
let connectionPolicyOperatorGuidance;
let connectionModeSelectionGuidance;
let physicalRetirementGuidance;
let physicalReopenGuidance;
let K1OperatorError;
let attemptNetworkPhaseLabel;
let hostFailureDiagnosticPresentation;
let shellPresentation;
let reconfigurationAllowsFreshDevice;
let readOnlyObservationShowsNetworkUnavailable;
let readOnlyFailureShowsNetworkUnavailable;
let savedBridgeRequiresNetworkSetup;
let isConnectionControlBootstrapSettling;
let provisioningFailureRequiresFreshCandidate;
let trustedConnectionBinding;
let transportRefEquivalenceKey;
let shouldRevealProvisioningNetworkStep;
let retiredPhysicalReopenAuthority;
let SnapshotRuntimeActionArbiter;
let runtimeActionResponseAlreadyAccepted;
let connectionActionAuthoritySnapshot;
let exactAppliedNetworkIntentCompleted;
let selectMonotonicXgridsState;
let canIssueCanonicalStop;
let physicalStopIntentCheckpoint;
let authoritativeStateSupersedesPhysicalStopIntent;
let connectionAttemptForRuntimeError;
let recommendedConnectionRecoveryObservationTarget;
let readOnlyConnectionObservationTarget;
const PROFILE_ID = "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2";
const OBSERVED_AT = "2026-08-06T12:00:00Z";
const provisioningSourceUrl = new URL(
"../../../plugins/xgrids-k1/frontend/src/components/K1ProvisioningPipeline.tsx",
import.meta.url,
);
const provisioningStylesUrl = new URL(
"../../../plugins/xgrids-k1/frontend/src/styles.css",
import.meta.url,
);
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({ normalizeXgridsK1MissionState } = await server.ssrLoadModule(
"@xgrids-k1/frontend/runtimeContext.tsx",
));
({
SnapshotRuntimeActionArbiter,
connectionActionAuthoritySnapshot,
exactAppliedNetworkIntentCompleted,
runtimeActionResponseAlreadyAccepted,
} = await server.ssrLoadModule(
"@xgrids-k1/frontend/useXgridsK1Runtime.ts",
));
({ selectMonotonicXgridsState } = await server.ssrLoadModule(
"@xgrids-k1/frontend/stateOrdering.ts",
));
({ xgridsK1Manifest } = await server.ssrLoadModule(
"@xgrids-k1/frontend/manifest.ts",
));
({ workspaces } = await server.ssrLoadModule("/src/productModel.ts"));
({ connectionModeOptions } = await server.ssrLoadModule(
"@xgrids-k1/frontend/configuration.ts",
));
({ K1Metrics } = await server.ssrLoadModule(
"@xgrids-k1/frontend/components/K1Metrics.tsx",
));
({
K1ProvisioningPipeline,
RuntimeActionFenceTestContext,
LOCAL_OPERATION_PROGRESS_DELAY_MILLISECONDS,
emptySearchPresentation,
emptyProvisioningAttemptPresentation,
emptyReadOnlyReconnectPresentation,
provisioningAttemptViewState,
unavailablePhysicalRetirementAuthority,
connectionAttemptOwnsAppliedNetworkRecovery,
connectionRecoveryObservationTargetMatches,
connectionRecoveryEscapeKey,
connectionRecoveryEscapeAfterScan,
connectionRecoveryIsRequired,
clearConnectionFailureAfterSuccessfulRefresh,
dispatchConnectionRecoveryObservationForCurrentRuntime,
dispatchUnavailablePhysicalRetirementForCurrentRuntime,
dispatchRetiredPhysicalReconciliationForCurrentRuntime,
retiredPhysicalReopenVerificationContext,
admitPhysicalReopenPresentation,
physicalReopenClickAuthority,
physicalReopenPresentationIsCurrent,
physicalReopenSettlementIsCurrent,
scenarioResetPresentationBoundary,
localScenarioActionEpochIsCurrent,
explicitProvisioningDraftMatches,
localProvisioningDraftFenceKey,
exactChangeNetworkCandidate,
connectionActionAuthorityMatches,
reconfigurationContinuationAuthority,
observedConnectionAuthorityAllowsTarget,
connectContinuationAuthority,
runtimeActionFenceMatches,
currentRuntimeActionRequest,
connectedReconfigurationActionApplicable,
} = await server.ssrLoadModule(
"@xgrids-k1/frontend/components/K1ProvisioningPipeline.tsx",
));
({ K1AcquisitionPipeline } = await server.ssrLoadModule(
"@xgrids-k1/frontend/components/K1AcquisitionPipeline.tsx",
));
({ K1Diagnostics } = await server.ssrLoadModule(
"@xgrids-k1/frontend/components/K1Diagnostics.tsx",
));
({
K1SpatialControlsView,
k1SpatialAuthorityState,
k1SpatialPhasePresentation,
} = await server.ssrLoadModule(
"@xgrids-k1/frontend/components/K1SpatialControls.tsx",
));
({
connectionModeSelectionGuidance,
connectionPolicyOperatorGuidance,
physicalRetirementGuidance,
physicalReopenGuidance,
} = await server.ssrLoadModule(
"@xgrids-k1/frontend/presentation.ts",
));
({
reconfigurationAllowsFreshDevice,
readOnlyObservationShowsNetworkUnavailable,
readOnlyFailureShowsNetworkUnavailable,
savedBridgeRequiresNetworkSetup,
isConnectionControlBootstrapSettling,
provisioningFailureRequiresFreshCandidate,
trustedConnectionBinding,
transportRefEquivalenceKey,
shouldRevealProvisioningNetworkStep,
retiredPhysicalReopenAuthority,
canIssueCanonicalStop,
physicalStopIntentCheckpoint,
authoritativeStateSupersedesPhysicalStopIntent,
connectionAttemptForRuntimeError,
recommendedConnectionRecoveryObservationTarget,
readOnlyConnectionObservationTarget,
} = await server.ssrLoadModule(
"@xgrids-k1/frontend/lifecycle.ts",
));
({
K1ConnectionPipelines,
physicalRecoveryConnectionDetail,
shouldRenderK1OperationalPanels,
} = await server.ssrLoadModule(
"@xgrids-k1/frontend/XgridsK1Connection.tsx",
));
({
K1OperatorError,
attemptNetworkPhaseLabel,
} = await server.ssrLoadModule(
"@xgrids-k1/frontend/components/K1OperatorError.tsx",
));
({ hostFailureDiagnosticPresentation } = await server.ssrLoadModule(
"@xgrids-k1/frontend/hostDiagnosticPresentation.ts",
));
shellPresentation = await server.ssrLoadModule("/src/presentation.ts");
({ contourRuntimeAuthorityPresentation } = await server.ssrLoadModule(
"/src/workspaces/ContourHealthWorkspace.tsx",
));
});
after(async () => {
await server?.close();
});
function sourceSlice(source, startMarker, endMarker) {
const start = source.indexOf(startMarker);
const end = source.indexOf(endMarker, start + startMarker.length);
assert.notEqual(start, -1, `missing source marker: ${startMarker}`);
assert.notEqual(end, -1, `missing source marker: ${endMarker}`);
return source.slice(start, end);
}
test("K1 one-intent source contract makes mode reset explicit and keeps device I/O separate", () => {
const source = readFileSync(provisioningSourceUrl, "utf8");
const search = sourceSlice(source, "const repeatDeviceScan", "const submitConnect");
const apply = sourceSlice(source, "const submitConnect", "const verifyAppliedNetwork");
const mode = sourceSlice(source, "const changeDesiredConnectionMode", "const selectFreshDevice");
const selection = sourceSlice(
source,
"const selectFreshDevice",
"const chooseAnother",
);
assert.match(search, /scanWithResult\(\{[^}]*durationSeconds:\s*BLE_DISCOVERY_TIMEOUT_SECONDS/);
assert.equal((search.match(/scanWithResult\(/g) ?? []).length, 1);
assert.doesNotMatch(search, /\b(?:connect|verifyConnection|submitConnect)\s*\(/);
assert.match(mode, /await selectConnectionMode\(\{/);
assert.match(mode, /reset_scenario: true/);
assert.match(mode, /reset_id: resetId/);
assert.doesNotMatch(
mode,
/scanWithResult\(|verifyConnection\(|connect\(|prepareConnection/,
);
assert.doesNotMatch(
selection,
/await|scanWithResult\(|verifyConnection\(|connect\(|retireUnavailablePhysicalCommand|reopenRetiredPhysicalReconciliation/,
);
assert.match(selection, /requestExplicitProvisioning\(device\.device_id/);
assert.match(selection, /const actionableDevices = devices\.filter\(candidateSelectionAllowed\)/);
assert.doesNotMatch(selection, /physicallyRetired|reopenAuthority/);
const resultRows = sourceSlice(
source,
'<div className="device-list" aria-label="Результаты Bluetooth">',
'<div className="empty-state" role="status">',
);
assert.match(resultRows, /actionLabel="Выбрать"/);
assert.match(resultRows, /onSelect=\{\(\) => selectCandidate\(device\)\}/);
assert.doesNotMatch(resultRows, /Переподключиться|reopen|verifyConnection/);
assert.match(source, /onChange=\{\(event\) => setSsid\(event\.target\.value\)\}/);
assert.match(source, /onChange=\{\(event\) => setPassword\(event\.target\.value\)\}/);
assert.equal((apply.match(/await connect\(/g) ?? []).length, 1);
assert.doesNotMatch(
apply,
/scanWithResult\(|verifyConnection\(|retireUnavailablePhysicalCommand|reopenRetiredPhysicalReconciliation|candidateRefreshRequest|void submitConnect/,
);
assert.doesNotMatch(source, /allow_host_wifi_switch/);
assert.doesNotMatch(source, /<(?:button|input|select|textarea)\b/);
assert.doesNotMatch(
source,
/(?:color|background(?:-color)?):\s*(?:#[0-9a-f]{3,8}|rgba?\()/i,
);
for (const sharedControl of ["Button", "IconButton", "TextField", "ActivityIndicator", "StatusBadge"]) {
assert.match(source, new RegExp(`<${sharedControl}\\b`), sharedControl);
}
assert.equal((source.match(/buttonLabel:\s*"Применить"/g) ?? []).length, 3);
assert.match(source, /устарел|stale/i);
assert.match(source, /network_outcome_unknown|safe_to_retry/i);
});
test("exact network-applied REST proof completes frontend Apply before control is ready", () => {
const request = {
device_id: "BLE-K1-ONE",
connection_mode: "bridge",
idempotency_key: "apply-intent-one",
};
const operation = {
operation_id: "network-operation-one",
action: "network.provision",
status: "succeeded",
idempotency_key: request.idempotency_key,
context: { connection_mode: request.connection_mode },
result: { phase: "network_applied" },
};
const exactState = (controlState) => ({
connection_attempt: {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: operation.operation_id,
phase: "network_applied",
connection_mode: request.connection_mode,
control_state: controlState,
},
network_mutation_ledger: {
status: "resolved",
mutation_allowed: true,
operation_id: operation.operation_id,
intended_mode: request.connection_mode,
resolution: "target-observed",
transport_ref: request.device_id,
},
connection_supervisor: {
observed: {
device_network: {
state: "applied",
connection_mode: request.connection_mode,
transport_ref: request.device_id.toLowerCase(),
},
},
},
});
assert.equal(
exactAppliedNetworkIntentCompleted(
exactState("control_not_ready"),
request,
operation,
),
true,
);
assert.equal(
exactAppliedNetworkIntentCompleted(exactState("unknown"), request, operation),
true,
);
assert.equal(
exactAppliedNetworkIntentCompleted({
...exactState("control_not_ready"),
connection_attempt: {
...exactState("control_not_ready").connection_attempt,
attempt_id: "another-operation",
},
}, request, operation),
false,
);
const runtime = readFileSync(new URL(
"../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts",
import.meta.url,
), "utf8");
const connectFlow = sourceSlice(
runtime,
"const connect = useCallback",
"const verifyConnection = useCallback",
);
assert.match(
connectFlow,
/const exactNetworkIntentCompleted = exactAppliedNetworkIntentCompleted\([\s\S]*?if \(\s*!exactNetworkIntentCompleted\s*&& !hasExactConnectionReady\([\s\S]*?return requireExactConnectionReady\([\s\S]*?nextState = acceptSuccessfulConnectState\(nextState\)/,
);
assert.match(
connectFlow,
/observeProvisioningRequest\([\s\S]*?observedState = observation\.state[\s\S]*?const exactNetworkIntentCompleted = exactAppliedNetworkIntentCompleted\(/,
);
assert.doesNotMatch(
connectFlow,
/openApplicationControlSession|waitForControlPhase|verifyConnection\(|scanWithResult\(/,
);
});
function model() {
const activeModel = xgridsK1Manifest.spec.models[0];
assert.ok(activeModel);
return activeModel;
}
function supervisor({
control = true,
data = false,
dataPlaneState = "idle",
} = {}) {
const target = { ipv4: "192.168.68.52", port: 1883 };
return {
schema_version: "missioncore.k1-connection-supervisor/v1",
revision: 9,
closed: false,
intent: {
intent_id: "intent-001",
requested_mode: "bridge",
expected_device_id: "device-k1-001",
requested_at: OBSERVED_AT,
},
observed: {
device_network: {
state: "applied",
intent_id: "intent-001",
transport_ref: "ble-k1-001",
connection_mode: "bridge",
target,
source: "ble-read-only-status",
observed_at: OBSERVED_AT,
},
host_path: {
epoch: 5,
available: true,
fingerprint: "en0:192.168.68.10",
interface: "en0",
source_ipv4: "192.168.68.10",
route_class: "direct",
reason_code: null,
observed_at: OBSERVED_AT,
},
endpoint: {
target,
tcp_state: "reachable",
intent_id: "intent-001",
host_path_epoch: 5,
reason_code: null,
observed_at: OBSERVED_AT,
},
device_identity: {
state: control ? "verified" : "stale",
intent_id: "intent-001",
logical_device_id: "device-k1-001",
compatibility_profile_id: PROFILE_ID,
connection_mode: "bridge",
source: "mqtt-device-info",
host_path_epoch: 5,
observed_at: OBSERVED_AT,
},
control_plane: {
state: control ? "healthy" : "lost",
session_id: control ? "control-session-001" : null,
host_path_epoch: control ? 5 : null,
reason_code: control ? null : "control-heartbeat-lost",
observed_at: OBSERVED_AT,
},
data_plane: {
state: data ? "healthy" : dataPlaneState,
session_id: data || dataPlaneState !== "idle" ? "data-session-001" : null,
host_path_epoch: data || dataPlaneState !== "idle" ? 5 : null,
reason_code: dataPlaneState === "lost" ? "data-heartbeat-lost" : null,
observed_at: data || dataPlaneState !== "idle" ? OBSERVED_AT : null,
},
},
lease: {
state: "reachable",
generation: 6,
intent_id: "intent-001",
host_path_epoch: 5,
connection_mode: "bridge",
target,
logical_device_id: "device-k1-001",
reason_code: null,
observed_at: OBSERVED_AT,
},
authority: {
network_mutation_allowed: false,
control_allowed: control,
acquisition_start_allowed: control,
data_ingest_authoritative: control && data,
physical_motion_allowed: false,
reason_codes: control ? [] : ["control-heartbeat-lost"],
},
last_known: null,
allowed_actions: control ? ["stop-acquisition"] : ["probe-endpoint"],
};
}
function connectionLifecycle({
control = true,
mode = "bridge",
revision = 9,
} = {}) {
return {
schema_version: "missioncore.xgrids-k1-connection-lifecycle/v1",
revision,
desired_mode: mode,
configured_mode: mode,
active_mode: control ? mode : null,
mode_change: {
state: control ? "ready" : "awaiting-control",
from: mode,
to: mode,
},
mode_selection: {
allowed: true,
reason_codes: [],
automatic_retry: false,
},
active_binding_key: control ? `binding-intent-001-${mode}` : null,
active_binding: control
? {
binding_key: `binding-intent-001-${mode}`,
intent_id: "intent-001",
transport_ref: "ble-k1-001",
connection_mode: mode,
target_ipv4: "192.168.68.52",
target_port: 1883,
host_path_epoch: 5,
control_session_id: "control-session-001",
logical_device_id: "device-k1-001",
compatibility_profile_id: PROFILE_ID,
}
: null,
connection_ready: control,
ready_to_start: control,
operation: null,
allowed_actions: control
? ["start-acquisition", "select-connection-mode"]
: ["select-connection-mode", "verify-control-read-only"],
automatic_retry: false,
};
}
function runtimeState() {
return {
phase: "live",
source_mode: "live",
ble_discovery_generation: 4,
connection_mode: "bridge",
configured_connection_mode: "bridge",
active_connection_mode: "bridge",
desired_connection_mode: "bridge",
desired_connection_mode_revision: 0,
k1_ip: "192.168.68.52",
rerun_grpc_url: "rerun+http://127.0.0.1:9877/proxy",
compatibility: {
profile_id: PROFILE_ID,
vendor_writes_enabled: true,
permitted_mode: "active-control",
},
device_ref: {
device_id: "device-k1-001",
model_id: model().id,
identity_stability: "stable",
identity_basis: "hardware-identifier",
},
device_session: {
device_session_id: "device-session-001",
device_id: "device-k1-001",
compatibility_profile_id: PROFILE_ID,
connectivity: "connected",
},
acquisition: {
acquisition_id: "acquisition-001",
device_id: "device-k1-001",
device_session_id: "device-session-001",
compatibility_profile_id: PROFILE_ID,
control_mode: "plugin-commanded",
requested_streams: ["spatial.point-cloud.live"],
target_host: "127.0.0.1",
duration_seconds: 0,
evidence_policy: "required",
state: "acquiring",
state_revision: 4,
},
sensor_catalog: {
schema_version: "missioncore.sensor-catalog/v1alpha2",
revision: "runtime-test",
streams: [{
stream_id: "spatial.point-cloud.live",
modality: "point-cloud",
availability: "streaming",
}],
},
metrics: {
pcl_frames: 10,
pose_frames: 5,
pipeline_ms: 12.5,
frame_rate_hz: 8,
point_count: 42_000,
ai_frame_rate_hz: 5,
device_elapsed_seconds: 30,
},
connection_supervisor: supervisor({ control: true, data: true }),
connection_lifecycle: connectionLifecycle(),
};
}
function activeRecoveryRuntimeState(recoveryOverrides = {}, stateOverrides = {}) {
const state = runtimeState();
return {
...state,
snapshot_runtime_id: "runtime-active-recovery-001",
snapshot_revision: 51,
producer_generation: 13,
phase: "reconnecting",
connection_supervisor: supervisor({
control: false,
data: false,
dataPlaneState: "lost",
}),
connection_lifecycle: connectionLifecycle({ control: false }),
connection_recovery: {
schema_version: "missioncore.xgrids-k1-active-stream-recovery/v1",
state: "reconnecting",
generation: 5,
acquisition_id: state.acquisition.acquisition_id,
attempt: 1,
started_at_utc: "2026-08-11T21:19:59Z",
elapsed_ms: 16_869,
reason_code: "host-route-unavailable",
force_finish_allowed: true,
automatic_read_only_rebind: true,
automatic_command_retry: false,
start_performed: false,
stop_performed: false,
ble_operation_performed: false,
network_mutation_performed: false,
runtime_producer_generation: 13,
camera_recovery: "owned",
camera_media_state: "pending-epoch",
camera_media_ready: false,
camera_epoch: null,
...recoveryOverrides,
},
...stateOverrides,
};
}
function normalize(state) {
return normalizeXgridsK1MissionState({ state }, model());
}
function durableTopologyState() {
return {
phase: "idle",
source_mode: "idle",
ble_discovery_generation: 0,
connection_mode: "bridge",
configured_connection_mode: "bridge",
active_connection_mode: null,
desired_connection_mode: "bridge",
desired_connection_mode_revision: 0,
devices: [],
operations: [],
network_write_reconciliation: null,
network_mutation_ledger: {
status: "empty",
mutation_allowed: true,
reason_code: null,
operation_id: null,
transport_ref: null,
intended_mode: null,
stage: null,
revision: null,
resolution: null,
updated_at_utc: null,
},
semantic_topology_store: {
status: "available",
configured_offline_evidence: true,
live_connection_authority: false,
reason_code: null,
record: {
schema_version: "missioncore.xgrids-k1-semantic-topology/v1",
revision: 3,
transport_ref: "ble-k1-001",
connection_mode: "bridge",
ipv4: "192.168.68.52",
compatibility_profile_id: PROFILE_ID,
firmware_version: "3.0.2",
source: "ble-read-only-status",
observed_at_utc: OBSERVED_AT,
},
},
};
}
function provisioningController(state) {
return {
state,
pendingAction: null,
scan: async () => undefined,
connect: async () => ({
succeeded: false,
networkIntentCompleted: false,
intentDisposition: "retain",
acceptedSessionKey: null,
}),
verifyConnection: async () => ({
succeeded: false,
reconciliationCompleted: false,
observedState: state,
}),
retireUnavailablePhysicalCommand: async () => false,
retireUnavailablePhysicalCommandWithResult: async () => ({
succeeded: false,
observedState: state,
}),
reopenRetiredPhysicalReconciliation: async () => ({
succeeded: false,
observedState: state,
}),
prepareConnectionReconfiguration: async () => false,
probeConfiguredEndpoint: async () => undefined,
};
}
function provisioningAttemptPresentation(overrides = {}) {
return {
snapshotRuntimeId: "runtime-network-action",
connectionMode: "bridge",
idempotencyKey: "apply-intent-one",
attemptId: null,
deviceId: "f89438fa-55ed-85ad-eed7-734ac84746d8",
label: "XGR-A46BE7",
rssi: -51,
ssid: "FIELD-NET",
localPhase: "submitting",
failureMessage: null,
freshStartAllowed: false,
...overrides,
};
}
function terminalConnectionRecoveryState({
phase = "network_outcome_unknown",
safeNextAction = "verify-control-read-only",
includeConfiguredTarget = true,
includeScan = true,
} = {}) {
const state = durableTopologyState();
state.snapshot_runtime_id = "runtime-terminal-connection-recovery";
state.snapshot_runtime_started_at_utc = "2026-08-11T18:00:00Z";
state.snapshot_revision = 27;
state.connection_attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: "op-b7ea404d-b0a2-460a-80bd-6922e85a2df5",
connection_mode: "bridge",
status: "failed",
phase,
control_state: "unknown",
stage: "network-operation-failed",
public_error_code: null,
side_effect_status: phase === "network_outcome_unknown" ? "unknown" : "none",
safe_next_action: safeNextAction,
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: OBSERVED_AT,
timeline: [],
diagnostic_bundle: {
schema_version: "missioncore.xgrids-k1-connection-diagnostic/v1",
redacted: true,
generated_at_utc: OBSERVED_AT,
snapshot_runtime_id: "runtime-terminal-connection-recovery",
attempt: {},
network_mutation_ledger: {},
connection_supervisor: {},
automatic_retry: false,
},
};
const allowedActions = [];
const actions = {};
if (includeConfiguredTarget) {
allowedActions.push("observe-configured-device-network");
actions["observe-configured-device-network"] = {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: "F89438FA-55ED-85AD-EED7-734AC84746D8",
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
automatic_retry: false,
};
}
if (includeScan) {
allowedActions.push("scan-ble");
actions["scan-ble"] = {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
};
}
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
recommended_action: includeConfiguredTarget
? "observe-configured-device-network"
: includeScan
? "scan-ble"
: "manual-recovery-required",
allowed_actions: allowedActions,
actions,
};
return state;
}
function reopenedPhysicalState({
stage = "observing",
advertisedRef = "f89438fa-55ed-85ad-eed7-734ac84746d8",
backendRef = "F89438FA-55ED-85AD-EED7-734AC84746D8",
reopeningId = "reopening-returned-k1",
discoveryGeneration = 13,
snapshotRevision = 20,
} = {}) {
const state = durableTopologyState();
state.snapshot_runtime_id = "runtime-reopened-k1";
state.snapshot_runtime_started_at_utc = "2026-08-10T12:00:00Z";
state.snapshot_revision = snapshotRevision;
state.desired_connection_mode = "bridge";
state.desired_connection_mode_revision = 7;
state.ble_discovery_generation = discoveryGeneration;
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
state.devices = [{
device_id: advertisedRef,
name: "XGR-A46BE7",
rssi: -61,
connectable: true,
likely_k1: true,
}];
state.physical_command = {
status: "unresolved",
reason_code: "physical-command-reconciliation-required",
requires_reconciliation: true,
automatic_replay_allowed: false,
normal_session_recovery_supported: false,
runtime_bound: false,
reconciliation_ready: true,
record: {
revision: 282,
operation_id: "old-stop-operation",
action: "stop",
stage,
resolution: null,
connection: { transport_ref: backendRef },
operator_retirements: [{
retirement_id: "retirement-old-stop",
retired_transport_ref: backendRef,
}],
operator_reconciliation_reopens: [{
reopening_id: reopeningId,
retirement_id: "retirement-old-stop",
retired_record_revision: 281,
reopened_transport_ref: advertisedRef,
discovery_generation: discoveryGeneration,
reason: "device-returned-for-explicit-reconciliation",
}],
},
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: {
retained_context_is_presence: false,
retired_transport_refs: [],
},
allowed_actions: ["observe-fresh-device-network", "scan-ble"],
actions: {
"observe-fresh-device-network": {
allowed: true,
reason_codes: [],
target_source: "fresh-scan",
required_transport_ref: backendRef,
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
"provision-fresh-device": {
allowed: false,
reason_codes: ["physical-command-reconciliation-required"],
target_source: "fresh-scan",
required_transport_ref: backendRef,
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
};
return state;
}
function retiredPhysicalReopenReadyState({
advertisedRef = "f89438fa-55ed-85ad-eed7-734ac84746d8",
backendRef = "F89438FA-55ED-85AD-EED7-734AC84746D8",
discoveryGeneration = 13,
snapshotRuntimeId = "runtime-reopened-k1",
} = {}) {
const state = reopenedPhysicalState({
advertisedRef,
backendRef,
discoveryGeneration,
});
state.snapshot_runtime_id = snapshotRuntimeId;
state.physical_command = {
status: "resolved",
reason_code: null,
requires_reconciliation: false,
automatic_replay_allowed: false,
normal_session_recovery_supported: false,
runtime_bound: false,
reconciliation_ready: false,
operator_reconciliation_reopen: {
allowed: true,
reason_codes: [],
expected_revision: 281,
expected_retirement_id: "retirement-old-stop",
expected_transport_ref: backendRef,
expected_discovery_generation: discoveryGeneration,
expected_desired_mode: "bridge",
expected_desired_mode_revision: 7,
device_io_performed: false,
automatic_retry: false,
},
record: {
revision: 281,
operation_id: "old-stop-operation",
action: "stop",
stage: "resolved",
resolution: "operator-retired-outcome-unknown",
connection: {
transport_ref: backendRef,
connection_mode: "bridge",
},
operator_retirements: [{
retirement_id: "retirement-old-stop",
retired_transport_ref: backendRef,
}],
operator_reconciliation_reopens: [],
},
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: {
retained_context_is_presence: false,
retired_transport_refs: [backendRef],
},
allowed_actions: ["scan-ble"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
"provision-fresh-device": {
allowed: false,
reason_codes: ["physical-command-target-retired"],
target_source: "fresh-scan",
required_transport_ref: backendRef,
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
};
return state;
}
function reopenedPhysicalAuthority({ discoveryGeneration = 13 } = {}) {
return {
snapshotRuntimeId: "runtime-reopened-k1",
connectionMode: "bridge",
desiredModeRevision: 7,
reconfigurationRevision: 0,
reconfigurationIntentId: null,
activeBindingKey: null,
discoveryGeneration,
};
}
function connectionReconfiguration({
intent = null,
status = intent ? "awaiting-fresh-scan" : "idle",
revision = 0,
intentId = intent ? `reconfigure-${revision}` : null,
requiredTransportRef = null,
requiredConnectionMode = null,
discoveryGeneration = null,
requiredTransportObserved = null,
} = {}) {
return {
schema_version: "missioncore.xgrids-k1-connection-reconfiguration/v1",
revision,
intent_id: intentId,
intent,
status,
required_transport_ref: requiredTransportRef,
required_connection_mode: requiredConnectionMode,
minimum_discovery_generation: intent ? (discoveryGeneration ?? 1) : null,
fresh_discovery_generation: status === "fresh-scan-completed"
? discoveryGeneration
: null,
required_transport_observed: requiredTransportObserved,
prepared_at: intent ? OBSERVED_AT : null,
automatic_retry: false,
};
}
function acquisitionController(state) {
return {
state,
pendingAction: null,
error: null,
physicalStopIntentSpent: false,
physicalStopInFlight: false,
closeApplicationControlSession: async () => false,
prepareCanonicalAcquisition: async () => false,
startPreparedAcquisition: async () => false,
startReplay: async () => false,
stop: async () => false,
stopLocalReceiver: async () => false,
abort: async () => false,
};
}
function connectionPipelinesController(state) {
return {
...provisioningController(state),
...acquisitionController(state),
backendStatus: "offline",
eventStatus: "disconnected",
latencyHistory: [],
scanWithResult: async () => ({
observedState: state,
discoveryGeneration: state?.ble_discovery_generation ?? 0,
}),
prepareConnectionReconfigurationWithResult: async () => ({
succeeded: false,
observedState: state,
}),
getConnectionActionAuthority: () => null,
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: () => true,
};
}
function renderConnectionPipelines(state, pendingAction = null) {
return renderToStaticMarkup(createElement(K1ConnectionPipelines, {
controller: {
...connectionPipelinesController(state),
pendingAction,
},
desiredConnectionMode: "bridge",
onDesiredConnectionModeChange() {},
operationalPanelsVisible: shouldRenderK1OperationalPanels(state, pendingAction),
openSpatialScene() {},
activateAutomaticSpatialSource() {},
sourceLabel: "Ожидание",
}));
}
function buttonMarkupWithText(markup, text) {
return (markup.match(/<button\b[\s\S]*?<\/button>/g) ?? [])
.filter((button) => button.includes(text));
}
function assertCanonicalConnectionCopy(markup) {
assert.doesNotMatch(
markup,
/[Ии]сходн|[Сс]охранён|[Пп]редыдущ|[Фф]изическ|[Пп]одключаемся/u,
);
}
function deviceRowOpeningTag(markup, deviceId) {
const deviceOffset = markup.indexOf(`<code>${deviceId}</code>`);
assert.notEqual(deviceOffset, -1, `${deviceId} must be rendered`);
const rowOffset = markup.lastIndexOf('<div class="device-row"', deviceOffset);
assert.notEqual(rowOffset, -1, `${deviceId} must belong to a device row`);
return markup.slice(rowOffset, markup.indexOf(">", rowOffset) + 1);
}
function deviceRowActionButton(markup, deviceId) {
const deviceOffset = markup.indexOf(`<code>${deviceId}</code>`);
assert.notEqual(deviceOffset, -1, `${deviceId} must be rendered`);
const buttonOffset = markup.indexOf("<button", deviceOffset);
assert.notEqual(buttonOffset, -1, `${deviceId} must have an action`);
const buttonEnd = markup.indexOf("</button>", buttonOffset);
assert.notEqual(buttonEnd, -1, `${deviceId} action must be complete`);
return markup.slice(buttonOffset, buttonEnd + "</button>".length);
}
function renderProvisioning(props) {
return renderToStaticMarkup(createElement(K1ProvisioningPipeline, props));
}
function captureProvisioningTree(props) {
let capturedTree = null;
function CaptureHarness() {
capturedTree = K1ProvisioningPipeline(props);
return capturedTree;
}
renderToStaticMarkup(createElement(CaptureHarness));
assert.ok(capturedTree);
return capturedTree;
}
function captureProvisioningTreeAfterSearch(
props,
{ completedDiscoveryGeneration } = {},
) {
let capturedTree = null;
function SearchCompletedCaptureHarness() {
const internals =
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const dispatcher = internals?.H;
assert.equal(typeof dispatcher?.useState, "function");
const originalUseState = dispatcher.useState;
dispatcher.useState = (initialState) => {
if (initialState === emptySearchPresentation) {
const state = props.controller.state;
return [{
sequence: 1,
snapshotRuntimeId: state.snapshot_runtime_id ?? null,
connectionMode: props.desiredMode,
desiredModeRevision: state.desired_connection_mode_revision ?? null,
active: false,
completedDiscoveryGeneration: completedDiscoveryGeneration
?? state.ble_discovery_generation
?? null,
}, () => undefined];
}
return originalUseState(initialState);
};
try {
capturedTree = K1ProvisioningPipeline(props);
return capturedTree;
} finally {
dispatcher.useState = originalUseState;
}
}
renderToStaticMarkup(createElement(SearchCompletedCaptureHarness));
assert.ok(capturedTree);
return capturedTree;
}
function elementByProp(node, propName, expectedValue) {
if (Array.isArray(node)) {
for (const child of node) {
const found = elementByProp(child, propName, expectedValue);
if (found) return found;
}
return null;
}
if (!React.isValidElement(node)) return null;
if (node.props[propName] === expectedValue) return node;
return elementByProp(node.props.children, propName, expectedValue);
}
function createStatefulProvisioningHarness(initialProps) {
const hookSlots = [];
let currentProps = initialProps;
let capturedTree = null;
let pendingEffects = [];
const dependenciesMatch = (left, right) => Boolean(
left
&& right
&& left.length === right.length
&& left.every((value, index) => Object.is(value, right[index])),
);
const render = (nextProps = currentProps) => {
currentProps = nextProps;
pendingEffects = [];
function StatefulCaptureHarness() {
const internals =
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const dispatcher = internals?.H;
assert.equal(typeof dispatcher?.useState, "function");
const originals = {
useState: dispatcher.useState,
useRef: dispatcher.useRef,
useMemo: dispatcher.useMemo,
useCallback: dispatcher.useCallback,
useEffect: dispatcher.useEffect,
};
let hookIndex = 0;
dispatcher.useState = (initialState) => {
const index = hookIndex;
hookIndex += 1;
if (!hookSlots[index]) {
hookSlots[index] = {
kind: "state",
initializer: initialState,
value: typeof initialState === "function"
? initialState()
: initialState,
};
}
const slot = hookSlots[index];
assert.equal(slot.kind, "state");
const setValue = (nextValue) => {
slot.value = typeof nextValue === "function"
? nextValue(slot.value)
: nextValue;
};
return [slot.value, setValue];
};
dispatcher.useRef = (initialValue) => {
const index = hookIndex;
hookIndex += 1;
if (!hookSlots[index]) {
hookSlots[index] = {
kind: "ref",
value: { current: initialValue },
};
}
const slot = hookSlots[index];
assert.equal(slot.kind, "ref");
return slot.value;
};
dispatcher.useMemo = (factory, dependencies) => {
const index = hookIndex;
hookIndex += 1;
const previous = hookSlots[index];
if (
!previous
|| previous.kind !== "memo"
|| !dependenciesMatch(previous.dependencies, dependencies)
) {
hookSlots[index] = {
kind: "memo",
dependencies,
value: factory(),
};
}
return hookSlots[index].value;
};
dispatcher.useCallback = (callback, dependencies) => {
const index = hookIndex;
hookIndex += 1;
const previous = hookSlots[index];
if (
!previous
|| previous.kind !== "callback"
|| !dependenciesMatch(previous.dependencies, dependencies)
) {
hookSlots[index] = {
kind: "callback",
dependencies,
value: callback,
};
}
return hookSlots[index].value;
};
dispatcher.useEffect = (effect, dependencies) => {
const index = hookIndex;
hookIndex += 1;
const previous = hookSlots[index];
const changed = !previous
|| previous.kind !== "effect"
|| !dependenciesMatch(previous.dependencies, dependencies);
hookSlots[index] = {
kind: "effect",
dependencies,
cleanup: previous?.kind === "effect" ? previous.cleanup : undefined,
};
if (changed) pendingEffects.push({ index, effect });
};
try {
capturedTree = K1ProvisioningPipeline(currentProps);
} finally {
dispatcher.useState = originals.useState;
dispatcher.useRef = originals.useRef;
dispatcher.useMemo = originals.useMemo;
dispatcher.useCallback = originals.useCallback;
dispatcher.useEffect = originals.useEffect;
}
return null;
}
renderToStaticMarkup(createElement(StatefulCaptureHarness));
assert.ok(capturedTree);
return capturedTree;
};
const flushEffects = () => {
const effects = pendingEffects;
pendingEffects = [];
for (const { index, effect } of effects) {
const slot = hookSlots[index];
slot.cleanup?.();
const cleanup = effect();
slot.cleanup = typeof cleanup === "function" ? cleanup : undefined;
}
};
const stateValue = (initializer) => hookSlots.find(
(slot) => slot?.kind === "state" && slot.initializer === initializer,
)?.value;
const dispose = () => {
for (const slot of hookSlots) {
if (slot?.kind === "effect") slot.cleanup?.();
}
};
return { dispose, flushEffects, render, stateValue };
}
function reactNodeText(node) {
if (typeof node === "string" || typeof node === "number") return String(node);
if (Array.isArray(node)) return node.map(reactNodeText).join("");
if (!React.isValidElement(node)) return "";
return reactNodeText(node.props.children);
}
function actionByLabel(node, label) {
if (Array.isArray(node)) {
for (const child of node) {
const found = actionByLabel(child, label);
if (found) return found;
}
return null;
}
if (!React.isValidElement(node)) return null;
if (
typeof node.props.onClick === "function"
&& reactNodeText(node.props.children).includes(label)
) return node;
return actionByLabel(node.props.children, label);
}
function renderProvisioningWithAttempt(props, presentation, afterSearch = false) {
function AttemptHarness() {
const internals =
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const dispatcher = internals?.H;
assert.equal(typeof dispatcher?.useState, "function");
const originalUseState = dispatcher.useState;
dispatcher.useState = (initialState) => {
if (afterSearch && initialState === emptySearchPresentation) {
const state = props.controller.state;
return [{ sequence: 1, snapshotRuntimeId: state.snapshot_runtime_id,
connectionMode: props.desiredMode, desiredModeRevision: state.desired_connection_mode_revision,
active: false, completedDiscoveryGeneration: state.ble_discovery_generation }, () => undefined];
}
if (initialState === emptyProvisioningAttemptPresentation) {
return [presentation, () => undefined];
}
return originalUseState(initialState);
};
try {
return K1ProvisioningPipeline(props);
} finally {
dispatcher.useState = originalUseState;
}
}
return renderToStaticMarkup(createElement(AttemptHarness));
}
function captureProvisioningTreeWithAttempt(props, presentation) {
let capturedTree = null;
function AttemptCaptureHarness() {
const internals =
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const dispatcher = internals?.H;
assert.equal(typeof dispatcher?.useState, "function");
const originalUseState = dispatcher.useState;
dispatcher.useState = (initialState) => {
if (initialState === emptyProvisioningAttemptPresentation) {
return [presentation, () => undefined];
}
return originalUseState(initialState);
};
try {
capturedTree = K1ProvisioningPipeline(props);
return capturedTree;
} finally {
dispatcher.useState = originalUseState;
}
}
renderToStaticMarkup(createElement(AttemptCaptureHarness));
assert.ok(capturedTree);
return capturedTree;
}
function renderProvisioningAfterSearch(
props,
{ completedDiscoveryGeneration } = {},
) {
function SearchCompletedHarness() {
const internals =
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const dispatcher = internals?.H;
assert.equal(typeof dispatcher?.useState, "function");
const originalUseState = dispatcher.useState;
dispatcher.useState = (initialState) => {
if (initialState === emptySearchPresentation) {
const state = props.controller.state;
return [{
sequence: 1,
snapshotRuntimeId: state.snapshot_runtime_id ?? null,
connectionMode: props.desiredMode,
desiredModeRevision: state.desired_connection_mode_revision ?? null,
active: false,
completedDiscoveryGeneration: completedDiscoveryGeneration
?? state.ble_discovery_generation
?? null,
}, () => undefined];
}
return originalUseState(initialState);
};
try {
return K1ProvisioningPipeline(props);
} finally {
dispatcher.useState = originalUseState;
}
}
return renderToStaticMarkup(createElement(SearchCompletedHarness));
}
function renderProvisioningWithCurrentPendingAction(
props,
{ publicSearch = true } = {},
) {
function CurrentPendingActionHarness() {
const state = props.controller.state;
const fence = {
snapshotRuntimeId: state.snapshot_runtime_id,
connectionMode: props.desiredMode,
desiredModeRevision: state.desired_connection_mode_revision,
reconfigurationRevision: state.connection_reconfiguration?.revision ?? 0,
reconfigurationIntentId: state.connection_reconfiguration?.intent_id ?? null,
activeBindingKey: state.connection_lifecycle?.active_binding_key ?? null,
discoveryGeneration: state.ble_discovery_generation,
clickToken: 1,
};
return createElement(
RuntimeActionFenceTestContext.Provider,
{ value: fence },
publicSearch
? createElement(SearchCompletedPendingHarness, { props })
: createElement(K1ProvisioningPipeline, props),
);
}
function SearchCompletedPendingHarness({ props: childProps }) {
const internals =
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const dispatcher = internals?.H;
assert.equal(typeof dispatcher?.useState, "function");
const originalUseState = dispatcher.useState;
dispatcher.useState = (initialState) => {
if (initialState === emptySearchPresentation) {
const state = childProps.controller.state;
return [{
sequence: 1,
snapshotRuntimeId: state.snapshot_runtime_id ?? null,
connectionMode: childProps.desiredMode,
desiredModeRevision: state.desired_connection_mode_revision ?? null,
active: true,
completedDiscoveryGeneration: null,
}, () => undefined];
}
return originalUseState(initialState);
};
try {
return K1ProvisioningPipeline(childProps);
} finally {
dispatcher.useState = originalUseState;
}
}
return renderToStaticMarkup(createElement(CurrentPendingActionHarness));
}
function renderProvisioningWithRetainedDraft(
props,
{ device, draft, ssid, password },
) {
function RetainedDraftHarness() {
const internals =
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const dispatcher = internals?.H;
assert.equal(typeof dispatcher?.useState, "function");
const originalUseState = dispatcher.useState;
let emptyStringStateIndex = 0;
let nullStateIndex = 0;
dispatcher.useState = (initialState) => {
if (initialState === "") {
emptyStringStateIndex += 1;
const seededValue = emptyStringStateIndex === 1
? device.device_id
: emptyStringStateIndex === 2
? ssid
: emptyStringStateIndex === 3
? password
: initialState;
return [seededValue, () => undefined];
}
if (initialState === null) {
nullStateIndex += 1;
if (nullStateIndex === 1) return [device, () => undefined];
if (nullStateIndex === 8) return [draft, () => undefined];
}
return originalUseState(initialState);
};
try {
return K1ProvisioningPipeline(props);
} finally {
dispatcher.useState = originalUseState;
}
}
return renderToStaticMarkup(createElement(RetainedDraftHarness));
}
test("K1 provisioning password authority is scoped to one exact operator draft", () => {
const draft = {
snapshotRuntimeId: "runtime-a",
deviceId: "ble-k1-001",
connectionMode: "bridge",
desiredModeRevision: 7,
discoveryGeneration: 13,
reconfigurationRevision: 5,
reconfigurationIntentId: "reconfigure-001",
activeBindingKey: null,
requiredTransportRef: "ble-k1-001",
requiredConnectionMode: "bridge",
};
const current = {
snapshotRuntimeId: "runtime-a",
deviceId: "ble-k1-001",
connectionMode: "bridge",
desiredModeRevision: 7,
discoveryGeneration: 13,
reconfigurationRevision: 5,
reconfigurationIntentId: "reconfigure-001",
activeBindingKey: null,
requiredTransportRef: "ble-k1-001",
requiredConnectionMode: "bridge",
};
assert.equal(explicitProvisioningDraftMatches(draft, current), true);
for (const drifted of [
{ ...current, snapshotRuntimeId: "runtime-b" },
{ ...current, deviceId: "another-k1" },
{ ...current, connectionMode: "direct-connect" },
{ ...current, desiredModeRevision: 8 },
{ ...current, discoveryGeneration: 14 },
{ ...current, reconfigurationRevision: 6 },
{ ...current, reconfigurationIntentId: "reconfigure-002" },
{ ...current, activeBindingKey: "binding-new" },
{ ...current, requiredTransportRef: "ble-k1-002" },
{ ...current, requiredConnectionMode: "direct-connect" },
{ ...current, deviceId: null },
]) {
assert.equal(explicitProvisioningDraftMatches(draft, drifted), false);
}
});
test("K1 provisioning local credential fence changes with backend runtime authority", () => {
const fence = {
snapshotRuntimeId: "runtime-a",
reconfigurationRevision: 5,
reconfigurationIntentId: "reconfigure-001",
activeBindingKey: null,
requiredTransportRef: "ble-k1-001",
requiredConnectionMode: "bridge",
};
assert.notEqual(
localProvisioningDraftFenceKey(fence),
localProvisioningDraftFenceKey({
...fence,
snapshotRuntimeId: "runtime-b",
}),
);
});
test("K1 click-owned action requests disappear across runtime and click interleavings", () => {
const authorityA = {
snapshotRuntimeId: "runtime-a",
connectionMode: "bridge",
desiredModeRevision: 7,
reconfigurationRevision: 10,
reconfigurationIntentId: "reconfigure-a",
activeBindingKey: "binding-a",
discoveryGeneration: 5,
};
const firstClick = {
...authorityA,
clickToken: 17,
};
const awaitingScan = {
...firstClick,
deviceId: "ble-k1-001",
previousDiscoveryGeneration: 5,
expectedDiscoveryGeneration: null,
scanTransportRefs: [],
stage: "awaiting-scan",
};
let latestAuthority = authorityA;
const latestAuthorityMatches = (fence) =>
connectionActionAuthorityMatches(fence, latestAuthority);
assert.equal(
runtimeActionFenceMatches(
firstClick,
"runtime-a",
firstClick,
latestAuthorityMatches,
),
true,
);
assert.equal(
currentRuntimeActionRequest(
awaitingScan,
"runtime-a",
firstClick,
latestAuthorityMatches,
),
awaitingScan,
);
// Same-runtime authority drift must invalidate the old click before the new
// React render commits. A late Quick candidate cannot re-arm or auto-submit.
latestAuthority = { ...authorityA, discoveryGeneration: 6 };
assert.equal(
runtimeActionFenceMatches(
firstClick,
"runtime-a",
firstClick,
latestAuthorityMatches,
),
false,
);
assert.equal(
currentRuntimeActionRequest(
awaitingScan,
"runtime-a",
firstClick,
latestAuthorityMatches,
),
null,
);
// Simulate acceptState(runtime-b) updating latestState.current before React
// commits the runtime-b render.
latestAuthority = { ...authorityA, snapshotRuntimeId: "runtime-b" };
const secondClick = {
...latestAuthority,
clickToken: 18,
};
assert.equal(
runtimeActionFenceMatches(
firstClick,
"runtime-b",
secondClick,
latestAuthorityMatches,
),
false,
);
assert.equal(
runtimeActionFenceMatches(
secondClick,
"runtime-b",
secondClick,
latestAuthorityMatches,
),
true,
);
});
test("K1 reconfiguration continuation requires exact correlated +1 revisions", () => {
const fence = {
snapshotRuntimeId: "runtime-a",
connectionMode: "bridge",
desiredModeRevision: 7,
reconfigurationRevision: 10,
reconfigurationIntentId: null,
activeBindingKey: "binding-a",
discoveryGeneration: 5,
};
const preparedState = {
snapshot_runtime_id: "runtime-a",
desired_connection_mode: "bridge",
desired_connection_mode_revision: 7,
ble_discovery_generation: 6,
connection_reconfiguration: connectionReconfiguration({
intent: "select-device",
status: "awaiting-fresh-scan",
revision: 11,
intentId: "reconfigure-b",
discoveryGeneration: 6,
}),
connection_lifecycle: {
active_binding_key: null,
active_binding: null,
},
};
const preparedAuthority = {
...fence,
reconfigurationRevision: 11,
reconfigurationIntentId: "reconfigure-b",
activeBindingKey: null,
discoveryGeneration: 6,
};
assert.deepEqual(
reconfigurationContinuationAuthority(
fence,
preparedState,
"select-device",
preparedAuthority,
),
preparedAuthority,
);
for (const drifted of [
{ ...preparedAuthority, discoveryGeneration: 7 },
{ ...preparedAuthority, reconfigurationRevision: 12 },
{ ...preparedAuthority, desiredModeRevision: 8 },
{ ...preparedAuthority, activeBindingKey: "foreign-binding" },
]) {
assert.equal(
reconfigurationContinuationAuthority(
fence,
preparedState,
"select-device",
drifted,
),
null,
);
}
assert.equal(
reconfigurationContinuationAuthority(
fence,
preparedState,
"change-network",
preparedAuthority,
),
null,
);
const contaminatedPreparedState = {
...preparedState,
connection_lifecycle: {
active_binding_key: "binding-foreign",
active_binding: {
binding_key: "binding-foreign",
transport_ref: "ble-k1-foreign",
connection_mode: "bridge",
},
},
};
assert.equal(
reconfigurationContinuationAuthority(
fence,
contaminatedPreparedState,
"select-device",
{ ...preparedAuthority, activeBindingKey: "binding-foreign" },
),
null,
);
const cancelFence = preparedAuthority;
const cancelledState = {
...preparedState,
ble_discovery_generation: 7,
connection_reconfiguration: connectionReconfiguration({ revision: 12 }),
};
const cancelledAuthority = {
...cancelFence,
reconfigurationRevision: 12,
reconfigurationIntentId: null,
discoveryGeneration: 7,
};
assert.deepEqual(
reconfigurationContinuationAuthority(
cancelFence,
cancelledState,
"cancel",
cancelledAuthority,
),
cancelledAuthority,
);
});
test("separately explicit Verify rejects a foreign same-runtime binding", () => {
const exact = {
selected_device_id: "ble-k1-001",
connection_mode: "bridge",
connection_lifecycle: {
active_binding_key: "binding-a",
active_binding: {
binding_key: "binding-a",
transport_ref: "ble-k1-001",
connection_mode: "bridge",
},
},
};
assert.equal(
observedConnectionAuthorityAllowsTarget(
exact,
"ble-k1-001",
"bridge",
),
true,
);
assert.equal(
observedConnectionAuthorityAllowsTarget(
{
...exact,
selected_device_id: "ble-k1-foreign",
connection_lifecycle: {
active_binding_key: "binding-b",
active_binding: {
binding_key: "binding-b",
transport_ref: "ble-k1-foreign",
connection_mode: "bridge",
},
},
},
"ble-k1-001",
"bridge",
{ allowUnbound: true },
),
false,
);
assert.equal(
observedConnectionAuthorityAllowsTarget(
{
selected_device_id: null,
connection_mode: null,
connection_lifecycle: {
active_binding_key: null,
active_binding: null,
},
},
"ble-k1-001",
"bridge",
{ allowUnbound: true },
),
true,
);
});
test("K1 Connect continuation accepts only unchanged or exactly consumed authority", () => {
const ordinaryFence = {
snapshotRuntimeId: "runtime-a",
connectionMode: "bridge",
desiredModeRevision: 7,
reconfigurationRevision: 10,
reconfigurationIntentId: null,
activeBindingKey: null,
discoveryGeneration: 5,
};
const connectedState = ({
deviceId = "ble-k1-001",
reconfigurationRevision = 10,
discoveryGeneration = 5,
} = {}) => ({
snapshot_runtime_id: "runtime-a",
desired_connection_mode: "bridge",
desired_connection_mode_revision: 7,
ble_discovery_generation: discoveryGeneration,
selected_device_id: deviceId,
connection_mode: "bridge",
connection_reconfiguration: connectionReconfiguration({
revision: reconfigurationRevision,
}),
connection_lifecycle: {
active_binding_key: `binding-${deviceId}`,
active_binding: {
binding_key: `binding-${deviceId}`,
transport_ref: deviceId,
connection_mode: "bridge",
},
},
});
const ordinaryState = connectedState();
const ordinaryCurrent = {
...ordinaryFence,
activeBindingKey: "binding-ble-k1-001",
};
assert.deepEqual(
connectContinuationAuthority(
ordinaryFence,
ordinaryState,
ordinaryCurrent,
"ble-k1-001",
"bridge",
),
ordinaryCurrent,
);
const reconfigurationFence = {
...ordinaryFence,
reconfigurationIntentId: "reconfigure-a",
};
const consumedState = connectedState({
reconfigurationRevision: 11,
discoveryGeneration: 6,
});
const consumedCurrent = {
...reconfigurationFence,
reconfigurationRevision: 11,
reconfigurationIntentId: null,
activeBindingKey: "binding-ble-k1-001",
discoveryGeneration: 6,
};
assert.deepEqual(
connectContinuationAuthority(
reconfigurationFence,
consumedState,
consumedCurrent,
"ble-k1-001",
"bridge",
),
consumedCurrent,
);
const skippedState = connectedState({
reconfigurationRevision: 12,
discoveryGeneration: 7,
});
const skippedCurrent = {
...consumedCurrent,
reconfigurationRevision: 12,
discoveryGeneration: 7,
};
assert.equal(
connectContinuationAuthority(
reconfigurationFence,
skippedState,
skippedCurrent,
"ble-k1-001",
"bridge",
),
null,
);
const foreignState = connectedState({ deviceId: "ble-k1-foreign" });
assert.equal(
connectContinuationAuthority(
ordinaryFence,
foreignState,
{
...ordinaryCurrent,
activeBindingKey: "binding-ble-k1-foreign",
},
"ble-k1-001",
"bridge",
),
null,
);
});
test("K1 runtime replacement retires A and isolates a new B action from late settlement", () => {
const arbiter = new SnapshotRuntimeActionArbiter();
const actionA = arbiter.begin(4);
assert.ok(actionA);
let pendingAction = "verify";
let acceptedState = "runtime-a";
let surfacedError = null;
assert.equal(
arbiter.retireForSnapshotChange("runtime-a", "runtime-b"),
true,
);
pendingAction = null;
acceptedState = "runtime-b";
assert.equal(pendingAction, null, "runtime-b controls are enabled without A loader");
const actionB = arbiter.begin(4);
assert.ok(actionB, "runtime-b click is admitted before action A settles");
pendingAction = "scan";
const acceptLateResult = (token, nextState) => {
if (!arbiter.isCurrent(token)) return false;
acceptedState = nextState;
return true;
};
const surfaceLateFailure = (token, message) => {
if (!arbiter.isCurrent(token)) return false;
surfacedError = message;
return true;
};
const finish = (token) => {
if (!arbiter.settle(token)) return false;
pendingAction = null;
return true;
};
assert.equal(acceptLateResult(actionA, "runtime-a-late"), false);
assert.equal(surfaceLateFailure(actionA, "late A error"), false);
assert.equal(finish(actionA), false);
assert.equal(acceptedState, "runtime-b");
assert.equal(surfacedError, null);
assert.equal(pendingAction, "scan", "late A finally cannot clear B pending state");
assert.equal(finish(actionB), true);
assert.equal(pendingAction, null);
});
test("successful action response may be superseded only by the same runtime revision", () => {
const response = {
snapshot_runtime_id: "runtime-a",
snapshot_revision: 41,
};
assert.equal(runtimeActionResponseAlreadyAccepted(response, {
snapshot_runtime_id: "runtime-a",
snapshot_revision: 42,
}), true);
assert.equal(runtimeActionResponseAlreadyAccepted(response, {
snapshot_runtime_id: "runtime-a",
snapshot_revision: 40,
}), false);
assert.equal(runtimeActionResponseAlreadyAccepted(response, {
snapshot_runtime_id: "runtime-b",
snapshot_revision: 99,
}), false);
assert.equal(runtimeActionResponseAlreadyAccepted(response, null), false);
});
test("explicit scenario reset B supersedes pending callback A in one runtime", () => {
const arbiter = new SnapshotRuntimeActionArbiter();
const actionA = arbiter.begin(12);
assert.ok(actionA);
const actionB = arbiter.begin(12, true);
assert.ok(actionB, "reset B is admitted while A is still pending");
assert.equal(arbiter.isCurrent(actionA), false);
assert.equal(arbiter.settle(actionA), false, "late A cannot clear B loader");
assert.equal(arbiter.isCurrent(actionB), true);
assert.equal(arbiter.settle(actionB), true);
});
test("acquisition and spatial STOP surfaces share one runtime action slot", () => {
const arbiter = new SnapshotRuntimeActionArbiter();
let physicalStopCallCount = 0;
const clickPhysicalStop = () => {
const token = arbiter.begin(7);
if (!token) return null;
physicalStopCallCount += 1;
return token;
};
const acquisitionSurface = clickPhysicalStop();
const spatialSurface = clickPhysicalStop();
assert.ok(acquisitionSurface);
assert.equal(spatialSurface, null);
assert.equal(physicalStopCallCount, 1);
assert.equal(arbiter.settle(acquisitionSurface), true);
});
test("change-network exact lookup never substitutes a neighboring UUID", () => {
const reconfiguration = connectionReconfiguration({
intent: "change-network",
status: "fresh-scan-completed",
revision: 8,
requiredTransportRef: "ble-k1-original",
requiredConnectionMode: "bridge",
discoveryGeneration: 11,
requiredTransportObserved: true,
});
const devices = [
{ device_id: "ble-k1-foreign", name: "Nearby", connectable: true },
{ device_id: "ble-k1-original", name: "Original", connectable: true },
];
assert.equal(
exactChangeNetworkCandidate(reconfiguration, devices, 11)?.device_id,
"ble-k1-original",
);
assert.equal(exactChangeNetworkCandidate(reconfiguration, devices, 12), null);
assert.equal(
exactChangeNetworkCandidate(
{ ...reconfiguration, required_transport_observed: false },
devices,
11,
),
null,
);
});
test("cold connection workflow exposes the mode selector and explicit Scan immediately", () => {
const state = durableTopologyState();
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
state.devices = [{
device_id: "ble-k1-001",
name: "XGR-A46BE7",
rssi: -45,
connectable: true,
likely_k1: true,
}];
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["scan-ble", "provision-fresh-device"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
"provision-fresh-device": {
allowed: true,
reason_codes: [],
target_source: "fresh-scan",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: true,
automatic_retry: false,
},
"prepare-select-device": {
allowed: false,
reason_codes: ["acquisition-active"],
target_source: "local-prestart-handoff",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
device_write_performed: false,
automatic_retry: false,
},
"prepare-change-network": {
allowed: false,
reason_codes: ["acquisition-active"],
target_source: "local-prestart-handoff",
required_transport_ref: "ble-k1-001",
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
device_write_performed: false,
automatic_retry: false,
},
},
};
const markup = renderToStaticMarkup(createElement(K1ProvisioningPipeline, {
controller: provisioningController(state),
desiredMode: "bridge",
}));
assert.equal(physicalRecoveryConnectionDetail(state), null);
assert.match(markup, /ПОДКЛЮЧЕНИЕ · ШАГИ 01–02/);
assert.match(markup, /<span>01<\/span>/);
assert.match(markup, /<h3>Подключение<\/h3>/);
assert.doesNotMatch(markup, /<span>02<\/span>|<span>03<\/span>/);
assert.doesNotMatch(markup, /Питание|индикатор горит/);
assert.doesNotMatch(markup, /Название общей сети Wi‑Fi|Пароль Wi‑Fi/);
assert.doesNotMatch(markup, /class="nodedc-activity-indicator"/);
const scanButton = buttonMarkupWithText(markup, "Найти по Bluetooth")[0];
assert.ok(scanButton);
assert.doesNotMatch(scanButton, /\bdisabled(?:=|\s|>)/);
assert.equal(
buttonMarkupWithText(markup, "Подключить новый K1").length,
0,
);
const modeToggle = markup.match(
/<button[^>]*aria-label="Способ подключения"[^>]*>/,
)?.[0];
assert.ok(modeToggle);
assert.doesNotMatch(modeToggle, /\bdisabled(?:=|\s|>)/);
assertCanonicalConnectionCopy(markup);
});
test("cold Scan click dispatches from the live runtime fence and releases it for retry", async () => {
const state = durableTopologyState();
state.snapshot_runtime_id = "runtime-live-scan-click";
state.snapshot_revision = 1;
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
state.connection_reconfiguration = connectionReconfiguration();
state.connection_lifecycle = connectionLifecycle({ control: false });
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["scan-ble"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
const authority = connectionActionAuthoritySnapshot(state, "bridge");
assert.ok(authority);
let scanCalls = 0;
let scanDispatched = null;
const controller = {
...provisioningController(state),
scanWithResult: async () => {
scanCalls += 1;
scanDispatched?.();
return {
succeeded: true,
snapshotRuntimeId: state.snapshot_runtime_id,
discoveryGeneration: state.ble_discovery_generation + scanCalls,
transportRefs: [],
};
},
selectConnectionMode: async () => true,
getConnectionActionAuthority: () => authority,
isSnapshotRuntimeCurrent: (runtimeId) => runtimeId === state.snapshot_runtime_id,
isConnectionActionAuthorityCurrent: (candidate) =>
connectionActionAuthorityMatches(candidate, authority),
isConnectionPolicyActionAllowedCurrent: (action) => action === "scan-ble",
};
const tree = captureProvisioningTree({
controller,
desiredMode: "bridge",
});
const scanButton = actionByLabel(tree, "Найти по Bluetooth");
assert.ok(scanButton);
const clickAndWaitForDispatch = async () => {
const dispatched = new Promise((resolve) => {
scanDispatched = resolve;
});
scanButton.props.onClick();
await Promise.race([
dispatched,
new Promise((_, reject) => setTimeout(
() => reject(new Error("Scan click did not reach scanWithResult")),
100,
)),
]);
await new Promise((resolve) => setTimeout(resolve, 0));
};
await clickAndWaitForDispatch();
await clickAndWaitForDispatch();
assert.equal(scanCalls, 2);
});
test("scenario reset epoch rejects every late settlement from the old local scenario", () => {
assert.equal(localScenarioActionEpochIsCurrent(4, 4), true);
assert.equal(localScenarioActionEpochIsCurrent(4, 5), false);
const source = readFileSync(provisioningSourceUrl, "utf8");
const search = sourceSlice(source, "const repeatDeviceScan", "const submitConnect");
const afterScan = search.indexOf("scanResult = await scanWithResult");
const epochGuard = search.indexOf(
"localScenarioActionEpochIsCurrent",
afterScan,
);
const firstSettlement = search.indexOf("setEscapedAppliedAttemptKey", afterScan);
assert.ok(afterScan >= 0);
assert.ok(epochGuard > afterScan);
assert.ok(firstSettlement > epochGuard);
const toolbarResetBoundary = sourceSlice(
source,
"if (\n scenarioResetPresentationKey",
"const currentRuntimeActionFence",
);
assert.match(toolbarResetBoundary, /localScenarioActionEpoch\.current \+= 1/);
assert.match(toolbarResetBoundary, /activeRuntimeActionFence\.current = null/);
assert.match(toolbarResetBoundary, /activeConnectIntent\.current = null/);
const resetEffect = sourceSlice(
source,
"useEffect(() => {\n if (\n !scenarioResetPresentationKey",
"const searchPresentationIsCurrent",
);
assert.match(resetEffect, /setConnectionAttemptPresentation\(null\)/);
assert.match(resetEffect, /setPreparingReconfigurationRequest\(null\)/);
assert.match(resetEffect, /setCandidateUnavailableMessage\(null\)/);
assert.doesNotMatch(source, /physicalReopenInFlight|setPhysicalReopenPresentation/);
});
test("toolbar reset in one runtime rejects late Scan A and admits exactly one Scan B", async () => {
const initialState = durableTopologyState();
initialState.snapshot_runtime_id = "runtime-toolbar-reset-during-scan";
initialState.snapshot_revision = 1;
initialState.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
initialState.connection_reconfiguration = connectionReconfiguration();
initialState.connection_lifecycle = connectionLifecycle({ control: false });
initialState.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["scan-ble"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
let currentState = initialState;
let resolveScanA;
let markScanADispatched;
let markScanBDispatched;
const scanAResult = new Promise((resolve) => {
resolveScanA = resolve;
});
const scanADispatched = new Promise((resolve) => {
markScanADispatched = resolve;
});
const scanBDispatched = new Promise((resolve) => {
markScanBDispatched = resolve;
});
let scanCalls = 0;
let scanBCalls = 0;
const controller = {
...provisioningController(initialState),
selectConnectionMode: async () => true,
scanWithResult: async () => {
scanCalls += 1;
if (scanCalls === 1) {
markScanADispatched();
return scanAResult;
}
scanBCalls += 1;
markScanBDispatched();
return {
succeeded: true,
snapshotRuntimeId: currentState.snapshot_runtime_id,
discoveryGeneration: currentState.ble_discovery_generation + 1,
transportRefs: [],
};
},
getCurrentState: () => currentState,
getConnectionActionAuthority: (mode) =>
connectionActionAuthoritySnapshot(currentState, mode),
isSnapshotRuntimeCurrent: (runtimeId) =>
runtimeId === currentState.snapshot_runtime_id,
isConnectionActionAuthorityCurrent: (candidate) =>
connectionActionAuthorityMatches(
candidate,
connectionActionAuthoritySnapshot(
currentState,
candidate.connectionMode,
),
),
isConnectionPolicyActionAllowedCurrent: (action) =>
currentState.connection_policy.allowed_actions.includes(action),
};
const props = () => ({
controller: { ...controller, state: currentState },
desiredMode: "bridge",
});
const harness = createStatefulProvisioningHarness(props());
try {
let tree = harness.render(props());
harness.flushEffects();
tree = harness.render(props());
harness.flushEffects();
const scanAButton = actionByLabel(tree, "Найти по Bluetooth");
assert.ok(scanAButton);
scanAButton.props.onClick();
await Promise.race([
scanADispatched,
new Promise((_, reject) => setTimeout(
() => reject(new Error("Scan A did not dispatch")),
100,
)),
]);
const resetState = structuredClone(initialState);
resetState.snapshot_revision = 2;
resetState.desired_connection_mode_revision = 1;
resetState.connection_scenario_reset = {
reset_id: "toolbar-reset-same-runtime",
request_revision: 0,
revision: 1,
desired_mode: "bridge",
active: false,
settled_by_discovery_generation: 0,
local_session_closed: true,
previous_device_may_continue_scanning: false,
physical_disposition: null,
network_disposition: null,
device_command_performed: false,
network_write_performed: false,
automatic_scan: false,
operation_sequence: 2,
};
currentState = resetState;
tree = harness.render(props());
harness.flushEffects();
tree = harness.render(props());
harness.flushEffects();
assert.equal(harness.stateValue(emptySearchPresentation), null);
assert.ok(actionByLabel(tree, "Найти по Bluetooth"));
assert.equal(actionByLabel(tree, "Повторить поиск Bluetooth"), null);
assert.equal(actionByLabel(tree, "Применить"), null);
resolveScanA({
succeeded: true,
snapshotRuntimeId: initialState.snapshot_runtime_id,
discoveryGeneration: 1,
transportRefs: ["stale-device-from-scan-a"],
});
await new Promise((resolve) => setTimeout(resolve, 0));
tree = harness.render(props());
harness.flushEffects();
tree = harness.render(props());
harness.flushEffects();
assert.equal(
harness.stateValue(emptySearchPresentation),
null,
"late Scan A must not repopulate the reset search latch",
);
assert.ok(actionByLabel(tree, "Найти по Bluetooth"));
assert.equal(actionByLabel(tree, "Повторить поиск Bluetooth"), null);
assert.equal(actionByLabel(tree, "Применить"), null);
const scanBButton = actionByLabel(tree, "Найти по Bluetooth");
scanBButton.props.onClick();
await Promise.race([
scanBDispatched,
new Promise((_, reject) => setTimeout(
() => reject(new Error("Scan B did not dispatch")),
100,
)),
]);
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(scanCalls, 2);
assert.equal(scanBCalls, 1);
} finally {
harness.dispose();
}
});
test("operator-local connection belongs to LAB and retains all test modes", () => {
const localConnection = workspaces.find((workspace) => workspace.id === "local-device");
assert.equal(localConnection?.root, "polygon");
assert.equal(localConnection?.label, "Тестовые устройства");
assert.equal(localConnection?.title, "Тестовые устройства");
assert.equal(model().displayName, "XGRIDS LixelKity K1");
assert.deepEqual(
connectionModeOptions.map(({ label }) => label),
[
"Общая сеть · Bridge",
"Локальная сеть · Quick Connect",
"Хотспот контроллера · Direct Connect",
],
);
assertCanonicalConnectionCopy(
connectionModeOptions
.map(({ label, description }) => `${label} ${description ?? ""}`)
.join(" "),
);
});
test("cold adjacent connection panels do not repeat the model or device noun", () => {
const state = durableTopologyState();
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["scan-ble", "provision-fresh-device"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
const provisioningMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{ controller: provisioningController(state), desiredMode: "bridge" },
));
const acquisitionMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: acquisitionController(state),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
const diagnosticsMarkup = renderToStaticMarkup(createElement(
K1Diagnostics,
{
controller: {
state,
backendStatus: "offline",
eventStatus: "disconnected",
latencyHistory: [],
},
sourceLabel: "Ожидание",
},
));
assertCanonicalConnectionCopy(
`${provisioningMarkup}${acquisitionMarkup}${diagnosticsMarkup}`,
);
});
test("legacy live fields do not create device, stream or metrics authority", () => {
const state = runtimeState();
delete state.connection_supervisor;
const normalized = normalize(state);
assert.ok(normalized);
assert.equal(normalized.activeDevice, null);
assert.equal(normalized.deviceSession.connectivity, "unknown");
assert.equal(normalized.sourceMode, "idle");
assert.equal(normalized.phase, "starting");
assert.equal(normalized.spatialSource, null);
assert.equal(normalized.metrics.latencyMs, null);
assert.equal(normalized.metrics.frameRateHz, null);
assert.equal(normalized.metrics.aiFrameRateHz, null);
assert.equal(normalized.observationSources[0].availability, "unverified");
assert.equal(normalized.observationSources[0].binding.deviceId, null);
});
test("control authority exposes the session but not unconfirmed data", () => {
const state = runtimeState();
state.connection_supervisor = supervisor({ control: true, data: false });
const normalized = normalize(state);
assert.ok(normalized?.activeDevice);
assert.equal(normalized.activeDevice.endpointLabel, "192.168.68.52");
assert.equal(normalized.deviceSession.connectivity, "connected");
assert.equal(normalized.sourceMode, "idle");
assert.equal(normalized.phase, "starting");
assert.equal(normalized.spatialSource, null);
assert.equal(normalized.metrics.pointCount, null);
assert.equal(normalized.observationSources[0].availability, "available");
assert.equal(normalized.observationSources[0].previewUrl, null);
});
test("control plus data authority is the only live streaming presentation", () => {
const normalized = normalize(runtimeState());
assert.ok(normalized?.activeDevice);
assert.equal(normalized.sourceMode, "live");
assert.equal(normalized.phase, "streaming");
assert.equal(normalized.deviceSession.connectivity, "connected");
assert.equal(normalized.spatialSource.url, "rerun+http://127.0.0.1:9877/proxy");
assert.equal(normalized.metrics.publishedFrameCount, 15);
assert.equal(normalized.metrics.latencyMs, 12.5);
assert.equal(normalized.metrics.aiFrameRateHz, 5);
assert.equal(normalized.observationSources[0].availability, "streaming");
});
test("successful K1 scanning state stays a success message", () => {
const state = runtimeState();
state.message = "K1 подтвердил режим сканирования; приём и запись активны.";
const normalized = normalize(state);
assert.equal(normalized.message, state.message);
assert.notEqual(
normalized.message,
"Операция не выполнена. Технические подробности сохранены в журнале сервера.",
);
});
test("data loss degrades the controlled device and withdraws stale stream data", () => {
const state = runtimeState();
state.connection_supervisor = supervisor({
control: true,
data: false,
dataPlaneState: "lost",
});
const normalized = normalize(state);
assert.ok(normalized?.activeDevice);
assert.equal(normalized.deviceSession.connectivity, "degraded");
assert.equal(normalized.sourceMode, "idle");
assert.equal(normalized.phase, "starting");
assert.equal(normalized.spatialSource, null);
assert.equal(normalized.metrics.frameRateHz, null);
assert.equal(normalized.observationSources[0].availability, "degraded");
assert.equal(normalized.observationSources[0].previewUrl, null);
});
test("exact reconnecting lineage retains only the current spatial presentation lease", () => {
const healthy = normalize(runtimeState());
const recoveryState = activeRecoveryRuntimeState();
const recovering = normalize(recoveryState);
assert.ok(healthy?.spatialSource && recovering?.spatialSource);
assert.equal(recovering.sourceMode, "live");
assert.equal(recovering.phase, "starting");
assert.equal(recovering.spatialSource.id, healthy.spatialSource.id);
assert.equal(recovering.spatialSource.url, healthy.spatialSource.url);
assert.equal(recovering.activeDevice, null);
assert.equal(recovering.metrics.publishedFrameCount, null);
assert.equal(recovering.metrics.latencyMs, null);
assert.equal(recovering.observationSources[0].availability, "connecting");
assert.equal(recovering.observationSources[0].previewUrl, healthy.spatialSource.url);
assert.deepEqual(recovering.observationSources[0].presentationLease, {
kind: "active-stream-recovery",
runtimeId: "runtime-active-recovery-001",
acquisitionId: "acquisition-001",
acquisitionStateRevision: 4,
producerGeneration: 13,
recoveryGeneration: 5,
});
const noCurrentUrl = structuredClone(recoveryState);
delete noCurrentUrl.rerun_grpc_url;
assert.equal(normalize(noCurrentUrl).spatialSource, null);
assert.equal(normalize(noCurrentUrl).observationSources[0].previewUrl, null);
});
test("stale or terminal recovery lineage cannot retain a spatial source", () => {
const staleProducer = activeRecoveryRuntimeState();
staleProducer.producer_generation += 1;
const differentAcquisition = activeRecoveryRuntimeState({
acquisition_id: "acquisition-from-old-runtime",
});
for (const state of [
staleProducer,
differentAcquisition,
activeRecoveryRuntimeState({ state: "blocked" }),
activeRecoveryRuntimeState({ state: "standby" }),
activeRecoveryRuntimeState({ state: "fault" }),
]) {
const normalized = normalize(state);
assert.equal(normalized.sourceMode, "idle");
assert.equal(normalized.spatialSource, null);
assert.equal(normalized.metrics.publishedFrameCount, null);
assert.equal(normalized.observationSources[0].previewUrl, null);
assert.equal(normalized.observationSources[0].presentationLease, null);
}
});
test("control loss turns a selected device back into an unverified snapshot", () => {
const state = runtimeState();
state.connection_supervisor = supervisor({ control: false, data: false });
const normalized = normalize(state);
assert.ok(normalized);
assert.equal(normalized.activeDevice, null);
assert.equal(normalized.deviceSession.connectivity, "connecting");
assert.equal(normalized.sourceMode, "idle");
assert.equal(normalized.spatialSource, null);
assert.equal(normalized.observationSources[0].availability, "unverified");
assert.equal(normalized.observationSources[0].binding.deviceId, null);
});
test("operator banner renders all safe host diagnostics and never the raw exception", () => {
const diagnostic = {
schema_version: "missioncore.host-failure-diagnostic/v1",
code: "host.keychain.interaction-required",
domain: "keychain",
impact: "control",
operator_action: "unlock-or-authorize-keychain",
automatic_retry: false,
redacted: true,
};
const presentation = hostFailureDiagnosticPresentation(diagnostic);
assert.ok(presentation);
assert.equal(
presentation.operatorActionLabel,
"Разблокируйте связку ключей macOS и подтвердите доступ Mission Core к профилю подключения.",
);
const privateException = "SecurityError: account=private-user password=never-render-this";
const attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: "op-00000000-0000-4000-8000-000000000123",
connection_mode: "bridge",
status: "failed",
stage: "status-observing-failed",
public_error_code: "network-session-interrupted",
side_effect_status: "unknown",
safe_next_action: "scan-select-connect",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: OBSERVED_AT,
timeline: [],
diagnostic_bundle: {
schema_version: "missioncore.xgrids-k1-connection-diagnostic/v1",
redacted: true,
generated_at_utc: OBSERVED_AT,
snapshot_runtime_id: "runtime-test",
attempt: {},
network_mutation_ledger: {},
connection_supervisor: {},
automatic_retry: false,
},
};
const markup = renderToStaticMarkup(createElement(K1OperatorError, {
message: privateException,
diagnostic,
attempt,
onRefresh() {},
onClear() {},
}));
assert.match(markup, /Причина/);
assert.match(markup, /Связка ключей требует явного подтверждения оператора/);
assert.match(markup, /Системный контур/);
assert.match(markup, /Связка ключей macOS/);
assert.match(markup, /Управляющая связь не установлена/);
assert.match(markup, /Разблокируйте связку ключей macOS/);
assert.match(markup, /Автоматического повтора не было/);
assert.match(markup, /op-00000000-0000-4000-8000-000000000123/);
assert.match(markup, /Ожидание ответа/);
assert.match(markup, /Результат команды не подтверждён/);
assert.match(markup, /новый поиск и выбрать результат/);
assert.match(markup, /Скопировать диагностику/);
assert.match(markup, /<details class="error-banner__details">/);
assert.doesNotMatch(markup, /<details[^>]*\sopen/);
assert.match(markup, /Проверить состояние/);
assert.doesNotMatch(markup, /SecurityError|private-user|never-render-this/);
assert.doesNotMatch(markup, /host\.keychain\.interaction-required/);
});
test("operator banner presents every canonical connection next action without fallback drift", () => {
const labels = new Map([
["wait-for-current-attempt", "Дождаться завершения текущей попытки"],
["continue-with-control-verification", "Продолжить текущее подключение"],
["verify-control-read-only", "Проверить управление без изменения сети"],
["start-acquisition", "Готово к запуску приёма"],
["stop-local-receiver", "Завершить только локальный приём"],
[
"retire-unavailable-physical-target",
"Исключить недоступный прежний K1 и выбрать другой",
],
["scan-select-connect", "Выполнить новый поиск и выбрать результат"],
["manual-recovery-required", "Требуется ручное восстановление"],
]);
for (const [safeNextAction, expectedLabel] of labels) {
const attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: `attempt-${safeNextAction}`,
connection_mode: "bridge",
status: "failed",
stage: "device-info-failed",
public_error_code: "connection-not-ready",
side_effect_status: "none",
safe_next_action: safeNextAction,
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: OBSERVED_AT,
timeline: [],
};
const markup = renderToStaticMarkup(createElement(K1OperatorError, {
message: "Связь не подтверждена",
attempt,
onRefresh() {},
onClear() {},
}));
assert.match(markup, new RegExp(expectedLabel));
}
});
test("operator banner never renders an unstructured legacy connection error", () => {
const markup = renderToStaticMarkup(createElement(K1OperatorError, {
message:
"K1: исходное устройство не найдено; подключаемся к сохранённому устройству",
onRefresh() {},
onClear() {},
}));
assert.match(
markup,
/Подключение не завершено\. Автоматического повтора не было/,
);
assertCanonicalConnectionCopy(markup);
});
test("compact connection error can expose only its contextual recovery path", () => {
const markup = renderToStaticMarkup(createElement(K1OperatorError, {
message: "hidden transport error",
compact: true,
showDefaultActions: false,
recoveryActions: createElement("button", null, "Подключить новый K1"),
onRefresh() {},
onClear() {},
}));
assert.match(markup, /Подключение не завершено/);
assert.match(markup, />Подключить новый K1<\/button>/);
assert.doesNotMatch(markup, /Проверить состояние|>Закрыть<\/button>/);
});
test("connection attempt network phase copy distinguishes absent, applied and unknown outcomes", () => {
assert.equal(
attemptNetworkPhaseLabel("network_not_applied"),
"Настройки сети не применены",
);
assert.equal(
attemptNetworkPhaseLabel("network_applied"),
"Настройки сети применены",
);
assert.equal(
attemptNetworkPhaseLabel("network_outcome_unknown"),
"Результат применения настроек сети не подтверждён",
);
});
test("runtime errors borrow diagnostics only from their exact Connect attempt", () => {
const state = durableTopologyState();
state.snapshot_runtime_id = "runtime-correlated-error";
state.connection_attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: "op-exact-connect",
connection_mode: "bridge",
status: "failed",
phase: "network_outcome_unknown",
control_state: "unknown",
stage: "ble-write-dispatched",
public_error_code: null,
side_effect_status: "unknown",
safe_next_action: "verify-control-read-only",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: OBSERVED_AT,
timeline: [],
};
const exact = {
action: "connect",
runtimeId: state.snapshot_runtime_id,
leaseGeneration: 0,
connectionAttemptId: state.connection_attempt.attempt_id,
};
assert.equal(connectionAttemptForRuntimeError(exact, state), state.connection_attempt);
for (const mismatch of [
{ ...exact, action: "scan" },
{ ...exact, runtimeId: "runtime-replaced" },
{ ...exact, connectionAttemptId: "op-another-connect" },
{ ...exact, connectionAttemptId: null },
]) {
assert.equal(connectionAttemptForRuntimeError(mismatch, state), null);
}
assert.equal(
connectionAttemptForRuntimeError(exact, {
...state,
connection_attempt: { ...state.connection_attempt, status: "running" },
}),
null,
);
});
test("connection recovery keeps current then durable priority over a stale fresh recommendation", () => {
const state = durableTopologyState();
state.snapshot_runtime_id = "runtime-recovery-priority";
state.devices = [{
device_id: "fresh-k1",
name: "Fresh K1",
connectable: true,
likely_k1: true,
}];
const decision = (target_source, required_transport_ref) => ({
allowed: true,
reason_codes: [],
target_source,
required_transport_ref,
required_connection_mode: "bridge",
requires_live_gatt_validation: target_source === "fresh-scan",
automatic_retry: false,
});
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
recommended_action: "observe-fresh-device-network",
allowed_actions: [
"observe-current-device-network",
"observe-configured-device-network",
"observe-fresh-device-network",
],
actions: {
"observe-current-device-network": decision(
"retained-current-process",
"current-k1",
),
"observe-configured-device-network": decision(
"durable-configured-state",
"configured-k1",
),
"observe-fresh-device-network": decision("fresh-scan", "fresh-k1"),
},
};
const recommended = recommendedConnectionRecoveryObservationTarget(state);
assert.equal(recommended?.action, "observe-current-device-network");
assert.equal(recommended?.deviceId, "current-k1");
state.connection_policy.actions["observe-current-device-network"].allowed = false;
const durable = recommendedConnectionRecoveryObservationTarget(state);
assert.equal(durable?.action, "observe-configured-device-network");
assert.equal(durable?.deviceId, "configured-k1");
state.connection_policy.actions["observe-configured-device-network"].allowed = false;
const fresh = recommendedConnectionRecoveryObservationTarget(state);
assert.equal(fresh?.action, "observe-fresh-device-network");
assert.equal(fresh?.deviceId, "fresh-k1");
state.connection_policy.recommended_action = "scan-ble";
state.connection_policy.actions["observe-current-device-network"].allowed = true;
const fallback = recommendedConnectionRecoveryObservationTarget(state);
assert.equal(fallback?.action, "observe-current-device-network");
assert.equal(fallback?.deviceId, "current-k1");
assert.equal(connectionRecoveryObservationTargetMatches(fallback, fallback), true);
assert.equal(
connectionRecoveryObservationTargetMatches(fallback, {
...fallback,
deviceId: "foreign-k1",
}),
false,
);
});
test("cold Quick recovery dispatches exact Verify without borrowing the mode draft", async () => {
const target = {
action: "observe-configured-device-network",
deviceId: "configured-quick-k1",
connectionMode: "quick-connect",
source: "durable-configured-state",
serverBound: true,
expectedDiscoveryGeneration: null,
};
let calls = 0;
const dispatched = await dispatchConnectionRecoveryObservationForCurrentRuntime(
"runtime-cold-quick",
target,
(runtimeId) => runtimeId === "runtime-cold-quick",
() => ({ ...target }),
async (exactTarget) => {
calls += 1;
assert.equal(exactTarget.connectionMode, "quick-connect");
return "verified";
},
);
assert.deepEqual(dispatched, { dispatched: true, result: "verified" });
assert.equal(calls, 1);
for (const [runtimeCurrent, currentTarget] of [
[false, target],
[true, { ...target, deviceId: "replacement-k1" }],
]) {
const blocked = await dispatchConnectionRecoveryObservationForCurrentRuntime(
"runtime-cold-quick",
target,
() => runtimeCurrent,
() => currentTarget,
async () => {
calls += 1;
return "must-not-dispatch";
},
);
assert.deepEqual(blocked, { dispatched: false, result: null });
}
assert.equal(calls, 1);
});
test("successful recovery Refresh clears only the compact connection failure", async () => {
let clearCalls = 0;
const refreshed = await clearConnectionFailureAfterSuccessfulRefresh(
async () => ({ snapshot_runtime_id: "runtime-refreshed" }),
() => {
clearCalls += 1;
},
);
assert.equal(refreshed, true);
assert.equal(clearCalls, 1);
const unavailable = await clearConnectionFailureAfterSuccessfulRefresh(
async () => null,
() => {
clearCalls += 1;
},
);
assert.equal(unavailable, false);
assert.equal(clearCalls, 1);
});
test("successful recovery Scan survives configured-to-fresh promotion for the same K1", () => {
const attempt = terminalConnectionRecoveryState().connection_attempt;
const configuredTarget = {
action: "observe-configured-device-network",
deviceId: "F89438FA-55ED-85AD-EED7-734AC84746D8",
connectionMode: "bridge",
source: "durable-configured-state",
serverBound: true,
expectedDiscoveryGeneration: null,
};
const freshTarget = {
...configuredTarget,
action: "observe-fresh-device-network",
deviceId: "f89438fa-55ed-85ad-eed7-734ac84746d8",
source: "fresh-scan",
expectedDiscoveryGeneration: 28,
};
const beforeScan = connectionRecoveryEscapeKey({
snapshotRuntimeId: "runtime-recovery-scan",
attempt,
target: configuredTarget,
});
const afterSuccessfulScan = connectionRecoveryEscapeKey({
snapshotRuntimeId: "runtime-recovery-scan",
attempt,
target: freshTarget,
});
assert.equal(afterSuccessfulScan, beforeScan);
const successfulEscape = connectionRecoveryEscapeAfterScan(true, beforeScan);
// Success stores the pre-Scan key, so the promoted fresh results own Step 01.
assert.equal(
connectionRecoveryIsRequired(afterSuccessfulScan, successfulEscape),
false,
);
// A failed Scan stores no escape and leaves the recovery card authoritative.
const failedEscape = connectionRecoveryEscapeAfterScan(false, beforeScan);
assert.equal(failedEscape, null);
assert.equal(connectionRecoveryIsRequired(afterSuccessfulScan, failedEscape), true);
for (const changed of [
{
snapshotRuntimeId: "runtime-replaced",
attempt,
target: freshTarget,
},
{
snapshotRuntimeId: "runtime-recovery-scan",
attempt: { ...attempt, attempt_id: "op-new-attempt" },
target: freshTarget,
},
{
snapshotRuntimeId: "runtime-recovery-scan",
attempt,
target: { ...freshTarget, deviceId: "replacement-k1" },
},
{
snapshotRuntimeId: "runtime-recovery-scan",
attempt,
target: { ...freshTarget, connectionMode: "quick-connect" },
},
]) {
assert.equal(
connectionRecoveryIsRequired(
connectionRecoveryEscapeKey(changed),
beforeScan,
),
true,
);
}
});
test("metric cards render values only for replay or supervisor-authoritative live data", () => {
const legacy = runtimeState();
delete legacy.connection_supervisor;
const legacyMarkup = renderToStaticMarkup(createElement(K1Metrics, {
controller: { state: legacy },
}));
assert.doesNotMatch(legacyMarkup, /12,5/);
assert.match(legacyMarkup, /ДО ПУБЛИКАЦИИ/);
const authoritativeMarkup = renderToStaticMarkup(createElement(K1Metrics, {
controller: { state: runtimeState() },
}));
assert.match(authoritativeMarkup, /12,5/);
assert.match(authoritativeMarkup, /42[\s ]000/);
assert.match(authoritativeMarkup, /Данные потока при этом сохраняются/);
assert.doesNotMatch(authoritativeMarkup, /Исходные данные/);
assertCanonicalConnectionCopy(authoritativeMarkup);
});
test("cold disconnected connection SSR hides every operational panel", () => {
const state = durableTopologyState();
const markup = renderConnectionPipelines(state);
const unresolvedHistory = reopenedPhysicalState();
const unresolvedHistoryMarkup = renderConnectionPipelines(unresolvedHistory);
assert.equal(shouldRenderK1OperationalPanels(state), false);
assert.equal(
shouldRenderK1OperationalPanels(unresolvedHistory),
false,
"unresolved durable physical history is handled inside the connection pipeline",
);
assert.match(markup, /class="[^"]*\bconnection-panel\b/);
assert.match(markup, /ПОДКЛЮЧЕНИЕ · ШАГИ 01–02/);
assert.doesNotMatch(markup, /class="metrics-grid/);
assert.doesNotMatch(markup, /class="[^"]*\bsession-panel\b/);
assert.doesNotMatch(markup, /class="diagnostics-grid/);
assert.doesNotMatch(markup, /class="device-workspace__side/);
assert.doesNotMatch(unresolvedHistoryMarkup, /class="metrics-grid/);
assert.doesNotMatch(unresolvedHistoryMarkup, /class="[^"]*\bsession-panel\b/);
assert.doesNotMatch(unresolvedHistoryMarkup, /class="diagnostics-grid/);
assert.doesNotMatch(unresolvedHistoryMarkup, /class="device-workspace__side/);
});
test("live preparation keeps operational panels mounted across a control handoff", () => {
const state = durableTopologyState();
const markup = renderConnectionPipelines(state, "live");
assert.equal(shouldRenderK1OperationalPanels(state, "live"), true);
assert.match(markup, /class="metrics-grid/);
assert.match(markup, /class="[^"]*\bsession-panel\b/);
assert.match(markup, /class="diagnostics-grid/);
assert.match(markup, /class="device-workspace__side/);
assert.match(markup, /Подключение установлено/);
assert.doesNotMatch(markup, /Переподключиться|Подключить заново/);
});
test("connected, active, replay and recovery SSR retain operational panels", () => {
const connected = runtimeState();
connected.phase = "connected";
connected.source_mode = "idle";
connected.acquisition = null;
const active = runtimeState();
delete active.connection_supervisor;
const replay = runtimeState();
replay.phase = "replay";
replay.source_mode = "replay";
replay.acquisition = null;
delete replay.connection_supervisor;
const recovery = durableTopologyState();
recovery.acquisition = {
acquisition_id: "acquisition-recovery",
device_id: "device-recovery",
device_session_id: "session-recovery",
compatibility_profile_id: PROFILE_ID,
control_mode: "plugin-commanded",
requested_streams: ["spatial.point-cloud.live"],
target_host: "127.0.0.1",
duration_seconds: 0,
evidence_policy: "required",
state: "failed",
state_revision: 8,
cleanup_pending: true,
};
for (const [name, state] of [
["connected", connected],
["active", active],
["replay", replay],
["recovery", recovery],
]) {
assert.equal(
shouldRenderK1OperationalPanels(state),
true,
`${name} must keep operational controls visible`,
);
const markup = renderConnectionPipelines(state);
assert.match(markup, /class="metrics-grid/, name);
assert.match(markup, /class="[^"]*\bsession-panel\b/, name);
assert.match(markup, /class="diagnostics-grid/, name);
assert.match(markup, /class="device-workspace__side/, name);
}
});
test("local connection shell scopes process-only configuring and connected labels", () => {
assert.equal(shellPresentation.localConnectionPhaseLabel("configuring"), "Подключение");
assert.equal(
shellPresentation.localConnectionPhaseLabel("connected"),
"Подключение установлено",
);
assert.equal(
shellPresentation.phaseLabel("configuring"),
"Настройка устройства",
"other workspaces keep the global runtime label",
);
assert.equal(
shellPresentation.phaseLabel("connected"),
"Устройство подключено",
"other workspaces keep the global runtime label",
);
});
test("replay and local-only stop branches use bounded process copy", () => {
const replayState = runtimeState();
replayState.phase = "replay";
replayState.source_mode = "replay";
const replayMarkup = renderToStaticMarkup(createElement(K1AcquisitionPipeline, {
controller: acquisitionController(replayState),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
}));
assert.match(replayMarkup, /Локальный файл записи/);
assert.doesNotMatch(replayMarkup, /Локальный файл исходных данных/);
assertCanonicalConnectionCopy(replayMarkup);
const stopState = runtimeState();
stopState.compatibility.vendor_writes_enabled = false;
stopState.acquisition.control_mode = "operator-manual";
stopState.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["stop-local-receiver"],
actions: {
"stop-local-receiver": {
allowed: true,
reason_codes: [],
target_source: "local-runtime",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
const stopMarkup = renderToStaticMarkup(createElement(K1AcquisitionPipeline, {
controller: acquisitionController(stopState),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
}));
assert.match(stopMarkup, /Состояние сканирования остаётся неизвестным/);
assert.doesNotMatch(stopMarkup, /Физическое состояние сканера/);
assertCanonicalConnectionCopy(stopMarkup);
});
test("software-commanded calibration exposes no teardown until canonical STOP is safe", () => {
const state = runtimeState();
state.snapshot_runtime_id = "runtime-calibration-001";
state.snapshot_revision = 31;
state.phase = "starting_live";
state.source_mode = "live";
state.acquisition.state = "awaiting_external_start";
state.acquisition.state_revision = 3;
state.application_control_session = {
session_generation: 5,
state_revision: 7,
state: "device-initializing",
can_stop: false,
control_socket_open: true,
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["stop-local-receiver"],
actions: {
"stop-acquisition": {
allowed: false,
reason_codes: ["supervisor-action-not-allowed"],
target_source: "connection-supervisor",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
"stop-local-receiver": {
allowed: true,
reason_codes: [],
target_source: "local-runtime",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
const pipelineMarkup = renderToStaticMarkup(createElement(K1AcquisitionPipeline, {
controller: acquisitionController(state),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
}));
const spatialMarkup = renderToStaticMarkup(createElement(K1SpatialControlsView, {
controller: acquisitionController(state),
}));
assert.match(pipelineMarkup, /Кнопка остановки появится только после подтверждённого SCANNING/);
assert.match(spatialMarkup, /K1 калибруется и готовит облако точек/);
for (const markup of [pipelineMarkup, spatialMarkup]) {
assert.equal(buttonMarkupWithText(markup, "Завершить локальный приём").length, 0);
assert.equal(buttonMarkupWithText(markup, "Аварийно завершить локальный приём").length, 0);
assert.equal(buttonMarkupWithText(markup, "Остановить устройство и запись").length, 0);
assert.equal(buttonMarkupWithText(markup, "Отменить запуск до START").length, 0);
}
});
test("physical STOP is fail-closed across both acquisition surfaces", () => {
const state = runtimeState();
state.snapshot_runtime_id = "runtime-stop-001";
state.snapshot_revision = 40;
state.application_control_session = {
session_generation: 5,
state_revision: 8,
state: "scanning",
can_stop: true,
control_socket_open: true,
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["stop-acquisition", "stop-local-receiver"],
actions: {
"stop-acquisition": {
allowed: true,
reason_codes: [],
target_source: "connection-supervisor",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
"stop-local-receiver": {
allowed: true,
reason_codes: [],
target_source: "local-runtime",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
assert.equal(canIssueCanonicalStop(state, false), true);
assert.equal(canIssueCanonicalStop(state, true), false);
const missingRuntimeIdentity = structuredClone(state);
delete missingRuntimeIdentity.snapshot_runtime_id;
assert.equal(physicalStopIntentCheckpoint(missingRuntimeIdentity), null);
assert.equal(canIssueCanonicalStop(missingRuntimeIdentity, false), false);
const zeroGeneration = structuredClone(state);
zeroGeneration.application_control_session.session_generation = 0;
assert.equal(physicalStopIntentCheckpoint(zeroGeneration), null);
const zeroRevision = structuredClone(state);
zeroRevision.application_control_session.state_revision = 0;
assert.equal(physicalStopIntentCheckpoint(zeroRevision), null);
const spentCheckpoint = physicalStopIntentCheckpoint(state);
assert.ok(spentCheckpoint);
const sameCasPoll = structuredClone(state);
sameCasPoll.snapshot_revision += 1;
assert.equal(
authoritativeStateSupersedesPhysicalStopIntent(spentCheckpoint, sameCasPoll),
false,
"a newer polling snapshot with the same control CAS must stay spent",
);
const nextControlTransition = structuredClone(sameCasPoll);
nextControlTransition.application_control_session.state_revision += 1;
assert.equal(
authoritativeStateSupersedesPhysicalStopIntent(
spentCheckpoint,
nextControlTransition,
),
true,
"a newer atomic snapshot plus a newer exact control CAS is fresh authority",
);
const sameTargetReplacement = structuredClone(state);
sameTargetReplacement.snapshot_runtime_id = "runtime-stop-002";
sameTargetReplacement.snapshot_revision = 1;
assert.equal(
authoritativeStateSupersedesPhysicalStopIntent(
spentCheckpoint,
sameTargetReplacement,
),
true,
"a newer accepted runtime with an exact STOP gate is fresh authority",
);
const nonAuthoritativeReplacement = structuredClone(sameTargetReplacement);
nonAuthoritativeReplacement.application_control_session.can_stop = false;
assert.equal(
authoritativeStateSupersedesPhysicalStopIntent(
spentCheckpoint,
nonAuthoritativeReplacement,
),
false,
"runtime replacement without an exact current STOP gate stays spent",
);
const distinctAcquisition = structuredClone(sameCasPoll);
distinctAcquisition.acquisition.acquisition_id = "acquisition-002";
assert.equal(
authoritativeStateSupersedesPhysicalStopIntent(
spentCheckpoint,
distinctAcquisition,
),
true,
"a newer accepted snapshot may admit a distinct acquisition target",
);
state.application_control_session.state = "failed";
assert.equal(canIssueCanonicalStop(state, false), false);
state.application_control_session.state = "scanning";
state.application_control_session.can_stop = false;
assert.equal(canIssueCanonicalStop(state, false), false);
state.application_control_session.can_stop = true;
state.connection_policy.actions["stop-acquisition"].allowed = false;
state.connection_policy.actions["stop-acquisition"].reason_codes = [
"physical-control-authority-unavailable",
];
state.connection_policy.allowed_actions = ["stop-local-receiver"];
assert.equal(canIssueCanonicalStop(state, false), false);
state.connection_policy.actions["stop-acquisition"].allowed = true;
state.connection_policy.actions["stop-acquisition"].reason_codes = [];
state.connection_policy.allowed_actions = [
"stop-acquisition",
"stop-local-receiver",
];
const physicalMarkup = renderToStaticMarkup(createElement(K1AcquisitionPipeline, {
controller: acquisitionController(state),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
}));
const physicalButtons = buttonMarkupWithText(
physicalMarkup,
"Остановить устройство и запись",
);
assert.equal(physicalButtons.length, 1);
assert.doesNotMatch(physicalButtons[0], /\bdisabled(?:=|\s|>)/);
assert.doesNotMatch(physicalMarkup, /Завершить локальный приём/);
const unrelatedErrorMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: {
...acquisitionController(state),
error: "unrelated local viewer error",
},
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.equal(
buttonMarkupWithText(
unrelatedErrorMarkup,
"Остановить устройство и запись",
).length,
1,
"a presentation error that did not spend physical STOP must not hide it",
);
const dismissedFailureMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: {
...acquisitionController(state),
// Closing a presentation banner clears `error`; the independent spent
// checkpoint must continue to suppress the same physical mutation.
error: null,
physicalStopIntentSpent: true,
},
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.doesNotMatch(dismissedFailureMarkup, /Остановить устройство и запись/);
const localButtons = buttonMarkupWithText(
dismissedFailureMarkup,
"Завершить локальный приём",
);
assert.equal(localButtons.length, 0);
assert.match(
dismissedFailureMarkup,
/Повторная команда и локальное завершение заблокированы/,
);
assertCanonicalConnectionCopy(dismissedFailureMarkup);
const classifiedStopState = structuredClone(state);
classifiedStopState.acquisition.state = "awaiting_external_stop";
classifiedStopState.connection_policy.actions["stop-acquisition"].allowed = false;
classifiedStopState.connection_policy.allowed_actions = ["stop-local-receiver"];
const classifiedStopMarkup = renderToStaticMarkup(createElement(
K1SpatialControlsView,
{
controller: {
...acquisitionController(classifiedStopState),
error: "STOP не был отправлен; требуется read-only восстановление",
physicalStopIntentSpent: true,
},
},
));
assert.equal(
buttonMarkupWithText(classifiedStopMarkup, "Завершить локальный приём").length,
0,
"a classified STOP must not leave a permanently disabled local action in the scene",
);
const localCleanupPendingMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: {
...acquisitionController(state),
pendingAction: "stop",
error: null,
physicalStopIntentSpent: true,
},
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.doesNotMatch(localCleanupPendingMarkup, /Завершение локального приёма…/);
assert.match(
localCleanupPendingMarkup,
/Повторная команда и локальное завершение заблокированы/,
);
assert.doesNotMatch(localCleanupPendingMarkup, /Остановка устройства…/);
const physicalStopPendingMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: {
...acquisitionController(state),
pendingAction: "stop",
physicalStopIntentSpent: true,
physicalStopInFlight: true,
},
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.match(physicalStopPendingMarkup, /Остановка устройства…/);
assert.doesNotMatch(physicalStopPendingMarkup, /Завершение локального приёма…/);
const terminalDeniedState = structuredClone(state);
terminalDeniedState.phase = "error";
terminalDeniedState.source_mode = "idle";
terminalDeniedState.acquisition.state = "failed";
terminalDeniedState.acquisition.cleanup_pending = true;
terminalDeniedState.connection_policy.actions["stop-acquisition"].allowed = false;
terminalDeniedState.connection_policy.actions["stop-acquisition"].reason_codes = [
"physical-control-authority-unavailable",
];
terminalDeniedState.connection_policy.allowed_actions = ["stop-local-receiver"];
const terminalDeniedMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: acquisitionController(terminalDeniedState),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.match(terminalDeniedMarkup, /ВОССТАНОВЛЕНИЕ · ЛОКАЛЬНЫЙ КОНТУР/);
assert.match(terminalDeniedMarkup, /Доступно локальное завершение приёма/);
assert.doesNotMatch(terminalDeniedMarkup, /Локальная запись завершена/);
assert.doesNotMatch(
terminalDeniedMarkup,
/явный STOP|Остановить сканирование|Сканирование продолжается|Требуется остановка/,
);
const terminalSpentState = structuredClone(terminalDeniedState);
terminalSpentState.connection_policy.actions["stop-acquisition"].allowed = true;
terminalSpentState.connection_policy.actions["stop-acquisition"].reason_codes = [];
terminalSpentState.connection_policy.allowed_actions = [
"stop-acquisition",
"stop-local-receiver",
];
const terminalReadyMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: acquisitionController(terminalSpentState),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.match(terminalReadyMarkup, /Локальный приём ещё требует завершения/);
assert.doesNotMatch(terminalReadyMarkup, /Локальная запись (?:уже )?завершена/);
const terminalSpentMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: {
...acquisitionController(terminalSpentState),
error: null,
physicalStopIntentSpent: true,
},
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.match(terminalSpentMarkup, /ВОССТАНОВЛЕНИЕ · ЛОКАЛЬНЫЙ КОНТУР/);
assert.match(terminalSpentMarkup, /Повторная команда K1 не отправляется/);
assert.doesNotMatch(
terminalSpentMarkup,
/явный STOP|Остановить сканирование|Сканирование продолжается|Требуется остановка/,
);
const terminalInFlightMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: {
...acquisitionController(terminalSpentState),
pendingAction: "stop",
physicalStopIntentSpent: true,
physicalStopInFlight: true,
},
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.match(terminalInFlightMarkup, /ВОССТАНОВЛЕНИЕ · КОМАНДА ОТПРАВЛЕНА/);
assert.match(terminalInFlightMarkup, /Команда остановки устройства уже отправлена/);
assert.match(terminalInFlightMarkup, /Остановка устройства…/);
assert.doesNotMatch(
terminalInFlightMarkup,
/требуется явный STOP|Нажмите «Остановить сканирование»/,
);
const noStopActionState = structuredClone(state);
noStopActionState.connection_policy.actions["stop-acquisition"].allowed = false;
noStopActionState.connection_policy.actions["stop-acquisition"].reason_codes = [
"physical-control-authority-unavailable",
];
noStopActionState.connection_policy.actions["stop-local-receiver"].allowed = false;
noStopActionState.connection_policy.actions["stop-local-receiver"].reason_codes = [
"local-acquisition-receiver-not-active",
];
noStopActionState.connection_policy.allowed_actions = [];
noStopActionState.connection_policy.recommended_action = "wait-for-operation";
noStopActionState.phase = "error";
noStopActionState.source_mode = "idle";
noStopActionState.acquisition.state = "failed";
noStopActionState.acquisition.cleanup_pending = true;
const noStopActionMarkup = renderToStaticMarkup(createElement(
K1AcquisitionPipeline,
{
controller: acquisitionController(noStopActionState),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
},
));
assert.equal(
buttonMarkupWithText(noStopActionMarkup, "Завершить локальный приём").length,
0,
);
assert.equal(
buttonMarkupWithText(noStopActionMarkup, "Остановить устройство и запись").length,
0,
);
assert.match(
noStopActionMarkup,
/ВОССТАНОВЛЕНИЕ · ТОЛЬКО ЧТЕНИЕ/,
);
assert.match(noStopActionMarkup, /Доступно только read-only восстановление/);
assert.doesNotMatch(
noStopActionMarkup,
/Доступно локальное завершение|Завершите локальный приём|явный STOP|Остановить сканирование/,
);
});
test("recovered physical SCANNING overrides replay with one explicit K1 STOP", () => {
const state = runtimeState();
state.snapshot_runtime_id = "runtime-recovered-stop";
state.snapshot_revision = 12;
state.phase = "replay";
state.source_mode = "replay";
state.acquisition = {
...state.acquisition,
state: "failed",
state_revision: 9,
cleanup_pending: false,
};
state.application_control_session = {
session_generation: 4,
state_revision: 11,
state: "scanning",
can_stop: true,
control_socket_open: true,
physical_command: {
requires_reconciliation: false,
resolved_active_recovery_required: true,
observed_session_state: "scanning",
},
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["stop-acquisition"],
actions: {
"stop-acquisition": {
allowed: true,
reason_codes: [],
target_source: "connection-supervisor",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
const markup = renderToStaticMarkup(createElement(K1AcquisitionPipeline, {
controller: acquisitionController(state),
desiredConnectionMode: "bridge",
openSpatialScene() {},
activateAutomaticSpatialSource() {},
}));
assert.match(markup, /ВОССТАНОВЛЕНИЕ · ОСТАНОВКА/);
assert.match(markup, /Сканирование продолжается/);
assert.match(markup, /Требуется остановка/);
assert.match(markup, /Сканирование подтверждено; требуется явный STOP/);
assert.doesNotMatch(markup, /Назовите проект и запустите приём/);
assert.doesNotMatch(markup, /Путь к записи|Запустить повтор записи/);
assert.doesNotMatch(markup, /Подготовить проект|Запустить сканирование/);
const stopButtons = buttonMarkupWithText(markup, "Остановить сканирование");
assert.equal(stopButtons.length, 1);
assert.doesNotMatch(stopButtons[0], /\bdisabled(?:=|\s|>)/);
assertCanonicalConnectionCopy(markup);
});
test("authoritative Bridge renders all completed steps with canonical process copy", () => {
const state = runtimeState();
state.phase = "connected";
state.source_mode = "idle";
state.acquisition = null;
state.devices = [];
state.message = "Готово. Включите устройство и начните с поиска по Bluetooth.";
state.connection_supervisor = supervisor({ control: true, data: false });
state.connection_lifecycle = connectionLifecycle({ control: true });
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["start-acquisition"],
actions: {
"scan-ble": {
allowed: false,
reason_codes: ["acquisition-active"],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
recommended_action: "start-acquisition",
};
const markup = renderToStaticMarkup(createElement(K1ProvisioningPipeline, {
controller: provisioningController(state),
desiredMode: "bridge",
}));
assert.doesNotMatch(markup, /Питание|aria-checked=/);
assert.match(markup, /<span>01<\/span>/);
assert.match(markup, /<span>02<\/span>/);
assert.match(markup, /<h3>Подключение<\/h3>/);
assert.match(markup, /<h3>Сеть<\/h3>/);
assert.match(markup, /Подключение установлено/);
assert.match(markup, /<strong>ble-k1-001<\/strong>/);
assert.match(markup, /<strong>Общая сеть · Bridge<\/strong>/);
assert.match(markup, /<small>192\.168\.68\.52<\/small>/);
assert.equal(buttonMarkupWithText(markup, "Выбрать другое").length, 0);
assert.equal(buttonMarkupWithText(markup, "Изменить сеть").length, 0);
assert.doesNotMatch(markup, /class="nodedc-activity-indicator"/);
assert.doesNotMatch(
markup,
/Найти устройство Bluetooth|Повторить поиск Bluetooth|Устройства пока не найдены/,
);
assertCanonicalConnectionCopy(markup);
});
test("connected Bridge action slots survive transient lifecycle contention A to B to A", () => {
const actionDecision = (reasonCodes) => ({
allowed: reasonCodes.length === 0,
reason_codes: reasonCodes,
target_source: "local-prestart-handoff",
required_transport_ref: "ble-k1-001",
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
device_write_performed: false,
automatic_retry: false,
});
const connectedState = (snapshotRevision, reasonCodes = []) => {
const state = runtimeState();
state.snapshot_runtime_id = "runtime-connected-actions";
state.snapshot_runtime_started_at_utc = "2026-08-11T06:00:00Z";
state.snapshot_revision = snapshotRevision;
state.phase = "connected";
state.source_mode = "idle";
state.snapshot_runtime_id = "runtime-ready-pending";
state.acquisition = null;
state.devices = [];
state.connection_supervisor = supervisor({ control: true, data: false });
state.connection_lifecycle = connectionLifecycle({ control: true });
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: reasonCodes.length === 0
? ["prepare-select-device", "prepare-change-network"]
: [],
actions: {
"prepare-select-device": actionDecision(reasonCodes),
"prepare-change-network": actionDecision(reasonCodes),
},
};
return state;
};
const frames = [
connectedState(40),
connectedState(41, [
"connection-reconfiguration-lifecycle-busy",
"k1-lifecycle-process-lease-network-owned",
]),
connectedState(42),
];
for (const reason of [
"connection-reconfiguration-lifecycle-busy",
"k1-lifecycle-process-lease-network-owned",
]) {
const singlyContended = connectedState(39, [reason]);
assert.equal(
connectedReconfigurationActionApplicable(
singlyContended,
"prepare-select-device",
),
true,
);
assert.equal(
connectedReconfigurationActionApplicable(
singlyContended,
"prepare-change-network",
),
true,
);
}
for (const [index, state] of frames.entries()) {
assert.equal(
connectedReconfigurationActionApplicable(state, "prepare-select-device"),
true,
);
assert.equal(
connectedReconfigurationActionApplicable(state, "prepare-change-network"),
true,
);
const markup = renderToStaticMarkup(createElement(K1ProvisioningPipeline, {
controller: provisioningController(state),
desiredMode: "bridge",
}));
assert.match(markup, /Подключение установлено/);
const selectAction = buttonMarkupWithText(markup, "Выбрать другое");
const networkAction = buttonMarkupWithText(markup, "Изменить сеть");
assert.equal(selectAction.length, 1, `frame ${index} keeps select action slot`);
assert.equal(networkAction.length, 1, `frame ${index} keeps network action slot`);
if (index === 1) {
assert.match(selectAction[0], /\bdisabled(?:=|\s|>)/);
assert.match(networkAction[0], /\bdisabled(?:=|\s|>)/);
} else {
assert.doesNotMatch(selectAction[0], /\bdisabled(?:=|\s|>)/);
assert.doesNotMatch(networkAction[0], /\bdisabled(?:=|\s|>)/);
}
}
const durableBlocker = connectedState(43, ["acquisition-active"]);
assert.equal(
connectedReconfigurationActionApplicable(
durableBlocker,
"prepare-select-device",
),
false,
);
assert.equal(
connectedReconfigurationActionApplicable(
durableBlocker,
"prepare-change-network",
),
false,
);
const durableMarkup = renderToStaticMarkup(createElement(K1ProvisioningPipeline, {
controller: provisioningController(durableBlocker),
desiredMode: "bridge",
}));
assert.equal(buttonMarkupWithText(durableMarkup, "Выбрать другое").length, 0);
assert.equal(buttonMarkupWithText(durableMarkup, "Изменить сеть").length, 0);
});
for (const pendingAction of ["connect", "verify"]) {
test(`authoritative Ready with pending ${pendingAction} keeps one canonical progress surface`, () => {
const state = runtimeState();
state.phase = "connected";
state.source_mode = "idle";
state.snapshot_runtime_id = "runtime-ready-pending";
state.acquisition = null;
state.devices = [];
state.connection_supervisor = supervisor({ control: true, data: false });
state.connection_lifecycle = connectionLifecycle({ control: true });
const markup = renderProvisioningWithCurrentPendingAction({
controller: {
...provisioningController(state),
pendingAction,
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: () => true,
},
desiredMode: "bridge",
}, { publicSearch: false });
assert.equal(
(markup.match(/class="nodedc-activity-indicator"/g) ?? []).length,
1,
);
assert.match(markup, /<strong>ble-k1-001<\/strong>/);
if (pendingAction === "connect") {
assert.match(markup, /<h3>Сеть<\/h3>/);
assert.match(markup, /Настройка сети…/);
} else {
assert.match(markup, /<h3>Сеть<\/h3>/);
assert.match(markup, /Проверка подключения без изменения сети…/);
assert.match(markup, /<span>02<\/span>/);
}
assertCanonicalConnectionCopy(markup);
});
}
test("explicit read-only recovery keeps its network-unavailable classification", () => {
const base = {
connection_verification: {
status: "endpoint-unreachable",
lease_state: "configured-unverified",
network_reachability: "unreachable",
},
};
assert.equal(readOnlyObservationShowsNetworkUnavailable(base), true);
assert.equal(readOnlyObservationShowsNetworkUnavailable({
connection_verification: {
...base.connection_verification,
status: "tcp-reachable-device-info-unverified",
network_reachability: "reachable",
},
}), false);
assert.equal(readOnlyObservationShowsNetworkUnavailable(null), false);
assert.equal(readOnlyObservationShowsNetworkUnavailable({
connection_verification: {
status: "device-network-applied",
lease_state: "configured-unverified",
network_reachability: "unknown",
reason_code: "endpoint-target-unconfigured",
},
}), true);
for (const reasonCode of [
"connection-verify-address-unavailable",
"connection-verify-connection-missing",
"connection-verify-route-mismatch",
"connection-verify-mqtt-unreachable",
"configured-endpoint-unavailable",
"endpoint-target-unconfigured",
]) {
assert.equal(readOnlyFailureShowsNetworkUnavailable(reasonCode), true);
}
for (const reasonCode of [
"connection-verify-device-not-rediscovered",
"connection-verify-status-read-invalid",
"device-identity-pin-mismatch",
"connection-verify-discovery-generation-conflict",
"connection-verify-lease-changed",
"connection-reconfiguration-revision-conflict",
"connection-verify-busy",
null,
]) {
assert.equal(readOnlyFailureShowsNetworkUnavailable(reasonCode), false);
}
});
test("a BLE-proven missing Bridge address requires network setup across later retries", () => {
const state = {
connection_verification: {
status: "unreachable",
reason_code: "connection-verify-address-unavailable",
},
last_operation: {
action: "connection.verify",
status: "failed",
error: { code: "connection-verify-device-not-rediscovered" },
},
};
assert.equal(savedBridgeRequiresNetworkSetup(state), true);
assert.equal(savedBridgeRequiresNetworkSetup({
last_operation: {
action: "connection.verify",
status: "failed",
error: { code: "connection-verify-address-unavailable" },
},
}), true);
assert.equal(savedBridgeRequiresNetworkSetup({
connection_verification: {
status: "unreachable",
reason_code: "connection-verify-device-not-rediscovered",
},
}), false);
});
test("pre-write candidate loss is classified stale without granting UI continuation", () => {
for (const reasonCode of [
"BleakDeviceNotFoundError",
"network-provision-candidate-not-fresh",
"network-provision-candidate-changed",
"network-provision-discovery-generation-conflict",
]) {
assert.equal(provisioningFailureRequiresFreshCandidate(reasonCode), true);
}
for (const reasonCode of [
"BleakGATTProtocolError",
"network-provision-target-not-distinguishable-from-baseline",
"network-provision-lifecycle-busy",
"host-wifi-operation-timeout",
null,
]) {
assert.equal(provisioningFailureRequiresFreshCandidate(reasonCode), false);
}
});
test("stale old-device reachability cannot own a fresh selection outcome", () => {
const staleOldDeviceProjection = {
connection_verification: {
status: "endpoint-unreachable",
lease_state: "configured-unverified",
network_reachability: "unreachable",
transport_ref: "ble-k1-old",
},
};
// The global projection is deliberately stale and unavailable, but the
// correlated fresh-device operation failed identity validation. The normal
// one-intent UI renders this only as a stale/safety outcome; it never scans,
// verifies or submits automatically.
assert.equal(
readOnlyObservationShowsNetworkUnavailable(staleOldDeviceProjection),
true,
);
assert.equal(
readOnlyFailureShowsNetworkUnavailable("connection-verify-status-read-invalid"),
false,
);
assert.equal(
readOnlyFailureShowsNetworkUnavailable("device-identity-pin-mismatch"),
false,
);
assert.equal(
readOnlyFailureShowsNetworkUnavailable("connection-reconfiguration-revision-conflict"),
false,
);
assert.equal(
readOnlyFailureShowsNetworkUnavailable("BleakGATTProtocolError"),
false,
);
});
test("Quick Connect does not expose Bridge reconfiguration actions", () => {
const state = runtimeState();
state.phase = "connected";
state.source_mode = "idle";
state.acquisition = null;
state.connection_mode = "quick-connect";
state.configured_connection_mode = "quick-connect";
state.active_connection_mode = "quick-connect";
state.desired_connection_mode = "quick-connect";
state.connection_supervisor = supervisor({ control: true, data: false });
state.connection_supervisor.intent.requested_mode = "quick-connect";
state.connection_supervisor.observed.device_network.connection_mode = "quick-connect";
state.connection_supervisor.observed.device_identity.connection_mode = "quick-connect";
state.connection_supervisor.lease.connection_mode = "quick-connect";
state.connection_lifecycle = connectionLifecycle({ mode: "quick-connect" });
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: [],
actions: {},
};
const markup = renderProvisioning({
controller: provisioningController(state),
desiredMode: "quick-connect",
});
assert.doesNotMatch(markup, /Выбрать другое устройство|Изменить сеть/);
});
test("a verify without current click authority does not invent network step 02", () => {
const state = durableTopologyState();
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
state.connection_supervisor = supervisor({ control: false, data: false });
state.connection_lifecycle = connectionLifecycle({ control: false });
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: [],
actions: {},
};
const markup = renderProvisioning({
controller: {
...provisioningController(state),
pendingAction: "verify",
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: () => false,
},
desiredMode: "bridge",
});
assert.match(markup, /<span>01<\/span>/);
assert.doesNotMatch(markup, /<span>02<\/span>|<span>03<\/span>/);
assert.doesNotMatch(markup, /aria-busy="true"/);
assert.equal((markup.match(/class="nodedc-activity-indicator"/g) ?? []).length, 0);
assertCanonicalConnectionCopy(markup);
});
test("a blocked local-only device escape explains backend safety reasons", () => {
const state = durableTopologyState();
state.physical_command = {
operator_retirement: {
allowed: false,
reason_codes: ["physical-command-retirement-operation-conflict"],
expected_operation_id: "old-stop-operation",
expected_revision: 280,
expected_transport_ref: "ble-k1-001",
physical_outcome: "unknown",
device_io_performed: false,
automatic_retry: false,
},
};
assert.match(
physicalRetirementGuidance(state),
/завершается другая операция с физическим состоянием устройства/,
);
for (const [reasonCode, expectedCopy] of [
["physical-command-retirement-state-unsafe", /Состояние предыдущей физической команды изменилось/],
["physical-command-retirement-not-required", /больше не удерживает выбор устройства/],
["physical-command-target-retired", /уже выведено из текущего контура/],
["acquisition-active", /Сканирование ещё активно/],
["control-session-state-unsafe", /Управляющая сессия устройства ещё не завершена/],
["ble-runtime-busy", /Bluetooth занят другой операцией устройства/],
["ble-runtime-cleanup-pending", /Bluetooth ещё завершает предыдущую операцию/],
]) {
state.physical_command.operator_retirement.reason_codes = [reasonCode];
assert.match(physicalRetirementGuidance(state), expectedCopy);
}
});
test("a blocked exact retired-device check explains safe next actions", () => {
const state = durableTopologyState();
state.physical_command = {
operator_reconciliation_reopen: {
allowed: false,
reason_codes: ["physical-command-reconciliation-reopen-target-not-observed"],
expected_revision: 281,
expected_retirement_id: "retirement-old-stop",
expected_transport_ref: "ble-k1-001",
expected_discovery_generation: 13,
expected_desired_mode: "bridge",
expected_desired_mode_revision: 0,
device_io_performed: false,
automatic_retry: false,
},
};
assert.match(physicalReopenGuidance(state), /не найдено в последнем Bluetooth-поиске/);
state.physical_command.operator_reconciliation_reopen.reason_codes = [
"physical-command-reconciliation-reopen-target-not-connectable",
];
assert.match(physicalReopenGuidance(state), /не принимает Bluetooth-подключение/);
state.physical_command.operator_reconciliation_reopen.reason_codes = [
"physical-command-reconciliation-reopen-candidate-ambiguous",
];
assert.match(physicalReopenGuidance(state), /не подтвердил один точный экземпляр/);
state.physical_command.operator_reconciliation_reopen.reason_codes = [
"device-calibration-read-active",
];
assert.match(physicalReopenGuidance(state), /читается калибровка/);
});
test("fresh Scan keeps retired audit rows selectable without recovery I/O", () => {
const state = durableTopologyState();
state.current_device_recovery = {
transport_ref: "ble-k1-001",
connection_mode: "bridge",
handle_retained: false,
advertised_now: false,
};
state.physical_command = {
status: "resolved",
reason_code: null,
requires_reconciliation: false,
automatic_replay_allowed: false,
normal_session_recovery_supported: false,
runtime_bound: false,
reconciliation_ready: false,
record: {
revision: 281,
operation_id: "old-stop-operation",
action: "stop",
stage: "resolved",
resolution: "operator-retired-outcome-unknown",
connection: { transport_ref: "ble-k1-001" },
operator_retirements: [{ retired_transport_ref: "ble-k1-001" }],
},
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: {
retained_context_is_presence: false,
retired_transport_refs: ["ble-k1-001"],
},
allowed_actions: ["scan-ble", "provision-fresh-device"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
state.connection_attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: "historical-network-attempt-before-retirement",
connection_mode: "bridge",
status: "failed",
phase: "network_applied",
control_state: "unknown",
stage: "host-route-and-control-endpoint",
public_error_code: "control-bootstrap-failed",
side_effect_status: "network-applied",
safe_next_action: "scan-select-connect",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: OBSERVED_AT,
timeline: [],
};
state.devices = [
{
device_id: "ble-k1-001",
name: "Retired old device",
rssi: -39,
connectable: true,
likely_k1: true,
},
{
device_id: "ble-k1-new",
name: "Replacement device",
rssi: -52,
connectable: true,
likely_k1: true,
},
];
assert.equal(trustedConnectionBinding(state), null);
assert.equal(
connectionAttemptOwnsAppliedNetworkRecovery(state.connection_attempt),
false,
);
const markup = renderProvisioningAfterSearch({
controller: provisioningController(state),
desiredMode: "bridge",
});
assert.match(markup, /Результатов: 2/);
assert.match(markup, /Повторить поиск Bluetooth/);
assert.doesNotMatch(markup, /old-stop-operation/);
const priorAction = deviceRowActionButton(markup, "ble-k1-001");
assert.match(priorAction, />Выбрать<\/button>/);
assert.doesNotMatch(priorAction, /\bdisabled(?:=|\s|>)/);
const replacementAction = deviceRowActionButton(markup, "ble-k1-new");
assert.match(replacementAction, />Выбрать<\/button>/);
assert.doesNotMatch(replacementAction, /\bdisabled(?:=|\s|>)/);
assert.equal(
buttonMarkupWithText(markup, "Подключить новый K1").length,
0,
);
assert.doesNotMatch(markup, /<button[^>]*disabled[^>]*>Недоступно<\/button>/);
assert.doesNotMatch(
markup,
/Попытка настройки завершена|Проверить подключение без изменения сети|Управление не подтверждено/,
);
assert.doesNotMatch(markup, /Название сети Wi‑Fi|Пароль Wi‑Fi|>Применить</);
assertCanonicalConnectionCopy(markup);
const onlyPrior = structuredClone(state);
onlyPrior.devices = [state.devices[0]];
const onlyPriorMarkup = renderProvisioningAfterSearch({
controller: provisioningController(onlyPrior),
desiredMode: "bridge",
});
assert.equal(
buttonMarkupWithText(onlyPriorMarkup, "Подключить новый K1").length,
0,
);
assert.doesNotMatch(
onlyPriorMarkup,
/Подходящих K1 не найдено\. Повторите поиск\./,
);
const onlyPriorAction = deviceRowActionButton(onlyPriorMarkup, "ble-k1-001");
assert.match(onlyPriorAction, />Выбрать<\/button>/);
assert.doesNotMatch(onlyPriorAction, /\bdisabled(?:=|\s|>)/);
assert.match(onlyPriorMarkup, /Результатов: 1/);
assert.doesNotMatch(onlyPriorMarkup, />Недоступно|Переподключиться/);
// Historical audit data is not an active deny once the authoritative policy
// projection removes the reference. The same advertised row then behaves as
// an ordinary fresh result, without a saved/reopen branch in the UI.
state.connection_policy.facts.retired_transport_refs = [];
state.connection_lifecycle = connectionLifecycle({ control: false });
state.connection_supervisor = supervisor({ control: false, data: false });
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
state.current_device_recovery = null;
const historicalAuditMarkup = renderProvisioningAfterSearch({
controller: provisioningController(state),
desiredMode: "bridge",
});
const historicallyRetiredAction = deviceRowActionButton(
historicalAuditMarkup,
"ble-k1-001",
);
assert.match(historicallyRetiredAction, />Выбрать<\/button>/);
assert.doesNotMatch(
historicallyRetiredAction,
/\bdisabled(?:=|\s|>)/,
);
assertCanonicalConnectionCopy(historicalAuditMarkup);
});
test("only an active network operation owns an applied-attempt screen", () => {
const attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: "attempt-network-recovery-ownership",
connection_mode: "bridge",
status: "failed",
phase: "network_applied",
control_state: "control_not_ready",
stage: "host-route-and-control-endpoint",
public_error_code: "control-bootstrap-failed",
side_effect_status: "network-applied",
safe_next_action: "verify-control-read-only",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: OBSERVED_AT,
timeline: [],
};
for (const safeNextAction of [
"continue-with-control-verification",
"verify-control-read-only",
"manual-recovery-required",
]) {
assert.equal(
connectionAttemptOwnsAppliedNetworkRecovery({
...attempt,
safe_next_action: safeNextAction,
}),
false,
safeNextAction,
);
}
for (const safeNextAction of [
"scan-select-connect",
"stop-local-receiver",
"retire-unavailable-physical-target",
"start-acquisition",
]) {
assert.equal(
connectionAttemptOwnsAppliedNetworkRecovery({
...attempt,
safe_next_action: safeNextAction,
}),
false,
safeNextAction,
);
}
assert.equal(
connectionAttemptOwnsAppliedNetworkRecovery({
...attempt,
status: "running",
safe_next_action: "wait-for-current-attempt",
}),
true,
);
assert.equal(
connectionAttemptOwnsAppliedNetworkRecovery({
...attempt,
control_state: "ready",
}),
false,
);
});
test("an exact prior CoreBluetooth UUID remains a normal fresh selection across casing", () => {
const state = retiredPhysicalReopenReadyState({
advertisedRef: "f89438fa-55ed-85ad-eed7-734ac84746d8",
backendRef: "F89438FA-55ED-85AD-EED7-734AC84746D8",
});
assert.equal(
transportRefEquivalenceKey(" F89438FA-55ED-85AD-EED7-734AC84746D8 "),
"f89438fa-55ed-85ad-eed7-734ac84746d8",
);
assert.equal(trustedConnectionBinding(state), null);
const markup = renderProvisioningAfterSearch({
controller: provisioningController(state),
desiredMode: "bridge",
});
const priorDeviceAction = deviceRowActionButton(
markup,
"f89438fa-55ed-85ad-eed7-734ac84746d8",
);
assert.match(priorDeviceAction, />Выбрать<\/button>/);
assert.doesNotMatch(priorDeviceAction, /\bdisabled(?:=|\s|>)/);
assert.equal(buttonMarkupWithText(markup, "Переподключиться").length, 0);
assertCanonicalConnectionCopy(markup);
});
test("an exact fresh prior row exposes one enabled Select without reconnect", () => {
const state = retiredPhysicalReopenReadyState();
assert.ok(retiredPhysicalReopenAuthority(
state,
state.devices[0].device_id,
"bridge",
));
const markup = renderProvisioningAfterSearch({
controller: provisioningController(state),
desiredMode: "bridge",
});
const selectActions = buttonMarkupWithText(markup, "Выбрать");
assert.equal(selectActions.length, 1);
assert.doesNotMatch(selectActions[0], /\bdisabled(?:=|\s|>)/);
assert.equal(buttonMarkupWithText(markup, "Переподключиться").length, 0);
assert.doesNotMatch(markup, /Вернуть прежний K1 и проверить/);
assert.doesNotMatch(markup, /Название общей сети Wi‑Fi|Пароль Wi‑Fi|>Применить</);
});
test("post-reset Scan selects the exact prior UUID locally and opens network fields", async () => {
const initialState = retiredPhysicalReopenReadyState();
initialState.devices.push({
device_id: "A1619D95-C352-1069-D430-5FB0BC13F7F9",
name: "dcCONSTRUCTIONS",
rssi: -55,
connectable: true,
likely_k1: false,
});
initialState.connection_scenario_reset = {
reset_id: "reset-before-retired-reconnect",
request_revision: 6,
revision: 7,
desired_mode: "bridge",
active: false,
settled_by_discovery_generation: initialState.ble_discovery_generation,
local_session_closed: true,
previous_device_may_continue_scanning: false,
physical_disposition: "retired",
network_disposition: null,
device_command_performed: false,
network_write_performed: false,
automatic_scan: false,
operation_sequence: 21,
};
let currentState = initialState;
let scanCalls = 0;
let reopenCalls = 0;
let verifyCalls = 0;
let connectCalls = 0;
let resetCalls = 0;
let prepareCalls = 0;
let markScanDispatched;
const scanDispatched = new Promise((resolve) => {
markScanDispatched = resolve;
});
const controller = {
...provisioningController(initialState),
scanWithResult: async () => {
scanCalls += 1;
markScanDispatched();
return {
succeeded: true,
snapshotRuntimeId: currentState.snapshot_runtime_id,
discoveryGeneration: currentState.ble_discovery_generation,
transportRefs: currentState.devices.map((device) => device.device_id),
};
},
reopenRetiredPhysicalReconciliation: async () => {
reopenCalls += 1;
return { succeeded: false, observedState: currentState };
},
verifyConnection: async () => {
verifyCalls += 1;
return {
succeeded: false,
reconciliationCompleted: false,
observedState: currentState,
};
},
connect: async () => {
connectCalls += 1;
return {
succeeded: false,
networkIntentCompleted: false,
intentDisposition: "retain",
acceptedSessionKey: null,
};
},
selectConnectionMode: async () => {
resetCalls += 1;
return true;
},
prepareConnectionReconfigurationWithResult: async () => {
prepareCalls += 1;
return { succeeded: false, observedState: currentState };
},
getCurrentState: () => currentState,
getConnectionRecoveryObservationTarget: () =>
recommendedConnectionRecoveryObservationTarget(currentState),
getConnectionActionAuthority: (mode) =>
connectionActionAuthoritySnapshot(currentState, mode),
isSnapshotRuntimeCurrent: (runtimeId) =>
runtimeId === currentState.snapshot_runtime_id,
isConnectionActionAuthorityCurrent: (authority) =>
connectionActionAuthorityMatches(
authority,
connectionActionAuthoritySnapshot(
currentState,
authority.connectionMode,
),
),
isConnectionPolicyActionAllowedCurrent: (action) =>
currentState.connection_policy.allowed_actions.includes(action),
};
const props = () => ({
controller: { ...controller, state: currentState },
desiredMode: "bridge",
});
const harness = createStatefulProvisioningHarness(props());
try {
let tree = harness.render(props());
harness.flushEffects();
tree = harness.render(props());
harness.flushEffects();
const scan = actionByLabel(tree, "Найти по Bluetooth");
assert.ok(scan);
scan.props.onClick();
await Promise.race([
scanDispatched,
new Promise((_, reject) => setTimeout(
() => reject(new Error("post-reset Scan did not dispatch")),
100,
)),
]);
await new Promise((resolve) => setTimeout(resolve, 0));
tree = harness.render(props());
harness.flushEffects();
const priorRow = elementByProp(tree, "actionLabel", "Выбрать");
assert.ok(priorRow);
assert.equal(priorRow.props.device.device_id, initialState.devices[0].device_id);
assert.equal(priorRow.props.selectionDisabled, false);
assert.equal(actionByLabel(tree, "Переподключиться"), null);
priorRow.props.onSelect();
tree = harness.render(props());
harness.flushEffects();
tree = harness.render(props());
const selectedMarkup = renderToStaticMarkup(tree);
assert.equal(scanCalls, 1);
assert.equal(reopenCalls, 0);
assert.equal(verifyCalls, 0);
assert.equal(connectCalls, 0);
assert.equal(resetCalls, 0);
assert.equal(prepareCalls, 0);
assert.match(selectedMarkup, /<span>02<\/span>/);
assert.match(selectedMarkup, /Название общей сети Wi‑Fi/);
assert.match(selectedMarkup, /Пароль WiFi/);
assert.doesNotMatch(selectedMarkup, /Переподключиться/);
assert.equal(
harness.stateValue(emptyProvisioningAttemptPresentation),
null,
"local selection must not manufacture a backend Apply attempt",
);
const passwordField = elementByProp(tree, "label", "Пароль WiFi");
assert.ok(passwordField);
assert.equal(passwordField.props.type, "password");
passwordField.props.onChange({ target: { value: "test-only-password" } });
tree = harness.render(props());
harness.flushEffects();
const showPassword = elementByProp(tree, "label", "Показать пароль");
assert.ok(showPassword);
assert.equal(showPassword.props.disabled, false);
showPassword.props.onClick();
tree = harness.render(props());
harness.flushEffects();
assert.equal(
elementByProp(tree, "label", "Пароль WiFi").props.type,
"text",
);
assert.ok(elementByProp(tree, "label", "Скрыть пароль"));
const chooseAnother = actionByLabel(tree, "Выбрать другое");
assert.ok(chooseAnother);
chooseAnother.props.onClick();
tree = harness.render(props());
harness.flushEffects();
tree = harness.render(props());
const returnedMarkup = renderToStaticMarkup(tree);
const returnedRows = buttonMarkupWithText(returnedMarkup, "Выбрать");
assert.equal(returnedRows.length, initialState.devices.length);
assert.ok(returnedRows.every((row) => !/\bdisabled(?:=|\s|>)/.test(row)));
assert.match(returnedMarkup, /Повторить поиск Bluetooth/);
assert.doesNotMatch(returnedMarkup, />Найти по Bluetooth</);
assert.doesNotMatch(
returnedMarkup,
/Название общей сети Wi‑Fi|Пароль WiFi|<span>02<\/span>/,
);
assert.equal(scanCalls, 1);
assert.equal(reopenCalls, 0);
assert.equal(verifyCalls, 0);
assert.equal(connectCalls, 0);
assert.equal(resetCalls, 0);
assert.equal(prepareCalls, 0);
} finally {
harness.dispose();
}
});
test("a rendered prior-device selection never dispatches reopen or Verify", async () => {
const initialState = retiredPhysicalReopenReadyState();
let currentState = initialState;
let reopenCalls = 0;
let verifyCalls = 0;
let reopenedRequest = null;
let verifiedRequest = null;
let verifiedOptions = null;
let markVerifyDispatched;
const verifyDispatched = new Promise((resolve) => {
markVerifyDispatched = resolve;
});
const controller = {
...provisioningController(initialState),
getCurrentState: () => currentState,
getConnectionRecoveryObservationTarget: () =>
recommendedConnectionRecoveryObservationTarget(currentState),
getConnectionActionAuthority: (mode) =>
connectionActionAuthoritySnapshot(currentState, mode),
isSnapshotRuntimeCurrent: (runtimeId) =>
runtimeId === currentState.snapshot_runtime_id,
reopenRetiredPhysicalReconciliation: async (request, runtimeId) => {
reopenCalls += 1;
reopenedRequest = request;
assert.equal(runtimeId, initialState.snapshot_runtime_id);
const committed = reopenedPhysicalState({
reopeningId: request.reopening_id,
discoveryGeneration: request.expected_discovery_generation,
});
committed.connection_policy.recommended_action = "select-connection-intent";
committed.connection_policy.allowed_actions = [
"observe-fresh-device-network",
"observe-configured-device-network",
"scan-ble",
];
committed.connection_policy.actions["observe-configured-device-network"] = {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: request.expected_transport_ref,
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
automatic_retry: false,
};
currentState = committed;
assert.equal(
recommendedConnectionRecoveryObservationTarget(currentState).source,
"durable-configured-state",
"the generic selector must reproduce the competing configured target",
);
assert.equal(
readOnlyConnectionObservationTarget(currentState).source,
"fresh-scan",
);
return { succeeded: true, observedState: currentState };
},
verifyConnection: async (request, options) => {
verifyCalls += 1;
verifiedRequest = request;
verifiedOptions = options;
markVerifyDispatched();
return {
succeeded: true,
reconciliationCompleted: true,
observedState: currentState,
};
},
};
const tree = captureProvisioningTreeAfterSearch({
controller,
desiredMode: "bridge",
});
const priorDeviceRow = elementByProp(
tree,
"actionLabel",
"Выбрать",
);
assert.ok(priorDeviceRow);
assert.equal(typeof priorDeviceRow.props.onSelect, "function");
assert.equal(actionByLabel(tree, "Переподключиться"), null);
priorDeviceRow.props.onSelect();
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(reopenCalls, 0);
assert.equal(verifyCalls, 0);
assert.equal(reopenedRequest, null);
assert.equal(verifiedRequest, null);
assert.equal(verifiedOptions, null);
});
test("retired physical reopen proof uses the backend target, not the visible row", () => {
const request = {
reopening_id: "reopening-returned-k1",
expected_revision: 281,
expected_retirement_id: "retirement-old-stop",
expected_transport_ref: "F89438FA-55ED-85AD-EED7-734AC84746D8",
expected_discovery_generation: 13,
expected_desired_mode: "bridge",
expected_desired_mode_revision: 7,
operator_confirmed: true,
reason: "device-returned-for-explicit-reconciliation",
};
const state = reopenedPhysicalState();
const target = recommendedConnectionRecoveryObservationTarget(state);
const authority = connectionActionAuthoritySnapshot(state, "bridge");
const context = retiredPhysicalReopenVerificationContext(
state,
request,
"runtime-reopened-k1",
target,
authority,
);
assert.ok(context);
assert.equal(context.target.deviceId, request.expected_transport_ref);
assert.equal(context.target.serverBound, true);
assert.equal(
context.target.deviceId,
state.connection_policy.actions["observe-fresh-device-network"]
.required_transport_ref,
);
assert.notEqual(context.target.deviceId, state.devices[0].device_id);
assert.equal(
transportRefEquivalenceKey(context.target.deviceId),
transportRefEquivalenceKey(state.devices[0].device_id),
);
const wrongTarget = {
...target,
deviceId: "visible-row-but-not-server-target",
};
assert.equal(retiredPhysicalReopenVerificationContext(
state,
request,
"runtime-reopened-k1",
wrongTarget,
authority,
), null);
});
test("exact lost reopen response continues once to read-only Verify", async () => {
const request = {
reopening_id: "reopening-returned-k1",
expected_revision: 281,
expected_retirement_id: "retirement-old-stop",
expected_transport_ref: "F89438FA-55ED-85AD-EED7-734AC84746D8",
expected_discovery_generation: 13,
expected_desired_mode: "bridge",
expected_desired_mode_revision: 7,
operator_confirmed: true,
reason: "device-returned-for-explicit-reconciliation",
};
const committed = reopenedPhysicalState();
let verifyCalls = 0;
let verifiedTarget = null;
const result = await dispatchRetiredPhysicalReconciliationForCurrentRuntime({
snapshotRuntimeId: "runtime-reopened-k1",
request,
isSnapshotRuntimeCurrent: (runtimeId) => runtimeId === "runtime-reopened-k1",
reopen: async () => ({ succeeded: false, observedState: committed }),
getCurrentState: () => committed,
getCurrentTarget: () => recommendedConnectionRecoveryObservationTarget(committed),
getCurrentAuthority: (mode) => connectionActionAuthoritySnapshot(committed, mode),
expectedAuthority: connectionActionAuthoritySnapshot(committed, "bridge"),
verify: async (context, runtimeId) => {
verifyCalls += 1;
verifiedTarget = context.target;
assert.equal(runtimeId, "runtime-reopened-k1");
return { succeeded: true };
},
});
assert.equal(result.reopenDispatched, true);
assert.equal(result.reopenResult.succeeded, false);
assert.equal(result.verifyDispatched, true);
assert.equal(verifyCalls, 1);
assert.equal(verifiedTarget.deviceId, request.expected_transport_ref);
});
test("retired combined recovery keeps the exact fresh target when configured observation is also allowed", async () => {
const request = {
reopening_id: "reopening-combined-live",
expected_revision: 281,
expected_retirement_id: "retirement-old-stop",
expected_transport_ref: "F89438FA-55ED-85AD-EED7-734AC84746D8",
expected_discovery_generation: 13,
expected_desired_mode: "bridge",
expected_desired_mode_revision: 7,
operator_confirmed: true,
reason: "device-returned-for-explicit-reconciliation",
};
const committed = reopenedPhysicalState({
reopeningId: request.reopening_id,
});
committed.connection_policy.recommended_action = "select-connection-intent";
committed.connection_policy.allowed_actions = [
"observe-fresh-device-network",
"observe-configured-device-network",
"scan-ble",
];
committed.connection_policy.actions["observe-configured-device-network"] = {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: request.expected_transport_ref,
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
automatic_retry: false,
};
const genericTarget = recommendedConnectionRecoveryObservationTarget(committed);
const exactFreshTarget = readOnlyConnectionObservationTarget(committed);
assert.equal(genericTarget.action, "observe-configured-device-network");
assert.equal(exactFreshTarget.action, "observe-fresh-device-network");
assert.equal(exactFreshTarget.source, "fresh-scan");
assert.equal(exactFreshTarget.expectedDiscoveryGeneration, 13);
let verifyCalls = 0;
const result = await dispatchRetiredPhysicalReconciliationForCurrentRuntime({
snapshotRuntimeId: committed.snapshot_runtime_id,
request,
isSnapshotRuntimeCurrent: () => true,
reopen: async () => ({ succeeded: true, observedState: committed }),
getCurrentState: () => committed,
getCurrentTarget: () => readOnlyConnectionObservationTarget(committed),
getCurrentAuthority: (mode) => connectionActionAuthoritySnapshot(committed, mode),
expectedAuthority: connectionActionAuthoritySnapshot(committed, "bridge"),
verify: async ({ target }) => {
verifyCalls += 1;
assert.equal(target.action, "observe-fresh-device-network");
assert.equal(target.source, "fresh-scan");
assert.equal(target.deviceId, request.expected_transport_ref);
return { succeeded: true };
},
});
assert.equal(result.verifyDispatched, true);
assert.equal(verifyCalls, 1);
});
test("runtime replacement and same-runtime re-retirement suppress post-reopen Verify", async () => {
const request = {
reopening_id: "reopening-returned-k1",
expected_revision: 281,
expected_retirement_id: "retirement-old-stop",
expected_transport_ref: "F89438FA-55ED-85AD-EED7-734AC84746D8",
expected_discovery_generation: 13,
expected_desired_mode: "bridge",
expected_desired_mode_revision: 7,
operator_confirmed: true,
reason: "device-returned-for-explicit-reconciliation",
};
const committed = reopenedPhysicalState();
let runtimeId = "runtime-B";
let reopenCalls = 0;
let verifyCalls = 0;
const staleBeforeDispatch = await dispatchRetiredPhysicalReconciliationForCurrentRuntime({
snapshotRuntimeId: "runtime-A",
request,
isSnapshotRuntimeCurrent: (expected) => expected === runtimeId,
reopen: async () => {
reopenCalls += 1;
return { succeeded: true, observedState: committed };
},
getCurrentState: () => committed,
getCurrentTarget: () => recommendedConnectionRecoveryObservationTarget(committed),
getCurrentAuthority: (mode) => connectionActionAuthoritySnapshot(committed, mode),
expectedAuthority: connectionActionAuthoritySnapshot(committed, "bridge"),
verify: async () => {
verifyCalls += 1;
return { succeeded: true };
},
});
assert.equal(staleBeforeDispatch.reopenDispatched, false);
assert.equal(reopenCalls, 0);
assert.equal(verifyCalls, 0);
runtimeId = "runtime-reopened-k1";
const reretired = retiredPhysicalReopenReadyState();
let currentState = committed;
const changedAfterSuccess = await dispatchRetiredPhysicalReconciliationForCurrentRuntime({
snapshotRuntimeId: runtimeId,
request,
isSnapshotRuntimeCurrent: (expected) => expected === runtimeId,
reopen: async () => {
currentState = reretired;
return { succeeded: true, observedState: committed };
},
getCurrentState: () => currentState,
getCurrentTarget: () => recommendedConnectionRecoveryObservationTarget(currentState),
getCurrentAuthority: (mode) => connectionActionAuthoritySnapshot(currentState, mode),
expectedAuthority: connectionActionAuthoritySnapshot(committed, "bridge"),
verify: async () => {
verifyCalls += 1;
return { succeeded: true };
},
});
assert.equal(changedAfterSuccess.reopenDispatched, true);
assert.equal(changedAfterSuccess.verifyDispatched, false);
assert.equal(verifyCalls, 0);
});
test("retired reopen click and settlement retain the complete authority fence", () => {
const rendered = retiredPhysicalReopenReadyState();
rendered.connection_reconfiguration = connectionReconfiguration();
rendered.connection_lifecycle = { active_binding_key: "binding-A" };
const reopenAuthority = retiredPhysicalReopenAuthority(
rendered,
rendered.devices[0].device_id,
"bridge",
);
const authorityA = connectionActionAuthoritySnapshot(rendered, "bridge");
assert.ok(authorityA);
assert.deepEqual(
physicalReopenClickAuthority(rendered, "bridge", authorityA, reopenAuthority),
authorityA,
);
const reconfigured = structuredClone(rendered);
reconfigured.connection_reconfiguration = connectionReconfiguration({
intent: "select-device",
revision: 1,
intentId: "reconfigure-B",
});
const authorityR1 = connectionActionAuthoritySnapshot(reconfigured, "bridge");
assert.equal(
physicalReopenClickAuthority(rendered, "bridge", authorityR1, reopenAuthority),
null,
"a rendered R0 CTA cannot borrow latest R1 before POST",
);
const rebound = structuredClone(rendered);
rebound.connection_lifecycle.active_binding_key = "binding-B";
const authorityB = connectionActionAuthoritySnapshot(rebound, "bridge");
assert.equal(
physicalReopenClickAuthority(rendered, "bridge", authorityB, reopenAuthority),
null,
"a rendered binding A CTA cannot borrow latest binding B before POST",
);
const requestA = {
reopening_id: "reopening-A",
expected_revision: reopenAuthority.expectedRevision,
expected_retirement_id: reopenAuthority.expectedRetirementId,
expected_transport_ref: reopenAuthority.expectedTransportRef,
expected_discovery_generation: reopenAuthority.expectedDiscoveryGeneration,
expected_desired_mode: reopenAuthority.expectedDesiredMode,
expected_desired_mode_revision: reopenAuthority.expectedDesiredModeRevision,
operator_confirmed: true,
reason: "device-returned-for-explicit-reconciliation",
};
const presentationA = {
key: "runtime-A:reopening-A:device",
snapshotRuntimeId: authorityA.snapshotRuntimeId,
request: requestA,
authority: authorityA,
};
assert.equal(
admitPhysicalReopenPresentation(null, presentationA, authorityA),
presentationA,
);
assert.equal(
admitPhysicalReopenPresentation(presentationA, presentationA, authorityA),
null,
"a double click is coalesced while A owns the action",
);
const authorityRuntimeB = {
...authorityA,
snapshotRuntimeId: "runtime-B",
};
const presentationB = {
...presentationA,
key: "runtime-B:reopening-B:device",
snapshotRuntimeId: "runtime-B",
request: { ...requestA, reopening_id: "reopening-B" },
authority: authorityRuntimeB,
};
assert.equal(physicalReopenPresentationIsCurrent(
presentationA,
authorityRuntimeB,
), false);
assert.equal(
admitPhysicalReopenPresentation(
presentationA,
presentationB,
authorityRuntimeB,
),
presentationB,
"runtime B synchronously replaces stale A without waiting for an effect",
);
assert.equal(physicalReopenSettlementIsCurrent(
presentationB,
presentationA.key,
authorityRuntimeB,
), false, "late A cannot message or clear B");
for (const [label, driftedAuthority] of [
["new reset revision", {
...authorityA,
desiredModeRevision: authorityA.desiredModeRevision + 1,
}],
["new discovery generation", {
...authorityA,
discoveryGeneration: authorityA.discoveryGeneration + 1,
}],
["new reconfiguration", authorityR1],
["new binding", authorityB],
]) {
assert.equal(physicalReopenPresentationIsCurrent(
presentationA,
driftedAuthority,
), false);
const replacement = {
...presentationA,
key: `runtime-A:reopening-B:${label}`,
request: {
...requestA,
reopening_id: `reopening-B-${label}`,
expected_desired_mode_revision: driftedAuthority.desiredModeRevision,
expected_discovery_generation: driftedAuthority.discoveryGeneration,
},
authority: driftedAuthority,
};
assert.equal(
admitPhysicalReopenPresentation(
presentationA,
replacement,
driftedAuthority,
),
replacement,
`${label} releases A synchronously so a current B click can start`,
);
}
});
test("same-runtime reconfiguration or binding drift after reopen suppresses Verify", async () => {
const request = {
reopening_id: "reopening-returned-k1",
expected_revision: 281,
expected_retirement_id: "retirement-old-stop",
expected_transport_ref: "F89438FA-55ED-85AD-EED7-734AC84746D8",
expected_discovery_generation: 13,
expected_desired_mode: "bridge",
expected_desired_mode_revision: 7,
operator_confirmed: true,
reason: "device-returned-for-explicit-reconciliation",
};
const committed = reopenedPhysicalState();
committed.connection_reconfiguration = connectionReconfiguration();
committed.connection_lifecycle = { active_binding_key: "binding-A" };
const expectedAuthority = connectionActionAuthoritySnapshot(committed, "bridge");
for (const drift of ["reconfiguration", "binding"]) {
const current = structuredClone(committed);
if (drift === "reconfiguration") {
current.connection_reconfiguration = connectionReconfiguration({
intent: "select-device",
revision: 1,
intentId: "reconfiguration-B",
});
} else {
current.connection_lifecycle.active_binding_key = "binding-B";
}
let verifyCalls = 0;
const result = await dispatchRetiredPhysicalReconciliationForCurrentRuntime({
snapshotRuntimeId: committed.snapshot_runtime_id,
request,
isSnapshotRuntimeCurrent: () => true,
reopen: async () => ({ succeeded: true, observedState: committed }),
getCurrentState: () => current,
getCurrentTarget: () => recommendedConnectionRecoveryObservationTarget(current),
getCurrentAuthority: (mode) => connectionActionAuthoritySnapshot(current, mode),
expectedAuthority,
verify: async () => {
verifyCalls += 1;
return { succeeded: true };
},
});
assert.equal(result.verifyDispatched, false, drift);
assert.equal(verifyCalls, 0, drift);
}
});
test("a settled reset marker keeps the exact prior UUID as an ordinary Select row", () => {
const state = retiredPhysicalReopenReadyState();
state.connection_scenario_reset = {
reset_id: "reset-settled",
request_revision: 6,
revision: 7,
desired_mode: "bridge",
active: false,
settled_by_discovery_generation: 13,
local_session_closed: true,
previous_device_may_continue_scanning: false,
physical_disposition: "retired",
network_disposition: null,
device_command_performed: false,
network_write_performed: false,
automatic_scan: false,
operation_sequence: 21,
};
assert.deepEqual(scenarioResetPresentationBoundary(state, "bridge"), {
current: true,
active: false,
key: "runtime-reopened-k1:7",
});
const markup = renderProvisioningAfterSearch({
controller: provisioningController(state),
desiredMode: "bridge",
});
assert.doesNotMatch(markup, /Прежний локальный сеанс закрыт/);
const select = buttonMarkupWithText(markup, "Выбрать");
assert.equal(select.length, 1);
assert.doesNotMatch(select[0], /\bdisabled(?:=|\s|>)/);
assert.equal(buttonMarkupWithText(markup, "Переподключиться").length, 0);
assert.doesNotMatch(markup, /Вернуть прежний K1 и проверить/);
});
test("an unresolved physical command has one explicit server-bound read-only recovery surface", () => {
const state = durableTopologyState();
state.snapshot_runtime_id = "runtime-physical-read-only";
const recoveryTransport = "F89438FA-55ED-85AD-EED7-734AC84746D8";
state.physical_command = {
status: "unresolved",
reason_code: "physical-command-reconciliation-required",
requires_reconciliation: true,
resolved_active_recovery_required: false,
automatic_replay_allowed: false,
normal_session_recovery_supported: false,
runtime_bound: true,
reconciliation_ready: true,
observed_session_state: "scan_stopping",
active_operation_id: "old-stop-operation",
record: {
revision: 306,
operation_id: "old-stop-operation",
action: "stop",
stage: "observing",
resolution: null,
connection: {
transport_ref: recoveryTransport,
connection_mode: "bridge",
target_ipv4: "192.168.68.51",
},
},
};
state.connection_attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: "historical-network-attempt-after-powered-off-start",
connection_mode: "bridge",
status: "failed",
phase: "network_applied",
control_state: "control_not_ready",
stage: "host-route-and-control-endpoint",
public_error_code: "control-bootstrap-failed",
side_effect_status: "network-applied",
safe_next_action: "manual-recovery-required",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: OBSERVED_AT,
timeline: [],
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false, retired_transport_refs: [] },
allowed_actions: ["scan-ble", "observe-configured-device-network"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
"provision-fresh-device": {
allowed: false,
reason_codes: ["physical-command-reconciliation-required"],
target_source: "fresh-scan",
required_transport_ref: null,
requires_live_gatt_validation: true,
automatic_retry: false,
},
"observe-configured-device-network": {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: recoveryTransport,
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
state.devices = [
{
device_id: recoveryTransport.toLowerCase(),
name: "XGR-A46BE7",
rssi: -42,
connectable: true,
likely_k1: true,
},
{
device_id: "nearby-unrelated-device",
name: "Nearby unrelated device",
rssi: -48,
connectable: true,
likely_k1: false,
},
];
const markup = renderToStaticMarkup(createElement(K1ProvisioningPipeline, {
controller: provisioningController(state),
desiredMode: "bridge",
}));
const phaseDetail = physicalRecoveryConnectionDetail(state);
assert.match(phaseDetail, /Проверьте состояние прежнего K1/);
assert.match(phaseDetail, /сохранённое системой подключение/);
assert.match(phaseDetail, /не отправляет START, STOP или настройки сети/);
assert.doesNotMatch(phaseDetail, /read-only/);
assert.doesNotMatch(phaseDetail, /серверн.*цел/i);
assert.doesNotMatch(markup, /read-only|серверн.*цел/i);
assert.doesNotMatch(phaseDetail, /[Пп]одтвердите питание|локально исключить/);
const reconnect = buttonMarkupWithText(markup, "Переподключиться");
const connectNew = buttonMarkupWithText(markup, "Подключить новый K1");
assert.equal(reconnect.length, 1);
assert.equal(connectNew.length, 1);
assert.doesNotMatch(reconnect[0], /\bdisabled(?:=|\s|>)/);
assert.doesNotMatch(connectNew[0], /\bdisabled(?:=|\s|>)/);
assert.doesNotMatch(
markup,
/Предыдущая команда завершилась|Проверить прежний K1 без изменений|Выберите способ восстановления|Подтверждаю:|Питание|индикатор горит/,
);
assert.doesNotMatch(markup, /<span>02<\/span>|<span>03<\/span>/);
assert.doesNotMatch(markup, /Попытка настройки завершена|Проверить подключение без изменения сети/);
assert.doesNotMatch(markup, /nearby-unrelated-device/);
assert.doesNotMatch(markup, />Применить<|>Выбрать<|Обновить Bluetooth-поиск/);
assert.doesNotMatch(markup, /old-stop-operation/);
const searchedMarkup = renderProvisioningAfterSearch({
controller: provisioningController(state),
desiredMode: "bridge",
});
assert.equal(buttonMarkupWithText(searchedMarkup, "Переподключиться").length, 1);
assert.equal(buttonMarkupWithText(searchedMarkup, "Подключить новый K1").length, 1);
assert.doesNotMatch(
searchedMarkup,
/Результаты последнего Bluetooth-поиска|nearby-unrelated-device|>Выбрать<|>Применить</,
);
const quickRecoveryInsideBridgeState = structuredClone(state);
quickRecoveryInsideBridgeState.physical_command.record.connection.connection_mode =
"quick-connect";
quickRecoveryInsideBridgeState.physical_command.record.connection.target_ipv4 =
"192.168.56.1";
quickRecoveryInsideBridgeState.semantic_topology_store.record.connection_mode =
"quick-connect";
quickRecoveryInsideBridgeState.semantic_topology_store.record.ipv4 = "192.168.56.1";
quickRecoveryInsideBridgeState.connection_policy.actions[
"observe-configured-device-network"
].required_connection_mode = "quick-connect";
const quickRecoveryInsideBridgeMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{
controller: provisioningController(quickRecoveryInsideBridgeState),
desiredMode: "bridge",
},
));
assert.equal(
buttonMarkupWithText(
quickRecoveryInsideBridgeMarkup,
"Переподключиться",
).length,
0,
);
assert.equal(
buttonMarkupWithText(
quickRecoveryInsideBridgeMarkup,
"Подключить новый K1",
).length,
1,
);
const selectedQuickRecoveryState = structuredClone(
quickRecoveryInsideBridgeState,
);
selectedQuickRecoveryState.desired_connection_mode = "quick-connect";
const selectedQuickRecoveryMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{
controller: provisioningController(selectedQuickRecoveryState),
desiredMode: "quick-connect",
},
));
assert.equal(
buttonMarkupWithText(selectedQuickRecoveryMarkup, "Переподключиться").length,
1,
);
const networkSetupState = structuredClone(state);
networkSetupState.connection_verification = {
status: "unreachable",
lease_state: "disconnected",
network_reachability: "unreachable",
reason_code: "connection-verify-address-unavailable",
};
networkSetupState.last_operation = {
action: "connection.verify",
status: "failed",
error: { code: "connection-verify-device-not-rediscovered" },
};
const networkSetupMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{
controller: provisioningController(networkSetupState),
desiredMode: "bridge",
},
));
const networkSetupReconnect = buttonMarkupWithText(
networkSetupMarkup,
"Переподключиться",
);
assert.equal(networkSetupReconnect.length, 1);
assert.doesNotMatch(networkSetupReconnect[0], /\bdisabled(?:=|\s|>)/);
const networkSetupAction = buttonMarkupWithText(
networkSetupMarkup,
"Подключить K1 к общей сети",
);
assert.equal(networkSetupAction.length, 1);
assert.doesNotMatch(networkSetupAction[0], /\bdisabled(?:=|\s|>)/);
assert.match(
networkSetupMarkup,
/K1 не подключён к сохранённой общей сети/,
);
assert.match(networkSetupMarkup, /не сообщил адрес Bridge/);
assert.doesNotMatch(
networkSetupMarkup,
/Локальная операция завершилась ошибкой|Проверьте питание и сеть/,
);
assert.match(
physicalRecoveryConnectionDetail(networkSetupState),
/K1 ответил по Bluetooth, но не подключён к сохранённой общей сети/,
);
const policyDeniedState = structuredClone(state);
policyDeniedState.connection_policy.allowed_actions = ["scan-ble"];
delete policyDeniedState.connection_policy.actions["observe-configured-device-network"];
const policyDeniedMarkup = renderProvisioningAfterSearch({
controller: provisioningController(policyDeniedState),
desiredMode: "bridge",
});
assert.equal(buttonMarkupWithText(policyDeniedMarkup, "Переподключиться").length, 0);
const deniedNew = buttonMarkupWithText(policyDeniedMarkup, "Подключить новый K1");
assert.equal(deniedNew.length, 1);
assert.doesNotMatch(deniedNew[0], /\bdisabled(?:=|\s|>)/);
assert.doesNotMatch(
policyDeniedMarkup,
/nearby-unrelated-device|Старый K1 недоступен|Подтверждаю:|>Применить</,
);
const pendingMarkup = renderProvisioningWithCurrentPendingAction({
controller: {
...provisioningController(state),
pendingAction: "verify",
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: () => true,
},
desiredMode: "bridge",
}, { publicSearch: false });
const pendingReconnect = buttonMarkupWithText(
pendingMarkup,
"Переподключение…",
);
assert.equal(pendingReconnect.length, 1);
assert.match(pendingReconnect[0], /disabled/);
assert.match(pendingReconnect[0], /aria-busy="true"/);
assert.match(pendingReconnect[0], /nodedc-activity-indicator/);
const pendingConnectNew = buttonMarkupWithText(
pendingMarkup,
"Подключить новый K1",
);
assert.equal(pendingConnectNew.length, 1);
assert.match(pendingConnectNew[0], /disabled/);
assert.doesNotMatch(pendingMarkup, /connection-action-progress|Подтверждаю:/);
const source = readFileSync(provisioningSourceUrl, "utf8");
const physicalRecovery = sourceSlice(
source,
"const verifyPhysicalRecovery",
"const prepareReconfiguration",
);
assert.equal((physicalRecovery.match(/await verifyConnection\(/g) ?? []).length, 1);
assert.doesNotMatch(
physicalRecovery,
/scanWithResult\(|connect\(|retireUnavailable|reopenRetired|reconcilePhysicalCommand/,
);
assert.match(physicalRecovery, /physicalRecoveryTarget\?\.serverBound/);
assert.match(physicalRecovery, /surfaceErrors: false/);
assert.match(
physicalRecovery,
/physicalRecoveryTarget\.connectionMode !== connectionMode/,
);
assert.doesNotMatch(
physicalRecovery,
/commitDesiredModeForExplicitAction|selectConnectionMode\(/,
);
});
test("supervisor DeviceInfo Verify outranks a stale exact fresh row for physical recovery", () => {
const state = durableTopologyState();
const recoveryTransport = "F89438FA-55ED-85AD-EED7-734AC84746D8";
state.snapshot_runtime_id = "runtime-terminal-control-physical-recovery";
state.semantic_topology_store.record.transport_ref = recoveryTransport;
state.physical_command = {
status: "unresolved",
reason_code: "physical-command-reconciliation-required",
requires_reconciliation: true,
resolved_active_recovery_required: false,
reconciliation_ready: true,
record: {
revision: 583,
operation_id: "old-start-operation",
action: "start",
stage: "observing",
resolution: null,
connection: {
transport_ref: recoveryTransport,
connection_mode: "bridge",
target_ipv4: "192.168.68.52",
},
},
};
const deniedObservation = (targetSource) => ({
allowed: false,
reason_codes: ["control-session-not-admissible-for-network-change"],
target_source: targetSource,
required_transport_ref: recoveryTransport,
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
});
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false, retired_transport_refs: [] },
recommended_action: "scan-ble",
allowed_actions: [
"scan-ble",
"observe-fresh-device-network",
"inspect-configured-endpoint",
"verify-control-device-info",
],
actions: {
"observe-fresh-device-network": {
allowed: true,
reason_codes: [],
target_source: "fresh-scan",
required_transport_ref: recoveryTransport,
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
"observe-current-device-network": deniedObservation(
"retained-current-process",
),
"observe-configured-device-network": deniedObservation(
"durable-configured-state",
),
"verify-control-device-info": {
allowed: true,
reason_codes: [],
target_source: "connection-supervisor",
required_transport_ref: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
state.devices = [{
device_id: recoveryTransport,
name: "Projected K1",
connectable: true,
likely_k1: true,
}];
state.ble_discovery_generation = 2;
assert.deepEqual(readOnlyConnectionObservationTarget(state), {
action: "verify-control-device-info",
deviceId: recoveryTransport,
connectionMode: "bridge",
source: "durable-configured-state",
serverBound: true,
expectedDiscoveryGeneration: null,
});
const markup = renderToStaticMarkup(createElement(K1ProvisioningPipeline, {
controller: provisioningController(state),
desiredMode: "bridge",
}));
const reconnect = buttonMarkupWithText(markup, "Переподключиться");
assert.equal(reconnect.length, 1);
assert.doesNotMatch(reconnect[0], /\bdisabled(?:=|\s|>)/);
assert.equal(buttonMarkupWithText(markup, "Подключить новый K1").length, 1);
const mismatched = structuredClone(state);
mismatched.semantic_topology_store.record.transport_ref = "another-k1";
mismatched.connection_policy.actions["observe-fresh-device-network"].allowed = false;
assert.equal(readOnlyConnectionObservationTarget(mismatched), null);
});
test("unavailable physical replacement stays CAS-protected behind the simple new-device path", () => {
const state = durableTopologyState();
const transportRef = "F89438FA-55ED-85AD-EED7-734AC84746D8";
state.snapshot_runtime_id = "runtime-retire-old-k1";
state.physical_command = {
status: "unresolved",
reason_code: "physical-command-reconciliation-required",
requires_reconciliation: true,
resolved_active_recovery_required: false,
automatic_replay_allowed: false,
normal_session_recovery_supported: false,
runtime_bound: false,
reconciliation_ready: true,
observed_session_state: "unknown",
active_operation_id: "old-start-operation",
operator_retirement: {
allowed: true,
reason_codes: [],
expected_operation_id: "old-start-operation",
expected_revision: 41,
expected_transport_ref: transportRef,
physical_outcome: "unknown",
device_io_performed: false,
automatic_retry: false,
},
record: {
revision: 41,
operation_id: "old-start-operation",
action: "start",
stage: "observing",
resolution: null,
connection: {
transport_ref: transportRef,
connection_mode: "bridge",
},
},
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false, retired_transport_refs: [] },
allowed_actions: ["retire-unavailable-physical-target"],
actions: {
"provision-fresh-device": {
allowed: false,
reason_codes: ["physical-command-reconciliation-required"],
target_source: "fresh-scan",
required_transport_ref: null,
requires_live_gatt_validation: true,
automatic_retry: false,
},
"retire-unavailable-physical-target": {
allowed: true,
reason_codes: [],
target_source: "durable-physical-command",
required_transport_ref: transportRef,
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
physical_command_allowed: false,
physical_outcome: "unknown",
device_write_performed: false,
automatic_retry: false,
},
},
};
assert.deepEqual(unavailablePhysicalRetirementAuthority(state), {
expectedOperationId: "old-start-operation",
expectedRevision: 41,
expectedTransportRef: transportRef,
});
const markup = renderToStaticMarkup(createElement(K1ProvisioningPipeline, {
controller: provisioningController(state),
desiredMode: "bridge",
}));
const connectNew = buttonMarkupWithText(markup, "Подключить новый K1");
assert.equal(connectNew.length, 1);
assert.doesNotMatch(connectNew[0], /\bdisabled(?:=|\s|>)/);
assert.equal(buttonMarkupWithText(markup, "Переподключиться").length, 0);
assert.doesNotMatch(markup, /<span>02<\/span>|<span>03<\/span>/);
assert.doesNotMatch(
markup,
/Старый K1 недоступен|Подтверждаю:|Выберите способ восстановления|Проверить прежний K1 без изменений|[Пп]итани/,
);
const phaseDetail = physicalRecoveryConnectionDetail(state);
assert.match(phaseDetail, /можно локально исключить без связи с устройством/);
assert.match(phaseDetail, /не отправляет START, STOP или настройки сети/);
assert.doesNotMatch(phaseDetail, /[Пп]итани|read-only/);
const denied = structuredClone(state);
denied.connection_policy.allowed_actions = [];
denied.connection_policy.actions["retire-unavailable-physical-target"].allowed = false;
denied.connection_policy.actions["retire-unavailable-physical-target"].reason_codes = [
"physical-command-retirement-state-unsafe",
];
assert.equal(unavailablePhysicalRetirementAuthority(denied), null);
const deniedMarkup = renderProvisioning({
controller: provisioningController(denied),
desiredMode: "bridge",
});
const deniedNew = buttonMarkupWithText(deniedMarkup, "Подключить новый K1");
assert.equal(deniedNew.length, 1);
assert.doesNotMatch(deniedNew[0], /\bdisabled(?:=|\s|>)/);
assert.equal(buttonMarkupWithText(deniedMarkup, "Переподключиться").length, 0);
assert.doesNotMatch(deniedMarkup, /Старый K1 недоступен|Подтверждаю:/);
assert.doesNotMatch(
physicalRecoveryConnectionDetail(denied),
/можно локально исключить/,
);
const resolvedActive = structuredClone(state);
resolvedActive.physical_command.status = "resolved";
resolvedActive.physical_command.requires_reconciliation = false;
resolvedActive.physical_command.resolved_active_recovery_required = true;
resolvedActive.physical_command.observed_session_state = "scanning";
resolvedActive.physical_command.record.stage = "resolved";
resolvedActive.physical_command.record.resolution = "start-active-observed";
resolvedActive.connection_policy.actions["provision-fresh-device"].reason_codes = [
"physical-device-already-active",
];
const resolvedActiveMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{
controller: provisioningController(resolvedActive),
desiredMode: "bridge",
},
));
const resolvedNew = buttonMarkupWithText(
resolvedActiveMarkup,
"Подключить новый K1",
);
assert.equal(resolvedNew.length, 1);
assert.doesNotMatch(resolvedNew[0], /\bdisabled(?:=|\s|>)/);
assert.equal(
buttonMarkupWithText(resolvedActiveMarkup, "Переподключиться").length,
0,
);
assert.doesNotMatch(resolvedActiveMarkup, /[Пп]итани/);
assert.doesNotMatch(resolvedActiveMarkup, /<span>02<\/span>|<span>03<\/span>/);
const bothAllowed = structuredClone(state);
bothAllowed.semantic_topology_store.record.transport_ref = transportRef;
bothAllowed.connection_policy.allowed_actions = [
"observe-configured-device-network",
"retire-unavailable-physical-target",
];
bothAllowed.connection_policy.actions["observe-configured-device-network"] = {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: transportRef,
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
automatic_retry: false,
};
const bothMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{
controller: provisioningController(bothAllowed),
desiredMode: "bridge",
},
));
const bothReconnect = buttonMarkupWithText(bothMarkup, "Переподключиться");
const bothNew = buttonMarkupWithText(bothMarkup, "Подключить новый K1");
assert.equal(bothReconnect.length, 1);
assert.equal(bothNew.length, 1);
assert.doesNotMatch(bothReconnect[0], /\bdisabled(?:=|\s|>)/);
assert.doesNotMatch(bothNew[0], /\bdisabled(?:=|\s|>)/);
assert.ok(
bothMarkup.indexOf("Переподключиться")
< bothMarkup.indexOf("Подключить новый K1"),
"read-only reconnect must be first",
);
assert.doesNotMatch(
bothMarkup,
/Выберите способ восстановления|Если прежний K1 снова доступен|Если прежний K1 недоступен постоянно|Подтверждаю:/,
);
assert.doesNotMatch(bothMarkup, /[Пп]итани|индикатор горит/);
assert.doesNotMatch(bothMarkup, /<span>02<\/span>|<span>03<\/span>/);
const bothPhaseDetail = physicalRecoveryConnectionDetail(bothAllowed);
assert.match(bothPhaseDetail, /Если прежний K1 снова доступен/);
assert.match(bothPhaseDetail, /недоступен постоянно или заменён/);
assert.match(bothPhaseDetail, /не отправляет START, STOP или настройки сети/);
assert.match(bothPhaseDetail, /без связи с устройством/);
assert.doesNotMatch(bothPhaseDetail, /read-only/);
assert.doesNotMatch(bothMarkup, /read-only/);
const bothPendingMarkup = renderProvisioningWithCurrentPendingAction({
controller: {
...provisioningController(bothAllowed),
pendingAction: "verify",
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: () => true,
},
desiredMode: "bridge",
}, { publicSearch: false });
const bothPendingReconnect = buttonMarkupWithText(
bothPendingMarkup,
"Переподключение…",
);
assert.equal(bothPendingReconnect.length, 1);
assert.match(bothPendingReconnect[0], /disabled/);
assert.match(bothPendingReconnect[0], /aria-busy="true"/);
assert.match(bothPendingReconnect[0], /nodedc-activity-indicator/);
assert.match(bothPendingMarkup, /Прежнее подключение не подтверждено/);
assert.doesNotMatch(bothPendingMarkup, /connection-action-progress|Подтверждаю:/);
const bothResolvedActive = structuredClone(bothAllowed);
bothResolvedActive.physical_command.status = "resolved";
bothResolvedActive.physical_command.requires_reconciliation = false;
bothResolvedActive.physical_command.resolved_active_recovery_required = true;
bothResolvedActive.physical_command.observed_session_state = "scanning";
bothResolvedActive.physical_command.record.stage = "resolved";
bothResolvedActive.physical_command.record.resolution = "start-active-observed";
bothResolvedActive.connection_policy.actions[
"provision-fresh-device"
].reason_codes = ["physical-device-already-active"];
const bothResolvedActiveMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{
controller: provisioningController(bothResolvedActive),
desiredMode: "bridge",
},
));
assert.equal(
buttonMarkupWithText(bothResolvedActiveMarkup, "Переподключиться").length,
1,
);
assert.equal(
buttonMarkupWithText(bothResolvedActiveMarkup, "Подключить новый K1").length,
1,
);
assert.doesNotMatch(
bothResolvedActiveMarkup,
/<span>02<\/span>|<span>03<\/span>/,
);
});
test("physical recovery new-device action performs only an explicit scenario reset", async () => {
const state = reopenedPhysicalState();
const resetRequests = [];
let desiredModeChanges = 0;
let scanCalls = 0;
let connectCalls = 0;
let verifyCalls = 0;
let reopenCalls = 0;
let markResetDispatched;
const resetDispatched = new Promise((resolve) => {
markResetDispatched = resolve;
});
const controller = {
...provisioningController(state),
selectConnectionMode: async (request) => {
resetRequests.push(request);
markResetDispatched();
return true;
},
scanWithResult: async () => {
scanCalls += 1;
return { succeeded: false };
},
connect: async () => {
connectCalls += 1;
return { succeeded: false };
},
verifyConnection: async () => {
verifyCalls += 1;
return { succeeded: false };
},
reopenRetiredPhysicalReconciliation: async () => {
reopenCalls += 1;
return { succeeded: false };
},
};
const props = {
controller,
desiredMode: "bridge",
onDesiredModeChange: async (mode) => {
assert.equal(mode, "bridge");
desiredModeChanges += 1;
},
};
const markup = renderProvisioning(props);
const resetButtons = buttonMarkupWithText(markup, "Подключить новый K1");
assert.equal(resetButtons.length, 1);
assert.doesNotMatch(resetButtons[0], /\bdisabled(?:=|\s|>)/);
const tree = captureProvisioningTree(props);
const connectNew = actionByLabel(tree, "Подключить новый K1");
assert.ok(connectNew);
connectNew.props.onClick();
await Promise.race([
resetDispatched,
new Promise((_, reject) => setTimeout(
() => reject(new Error("new-device action did not dispatch scenario reset")),
100,
)),
]);
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(resetRequests.length, 1);
assert.equal(resetRequests[0].connection_mode, "bridge");
assert.equal(
resetRequests[0].expected_revision,
state.desired_connection_mode_revision,
);
assert.equal(resetRequests[0].reset_scenario, true);
assert.equal(typeof resetRequests[0].reset_id, "string");
assert.ok(resetRequests[0].reset_id.length > 0);
assert.equal(desiredModeChanges, 1);
assert.equal(scanCalls, 0);
assert.equal(connectCalls, 0);
assert.equal(verifyCalls, 0);
assert.equal(reopenCalls, 0);
});
test("topology switch stays silent for two seconds and then uses only the inline loader", async () => {
const state = terminalConnectionRecoveryState();
state.connection_attempt = null;
let resolveReset;
const resetSettlement = new Promise((resolve) => {
resolveReset = resolve;
});
const resetRequests = [];
const controller = {
...provisioningController(state),
selectConnectionMode: (request) => {
resetRequests.push(request);
return resetSettlement;
},
};
const props = {
controller,
desiredMode: "bridge",
onDesiredModeChange: () => undefined,
};
const originalSetTimeout = globalThis.setTimeout;
const originalClearTimeout = globalThis.clearTimeout;
const timers = [];
globalThis.setTimeout = (callback, delay, ...args) => {
const timer = { callback, delay, args, cleared: false };
timers.push(timer);
return timer;
};
globalThis.clearTimeout = (timer) => {
timer.cleared = true;
};
const harness = createStatefulProvisioningHarness(props);
try {
let tree = harness.render();
harness.flushEffects();
const modeSelect = elementByProp(tree, "label", "Способ подключения");
assert.ok(modeSelect);
modeSelect.props.onChange("quick-connect");
assert.equal(resetRequests.length, 1);
tree = harness.render();
harness.flushEffects();
let markup = renderToStaticMarkup(tree);
assert.doesNotMatch(markup, /Переключаем способ подключения/);
assert.doesNotMatch(markup, /Завершение прежней локальной границы/);
const progressTimer = timers.find(
(timer) => timer.delay === LOCAL_OPERATION_PROGRESS_DELAY_MILLISECONDS,
);
assert.ok(progressTimer);
assert.equal(progressTimer.cleared, false);
progressTimer.callback(...progressTimer.args);
tree = harness.render();
markup = renderToStaticMarkup(tree);
assert.match(markup, /Переключаем способ подключения/);
assert.match(markup, /connection-action-progress/);
assert.doesNotMatch(markup, /dialog|modal|window/i);
resolveReset(true);
await Promise.resolve();
await Promise.resolve();
tree = harness.render();
harness.flushEffects();
markup = renderToStaticMarkup(tree);
assert.doesNotMatch(markup, /Переключаем способ подключения/);
} finally {
harness.dispose();
globalThis.setTimeout = originalSetTimeout;
globalThis.clearTimeout = originalClearTimeout;
}
});
test("physical retirement dispatch refuses a rendered runtime A after runtime B is current", async () => {
let currentRuntimeId = "runtime-B";
let mutationRequests = 0;
const stale = await dispatchUnavailablePhysicalRetirementForCurrentRuntime(
"runtime-A",
(expectedSnapshotRuntimeId) => expectedSnapshotRuntimeId === currentRuntimeId,
async () => {
mutationRequests += 1;
return { succeeded: true };
},
);
assert.deepEqual(stale, { dispatched: false, result: null });
assert.equal(mutationRequests, 0);
currentRuntimeId = "runtime-A";
const current = await dispatchUnavailablePhysicalRetirementForCurrentRuntime(
"runtime-A",
(expectedSnapshotRuntimeId) => expectedSnapshotRuntimeId === currentRuntimeId,
async (expectedSnapshotRuntimeId) => {
mutationRequests += 1;
return { expectedSnapshotRuntimeId };
},
);
assert.deepEqual(current, {
dispatched: true,
result: { expectedSnapshotRuntimeId: "runtime-A" },
});
assert.equal(mutationRequests, 1);
const runtimeSource = readFileSync(new URL(
"../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts",
import.meta.url,
), "utf8");
const retirementHook = sourceSlice(
runtimeSource,
"const retireUnavailablePhysicalCommandWithResult",
"const retireUnavailablePhysicalCommand = useCallback",
);
assert.match(
retirementHook,
/!isSnapshotRuntimeCurrent\(exactSnapshotRuntimeId\)[\s\S]*?expected_snapshot_runtime_id:\s*exactSnapshotRuntimeId/,
);
assert.doesNotMatch(
retirementHook,
/expected_snapshot_runtime_id:\s*expectedSnapshotRuntimeId\(\)/,
);
});
test("an explicit network action keeps one disabled Step-2 form with an in-place loader", () => {
const state = durableTopologyState();
state.snapshot_runtime_id = "runtime-network-action";
state.desired_connection_mode_revision = 7;
state.ble_discovery_generation = 13;
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
const device = {
device_id: "f89438fa-55ed-85ad-eed7-734ac84746d8",
name: "XGR-A46BE7",
rssi: -51,
connectable: true,
likely_k1: true,
};
state.devices = [device];
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["provision-fresh-device"],
actions: {
"provision-fresh-device": {
allowed: true,
reason_codes: [],
target_source: "fresh-scan",
required_transport_ref: null,
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
};
const presentation = provisioningAttemptPresentation({
snapshotRuntimeId: state.snapshot_runtime_id,
deviceId: device.device_id,
});
const markup = renderProvisioningWithAttempt({
controller: provisioningController(state),
desiredMode: "bridge",
}, presentation);
assert.doesNotMatch(markup, /class="connection-action-progress"/);
assert.match(markup, /aria-busy="true"/);
assert.equal((markup.match(/class="nodedc-activity-indicator"/g) ?? []).length, 1);
assert.match(markup, /Устройство выбрано/);
assert.match(markup, /XGR-A46BE7/);
assert.match(markup, /<span>02<\/span>/);
assert.match(markup, /Применение настроек…/);
assert.match(markup, /FIELD-NET/);
assert.match(markup, /Пароль передан/);
assert.doesNotMatch(markup, /secret/);
assert.equal((markup.match(/<input[^>]*disabled=""/g) ?? []).length, 2);
assert.doesNotMatch(markup, />Применить<\/button>/);
assertCanonicalConnectionCopy(markup);
});
test("Apply presentation stays correlated through ACK, bootstrap, terminal and connected projections", () => {
const presentation = provisioningAttemptPresentation({
deviceId: "ble-k1-001",
});
const initialState = {
...durableTopologyState(),
snapshot_runtime_id: presentation.snapshotRuntimeId,
};
assert.equal(
provisioningAttemptViewState(presentation, initialState),
"submitting",
);
const operation = {
operation_id: "network-operation-one",
action: "network.provision",
status: "succeeded",
idempotency_key: presentation.idempotencyKey,
};
assert.equal(
provisioningAttemptViewState({
...presentation,
localPhase: "failed",
}, {
...initialState,
operations: [{ ...operation, status: "running" }],
}),
"settling",
"an authoritative running operation supersedes a presentation error",
);
assert.equal(
provisioningAttemptViewState(presentation, {
...initialState,
operations: [operation],
}),
"settling",
"a fast network ACK is not yet a connected result",
);
const correlated = {
...presentation,
attemptId: operation.operation_id,
localPhase: "settling",
};
const attempt = {
attempt_id: operation.operation_id,
connection_mode: "bridge",
status: "running",
phase: "network_applied",
control_state: "unknown",
safe_next_action: "wait-for-current-attempt",
};
assert.equal(
provisioningAttemptViewState(correlated, {
...initialState,
operations: [operation],
connection_attempt: attempt,
}),
"settling",
);
assert.equal(
provisioningAttemptViewState(correlated, {
...initialState,
operations: [operation],
connection_attempt: {
...attempt,
status: "succeeded",
control_state: "ready",
safe_next_action: "start-acquisition",
},
}),
"settling",
"ready child success waits for the exact reachable lease projection",
);
assert.equal(
provisioningAttemptViewState(correlated, {
...initialState,
operations: [operation],
connection_attempt: {
...attempt,
status: "succeeded",
control_state: "unknown",
safe_next_action: "verify-control-read-only",
},
}),
"settling",
"the network-success/control-bootstrap handoff keeps the existing loader",
);
assert.equal(
provisioningAttemptViewState(correlated, {
...initialState,
operations: [operation],
connection_attempt: {
...attempt,
status: "failed",
control_state: "control_not_ready",
safe_next_action: "manual-recovery-required",
},
}),
"failed",
);
const connectedState = runtimeState();
connectedState.snapshot_runtime_id = presentation.snapshotRuntimeId;
assert.equal(
provisioningAttemptViewState(correlated, connectedState),
"connected",
);
assert.equal(
provisioningAttemptViewState(correlated, {
...initialState,
snapshot_runtime_id: "replacement-runtime",
}),
"retired",
);
});
test("current Bridge bootstrap stays visible over an older unresolved STOP checkpoint", () => {
const presentation = provisioningAttemptPresentation({
localPhase: "settling",
attemptId: "network-operation-current",
});
const state = durableTopologyState();
state.snapshot_runtime_id = presentation.snapshotRuntimeId;
state.connection_attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: presentation.attemptId,
connection_mode: "bridge",
status: "running",
phase: "network_applied",
control_state: "unknown",
stage: "mqtt-device-info",
public_error_code: null,
side_effect_status: "applied",
safe_next_action: "wait-for-current-attempt",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: null,
timeline: [],
};
state.operations = [{
operation_id: presentation.attemptId,
action: "network.provision",
status: "succeeded",
idempotency_key: presentation.idempotencyKey,
}];
state.physical_command = {
status: "unresolved",
reason_code: "physical-command-reconciliation-required",
requires_reconciliation: true,
resolved_active_recovery_required: false,
automatic_replay_allowed: false,
runtime_bound: true,
reconciliation_ready: true,
observed_session_state: "scan_stopping",
active_operation_id: "older-stop-operation",
record: {
revision: 306,
operation_id: "older-stop-operation",
action: "stop",
stage: "observing",
resolution: null,
connection: {
transport_ref: presentation.deviceId,
connection_mode: "quick-connect",
target_ipv4: "192.168.56.1",
},
},
};
assert.equal(isConnectionControlBootstrapSettling(state), true);
const markup = renderProvisioningWithAttempt({
controller: provisioningController(state),
desiredMode: "bridge",
}, presentation);
assert.match(markup, /Подтверждение подключения…/);
assert.match(markup, /Настройки переданы один раз/);
assert.match(markup, /<span>02<\/span>/);
assert.match(markup, /nodedc-activity-indicator/);
assert.doesNotMatch(markup, /Прежнее подключение не подтверждено/);
assert.doesNotMatch(markup, />Переподключиться<\/button>/);
assert.doesNotMatch(markup, />Подключить новый K1<\/button>/);
assert.equal(isConnectionControlBootstrapSettling({
...state,
connection_attempt: {
...state.connection_attempt,
status: "succeeded",
safe_next_action: "verify-control-read-only",
},
}), true);
assert.equal(isConnectionControlBootstrapSettling({
...state,
connection_attempt: {
...state.connection_attempt,
status: "failed",
control_state: "control_not_ready",
safe_next_action: "manual-recovery-required",
},
}), false);
});
test("Apply spends secret state before I/O and never stores a password in its presentation latch", () => {
const source = readFileSync(provisioningSourceUrl, "utf8");
const presentationType = sourceSlice(
source,
"export interface ProvisioningAttemptPresentation",
"export function emptyProvisioningAttemptPresentation",
);
const apply = sourceSlice(source, "const submitConnect", "const verifyAppliedNetwork");
assert.doesNotMatch(presentationType, /password\s*:/i);
assert.ok(apply.indexOf('setPassword("")') < apply.indexOf("await connect("));
assert.ok(apply.indexOf("setExplicitProvisioningDraft(null)") < apply.indexOf("await connect("));
assert.match(apply, /const attemptedPassword = password/);
assert.match(apply, /value|password/);
assert.match(source, /\|\| connectionAttemptSettling[\s\S]*?\|\| connectionAttemptFailed/);
assert.match(source, /icon=\{<ActivityIndicator \/>\}[\s\S]*?disabled/);
});
test("terminal Apply recovery is bounded and never claims that the network is ready", () => {
const presentation = provisioningAttemptPresentation({
localPhase: "settling",
attemptId: "network-operation-one",
});
const state = durableTopologyState();
state.snapshot_runtime_id = presentation.snapshotRuntimeId;
state.connection_attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: presentation.attemptId,
connection_mode: "bridge",
status: "failed",
phase: "network_applied",
control_state: "control_not_ready",
stage: "host-route-and-control-endpoint",
public_error_code: "control-bootstrap-failed",
side_effect_status: "network-applied",
safe_next_action: "manual-recovery-required",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: OBSERVED_AT,
timeline: [],
};
state.operations = [{
operation_id: presentation.attemptId,
action: "network.provision",
status: "failed",
idempotency_key: presentation.idempotencyKey,
}];
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: [],
actions: {},
};
const markup = renderProvisioningWithAttempt({
controller: provisioningController(state),
desiredMode: "bridge",
}, presentation);
assert.match(markup, /Сохранённое подключение/);
assert.match(markup, /Подключить заново/);
assert.equal(
buttonMarkupWithText(markup, "Подключить новый K1").length,
1,
);
assert.doesNotMatch(
markup,
/Управление не подтверждено|выбор заблокирован|Попытка настройки завершена/,
);
assert.doesNotMatch(markup, /Сеть (?:готова|настроена)|Сетевые настройки уже применены/);
assert.doesNotMatch(markup, /Пароль передан|FIELD-NET|>Применить</);
assert.doesNotMatch(markup, /aria-busy="true"/);
});
test("correlated terminal recovery resets before exposing a separate clean Scan", async () => {
const state = terminalConnectionRecoveryState({
phase: "network_not_applied",
safeNextAction: "scan-select-connect",
includeConfiguredTarget: true,
});
// A proven pre-dispatch failure must follow its exact Scan recovery instead
// of borrowing an older durable K1 observation that is still policy-visible.
state.connection_policy.recommended_action = "scan-ble";
const presentation = provisioningAttemptPresentation({
snapshotRuntimeId: state.snapshot_runtime_id,
attemptId: state.connection_attempt.attempt_id,
localPhase: "failed",
failureMessage: "Результат отправки неизвестен.",
freshStartAllowed: false,
});
const exactCorrelation = {
action: "connect",
runtimeId: state.snapshot_runtime_id,
leaseGeneration: 0,
connectionAttemptId: state.connection_attempt.attempt_id,
};
let resetCalls = 0;
let scanCalls = 0;
let resetRequest = null;
let markResetDispatched;
const resetDispatched = new Promise((resolve) => {
markResetDispatched = resolve;
});
const controller = {
...provisioningController(state),
error: "private transport exception must stay hidden",
errorDiagnostic: null,
errorCorrelation: exactCorrelation,
refresh: async () => state,
clearError() {},
selectConnectionMode: async (request) => {
resetCalls += 1;
resetRequest = request;
markResetDispatched();
return true;
},
scanWithResult: async () => {
scanCalls += 1;
return { succeeded: false };
},
};
const markup = renderProvisioningWithAttempt({
controller,
desiredMode: "bridge",
}, presentation);
assert.match(markup, /Подключение не завершено/);
assert.match(markup, /<details class="error-banner__details">/);
assert.doesNotMatch(markup, /<details[^>]*\sopen/);
assert.equal(
buttonMarkupWithText(markup, "Подключить новый K1").length,
1,
);
assert.equal(
buttonMarkupWithText(markup, "Проверить прежнее подключение").length,
0,
);
assert.doesNotMatch(markup, /Проверить состояние|>Закрыть<\/button>/);
assert.doesNotMatch(markup, /Выбрать другое|Пароль Wi‑Fi|Пароль передан|>Применить</);
assert.doesNotMatch(markup, /<span>02<\/span>|private transport exception/);
const busyMarkup = renderProvisioningWithAttempt({
controller: {
...controller,
pendingAction: "mode",
},
desiredMode: "bridge",
}, presentation);
const busyReset = buttonMarkupWithText(
busyMarkup,
"Подключить новый K1",
)[0];
assert.ok(busyReset);
assert.match(busyReset, /\bdisabled(?:=|\s|>)/);
const tree = captureProvisioningTreeWithAttempt({
controller,
desiredMode: "bridge",
}, presentation);
const errorSurface = elementByProp(
tree,
"title",
"Подключение не завершено",
);
assert.ok(errorSurface);
const resetAction = actionByLabel(
errorSurface.props.recoveryActions,
"Подключить новый K1",
);
assert.ok(resetAction);
resetAction.props.onClick();
await Promise.race([
resetDispatched,
new Promise((_, reject) => setTimeout(
() => reject(new Error("terminal recovery did not dispatch scenario reset")),
100,
)),
]);
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(resetCalls, 1);
assert.deepEqual(
{
connection_mode: resetRequest.connection_mode,
expected_revision: resetRequest.expected_revision,
reset_scenario: resetRequest.reset_scenario,
},
{
connection_mode: "bridge",
expected_revision: state.desired_connection_mode_revision,
reset_scenario: true,
},
);
assert.equal(typeof resetRequest.reset_id, "string");
assert.ok(resetRequest.reset_id.length > 0);
assert.equal(scanCalls, 0);
const cleanState = structuredClone(state);
cleanState.connection_attempt = null;
cleanState.operations = [];
cleanState.desired_connection_mode_revision += 1;
cleanState.connection_scenario_reset = {
reset_id: resetRequest.reset_id,
request_revision: state.desired_connection_mode_revision,
revision: cleanState.desired_connection_mode_revision,
desired_mode: "bridge",
active: false,
settled_by_discovery_generation: cleanState.ble_discovery_generation,
local_session_closed: true,
previous_device_may_continue_scanning: false,
physical_disposition: null,
network_disposition: null,
device_command_performed: false,
network_write_performed: false,
automatic_scan: false,
operation_sequence: 9,
};
const cleanMarkup = renderProvisioning({
controller: provisioningController(cleanState),
desiredMode: "bridge",
});
const cleanScan = buttonMarkupWithText(cleanMarkup, "Найти по Bluetooth");
assert.equal(cleanScan.length, 1);
assert.doesNotMatch(cleanScan[0], /\bdisabled(?:=|\s|>)/);
assert.equal(
buttonMarkupWithText(cleanMarkup, "Подключить новый K1").length,
0,
);
assert.equal(scanCalls, 0);
const deniedState = terminalConnectionRecoveryState({
phase: "network_not_applied",
safeNextAction: "scan-select-connect",
includeConfiguredTarget: false,
includeScan: false,
});
const deniedMarkup = renderProvisioningWithAttempt({
controller: {
...provisioningController(deniedState),
error: "denied",
errorCorrelation: {
...exactCorrelation,
runtimeId: deniedState.snapshot_runtime_id,
connectionAttemptId: deniedState.connection_attempt.attempt_id,
},
refresh: async () => deniedState,
clearError() {},
},
desiredMode: "bridge",
}, {
...presentation,
snapshotRuntimeId: deniedState.snapshot_runtime_id,
attemptId: deniedState.connection_attempt.attempt_id,
});
assert.equal(
buttonMarkupWithText(deniedMarkup, "Подключить новый K1").length,
1,
);
const source = readFileSync(provisioningSourceUrl, "utf8");
const search = sourceSlice(source, "const repeatDeviceScan", "const submitConnect");
const actions = sourceSlice(
source,
"const connectionRecoveryActions",
"return (",
);
assert.equal((search.match(/scanWithResult\(/g) ?? []).length, 1);
assert.match(
search,
/isConnectionPolicyActionAllowedCurrent\("scan-ble"\)/,
);
assert.match(
actions,
/changeDesiredConnectionMode\(connectionMode\)/,
);
assert.doesNotMatch(
actions,
/repeatDeviceScan\(|scanWithResult\(|xgridsK1Api|\.scanBle\(/,
);
});
test("unknown and cold durable recovery offer one reconnect and one new-device path", () => {
const state = terminalConnectionRecoveryState();
const target = recommendedConnectionRecoveryObservationTarget(state);
assert.equal(target?.action, "observe-configured-device-network");
const presentation = provisioningAttemptPresentation({
snapshotRuntimeId: state.snapshot_runtime_id,
attemptId: state.connection_attempt.attempt_id,
localPhase: "failed",
failureMessage: "Результат отправки неизвестен.",
freshStartAllowed: false,
});
const controller = {
...provisioningController(state),
error: "hidden",
errorDiagnostic: null,
errorCorrelation: {
action: "connect",
runtimeId: state.snapshot_runtime_id,
leaseGeneration: 0,
connectionAttemptId: state.connection_attempt.attempt_id,
},
refresh: async () => state,
clearError() {},
getConnectionRecoveryObservationTarget: () => target,
};
const markup = renderProvisioningWithAttempt({
controller,
desiredMode: "bridge",
}, presentation);
const reconnectOffset = markup.indexOf("Переподключиться");
const newDeviceOffset = markup.indexOf("Подключить новый K1");
assert.ok(reconnectOffset > 0);
assert.ok(newDeviceOffset > reconnectOffset);
assert.match(markup, /Результат применения настроек сети не подтверждён/);
assert.doesNotMatch(markup, /Настройки сети не применены/);
assert.doesNotMatch(markup, /Сеть (?:готова|настроена)|>Применить</);
assert.doesNotMatch(markup, /<span>02<\/span>/);
const coldState = structuredClone(state);
coldState.connection_attempt = null;
const coldTarget = recommendedConnectionRecoveryObservationTarget(coldState);
const coldMarkup = renderProvisioning({
controller: {
...provisioningController(coldState),
getConnectionRecoveryObservationTarget: () => coldTarget,
},
desiredMode: "bridge",
});
const coldReconnectOffset = coldMarkup.indexOf("Переподключиться");
const coldNewDeviceOffset = coldMarkup.indexOf("Подключить новый K1");
assert.ok(coldReconnectOffset > 0);
assert.ok(coldNewDeviceOffset > coldReconnectOffset);
assert.doesNotMatch(coldMarkup, /Локальная операция завершилась ошибкой/);
assert.doesNotMatch(coldMarkup, /<span>02<\/span>|>Применить</);
const coldQuickState = structuredClone(coldState);
coldQuickState.connection_policy.actions[
"observe-configured-device-network"
].required_connection_mode = "quick-connect";
const coldQuickTarget = recommendedConnectionRecoveryObservationTarget(
coldQuickState,
);
const coldQuickMarkup = renderProvisioning({
controller: {
...provisioningController(coldQuickState),
getConnectionRecoveryObservationTarget: () => coldQuickTarget,
},
desiredMode: "quick-connect",
});
const coldQuickReconnect = buttonMarkupWithText(
coldQuickMarkup,
"Переподключиться",
)[0];
assert.ok(coldQuickReconnect);
assert.doesNotMatch(coldQuickReconnect, /\bdisabled(?:=|\s|>)/);
assert.equal(
buttonMarkupWithText(coldQuickMarkup, "Подключить новый K1").length,
1,
);
assert.match(coldQuickMarkup, /Quick Connect/);
const quickTargetInsideBridgeMarkup = renderProvisioning({
controller: {
...provisioningController(coldQuickState),
getConnectionRecoveryObservationTarget: () => coldQuickTarget,
},
desiredMode: "bridge",
});
assert.equal(
buttonMarkupWithText(
quickTargetInsideBridgeMarkup,
"Переподключиться",
).length,
0,
);
assert.equal(
buttonMarkupWithText(
quickTargetInsideBridgeMarkup,
"Найти по Bluetooth",
).length,
1,
);
assert.doesNotMatch(
quickTargetInsideBridgeMarkup,
/Сохранённое подключение/,
);
const unrelatedMarkup = renderProvisioningWithAttempt({
controller: {
...controller,
errorCorrelation: { ...controller.errorCorrelation, action: "scan" },
},
desiredMode: "bridge",
}, presentation);
assert.doesNotMatch(unrelatedMarkup, /op-b7ea404d/);
assert.match(unrelatedMarkup, /Сохранённое подключение/);
});
test("saved Bridge reconnect stays hidden in a fresh Quick Connect draft", () => {
const state = terminalConnectionRecoveryState();
state.connection_attempt = null;
const bridgeTarget = recommendedConnectionRecoveryObservationTarget(state);
assert.equal(bridgeTarget?.connectionMode, "bridge");
const controller = {
...provisioningController(state),
getConnectionRecoveryObservationTarget: () => bridgeTarget,
};
const quickConnectMarkup = renderProvisioning({
controller,
desiredMode: "quick-connect",
});
assert.equal(
buttonMarkupWithText(quickConnectMarkup, "Переподключиться").length,
0,
);
assert.equal(
buttonMarkupWithText(quickConnectMarkup, "Найти по Bluetooth").length,
1,
);
assert.doesNotMatch(quickConnectMarkup, /Сохранённое подключение/);
const bridgeMarkup = renderProvisioning({
controller,
desiredMode: "bridge",
});
assert.equal(
buttonMarkupWithText(bridgeMarkup, "Переподключиться").length,
1,
);
assert.match(bridgeMarkup, /Сохранённое подключение/);
});
test("read-only reconnect keeps its card and loader across a transient projection", async () => {
const initialState = terminalConnectionRecoveryState();
initialState.connection_attempt = null;
let currentState = initialState;
let resolveVerification;
let markVerificationStarted;
const verificationStarted = new Promise((resolve) => {
markVerificationStarted = resolve;
});
const controller = {
...provisioningController(initialState),
verifyConnection: async () => {
markVerificationStarted();
return new Promise((resolve) => {
resolveVerification = resolve;
});
},
getConnectionRecoveryObservationTarget: () =>
recommendedConnectionRecoveryObservationTarget(currentState),
isSnapshotRuntimeCurrent: (runtimeId) =>
runtimeId === currentState.snapshot_runtime_id,
};
const props = () => ({
controller: { ...controller, state: currentState },
desiredMode: "bridge",
});
const harness = createStatefulProvisioningHarness(props());
try {
let tree = harness.render(props());
const reconnect = actionByLabel(tree, "Переподключиться");
assert.ok(reconnect);
reconnect.props.onClick();
await Promise.race([
verificationStarted,
new Promise((_, reject) => setTimeout(
() => reject(new Error("read-only reconnect did not dispatch")),
100,
)),
]);
const runningVerificationState = structuredClone(initialState);
runningVerificationState.connection_attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: "verify-saved-k1-running",
connection_mode: "bridge",
status: "running",
phase: "network_applied",
control_state: "unknown",
stage: "host-route-and-control-endpoint",
public_error_code: null,
side_effect_status: "network-applied",
safe_next_action: "wait-for-current-attempt",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: null,
timeline: [],
};
currentState = runningVerificationState;
tree = harness.render(props());
const runningMarkup = renderToStaticMarkup(tree);
const runningReconnect = buttonMarkupWithText(
runningMarkup,
"Переподключение…",
);
assert.equal(runningReconnect.length, 1);
assert.match(runningReconnect[0], /disabled/);
assert.match(runningReconnect[0], /aria-busy="true"/);
assert.match(runningReconnect[0], /nodedc-activity-indicator/);
assert.match(runningMarkup, /Сохранённое подключение/);
assert.doesNotMatch(runningMarkup, /Команда настройки завершена/);
assert.doesNotMatch(runningMarkup, /Подтверждение управления/);
const transientState = structuredClone(initialState);
transientState.connection_policy.allowed_actions =
transientState.connection_policy.allowed_actions.filter(
(action) => action !== "observe-configured-device-network",
);
delete transientState.connection_policy.actions[
"observe-configured-device-network"
];
currentState = transientState;
tree = harness.render(props());
const pendingMarkup = renderToStaticMarkup(tree);
const pendingReconnect = buttonMarkupWithText(
pendingMarkup,
"Переподключение…",
);
assert.equal(pendingReconnect.length, 1);
assert.match(pendingReconnect[0], /disabled/);
assert.match(pendingReconnect[0], /aria-busy="true"/);
assert.match(pendingReconnect[0], /nodedc-activity-indicator/);
assert.match(pendingMarkup, /Сохранённое подключение/);
assert.doesNotMatch(pendingMarkup, /connection-action-progress/);
assert.equal(
harness.stateValue(emptyReadOnlyReconnectPresentation)?.kind,
"connection",
);
currentState = initialState;
resolveVerification({
succeeded: false,
reconciliationCompleted: false,
observedState: initialState,
});
await new Promise((resolve) => setTimeout(resolve, 0));
tree = harness.render(props());
const failedMarkup = renderToStaticMarkup(tree);
const retry = buttonMarkupWithText(failedMarkup, "Переподключиться");
assert.equal(retry.length, 1);
assert.doesNotMatch(retry[0], /disabled|aria-busy="true"/);
assert.match(failedMarkup, /Проверьте питание и сеть, затем повторите проверку/);
assert.equal(harness.stateValue(emptyReadOnlyReconnectPresentation), null);
} finally {
harness.dispose();
}
});
test("cold saved target keeps fast reconnect after a reset and reload", async () => {
const state = terminalConnectionRecoveryState();
state.connection_attempt = null;
const target = recommendedConnectionRecoveryObservationTarget(state);
assert.ok(target);
const resetRequests = [];
let scanCalls = 0;
let verifyCalls = 0;
let connectCalls = 0;
let markResetDispatched;
const resetDispatched = new Promise((resolve) => {
markResetDispatched = resolve;
});
const controller = {
...provisioningController(state),
getConnectionRecoveryObservationTarget: () => target,
selectConnectionMode: async (request) => {
resetRequests.push(request);
markResetDispatched();
return true;
},
scanWithResult: async () => {
scanCalls += 1;
return { succeeded: false };
},
verifyConnection: async () => {
verifyCalls += 1;
return { succeeded: false };
},
connect: async () => {
connectCalls += 1;
return { succeeded: false };
},
};
const props = {
controller,
desiredMode: "bridge",
};
const markup = renderProvisioning(props);
const reconnect = buttonMarkupWithText(markup, "Переподключиться");
const connectNew = buttonMarkupWithText(markup, "Подключить новый K1");
assert.equal(reconnect.length, 1);
assert.equal(connectNew.length, 1);
assert.doesNotMatch(reconnect[0], /\bdisabled(?:=|\s|>)/);
assert.doesNotMatch(connectNew[0], /\bdisabled(?:=|\s|>)/);
const tree = captureProvisioningTree(props);
const resetAction = actionByLabel(tree, "Подключить новый K1");
assert.ok(resetAction);
resetAction.props.onClick();
await Promise.race([
resetDispatched,
new Promise((_, reject) => setTimeout(
() => reject(new Error("cold new-device path did not dispatch reset")),
100,
)),
]);
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(resetRequests.length, 1);
assert.deepEqual(
{
connection_mode: resetRequests[0].connection_mode,
expected_revision: resetRequests[0].expected_revision,
reset_scenario: resetRequests[0].reset_scenario,
},
{
connection_mode: "bridge",
expected_revision: state.desired_connection_mode_revision,
reset_scenario: true,
},
);
assert.equal(typeof resetRequests[0].reset_id, "string");
assert.ok(resetRequests[0].reset_id.length > 0);
assert.equal(scanCalls, 0);
assert.equal(verifyCalls, 0);
assert.equal(connectCalls, 0);
const reloaded = structuredClone(state);
reloaded.desired_connection_mode_revision += 1;
reloaded.connection_scenario_reset = {
reset_id: resetRequests[0].reset_id,
request_revision: state.desired_connection_mode_revision,
revision: reloaded.desired_connection_mode_revision,
desired_mode: "bridge",
active: false,
settled_by_discovery_generation: reloaded.ble_discovery_generation,
local_session_closed: true,
previous_device_may_continue_scanning: false,
physical_disposition: null,
network_disposition: null,
device_command_performed: false,
network_write_performed: false,
automatic_scan: false,
operation_sequence: 31,
};
const reloadedMarkup = renderProvisioning({
controller: {
...provisioningController(reloaded),
getConnectionRecoveryObservationTarget: () =>
recommendedConnectionRecoveryObservationTarget(reloaded),
},
desiredMode: "bridge",
});
const reloadedReconnect = buttonMarkupWithText(
reloadedMarkup,
"Переподключиться",
);
assert.equal(reloadedReconnect.length, 1);
assert.doesNotMatch(reloadedReconnect[0], /\bdisabled(?:=|\s|>)/);
const cleanScan = buttonMarkupWithText(reloadedMarkup, "Найти по Bluetooth");
assert.equal(cleanScan.length, 1);
assert.doesNotMatch(cleanScan[0], /\bdisabled(?:=|\s|>)/);
assert.match(reloadedMarkup, /Сохранённое подключение/);
assert.match(reloadedMarkup, /Можно переподключиться/);
assert.doesNotMatch(reloadedMarkup, /Подключить новый K1/);
});
test("a current post-reset failed or unknown attempt outranks the durable reset marker after reload", () => {
const withSettledReset = (state) => {
state.desired_connection_mode_revision = 1;
state.connection_scenario_reset = {
reset_id: "reset-before-new-attempt",
request_revision: 0,
revision: 1,
desired_mode: "bridge",
active: false,
settled_by_discovery_generation: state.ble_discovery_generation,
local_session_closed: true,
previous_device_may_continue_scanning: false,
physical_disposition: null,
network_disposition: null,
device_command_performed: false,
network_write_performed: false,
automatic_scan: false,
// Operation sequence is per operation, not a global chronology. The new
// post-reset operation below can therefore legitimately have 3 < 6.
operation_sequence: 6,
};
state.operations = [{
operation_id: state.connection_attempt.attempt_id,
action: "network.provision",
status: "failed",
sequence: 3,
idempotency_key: "post-reset-new-network-attempt",
}];
return state;
};
const unknown = withSettledReset(terminalConnectionRecoveryState({
phase: "network_outcome_unknown",
safeNextAction: "verify-control-read-only",
}));
const unknownTarget = recommendedConnectionRecoveryObservationTarget(unknown);
assert.ok(unknownTarget);
const unknownReloadMarkup = renderProvisioning({
controller: {
...provisioningController(unknown),
getConnectionRecoveryObservationTarget: () => unknownTarget,
},
desiredMode: "bridge",
});
assert.match(unknownReloadMarkup, /Сохранённое подключение/);
assert.equal(
buttonMarkupWithText(unknownReloadMarkup, "Переподключиться").length,
1,
);
assert.equal(
buttonMarkupWithText(unknownReloadMarkup, "Подключить новый K1").length,
1,
);
assert.equal(
buttonMarkupWithText(unknownReloadMarkup, "Найти по Bluetooth").length,
0,
);
const failed = withSettledReset(terminalConnectionRecoveryState({
phase: "network_applied",
safeNextAction: "manual-recovery-required",
}));
failed.connection_attempt.control_state = "control_not_ready";
const failedReloadMarkup = renderProvisioning({
controller: provisioningController(failed),
desiredMode: "bridge",
});
assert.match(failedReloadMarkup, /Сохранённое подключение/);
assert.match(failedReloadMarkup, /Можно переподключиться/);
assert.equal(
buttonMarkupWithText(failedReloadMarkup, "Переподключиться").length,
1,
);
assert.equal(
buttonMarkupWithText(failedReloadMarkup, "Подключить новый K1").length,
1,
);
assert.doesNotMatch(
failedReloadMarkup,
/Управление не подтверждено|выбор заблокирован|Новый выбор временно заблокирован/,
);
});
test("Apply never owns hidden refresh or an automatic continuation", () => {
const source = readFileSync(provisioningSourceUrl, "utf8");
const apply = sourceSlice(source, "const submitConnect", "const verifyAppliedNetwork");
assert.doesNotMatch(
apply,
/scanWithResult\(|candidateRefresh|verifyConnection\(|void submitConnect/,
);
});
test("stale authority is explicit and never settles a hidden refresh", () => {
const source = readFileSync(provisioningSourceUrl, "utf8");
const apply = sourceSlice(source, "const submitConnect", "const verifyAppliedNetwork");
assert.doesNotMatch(apply, /candidateRefresh|scanWithResult\(/);
assert.match(source, /устарел|stale/i);
});
test("a same-runtime authority drift keeps one neutral settling surface", () => {
const state = durableTopologyState();
const markup = renderProvisioning({
controller: {
...provisioningController(state),
pendingAction: "verify",
// A synchronous authority read has already moved beyond the click-owned
// fence while the controller is still settling its old I/O.
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: () => false,
},
desiredMode: "bridge",
});
assert.match(markup, /<span>01<\/span>/);
assert.doesNotMatch(markup, /<span>02<\/span>|<span>03<\/span>/);
assert.doesNotMatch(markup, /Завершаем ранее начатое действие…/);
assert.equal((markup.match(/class="nodedc-activity-indicator"/g) ?? []).length, 0);
assert.doesNotMatch(markup, /Проверяем сохранённое подключение…/);
assert.doesNotMatch(markup, /Подключаемся к сохранённому K1…/);
});
test("a stale reopen settlement cannot own the current wizard surface", () => {
const state = durableTopologyState();
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["scan-ble"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
const markup = renderProvisioning({
controller: {
...provisioningController(state),
pendingAction: "reopen",
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: () => false,
},
desiredMode: "bridge",
});
assert.match(markup, /<span>01<\/span>/);
assert.doesNotMatch(markup, /Подключение…|aria-busy="true"/);
assert.doesNotMatch(markup, /<span>02<\/span>|<span>03<\/span>/);
assert.match(markup, />Найти по Bluetooth<\/button>/);
const modeToggle = markup.match(
/<button[^>]*aria-label="Способ подключения"[^>]*>/,
)?.[0];
assert.ok(modeToggle);
assert.doesNotMatch(modeToggle, /\bdisabled(?:=|\s|>)/);
assertCanonicalConnectionCopy(markup);
});
test("network step 02 is disclosed only by a selected device or a real network intent", () => {
assert.equal(shouldRevealProvisioningNetworkStep({
deviceExplicitlySelectedOrAdmitted: false,
networkIntentStarted: false,
}), false);
assert.equal(shouldRevealProvisioningNetworkStep({
deviceExplicitlySelectedOrAdmitted: true,
networkIntentStarted: false,
}), true);
assert.equal(shouldRevealProvisioningNetworkStep({
deviceExplicitlySelectedOrAdmitted: false,
networkIntentStarted: true,
}), true);
});
test("a current-authority Bluetooth scan owns Step 01 and no network step", () => {
const state = reopenedPhysicalState();
state.physical_command = null;
state.connection_policy.actions["provision-fresh-device"] = {
allowed: true,
reason_codes: [],
target_source: "fresh-scan",
required_transport_ref: null,
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
};
state.connection_policy.allowed_actions.push("provision-fresh-device");
const authority = reopenedPhysicalAuthority();
const markup = renderProvisioningWithCurrentPendingAction({
controller: {
...provisioningController(state),
pendingAction: "scan",
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: (candidate) =>
connectionActionAuthorityMatches(candidate, authority),
},
desiredMode: "bridge",
});
assert.match(markup, /<span>01<\/span>/);
assert.match(markup, /Поиск Bluetooth · до 20 с/);
assert.equal(
(markup.match(/class="nodedc-activity-indicator"/g) ?? []).length,
1,
);
assert.doesNotMatch(markup, /Найдено: 0|Совпадений нет|Результатов:/);
assert.equal(
buttonMarkupWithText(markup, "Подключить новый K1").length,
0,
);
assert.doesNotMatch(markup, /<span>02<\/span>|<span>03<\/span>/);
assert.doesNotMatch(markup, /Настройка сети|Название общей сети Wi‑Fi/);
assertCanonicalConnectionCopy(markup);
});
test("stale raw Bluetooth results stay hidden until an explicit search", () => {
const state = durableTopologyState();
state.semantic_topology_store = {
...state.semantic_topology_store,
status: "empty",
configured_offline_evidence: false,
record: null,
};
state.devices = [{
device_id: "replacement-k1",
name: "Replacement K1",
rssi: -44,
connectable: true,
likely_k1: true,
}];
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["scan-ble", "provision-fresh-device"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
"provision-fresh-device": {
allowed: true,
reason_codes: [],
target_source: "fresh-scan",
required_transport_ref: null,
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
};
const markup = renderProvisioning({
controller: {
...provisioningController(state),
// The raw promise is still settling, but its click authority has already
// been retired by the completed discovery-generation transition.
pendingAction: "scan",
isSnapshotRuntimeCurrent: () => true,
isConnectionActionAuthorityCurrent: () => false,
},
desiredMode: "bridge",
});
assert.match(markup, /<span>01<\/span>/);
assert.doesNotMatch(markup, /Replacement K1/);
assert.match(markup, />Найти по Bluetooth<\/button>/);
assert.doesNotMatch(markup, /aria-busy="true"/);
assert.doesNotMatch(markup, /<span>02<\/span>|<span>03<\/span>/);
assert.doesNotMatch(markup, /Завершаем предыдущее действие|Завершаем ранее начатое действие/);
assert.doesNotMatch(markup, /Настройка сети|Сначала найдите и выберите K1/);
assertCanonicalConnectionCopy(markup);
});
test("a completed search never adopts another tab's discovery generation", () => {
const state = durableTopologyState();
state.ble_discovery_generation = 8;
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
state.devices = [{
device_id: "generation-eight-result",
name: "Generation eight",
rssi: -46,
connectable: true,
likely_k1: true,
}];
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["scan-ble"],
actions: {
"scan-ble": {
allowed: true,
reason_codes: [],
target_source: "none",
required_transport_ref: null,
required_connection_mode: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
};
const markup = renderProvisioningAfterSearch({
controller: provisioningController(state),
desiredMode: "bridge",
}, { completedDiscoveryGeneration: 7 });
assert.doesNotMatch(markup, /generation-eight-result|Generation eight/);
assert.match(markup, /Найти по Bluetooth/);
assert.doesNotMatch(markup, /Результатов:|Совпадений нет/);
assertCanonicalConnectionCopy(markup);
});
test("change-network opens credentials immediately and Apply does not refresh", () => {
const source = readFileSync(provisioningSourceUrl, "utf8");
const apply = sourceSlice(source, "const submitConnect", "const verifyAppliedNetwork");
assert.doesNotMatch(apply, /scanWithResult\(|verifyConnection\(|candidateRefresh/);
assert.equal((source.match(/buttonLabel:\s*"Применить"/g) ?? []).length, 3);
});
test("Step-2 credentials and Apply share one canonical field stack", () => {
const source = readFileSync(provisioningSourceUrl, "utf8");
const styles = readFileSync(provisioningStylesUrl, "utf8");
const form = sourceSlice(
source,
"const provisioningDraftContent = (",
"return (",
);
assert.match(
form,
/:\s*\(\s*<div className="field-stack"[\s\S]*?label="Пароль WiFi"[\s\S]*?\{applyAction\}\s*<\/div>/,
);
assert.match(form, /disabled=\{provisioningFieldsDisabled\}/);
assert.match(form, /value=\{connectionAttemptOwnsDraft \? "" : password\}/);
assert.match(
styles,
/\.field-stack,\s*\.session-form\s*\{\s*display:\s*grid;\s*gap:\s*0\.85rem;/,
);
});
test("applied-network recovery spends the old intent and admits only explicit server-authorized paths", () => {
const source = readFileSync(provisioningSourceUrl, "utf8");
const apply = sourceSlice(source, "const submitConnect", "const verifyAppliedNetwork");
const recoveryState = sourceSlice(
source,
"const appliedNetworkAttempt",
"const localProvisioningPrerequisitesReady",
);
const appliedRecoveryTarget = sourceSlice(
source,
"const appliedNetworkRecoveryTarget",
"const networkRecoveryModeLabel",
);
const connectAuthority = sourceSlice(
source,
"const canConnect",
"const scanAllowedByPolicy",
);
const scanAuthority = sourceSlice(
source,
"const backendScanAllowed",
"const physicalStopRecoverySettling",
);
const search = sourceSlice(source, "const repeatDeviceScan", "const submitConnect");
const recovery = sourceSlice(
source,
"const verifyAppliedNetwork",
"const verifyConnectionRecoveryTarget",
);
const prepare = sourceSlice(
source,
"const prepareReconfiguration",
"const changeDesiredConnectionMode",
);
const mode = sourceSlice(
source,
"const changeDesiredConnectionMode",
"const selectFreshDevice",
);
const selection = sourceSlice(
source,
"const selectFreshDevice",
"// Only an explicit public search",
);
const recoveryEscape = sourceSlice(
source,
"const recoverBySelectingAnotherDevice",
"const attemptButtonLabel",
);
assert.doesNotMatch(apply, /verifyConnection\(/);
assert.match(recoveryState, /state\?\.connection_attempt\?\.phase === "network_applied"/);
assert.match(
recoveryState,
/connectionAttemptOwnsAppliedNetworkRecovery\(appliedNetworkAttempt\)/,
);
assert.match(
recoveryState,
/`\$\{snapshotRuntimeId\}:\$\{appliedNetworkAttempt\.attempt_id\}`/,
);
assert.match(
recoveryState,
/escapedAppliedAttemptKey === appliedAttemptRecoveryKey[\s\S]*?\|\| appliedRecoveryReconfigurationPrepared/,
);
assert.match(
recoveryState,
/connectionAttemptOwnsAppliedNetworkRecovery\(appliedNetworkAttempt\)[\s\S]*?&& !appliedRecoveryExplicitlyEscaped/,
);
assert.match(recoveryState, /const networkRecoveryRequired = unresolvedAppliedAttempt !== null/);
assert.match(
recoveryState,
/const appliedControlSettlementPending = Boolean\([\s\S]*?\["accepted", "running"\]\.includes\(unresolvedAppliedAttempt\.status\)[\s\S]*?safe_next_action === "wait-for-current-attempt"/,
);
assert.doesNotMatch(
appliedRecoveryTarget,
/\bconnectionMode\b|selectedDeviceId|selectedTarget/,
);
assert.match(
appliedRecoveryTarget,
/serverBoundAppliedNetworkObservationTarget\(\s*state,\s*unresolvedAppliedAttempt\.connection_mode/,
);
assert.match(connectAuthority, /!unresolvedAppliedAttempt/);
assert.match(scanAuthority, /!networkRecoveryRequired/);
assert.match(apply, /\|\| unresolvedAppliedAttempt/);
assert.match(apply, /provisioningIntentKey\(null\)/);
assert.match(mode, /if \(modeResetInFlight\) return/);
assert.match(mode, /reset_scenario: true/);
assert.match(selection, /networkRecoveryRequired\s*\|\|/);
assert.doesNotMatch(
source,
/powerConfirmed|powerConfirmationEpoch|resetPowerConfirmation|Питание включено|title="Питание"/,
);
assert.match(source, /value=\{connectionMode\}[\s\S]*?onChange=\{\(value\) => void changeDesiredConnectionMode\(value\)\}/);
assert.match(
sourceSlice(source, "<Select\n label=\"Способ подключения\"", "<Button"),
/disabled=\{modeResetInFlight\}/,
);
assert.match(recovery, /appliedNetworkRecoveryTarget/);
assert.match(recovery, /appliedControlSettlementPending/);
assert.equal((recovery.match(/await verifyConnection\(/g) ?? []).length, 1);
assert.doesNotMatch(
recovery,
/selectedDeviceId|selectedTarget|selectedDeviceSnapshot|provisioningCandidateById/,
);
assert.match(
source,
/const canPrepareRecoverySelectDevice = Boolean\(\s*unresolvedAppliedAttempt\?\.connection_mode === "bridge"[\s\S]*?selectDeviceAllowedByPolicy/,
);
assert.match(
source,
/const canPrepareRecoverySelectDevice = Boolean\([\s\S]*?&& !appliedControlSettlementPending/,
);
assert.match(
recoveryEscape,
/prepareReconfiguration\("select-device", \{\s*appliedRecoveryEscape: true/,
);
assert.match(
prepare,
/const recoveryEscapeAllowed = Boolean\([\s\S]*?intent === "select-device"[\s\S]*?canPrepareRecoverySelectDevice[\s\S]*?unresolvedAppliedAttempt\?\.connection_mode === "bridge"/,
);
assert.match(prepare, /networkRecoveryRequired && !recoveryEscapeAllowed/);
assert.match(
prepare,
/if \(!promotedReconfigurationFence\) return;[\s\S]*?if \(recoveryEscapeAllowed && appliedAttemptRecoveryKey\) \{\s*setEscapedAppliedAttemptKey\(appliedAttemptRecoveryKey\)/,
);
assert.doesNotMatch(
prepare,
/scanWithResult\(|connect\(|verifyConnection\(|selectFreshDevice\(/,
);
assert.match(source, /Начать выбор другого K1/);
assert.match(
source,
/const canScanAppliedRecovery = Boolean\(\s*unresolvedAppliedAttempt[\s\S]*?connection_mode !== "bridge"[\s\S]*?scanAllowedByPolicy/,
);
assert.match(
search,
/const recoveryScanAttempt = appliedRecoveryEscape[\s\S]*?canScanAppliedRecovery[\s\S]*?unresolvedAppliedAttempt/,
);
assert.match(search, /scanResult = await scanWithResult\(\{ durationSeconds: BLE_DISCOVERY_TIMEOUT_SECONDS \}\)/);
assert.match(
search,
/if \(scanResult\.succeeded && recoveryAttemptKey\) \{\s*setEscapedAppliedAttemptKey\(recoveryAttemptKey\)/,
);
assert.equal((search.match(/setEscapedAppliedAttemptKey\(/g) ?? []).length, 1);
assert.match(
source,
/onClick=\{\(\) => void repeatDeviceScan\(\{\s*appliedRecoveryEscape: true/,
);
assert.match(source, /Начать новый поиск Bluetooth/);
assert.match(source, /Подтверждение управляющего подключения/);
assert.match(source, /BLE-команда не повторяется/);
assert.match(
source,
/status=\{\s*searchActive[\s\S]*?: presentedPhysicalRecoveryRequired[\s\S]*?: presentedConnectionRecoveryRequired[\s\S]*?: networkRecoveryRequired/,
);
assert.match(
source,
/networkRecoveryRequired\s*&& !connectionAttemptSettling\s*&& !connectionRecoveryVerificationPending \? \(/,
);
assert.match(
source,
/if \(!appliedNetworkAttempt\) return;[\s\S]*?setExplicitProvisioningDraft\(null\);[\s\S]*?setSsid\(""\);[\s\S]*?setPassword\(""\)/,
);
const appliedAttemptEffect = sourceSlice(
source,
"if (!appliedNetworkAttempt) return;",
"if (connectionAttemptView !== \"retired\") return;",
);
assert.doesNotMatch(appliedAttemptEffect, /setConnectionAttemptPresentation\(null\)/);
assert.doesNotMatch(apply, /void submitConnect|repeatDeviceScan\(/);
const settlingState = durableTopologyState();
settlingState.connection_attempt = {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
attempt_id: "network-apply-settling",
connection_mode: "bridge",
status: "running",
phase: "network_applied",
control_state: "unknown",
stage: "host-route-and-control-endpoint",
public_error_code: null,
side_effect_status: "none",
safe_next_action: "wait-for-current-attempt",
automatic_retry: false,
accepted_at: OBSERVED_AT,
completed_at: null,
recovery_operation_id: null,
timeline: [],
};
const settlingMarkup = renderProvisioning({
controller: provisioningController(settlingState),
desiredMode: "bridge",
});
assert.match(settlingMarkup, /Подтверждение управляющего подключения/);
assert.match(settlingMarkup, /BLE-команда не повторяется/);
assert.doesNotMatch(settlingMarkup, /Сеть (?:готова|настроена)|Сетевые настройки уже применены/);
assert.equal(
(settlingMarkup.match(/class="connection-action-progress"/g) ?? []).length,
1,
);
assert.doesNotMatch(
settlingMarkup,
/Проверить подключение без изменения сети|Начать выбор другого K1|Начать новый поиск Bluetooth/,
);
});
test("incomplete historical recovery policy stays outside the normal connection form", () => {
const state = durableTopologyState();
state.network_mutation_ledger = {
...state.network_mutation_ledger,
status: "unresolved",
mutation_allowed: false,
operation_id: "operation-002",
transport_ref: "ble-k1-001",
intended_mode: "bridge",
stage: "observing",
revision: 6,
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: ["observe-configured-device-network"],
actions: {
"observe-configured-device-network": {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: "ble-k1-001",
required_connection_mode: null,
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
recommended_action: "observe-configured-device-network",
};
const markup = renderProvisioning({
controller: provisioningController(state),
desiredMode: "bridge",
});
assert.doesNotMatch(markup, /Сервер пока не выдал одну точную цель/);
assert.doesNotMatch(markup, /не подменяют UUID и режим незавершённой операции/);
assert.doesNotMatch(markup, /Проверить .*без записи/);
assert.equal(
buttonMarkupWithText(markup, "Подключиться к сохранённому устройству").length,
0,
);
assert.doesNotMatch(markup, /class="connection-action-progress"/);
assert.doesNotMatch(markup, /Проверить связь/);
assert.doesNotMatch(markup, /Подключить K1 к общей сети/);
});
test("configured endpoint policy explains missing durable evidence without implying BLE", () => {
const state = durableTopologyState();
state.semantic_topology_store = {
status: "empty",
configured_offline_evidence: false,
live_connection_authority: false,
reason_code: null,
record: null,
};
state.connection_policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
facts: { retained_context_is_presence: false },
allowed_actions: [],
actions: {
"inspect-configured-endpoint": {
allowed: false,
reason_codes: ["configured-endpoint-unavailable"],
target_source: "configured-topology",
required_transport_ref: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
recommended_action: "inspect-host-network",
};
const guidance = connectionPolicyOperatorGuidance(
state,
"inspect-configured-endpoint",
);
assert.match(guidance.reason, /Нет подтверждённого сохранённого адреса K1/);
assert.match(guidance.nextAction, /Проверьте активную локальную сеть/);
assert.doesNotMatch(`${guidance.reason} ${guidance.nextAction}`, /Bluetooth|BLE/);
});
test("spatial controls distinguish control authority from data authority", () => {
const live = runtimeState();
assert.deepEqual(k1SpatialAuthorityState(live), {
controlAuthoritative: true,
dataAuthoritative: true,
softwareCommanded: true,
authorityFailure: null,
});
live.connection_supervisor = supervisor({ control: true, data: false });
const waiting = k1SpatialAuthorityState(live);
assert.equal(waiting.controlAuthoritative, true);
assert.equal(waiting.dataAuthoritative, false);
assert.equal(waiting.softwareCommanded, true);
assert.match(waiting.authorityFailure, /Телеметрия скрыта/);
live.connection_supervisor = supervisor({ control: false, data: false });
const lost = k1SpatialAuthorityState(live);
assert.equal(lost.controlAuthoritative, false);
assert.equal(lost.dataAuthoritative, false);
assert.equal(lost.softwareCommanded, false);
assert.match(lost.authorityFailure, /команды устройству запрещены/);
});
test("spatial controls explain the bounded K1 calibration wait before point data", () => {
const acquisition = runtimeState().acquisition;
assert.ok(acquisition);
for (const state of ["awaiting_external_start", "starting"]) {
const phase = k1SpatialPhasePresentation({ ...acquisition, state }, true);
assert.equal(phase.busy, true);
assert.match(phase.label, /калибруется.*облако точек/i);
assert.match(phase.detail, /десятки секунд/i);
assert.match(phase.detail, /не перемещайте/i);
assert.doesNotMatch(phase.detail, /30\s*с/i);
}
});
test("contour health never promotes selection or replay metrics to live authority", () => {
const selectedOnly = {
phase: "starting",
sourceMode: "idle",
activeDevice: {
pluginId: "xgrids-k1",
modelId: "lixelkity-k1",
displayName: "XGRIDS LixelKity K1",
instanceId: "device-k1-001",
endpointLabel: "192.168.68.52",
},
deviceSession: {
sessionId: "device-session-001",
deviceId: "device-k1-001",
compatibilityProfileId: PROFILE_ID,
connectivity: "unknown",
},
metrics: { aiFrameRateHz: 8 },
};
const unverified = contourRuntimeAuthorityPresentation(selectedOnly);
assert.equal(unverified.controlledDevice, null);
assert.equal(unverified.aiActive, false);
const live = contourRuntimeAuthorityPresentation({
...selectedOnly,
phase: "streaming",
sourceMode: "live",
deviceSession: { ...selectedOnly.deviceSession, connectivity: "connected" },
});
assert.equal(live.controlledDevice.instanceId, "device-k1-001");
assert.equal(live.aiActive, true);
const replay = contourRuntimeAuthorityPresentation({
...selectedOnly,
phase: "replaying",
sourceMode: "replay",
deviceSession: { ...selectedOnly.deviceSession, connectivity: "connected" },
});
assert.equal(replay.aiActive, false);
});
test("the recovery panel explains the reviewed K1 network-not-found reply", () => {
const state = terminalConnectionRecoveryState();
state.connection_attempt.public_error_code = "k1-wifi-network-not-found";
const markup = renderToStaticMarkup(createElement(K1OperatorError, {
attempt: state.connection_attempt, onRefresh() {}, onClear() {},
}));
assert.match(markup, /K1 не смог найти указанную сеть Wi‑Fi/);
assert.match(markup, /точное название сети/);
assert.doesNotMatch(markup, /ошибкой Bluetooth|INVALID_PDU/);
});
test("a reviewed Wi-Fi rejection offers explicit network setup for the same K1", () => {
const state = terminalConnectionRecoveryState();
state.connection_attempt.public_error_code = "k1-wifi-network-not-found";
const controller = {
...provisioningController(state), error: "private transport error",
errorCorrelation: {
action: "connect", runtimeId: state.snapshot_runtime_id, leaseGeneration: 0,
connectionAttemptId: state.connection_attempt.attempt_id,
},
getConnectionRecoveryObservationTarget: () => recommendedConnectionRecoveryObservationTarget(state),
};
const markup = renderProvisioningWithAttempt({ controller, desiredMode: "bridge" },
provisioningAttemptPresentation({ snapshotRuntimeId: state.snapshot_runtime_id,
attemptId: state.connection_attempt.attempt_id, localPhase: "failed" }), true);
assert.equal(buttonMarkupWithText(markup, "Указать сеть Wi‑Fi заново").length, 1);
assert.doesNotMatch(markup, /Подключить новый K1|private transport error/);
});
test("a failed Connect after completed Bluetooth search exposes recovery instead of a locked form", () => {
const state = terminalConnectionRecoveryState();
state.ble_discovery_generation = 6;
state.connection_attempt.public_error_code = "BleakGATTProtocolError";
state.connection_attempt.stage = "gatt-write-failed";
const controller = {
...provisioningController(state),
error: "private transport exception must stay hidden",
errorCorrelation: {
action: "connect", runtimeId: state.snapshot_runtime_id, leaseGeneration: 0,
connectionAttemptId: state.connection_attempt.attempt_id,
},
getConnectionRecoveryObservationTarget: () => recommendedConnectionRecoveryObservationTarget(state),
};
const markup = renderProvisioningWithAttempt({ controller, desiredMode: "bridge" },
provisioningAttemptPresentation({ snapshotRuntimeId: state.snapshot_runtime_id,
attemptId: state.connection_attempt.attempt_id, localPhase: "failed" }), true);
assert.equal(buttonMarkupWithText(markup, "Переподключиться").length, 1);
assert.equal(buttonMarkupWithText(markup, "Подключить новый K1").length, 1);
assert.match(markup, /K1 ответил ошибкой Bluetooth/);
assert.doesNotMatch(markup, /Подключение не выполнено|дождитесь, пока система|private transport exception|Пароль передан/);
});