Files
NODEDC_MISSION_CORE/apps/control-station/test/devicePluginContracts.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

4259 lines
145 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
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 { readFile } from "node:fs/promises";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let parseDevicePluginManifest;
let createDevicePluginRegistry;
let xgridsK1Manifest;
let xgridsK1Actions;
let xgridsK1Api;
let ApiError;
let localizeRuntimeMessage;
let lifecycle;
let projectName;
let automaticSourceStart;
let presentation;
let operatorIntentGeneration;
let configuration;
let compatibility;
let networkProvisionFailureMessage;
let awaitNetworkProvisionSettlementAfterLostResponse;
let discoveryScanFailureMessage;
let connectionVerificationFailureMessage;
let operationById;
let physicalCommandConfirmation;
let controlSessionCas;
let ApiRequestTimeoutError;
let requestTimeoutMsForAction;
let isXgridsConnectionVerification;
let isXgridsConnectionReconfiguration;
let isXgridsConnectionPolicy;
let isXgridsConnectionPolicyDecision;
let isXgridsHostFailureDiagnostic;
let XGRIDS_CONNECTION_VERIFICATION_STATUSES;
let XGRIDS_CONNECTION_VERIFICATION_LEASE_STATES;
let XGRIDS_CONNECTION_POLICY_ACTIONS;
let XGRIDS_CONNECTION_POLICY_TARGET_SOURCES;
let XGRIDS_CONNECTION_ATTEMPT_PHASES;
let isXgridsConnectionAttemptPhase;
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({ parseDevicePluginManifest } = await server.ssrLoadModule(
"/src/core/device-plugins/manifestParser.ts",
));
({ createDevicePluginRegistry } = await server.ssrLoadModule(
"/src/core/device-plugins/registry.ts",
));
({ xgridsK1Manifest, xgridsK1Actions } = await server.ssrLoadModule(
"@xgrids-k1/frontend/manifest.ts",
));
lifecycle = await server.ssrLoadModule(
"@xgrids-k1/frontend/lifecycle.ts",
);
projectName = await server.ssrLoadModule(
"@xgrids-k1/frontend/projectName.ts",
);
automaticSourceStart = await server.ssrLoadModule(
"@xgrids-k1/frontend/automaticSourceStart.ts",
);
presentation = await server.ssrLoadModule(
"@xgrids-k1/frontend/presentation.ts",
);
operatorIntentGeneration = await server.ssrLoadModule(
"@xgrids-k1/frontend/operatorIntentGeneration.ts",
);
configuration = await server.ssrLoadModule(
"@xgrids-k1/frontend/configuration.ts",
);
compatibility = await server.ssrLoadModule(
"@xgrids-k1/frontend/compatibility.ts",
);
({
xgridsK1Api,
ApiError,
ApiRequestTimeoutError,
requestTimeoutMsForAction,
isXgridsConnectionVerification,
isXgridsConnectionReconfiguration,
isXgridsConnectionPolicy,
isXgridsConnectionPolicyDecision,
isXgridsHostFailureDiagnostic,
XGRIDS_CONNECTION_VERIFICATION_STATUSES,
XGRIDS_CONNECTION_VERIFICATION_LEASE_STATES,
XGRIDS_CONNECTION_POLICY_ACTIONS,
XGRIDS_CONNECTION_POLICY_TARGET_SOURCES,
XGRIDS_CONNECTION_ATTEMPT_PHASES,
isXgridsConnectionAttemptPhase,
} = await server.ssrLoadModule(
"@xgrids-k1/frontend/api.ts",
));
({ localizeRuntimeMessage } = await server.ssrLoadModule(
"@xgrids-k1/frontend/messages.ts",
));
({
networkProvisionFailureMessage,
awaitNetworkProvisionSettlementAfterLostResponse,
discoveryScanFailureMessage,
connectionVerificationFailureMessage,
operationById,
} = await server.ssrLoadModule("@xgrids-k1/frontend/useXgridsK1Runtime.ts"));
physicalCommandConfirmation = await server.ssrLoadModule(
"@xgrids-k1/frontend/physicalCommandConfirmation.ts",
);
controlSessionCas = await server.ssrLoadModule(
"@xgrids-k1/frontend/controlSessionCas.ts",
);
});
after(async () => {
await server?.close();
});
function manifestDocument({
apiVersion = "missioncore.nodedc/v1alpha1",
pluginId = "test.device.plugin",
modelId = "test.device.model",
} = {}) {
const v1alpha2 = apiVersion === "missioncore.nodedc/v1alpha2";
return {
apiVersion,
kind: "DevicePlugin",
metadata: {
id: pluginId,
version: "1.0.0",
displayName: "Test device",
},
spec: {
hostApiRange: v1alpha2 ? "v1alpha2" : "v1alpha1",
runtime: {
backendEntrypoint: "test.plugin:build",
isolation: "transitional-in-process",
},
...(v1alpha2
? {
compatibilityProfiles: [
{
profileId: `${modelId}.fw-1.v1`,
path: "profiles/fw-1/profile.v1.json",
modelId,
},
],
}
: {}),
permissions: ["device.read"],
actions: [{ id: "state.read", mutating: false, secretFields: [] }],
models: [
{
id: modelId,
vendor: "Test",
displayName: "Test model",
category: "Sensor",
description: "Fixture model",
verified: true,
capabilities: [{ id: "device.read", label: "Read" }],
ui: { slot: "device.connection", componentKey: "test.connection" },
},
],
},
};
}
function uiPlugin(manifest) {
return {
manifest,
RuntimeProvider: ({ children }) => children,
connectionViews: { "test.connection": () => null },
};
}
function supervisedConnectionState({
mode = "bridge",
leaseState = "reachable",
generation = 1,
intentId = `intent-${mode}-1`,
hostPathEpoch = 3,
target = mode === "quick-connect"
? { ipv4: "192.168.56.1", port: 1883 }
: { ipv4: "192.168.68.50", port: 1883 },
controlAllowed = leaseState === "reachable",
dataAuthoritative = false,
lastKnown = null,
deviceNetworkState = "applied",
hostAvailable = true,
endpointState = "reachable",
} = {}) {
const observedAt = "2026-08-06T12:00:00Z";
const identityVerified = leaseState === "reachable";
const connectionReady = Boolean(
controlAllowed
&& identityVerified
&& leaseState === "reachable"
&& deviceNetworkState === "applied"
&& hostAvailable
&& endpointState === "reachable",
);
return {
snapshot_runtime_id: "runtime-a",
network_write_reconciliation: null,
connection_lifecycle: {
schema_version: "missioncore.xgrids-k1-connection-lifecycle/v1",
revision: generation,
desired_mode: mode,
configured_mode: deviceNetworkState === "applied" ? mode : null,
active_mode: connectionReady ? mode : null,
mode_change: {
state: connectionReady ? "ready" : "awaiting-control",
from: deviceNetworkState === "applied" ? mode : null,
to: mode,
},
mode_selection: {
allowed: true,
reason_codes: [],
automatic_retry: false,
},
active_binding_key: connectionReady ? `binding-${intentId}-${hostPathEpoch}` : null,
active_binding: connectionReady
? {
binding_key: `binding-${intentId}-${hostPathEpoch}`,
intent_id: intentId,
transport_ref: "ble-k1-001",
connection_mode: mode,
target_ipv4: target.ipv4,
target_port: target.port,
host_path_epoch: hostPathEpoch,
control_session_id: "control-session-001",
logical_device_id: "device-k1-001",
}
: null,
connection_ready: connectionReady,
ready_to_start: connectionReady,
operation: null,
allowed_actions: connectionReady
? ["start-acquisition", "select-connection-mode"]
: ["select-connection-mode"],
automatic_retry: false,
},
connection_supervisor: {
schema_version: "missioncore.k1-connection-supervisor/v1",
revision: generation,
closed: false,
intent: {
intent_id: intentId,
requested_mode: mode,
expected_device_id: "device-k1-001",
requested_at: observedAt,
},
observed: {
device_network: {
state: deviceNetworkState,
intent_id: deviceNetworkState === "applied" ? intentId : null,
transport_ref: deviceNetworkState === "applied" ? "ble-k1-001" : null,
connection_mode: deviceNetworkState === "applied" ? mode : null,
target: deviceNetworkState === "applied" ? target : null,
source: deviceNetworkState === "applied" ? "ble-read-only-status" : null,
observed_at: deviceNetworkState === "applied" ? observedAt : null,
},
host_path: {
epoch: hostPathEpoch,
available: hostAvailable,
fingerprint: `en0:${hostPathEpoch}`,
interface: "en0",
source_ipv4: "192.168.68.10",
route_class: hostAvailable ? "direct" : "unavailable",
reason_code: null,
observed_at: observedAt,
},
endpoint: {
target,
tcp_state: endpointState,
intent_id: intentId,
host_path_epoch: hostPathEpoch,
reason_code: null,
observed_at: observedAt,
},
device_identity: {
state: identityVerified ? "verified" : "unverified",
intent_id: identityVerified ? intentId : null,
logical_device_id: identityVerified ? "device-k1-001" : null,
compatibility_profile_id: identityVerified
? "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2"
: null,
connection_mode: identityVerified ? mode : null,
source: identityVerified ? "mqtt-device-info" : null,
host_path_epoch: identityVerified ? hostPathEpoch : null,
observed_at: identityVerified ? observedAt : null,
},
control_plane: {
state: controlAllowed ? "healthy" : "idle",
session_id: controlAllowed ? "control-session-001" : null,
host_path_epoch: controlAllowed ? hostPathEpoch : null,
reason_code: null,
observed_at: controlAllowed ? observedAt : null,
},
data_plane: {
state: dataAuthoritative ? "healthy" : "idle",
session_id: dataAuthoritative ? "data-session-001" : null,
host_path_epoch: dataAuthoritative ? hostPathEpoch : null,
reason_code: null,
observed_at: dataAuthoritative ? observedAt : null,
},
},
lease: {
state: leaseState,
generation,
intent_id: intentId,
host_path_epoch: hostPathEpoch,
connection_mode: mode,
target,
logical_device_id: identityVerified ? "device-k1-001" : null,
reason_code: null,
observed_at: observedAt,
},
authority: {
network_mutation_allowed: false,
control_allowed: controlAllowed,
acquisition_start_allowed: controlAllowed,
data_ingest_authoritative: dataAuthoritative,
physical_motion_allowed: false,
reason_codes: [],
},
last_known: lastKnown,
allowed_actions: [],
},
};
}
test("parser accepts reviewed v1alpha1 and v1alpha2 shapes", () => {
const legacy = parseDevicePluginManifest(manifestDocument());
const current = parseDevicePluginManifest(
manifestDocument({ apiVersion: "missioncore.nodedc/v1alpha2" }),
);
assert.equal(legacy.apiVersion, "missioncore.nodedc/v1alpha1");
assert.equal(legacy.spec.hostApiRange, "v1alpha1");
assert.equal(current.apiVersion, "missioncore.nodedc/v1alpha2");
assert.equal(current.spec.hostApiRange, "v1alpha2");
assert.deepEqual(current.spec.compatibilityProfiles, [
{
profileId: "test.device.model.fw-1.v1",
path: "profiles/fw-1/profile.v1.json",
modelId: "test.device.model",
},
]);
});
test("v1alpha1 keeps the original nonblank identifier compatibility", () => {
const legacyDocument = manifestDocument({
pluginId: "legacy plugin id",
modelId: "legacy model id",
});
legacyDocument.spec.permissions = ["legacy permission"];
legacyDocument.spec.actions[0].secretFields = ["legacy secret field"];
legacyDocument.spec.models[0].capabilities = [
{ id: "legacy capability", label: "Legacy" },
];
const legacy = parseDevicePluginManifest(legacyDocument);
assert.equal(legacy.metadata.id, "legacy plugin id");
assert.equal(legacy.spec.models[0].id, "legacy model id");
assert.deepEqual(legacy.spec.permissions, ["legacy permission"]);
});
test("v1alpha2 applies strict identifiers without redefining v1alpha1", () => {
const current = manifestDocument({
apiVersion: "missioncore.nodedc/v1alpha2",
pluginId: "current plugin id",
});
assert.throws(
() => parseDevicePluginManifest(current),
/не является идентификатором/,
);
});
test("v1alpha2 parser and registry accept multiple independently profiled models", () => {
const document = manifestDocument({
apiVersion: "missioncore.nodedc/v1alpha2",
pluginId: "test.family",
modelId: "test.family.model-a",
});
document.spec.models.push({
...document.spec.models[0],
id: "test.family.model-b",
displayName: "Test model B",
});
document.spec.compatibilityProfiles.push({
profileId: "test.family.model-b.fw-1.v1",
path: "profiles/fw-1/model-b.v1.json",
modelId: "test.family.model-b",
});
const manifest = parseDevicePluginManifest(document);
const plugin = {
...uiPlugin(manifest),
connectionViews: { "test.connection": () => null },
};
const registry = createDevicePluginRegistry([plugin]);
assert.deepEqual(registry.models.map(({ model }) => model.id), [
"test.family.model-a",
"test.family.model-b",
]);
});
test("installed XGRIDS frontend manifest exposes the semantic v1alpha2 actions", () => {
assert.equal(xgridsK1Manifest.apiVersion, "missioncore.nodedc/v1alpha2");
assert.deepEqual(xgridsK1Manifest.spec.compatibilityProfiles, [
{
profileId: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
path: "profiles/fw-3.0.2/local-network.v2.json",
modelId: "xgrids.lixelkity-k1",
},
]);
assert.equal(xgridsK1Actions.acquisitionPrepare, "acquisition.prepare");
assert.equal(xgridsK1Actions.acquisitionStart, "acquisition.start");
assert.equal(xgridsK1Actions.acquisitionStop, "acquisition.stop");
assert.equal(xgridsK1Actions.connectionVerify, "connection.verify");
assert.equal(
xgridsK1Actions.configuredEndpointProbe,
"connection.endpoint-probe",
);
});
test("one operator action can open at most one K1 control session", () => {
assert.equal(lifecycle.controlSessionEntryPlan("idle", false, true), "open");
assert.equal(lifecycle.controlSessionEntryPlan("failed", false, true), "open");
assert.equal(lifecycle.controlSessionEntryPlan("failed", false, false), "failed");
assert.equal(lifecycle.controlSessionEntryPlan("failed", true, true), "failed");
assert.equal(
lifecycle.controlSessionEntryPlan("idle", true, true),
"duplicate-open",
);
assert.equal(
lifecycle.controlSessionEntryPlan("connection-ready", true, false),
"continue",
);
});
test("K1 operator intent stays invalid after runtime deactivate and reactivate", () => {
const generation = new operatorIntentGeneration.OperatorIntentGeneration();
generation.activateRuntime();
const oldIntent = generation.beginOperatorIntent();
assert.ok(oldIntent);
assert.equal(generation.isOperatorIntentCurrent(oldIntent), true);
generation.deactivateRuntime();
generation.activateRuntime();
const freshIntent = generation.beginOperatorIntent();
assert.ok(freshIntent);
assert.notEqual(freshIntent.runtimeGeneration, oldIntent.runtimeGeneration);
assert.equal(generation.isOperatorIntentCurrent(oldIntent), false);
assert.equal(generation.isOperatorIntentCurrent(freshIntent), true);
});
test("stale K1 intent cannot continue past an await after runtime reactivation", async () => {
const generation = new operatorIntentGeneration.OperatorIntentGeneration();
generation.activateRuntime();
const oldIntent = generation.beginOperatorIntent();
assert.ok(oldIntent);
let resolveOldRead;
const oldRead = new Promise((resolve) => {
resolveOldRead = resolve;
});
const writes = [];
const assertOldIntent = () => {
if (!generation.isOperatorIntentCurrent(oldIntent)) {
throw new Error("stale operator intent");
}
};
const oldContinuation = operatorIntentGeneration.awaitWhileIntentCurrent(
assertOldIntent,
() => oldRead,
).then(() => writes.push("old-checkpoint"));
generation.deactivateRuntime();
generation.activateRuntime();
const freshIntent = generation.beginOperatorIntent();
assert.ok(freshIntent);
resolveOldRead({ phase: "connection-ready" });
await assert.rejects(oldContinuation, /stale operator intent/);
assert.deepEqual(writes, []);
const assertFreshIntent = () => {
if (!generation.isOperatorIntentCurrent(freshIntent)) {
throw new Error("stale fresh intent");
}
};
await operatorIntentGeneration.awaitWhileIntentCurrent(
assertFreshIntent,
async () => ({ phase: "connection-ready" }),
);
writes.push("fresh-checkpoint");
assert.deepEqual(writes, ["fresh-checkpoint"]);
});
test("canonical K1 intent cannot cross from snapshot runtime A into B", async () => {
const generation = new operatorIntentGeneration.OperatorIntentGeneration();
generation.activateRuntime();
const intent = generation.beginOperatorIntent();
assert.ok(intent);
const actionRuntimeId = "snapshot-runtime-a";
let currentRuntimeId = actionRuntimeId;
const writes = [];
const assertActionCurrent = () => {
if (
!generation.isOperatorIntentCurrent(intent)
|| !operatorIntentGeneration.isSnapshotRuntimeCurrent(
actionRuntimeId,
currentRuntimeId,
)
) {
throw new Error("snapshot runtime changed");
}
};
const continuation = operatorIntentGeneration.awaitWhileIntentCurrent(
assertActionCurrent,
async () => {
currentRuntimeId = "snapshot-runtime-b";
return { phase: "connection-ready" };
},
).then(() => writes.push("next-mutation"));
await assert.rejects(continuation, /snapshot runtime changed/);
assert.deepEqual(writes, []);
});
test("a fresh explicit K1 intent supersedes the previous intent in one runtime", () => {
const generation = new operatorIntentGeneration.OperatorIntentGeneration();
generation.activateRuntime();
const first = generation.beginOperatorIntent();
const second = generation.beginOperatorIntent();
assert.ok(first);
assert.ok(second);
assert.equal(first.runtimeGeneration, second.runtimeGeneration);
assert.notEqual(first.intentGeneration, second.intentGeneration);
assert.equal(generation.isOperatorIntentCurrent(first), false);
assert.equal(generation.isOperatorIntentCurrent(second), true);
});
test("canonical K1 preparation stops before START and guards every async stage", async () => {
const hookSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts",
import.meta.url,
),
"utf8",
);
const canonicalPreparation = hookSource.slice(
hookSource.indexOf("const prepareCanonicalAcquisition"),
hookSource.indexOf("const prepareAcquisition"),
);
const finalStart = hookSource.slice(
hookSource.indexOf("const startPreparedAcquisition"),
hookSource.indexOf("const startReplay"),
);
const controlPollingLoop = hookSource.slice(
hookSource.indexOf("async function waitForControlPhase"),
hookSource.indexOf("async function waitForPhysicalReconciliationProof"),
);
const reconciliationPollingLoop = hookSource.slice(
hookSource.indexOf("async function waitForPhysicalReconciliationProof"),
hookSource.indexOf("function messageFor"),
);
assert.doesNotMatch(hookSource, /mounted\.current/);
assert.match(canonicalPreparation, /beginOperatorIntent\(\)/);
assert.match(canonicalPreparation, /isOperatorIntentCurrent\(intentToken\)/);
assert.match(
canonicalPreparation,
/const actionSnapshotRuntimeId = expectedSnapshotRuntimeId\(\)/,
);
assert.match(
canonicalPreparation,
/isSnapshotRuntimeCurrent\(actionSnapshotRuntimeId\)/,
);
assert.equal(
canonicalPreparation.match(
/expected_snapshot_runtime_id: actionSnapshotRuntimeId/g,
)?.length,
4,
);
assert.match(canonicalPreparation, /xgridsK1Api\.openApplicationControlSession\(\{/);
assert.match(canonicalPreparation, /\.\.\.request\.physicalAcceptance/);
assert.ok(
canonicalPreparation.indexOf("xgridsK1Api.openApplicationControlSession")
< canonicalPreparation.indexOf("xgridsK1Api.enterApplicationWorkspace"),
"Verify inspection must be replaced before workspace entry",
);
assert.match(canonicalPreparation, /xgridsK1Api\.reconcilePhysicalCommand\(\{/);
assert.doesNotMatch(canonicalPreparation, /await xgridsK1Api\./);
assert.doesNotMatch(canonicalPreparation, /await waitForControlPhase\(/);
assert.doesNotMatch(canonicalPreparation, /xgridsK1Api\.startAcquisition/);
assert.match(finalStart, /xgridsK1Api\.startAcquisition/);
assert.ok(
canonicalPreparation.match(/awaitWhileIntentCurrent\(/g)?.length >= 7,
"each preparation REST/checkpoint boundary must use the intent guard",
);
assert.match(controlPollingLoop, /for \(;;\) \{\s*assertOperatorIntentCurrent\(\)/);
assert.equal(controlPollingLoop.match(/awaitWhileIntentCurrent\(/g)?.length, 2);
assert.match(
reconciliationPollingLoop,
/for \(;;\) \{\s*assertOperatorIntentCurrent\(\)/,
);
assert.equal(
reconciliationPollingLoop.match(/awaitWhileIntentCurrent\(/g)?.length,
2,
);
});
test("K1 control-phase polling fails closed instead of stacking timed-out state reads", async () => {
const hookSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts",
import.meta.url,
),
"utf8",
);
const controlPollingLoop = hookSource.slice(
hookSource.indexOf("async function waitForControlPhase"),
hookSource.indexOf("async function waitForPhysicalReconciliationProof"),
);
assert.match(hookSource, /const CONTROL_PHASE_WAIT_TIMEOUT_MS = 120_000/);
assert.match(controlPollingLoop, /xgridsK1Api\.getState\(\)/);
assert.doesNotMatch(controlPollingLoop, /ApiRequestTimeoutError/);
assert.doesNotMatch(controlPollingLoop, /catch \(error\)/);
assert.doesNotMatch(
controlPollingLoop,
/(?:openApplicationControlSession|enterApplicationWorkspace|prepareAcquisition|startAcquisition|stopAcquisition)\(/,
);
});
test("K1 frontend coalesces concurrent read-only state requests without caching them", async () => {
const apiSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/api.ts",
import.meta.url,
),
"utf8",
);
const singleFlight = apiSource.slice(
apiSource.indexOf("let stateReadInFlight"),
apiSource.indexOf("export const xgridsK1Api"),
);
const getState = apiSource.slice(
apiSource.indexOf("async getState"),
apiSource.indexOf("scanBle("),
);
assert.match(singleFlight, /if \(stateReadInFlight\) return stateReadInFlight/);
assert.match(singleFlight, /invokeState\(xgridsK1Actions\.stateRead\)/);
assert.match(singleFlight, /stateReadInFlight === request[\s\S]*?stateReadInFlight = null/);
assert.match(getState, /return readStateSingleFlight\(\)/);
assert.doesNotMatch(singleFlight, /setTimeout|setInterval|retry/i);
});
test("K1 control-session CAS is exact, integer-only and mapped for each mutation family", () => {
const state = {
application_control_session: {
mode: "interactive-canonical",
state: "workspace-ready",
session_generation: 17,
state_revision: 43,
},
};
assert.deepEqual(
controlSessionCas.exactApplicationControlCas(state, "ENTER"),
{
expected_session_generation: 17,
expected_state_revision: 43,
},
);
assert.deepEqual(
controlSessionCas.exactAcquisitionControlCas(state, "PREPARE"),
{
expected_control_session_generation: 17,
expected_control_state_revision: 43,
},
);
assert.equal(controlSessionCas.acquisitionMutationUsesControlSession(state), true);
assert.equal(
controlSessionCas.acquisitionMutationUsesControlSession({
application_control_session: { ...state.application_control_session, state: "closed" },
}),
false,
);
for (const [field, value] of [
["session_generation", undefined],
["session_generation", 1.5],
["session_generation", -1],
["session_generation", Number.NaN],
["state_revision", undefined],
["state_revision", 2.25],
["state_revision", -1],
["state_revision", Number.POSITIVE_INFINITY],
]) {
assert.throws(
() => controlSessionCas.exactApplicationControlCas({
application_control_session: {
...state.application_control_session,
[field]: value,
},
}, "TEST"),
(error) => error instanceof ApiError && /не отправлена/.test(error.message),
`${field}=${String(value)}`,
);
}
});
test("K1 frontend reads CAS only from latest accepted state immediately before API mutations", async () => {
const apiSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/api.ts",
import.meta.url,
),
"utf8",
);
const hookSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts",
import.meta.url,
),
"utf8",
);
assert.match(apiSource, /session_generation:\s*number/);
assert.match(apiSource, /state_revision:\s*number/);
assert.match(apiSource, /expected_session_generation:\s*number/);
assert.match(apiSource, /expected_control_session_generation:\s*number/);
assert.match(apiSource, /closeApplicationControlSession\(\s*body:/);
assert.doesNotMatch(hookSource, /closeApplicationControlSession\(\)/);
assert.ok(
[...hookSource.matchAll(/exactApplicationControlCas\(\s*latestState\.current/g)].length >= 3,
"standalone ENTER, CLOSE and canonical ENTER must use latest accepted state",
);
assert.ok(
[...hookSource.matchAll(/exactAcquisitionControlCas\(\s*latestState\.current/g)].length >= 4,
"canonical PREPARE, generic PREPARE, START and STOP must use latest accepted state",
);
assert.match(
hookSource,
/nextState = latestState\.current \?\? nextState;[\s\S]*?const phase = controlPhase\(nextState\)/,
);
assert.match(
hookSource,
/mode:\s*"graceful",[\s\S]*?\.\.\.newMutationContext\("acquisition\.stop"\),[\s\S]*?\.\.\.controlCas/,
);
assert.match(hookSource, /mode:\s*"capture-only"/);
const stopMutation = hookSource.slice(
hookSource.indexOf("const stop = useCallback"),
hookSource.indexOf("const stopLocalReceiver = useCallback"),
);
const localReceiverCleanup = hookSource.slice(
hookSource.indexOf("const stopLocalReceiver = useCallback"),
hookSource.indexOf("const abort = useCallback"),
);
const mutationGate = stopMutation.indexOf(
"physicalStopIntentCheckpoint(dispatchState)",
);
const exactCas = stopMutation.indexOf("exactAcquisitionControlCas(", mutationGate);
const spentFence = stopMutation.indexOf("spendPhysicalStopIntent(checkpoint)", exactCas);
const physicalCall = stopMutation.indexOf("xgridsK1Api.stopAcquisition({", spentFence);
assert.ok(
mutationGate >= 0
&& exactCas > mutationGate
&& spentFence > exactCas
&& physicalCall > spentFence,
"physical STOP must re-read exact authority and spend it synchronously before its API call",
);
assert.match(stopMutation, /physicalStopPresentationOwner\.current === stopPresentationOwner/);
const captureOnlyMarker = stopMutation.indexOf('mode: "capture-only"');
const captureOnlyPolicyGate = stopMutation.lastIndexOf(
'connectionPolicyAllows(currentState, "stop-local-receiver")',
captureOnlyMarker,
);
const compatibilityCall = stopMutation.indexOf(
"xgridsK1Api.stopSessionCompatibility({",
captureOnlyMarker,
);
const compatibilityPolicyGate = stopMutation.lastIndexOf(
'connectionPolicyAllows(currentState, "stop-local-receiver")',
compatibilityCall,
);
assert.ok(
captureOnlyPolicyGate >= 0
&& captureOnlyPolicyGate < captureOnlyMarker
&& compatibilityPolicyGate > captureOnlyMarker
&& compatibilityPolicyGate < compatibilityCall,
"generic capture-only and compatibility STOP must fail closed on the current local-stop policy before API dispatch",
);
const localReceiverPolicyGate = localReceiverCleanup.indexOf(
'connectionPolicyAllows(currentState, "stop-local-receiver")',
);
const localReceiverFirstApiCall = localReceiverCleanup.indexOf("xgridsK1Api.");
assert.ok(
localReceiverPolicyGate >= 0
&& localReceiverPolicyGate < localReceiverFirstApiCall,
"a direct or stale local cleanup call must be denied before either API path",
);
assert.match(
localReceiverCleanup,
/const stopPlan = localReceiverStopPlan\(currentState\)/,
);
assert.match(
localReceiverCleanup,
/stopPlan\.kind === "acquisition"/,
);
assert.match(
localReceiverCleanup,
/xgridsK1Api\.stopAcquisition\(\{[\s\S]*?acquisition_id: stopPlan\.acquisitionId,[\s\S]*?mode: "capture-only"[\s\S]*?expected_snapshot_runtime_id: snapshotRuntimeId/,
);
assert.match(
localReceiverCleanup,
/xgridsK1Api\.stopSessionCompatibility\(\{[\s\S]*?expected_snapshot_runtime_id: snapshotRuntimeId/,
);
assert.doesNotMatch(
localReceiverCleanup,
/exactAcquisitionControlCas|physical_acceptance|spendPhysicalStopIntent/,
);
});
test("K1 API forwards runtime fences and exact CAS fields without dropping them", async () => {
const originalFetch = globalThis.fetch;
const calls = [];
globalThis.fetch = async (path, init) => {
calls.push({ path, init });
return new Response(JSON.stringify({ state: { source_mode: "idle" } }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
};
try {
await xgridsK1Api.openApplicationControlSession({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operator_present: true,
owner_controlled_device: true,
lixelgo_closed: true,
battery_storage_confirmed: true,
expected_physical_state_confirmed: true,
timezone_name: "Europe/Moscow",
});
await xgridsK1Api.enterApplicationWorkspace({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operator_confirmed: true,
expected_session_generation: 7,
expected_state_revision: 8,
});
await xgridsK1Api.closeApplicationControlSession({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
expected_session_generation: 9,
expected_state_revision: 10,
});
await xgridsK1Api.reconcilePhysicalCommand({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
reconciliation_id: "reconciliation-cas",
expected_session_generation: 9,
expected_state_revision: 10,
});
await xgridsK1Api.prepareAcquisition({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operation_id: "op-00000000-0000-4000-8000-000000000101",
idempotency_key: "acquisition.prepare:op-00000000-0000-4000-8000-000000000101",
project_name: "CAS01",
mount_type: "handheld",
gnss_mode: "none",
compatibility_attestation: {
firmware_version: "3.0.2",
topology: "direct-lan",
verification: "live-device-info",
},
expected_control_session_generation: 11,
expected_control_state_revision: 12,
});
await xgridsK1Api.startAcquisition({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operation_id: "op-00000000-0000-4000-8000-000000000102",
idempotency_key: "acquisition.start:op-00000000-0000-4000-8000-000000000102",
acquisition_id: "acquisition-cas",
expected_control_session_generation: 13,
expected_control_state_revision: 14,
});
await xgridsK1Api.stopAcquisition({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operation_id: "op-00000000-0000-4000-8000-000000000103",
idempotency_key: "acquisition.stop:op-00000000-0000-4000-8000-000000000103",
acquisition_id: "acquisition-cas",
mode: "graceful",
expected_control_session_generation: 15,
expected_control_state_revision: 16,
});
await xgridsK1Api.abortAcquisition({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operation_id: "op-00000000-0000-4000-8000-000000000104",
idempotency_key: "acquisition.abort:op-00000000-0000-4000-8000-000000000104",
acquisition_id: "acquisition-cas",
expected_control_session_generation: 17,
expected_control_state_revision: 18,
});
await xgridsK1Api.stopSessionCompatibility({
expected_snapshot_runtime_id: "snapshot-runtime-cas",
});
} finally {
globalThis.fetch = originalFetch;
}
assert.deepEqual(
calls.map(({ init }) => JSON.parse(init.body).input),
[
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operator_present: true,
owner_controlled_device: true,
lixelgo_closed: true,
battery_storage_confirmed: true,
expected_physical_state_confirmed: true,
timezone_name: "Europe/Moscow",
},
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operator_confirmed: true,
expected_session_generation: 7,
expected_state_revision: 8,
},
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
expected_session_generation: 9,
expected_state_revision: 10,
},
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
reconciliation_id: "reconciliation-cas",
expected_session_generation: 9,
expected_state_revision: 10,
},
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operation_id: "op-00000000-0000-4000-8000-000000000101",
idempotency_key: "acquisition.prepare:op-00000000-0000-4000-8000-000000000101",
project_name: "CAS01",
mount_type: "handheld",
gnss_mode: "none",
compatibility_attestation: {
firmware_version: "3.0.2",
topology: "direct-lan",
verification: "live-device-info",
},
expected_control_session_generation: 11,
expected_control_state_revision: 12,
},
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operation_id: "op-00000000-0000-4000-8000-000000000102",
idempotency_key: "acquisition.start:op-00000000-0000-4000-8000-000000000102",
acquisition_id: "acquisition-cas",
expected_control_session_generation: 13,
expected_control_state_revision: 14,
},
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operation_id: "op-00000000-0000-4000-8000-000000000103",
idempotency_key: "acquisition.stop:op-00000000-0000-4000-8000-000000000103",
acquisition_id: "acquisition-cas",
mode: "graceful",
expected_control_session_generation: 15,
expected_control_state_revision: 16,
},
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
operation_id: "op-00000000-0000-4000-8000-000000000104",
idempotency_key: "acquisition.abort:op-00000000-0000-4000-8000-000000000104",
acquisition_id: "acquisition-cas",
expected_control_session_generation: 17,
expected_control_state_revision: 18,
},
{
expected_snapshot_runtime_id: "snapshot-runtime-cas",
},
],
);
});
test("K1 lifecycle mutation context is unique and binds one key to one operation", () => {
const first = lifecycle.newMutationContext("acquisition.start");
const second = lifecycle.newMutationContext("acquisition.start");
assert.match(first.operation_id, /^op-[0-9a-f-]{36}$/);
assert.equal(first.idempotency_key, `acquisition.start:${first.operation_id}`);
assert.notEqual(second.operation_id, first.operation_id);
assert.equal(second.idempotency_key, `acquisition.start:${second.operation_id}`);
assert.throws(
() => lifecycle.newMutationContext(" "),
/безопасный ключ не создан/,
);
});
test("K1 API uses bounded no-retry timeout classes per operation family", async () => {
const apiSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/api.ts",
import.meta.url,
),
"utf8",
);
assert.equal(requestTimeoutMsForAction(xgridsK1Actions.stateRead), 8_000);
assert.equal(requestTimeoutMsForAction(xgridsK1Actions.discoveryScan), 70_000);
assert.equal(requestTimeoutMsForAction(xgridsK1Actions.networkProvision), 300_000);
assert.equal(requestTimeoutMsForAction(xgridsK1Actions.connectionVerify), 150_000);
assert.equal(requestTimeoutMsForAction(xgridsK1Actions.configuredEndpointProbe), 15_000);
for (const action of [
xgridsK1Actions.applicationControlSessionOpen,
xgridsK1Actions.applicationControlWorkspaceEnter,
xgridsK1Actions.applicationControlSessionClose,
xgridsK1Actions.acquisitionPrepare,
xgridsK1Actions.acquisitionStart,
xgridsK1Actions.acquisitionStop,
]) {
assert.equal(requestTimeoutMsForAction(action), 120_000, action);
}
const timeout = new ApiRequestTimeoutError("acquisition.start", 120_000);
assert.equal(timeout.outcomeUnknown, true);
assert.equal(timeout.automaticRetry, false);
assert.equal(timeout.transportUnavailable, false);
assert.match(timeout.message, /автоматический повтор запрещён/);
assert.match(apiSource, /const controller = new AbortController\(\)/);
assert.match(apiSource, /setTimeout\(\(\) => \{\s*timedOut = true;\s*controller\.abort\(\)/);
assert.match(apiSource, /finally \{\s*clearTimeout\(timeout\)/);
assert.doesNotMatch(apiSource, /automaticRetry\s*=\s*true/);
});
test("lost Quick response follows the admitted Apply by journal reads only", async () => {
const idempotencyKey = "network-provision:quick-lost-response";
let nowMs = 1_000;
let reads = 0;
const accepted = [];
const operation = {
operation_id: "op-quick-lost-response",
action: "network.provision",
status: "running",
idempotency_key: idempotencyKey,
deadline_at: new Date(5_000).toISOString(),
};
const initialState = {
snapshot_runtime_id: "runtime-quick-lost-response",
operations: [operation],
};
const terminalState = {
...initialState,
operations: [{
...operation,
status: "succeeded",
result: { phase: "network_applied" },
}],
};
const settled = await awaitNetworkProvisionSettlementAfterLostResponse(
initialState,
idempotencyKey,
async () => {
reads += 1;
if (reads === 1) {
throw new ApiError("transient localhost handoff", 0, true);
}
return terminalState;
},
(state) => accepted.push(state),
() => {},
{
now: () => nowMs,
wait: async (delayMs) => {
nowMs += delayMs;
},
},
);
assert.equal(reads, 2);
assert.deepEqual(accepted, [terminalState]);
assert.equal(settled.operations[0].status, "succeeded");
});
test("one explicit K1 operator action supplies the backend physical acceptance", () => {
assert.deepEqual(physicalCommandConfirmation.operatorActionPhysicalAcceptance(), {
operator_present: true,
owner_controlled_device: true,
lixelgo_closed: true,
battery_storage_confirmed: true,
expected_physical_state_confirmed: true,
});
});
test("final K1 START target requires exact prepared project and fresh READY authority", () => {
const state = {
...supervisedConnectionState(),
phase: "ready",
source_mode: "idle",
selected_device_id: "ble-k1-001",
device_ref: {
device_id: "device-k1-001",
},
device_session: {
device_session_id: "device-session-001",
device_id: "device-k1-001",
connectivity: "connected",
},
compatibility: {
permitted_mode: "active-control",
vendor_writes_enabled: true,
},
acquisition: {
acquisition_id: "acquisition-001",
device_id: "device-k1-001",
device_session_id: "device-session-001",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
control_mode: "plugin-commanded",
project_name: "RAVNOVES01",
requested_streams: [],
target_host: "127.0.0.1",
duration_seconds: null,
evidence_policy: "required",
state: "prepared",
state_revision: 4,
},
application_control_session: {
session_generation: 5,
state_revision: 8,
state: "project-ready",
control_socket_open: true,
can_start: true,
verified_control: {
logical_device_id: "device-k1-001",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
control_session_id: "control-session-001",
source: "mqtt-device-info",
intent_id: "intent-bridge-1",
transport_ref: "ble-k1-001",
host_path_epoch: 3,
target_ipv4: "192.168.68.50",
target_port: 1883,
connection_mode: "bridge",
control_proof_revision: 9,
control_proof_source: "device-status",
control_proof_fresh: true,
},
transport: {
latest_device_session_state: "ready",
latest_device_project_bound: true,
latest_device_init_ready: false,
},
},
};
const target = physicalCommandConfirmation.preparedStartTarget(state);
assert.ok(target);
const { fence, ...displayTarget } = target;
assert.deepEqual(displayTarget, {
deviceId: "device-k1-001",
connection: "bridge · 192.168.68.50:1883",
projectName: "RAVNOVES01",
acquisitionId: "acquisition-001",
deviceState: "READY · проект привязан · инициализация не запущена",
});
assert.equal(fence.kind, "start");
assert.equal(fence.controlSessionGeneration, 5);
assert.equal(fence.controlStateRevision, 8);
assert.equal(fence.connectionIntentId, "intent-bridge-1");
assert.equal(fence.transportRef, "ble-k1-001");
assert.equal(fence.acquisitionStateRevision, 4);
for (const mutate of [
(candidate) => { candidate.application_control_session.can_start = false; },
(candidate) => { candidate.application_control_session.transport.latest_device_session_state = "scanning"; },
(candidate) => { candidate.application_control_session.transport.latest_device_project_bound = false; },
(candidate) => { candidate.application_control_session.transport.latest_device_init_ready = true; },
(candidate) => { candidate.application_control_session.verified_control.control_proof_fresh = false; },
(candidate) => { candidate.connection_supervisor.authority.acquisition_start_allowed = false; },
(candidate) => { candidate.acquisition.device_id = "another-device"; },
(candidate) => { candidate.application_control_session.verified_control.intent_id = "stale-intent"; },
(candidate) => { candidate.application_control_session.verified_control.host_path_epoch = 2; },
(candidate) => { candidate.application_control_session.verified_control.transport_ref = "stale-transport"; },
(candidate) => { candidate.application_control_session.verified_control.target_port = 1884; },
(candidate) => { candidate.connection_lifecycle.ready_to_start = false; },
]) {
const stale = structuredClone(state);
mutate(stale);
assert.equal(physicalCommandConfirmation.preparedStartTarget(stale), null);
}
});
test("physical K1 modal checkpoint stays stable on refresh and invalidates on topology, CAS or state changes", () => {
const state = {
...supervisedConnectionState(),
phase: "ready",
source_mode: "idle",
selected_device_id: "ble-k1-001",
device_ref: { device_id: "device-k1-001" },
device_session: {
device_session_id: "device-session-001",
device_id: "device-k1-001",
connectivity: "connected",
},
acquisition: {
acquisition_id: "acquisition-fence-1",
device_id: "device-k1-001",
device_session_id: "device-session-001",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
control_mode: "plugin-commanded",
project_name: "FENCE01",
requested_streams: [],
target_host: "127.0.0.1",
duration_seconds: null,
evidence_policy: "required",
state: "prepared",
state_revision: 21,
},
application_control_session: {
session_generation: 13,
state_revision: 34,
state: "project-ready",
control_socket_open: true,
can_start: true,
verified_control: {
logical_device_id: "device-k1-001",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
control_session_id: "control-session-001",
source: "mqtt-device-info",
intent_id: "intent-bridge-1",
transport_ref: "ble-k1-001",
host_path_epoch: 3,
target_ipv4: "192.168.68.50",
target_port: 1883,
connection_mode: "bridge",
control_proof_revision: 55,
control_proof_source: "device-status",
control_proof_fresh: true,
},
transport: {
latest_device_session_state: "ready",
latest_device_project_bound: true,
latest_device_init_ready: false,
},
},
};
const openingTarget = physicalCommandConfirmation.preparedStartTarget(state);
assert.ok(openingTarget);
const checkpoint = physicalCommandConfirmation.createPhysicalCommandCheckpoint(
"start",
openingTarget,
);
const readOnlyRefresh = structuredClone(state);
readOnlyRefresh.snapshot_revision = 999;
// The supervisor revision is an observation counter, not a topology
// generation: a semantically identical host/MQTT poll increments it.
// Such a refresh must not destroy an operator confirmation in progress.
readOnlyRefresh.connection_supervisor.revision += 1;
readOnlyRefresh.snapshot_runtime_started_at_utc = "2026-08-06T12:01:00Z";
readOnlyRefresh.connection_supervisor.observed.host_path.observed_at =
"2026-08-06T12:01:00Z";
readOnlyRefresh.connection_supervisor.observed.endpoint.observed_at =
"2026-08-06T12:01:00Z";
const unchangedTarget = physicalCommandConfirmation.preparedStartTarget(readOnlyRefresh);
assert.ok(unchangedTarget);
assert.equal(
physicalCommandConfirmation.physicalCommandCheckpointMatches(
checkpoint,
"start",
unchangedTarget,
),
true,
);
assert.equal(
physicalCommandConfirmation.physicalCommandCheckpointMatches(
checkpoint,
"stop",
unchangedTarget,
),
false,
);
assert.equal(Object.isFrozen(checkpoint), true);
assert.equal(Object.isFrozen(checkpoint.fence), true);
assert.equal(Object.isFrozen(checkpoint.target), true);
const topologyChanged = structuredClone(state);
topologyChanged.connection_supervisor.revision += 1;
topologyChanged.connection_supervisor.intent.intent_id = "intent-bridge-2";
topologyChanged.connection_supervisor.observed.device_network.intent_id = "intent-bridge-2";
topologyChanged.connection_supervisor.observed.endpoint.intent_id = "intent-bridge-2";
topologyChanged.connection_supervisor.observed.device_identity.intent_id = "intent-bridge-2";
topologyChanged.connection_supervisor.lease.intent_id = "intent-bridge-2";
topologyChanged.connection_lifecycle.active_binding.intent_id = "intent-bridge-2";
topologyChanged.connection_lifecycle.active_binding.binding_key = "binding-intent-bridge-2-3";
topologyChanged.connection_lifecycle.active_binding_key = "binding-intent-bridge-2-3";
topologyChanged.application_control_session.verified_control.intent_id = "intent-bridge-2";
const topologyTarget = physicalCommandConfirmation.preparedStartTarget(topologyChanged);
assert.ok(topologyTarget);
assert.equal(
physicalCommandConfirmation.physicalCommandCheckpointMatches(
checkpoint,
"start",
topologyTarget,
),
false,
);
const casChanged = structuredClone(state);
casChanged.application_control_session.session_generation += 1;
casChanged.application_control_session.state_revision += 1;
const casTarget = physicalCommandConfirmation.preparedStartTarget(casChanged);
assert.ok(casTarget);
assert.equal(
physicalCommandConfirmation.physicalCommandCheckpointMatches(
checkpoint,
"start",
casTarget,
),
false,
);
const runtimeStateChanged = structuredClone(state);
runtimeStateChanged.phase = "degraded";
const runtimeTarget = physicalCommandConfirmation.preparedStartTarget(runtimeStateChanged);
assert.ok(runtimeTarget);
assert.equal(
physicalCommandConfirmation.physicalCommandCheckpointMatches(
checkpoint,
"start",
runtimeTarget,
),
false,
);
assert.equal(checkpoint.target.projectName, "FENCE01");
const changedDisplay = structuredClone(openingTarget);
changedDisplay.projectName = "FENCE02";
assert.equal(
physicalCommandConfirmation.physicalCommandCheckpointMatches(
checkpoint,
"start",
changedDisplay,
),
false,
);
assert.equal(checkpoint.target.projectName, "FENCE01");
});
test("K1 STOP target is bound to the active acquisition instead of START constants", () => {
const state = {
compatibility: {
permitted_mode: "active-control",
vendor_writes_enabled: true,
},
acquisition: {
acquisition_id: "acquisition-active-77",
device_id: "device-k1-active",
device_session_id: "device-session-active",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
control_mode: "plugin-commanded",
project_name: "ROUTE77",
requested_streams: [],
target_host: "127.0.0.1",
duration_seconds: null,
evidence_policy: "required",
state: "acquiring",
state_revision: 12,
},
application_control_session: {
state: "scanning",
verified_control: {
logical_device_id: "device-k1-active",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
connection_mode: "quick-connect",
target_ipv4: "192.168.56.1",
target_port: 1883,
},
transport: {
latest_device_session_state: "scanning",
latest_device_project_bound: true,
latest_device_init_ready: true,
},
},
};
const target = physicalCommandConfirmation.activeStopTarget(state);
assert.ok(target);
const { fence, ...displayTarget } = target;
assert.deepEqual(displayTarget, {
deviceId: "device-k1-active",
connection: "quick-connect · 192.168.56.1:1883",
projectName: "ROUTE77",
acquisitionId: "acquisition-active-77",
deviceState: "SCANNING · проект привязан · инициализация завершена",
});
assert.equal(fence.kind, "stop");
assert.equal(fence.acquisitionStateRevision, 12);
assert.equal(
physicalCommandConfirmation.activeStopTarget({
...state,
acquisition: { ...state.acquisition, control_mode: "operator-manual" },
}),
null,
);
});
test("K1 control errors stay informative and only fetch failures mark transport unavailable", async () => {
assert.equal(
localizeRuntimeMessage(
"control MQTT connect call failed: [Errno 61] Connection refused",
),
"Управляющее соединение со сканером не открылось: устройство не приняло MQTT-соединение. Команды сканирования не отправлялись.",
);
const domainError = new ApiError("Диалог остановлен до команды START.");
assert.equal(domainError.transportUnavailable, false);
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => {
throw new TypeError("synthetic network failure");
};
try {
await assert.rejects(
() => xgridsK1Api.getState(),
(error) => error instanceof ApiError && error.transportUnavailable === true,
);
} finally {
globalThis.fetch = originalFetch;
}
});
test("v1alpha2 compatibility profile is exact-key and rejects duplicated profile status", () => {
const document = manifestDocument({ apiVersion: "missioncore.nodedc/v1alpha2" });
document.spec.compatibilityProfiles[0].status = "verified";
assert.throws(
() => parseDevicePluginManifest(document),
/неизвестные поля status/,
);
});
test("v1alpha2 compatibility profile fails closed on unsafe paths", () => {
const document = manifestDocument({ apiVersion: "missioncore.nodedc/v1alpha2" });
document.spec.compatibilityProfiles[0].path = "../private/profile.json";
assert.throws(
() => parseDevicePluginManifest(document),
/безопасным относительным JSON-путём/,
);
});
test("v1alpha2 compatibility profile cannot reference an unknown model", () => {
const document = manifestDocument({ apiVersion: "missioncore.nodedc/v1alpha2" });
document.spec.compatibilityProfiles[0].modelId = "missing.model";
assert.throws(
() => parseDevicePluginManifest(document),
/ссылается на неизвестную модель missing\.model/,
);
});
test("registry accepts v1alpha1 and v1alpha2 plugins together", () => {
const legacy = parseDevicePluginManifest(
manifestDocument({ pluginId: "test.legacy", modelId: "test.legacy.model" }),
);
const current = parseDevicePluginManifest(
manifestDocument({
apiVersion: "missioncore.nodedc/v1alpha2",
pluginId: "test.current",
modelId: "test.current.model",
}),
);
const registry = createDevicePluginRegistry([uiPlugin(legacy), uiPlugin(current)]);
assert.equal(registry.plugins.length, 2);
assert.equal(registry.models.length, 2);
assert.equal(registry.resolveModel("test.current.model")?.plugin.manifest.metadata.id, "test.current");
});
test("registry independently rejects an uncovered v1alpha2 model", () => {
const current = parseDevicePluginManifest(
manifestDocument({ apiVersion: "missioncore.nodedc/v1alpha2" }),
);
current.spec.compatibilityProfiles[0].modelId = "missing.model";
assert.throws(
() => createDevicePluginRegistry([uiPlugin(current)]),
/ссылается на неизвестную модель missing\.model/,
);
});
test("live source is confirmed only by an acquiring acquisition", () => {
const waiting = {
source_mode: "live",
phase: "live",
acquisition: { state: "awaiting_external_start" },
};
const acquiring = {
...supervisedConnectionState({ dataAuthoritative: true }),
...waiting,
acquisition: { state: "acquiring" },
};
assert.equal(lifecycle.isConfirmedLiveState(waiting), false);
assert.equal(lifecycle.confirmedRuntimeSourceMode(waiting), "idle");
assert.equal(lifecycle.sourceStatusLabel(waiting), "Ожидание реальных данных");
assert.equal(lifecycle.isConfirmedLiveState(acquiring), true);
assert.equal(lifecycle.confirmedRuntimeSourceMode(acquiring), "live");
assert.equal(lifecycle.liveStartPlan(acquiring), "already-running");
const staleDataEpoch = structuredClone(acquiring);
staleDataEpoch.connection_supervisor.observed.data_plane.host_path_epoch = 2;
assert.equal(lifecycle.isConfirmedLiveState(staleDataEpoch), false);
assert.equal(
lifecycle.controlSessionEntryPlan("scanning", false, false),
"continue",
);
});
test("prepared acquisition resumes without another prepare and remains recoverable", () => {
const prepared = {
source_mode: "idle",
acquisition: {
acquisition_id: "acq-1",
state: "prepared",
},
};
assert.equal(lifecycle.liveStartPlan(prepared), "resume-prepared");
assert.equal(lifecycle.recoverableAcquisition(prepared)?.acquisition_id, "acq-1");
});
test("project name is canonicalized and rejected outside the bounded safe contract", () => {
assert.deepEqual(projectName.validateProjectName(" Mission 01 "), {
value: "Mission 01",
error: null,
});
assert.match(projectName.validateProjectName("line\nbreak").error, /управляющие/);
assert.match(projectName.validateProjectName("\ud800").error, /управляющие/);
assert.match(projectName.validateProjectName("x".repeat(97)).error, /не длиннее 96/);
assert.match(projectName.validateProjectName(" \t ").error, /Введите название/);
});
test("automatic spatial source replaces the old scene only after a successful start", async () => {
const failedEvents = [];
assert.equal(await automaticSourceStart.runAutomaticSpatialSourceStart(
async () => {
failedEvents.push("start");
return false;
},
() => failedEvents.push("activate"),
() => failedEvents.push("open"),
), false);
assert.deepEqual(failedEvents, ["start"]);
const successfulEvents = [];
assert.equal(await automaticSourceStart.runAutomaticSpatialSourceStart(
async () => {
successfulEvents.push("start");
return true;
},
() => successfulEvents.push("activate"),
() => successfulEvents.push("open"),
), true);
assert.deepEqual(successfulEvents, ["start", "activate", "open"]);
});
test("vendor commands fail closed unless the profile and acquisition both enable them", () => {
const capability = {
compatibility: {
vendor_writes_enabled: true,
permitted_mode: "active-control",
},
};
assert.equal(lifecycle.isVendorWriteCapable(capability), true);
assert.equal(lifecycle.isVendorWriteCapable({
compatibility: { vendor_writes_enabled: true, permitted_mode: "read-only" },
}), false);
assert.equal(lifecycle.isSoftwareCommandedAcquisition({
...capability,
acquisition: { control_mode: "operator-manual" },
}), false);
assert.equal(lifecycle.isSoftwareCommandedAcquisition({
...capability,
acquisition: { control_mode: "plugin-commanded" },
}), true);
});
test("device modeling telemetry maps only finite non-negative values", () => {
assert.deepEqual(presentation.deviceTelemetry({
device_elapsed_seconds: 12.5,
device_route_distance_meters: 8.25,
device_speed_meters_per_second: 0.75,
}), {
elapsedSeconds: 12.5,
routeDistanceMeters: 8.25,
speedMetersPerSecond: 0.75,
});
assert.deepEqual(presentation.deviceTelemetry({
device_elapsed_seconds: -1,
device_route_distance_meters: Number.NaN,
device_speed_meters_per_second: Number.POSITIVE_INFINITY,
}), {
elapsedSeconds: null,
routeDistanceMeters: null,
speedMetersPerSecond: null,
});
});
test("spatial K1 action failures have an explicit retry-safe presentation", () => {
assert.equal(presentation.spatialActionFailure(null), null);
assert.equal(presentation.spatialActionFailure(" "), null);
assert.deepEqual(presentation.spatialActionFailure(" stop failed "), {
title: "Действие K1 не выполнено",
detail: "stop failed",
});
assert.equal(lifecycle.shouldRenderSpatialControls({
source_mode: "live",
acquisition: { state: "failed", cleanup_pending: true },
}), true);
assert.equal(lifecycle.shouldRenderSpatialControls({
source_mode: "idle",
acquisition: { state: "failed", cleanup_pending: false },
}), false);
});
test("physical-command guidance projects backend policy without exposing reason codes", () => {
const denied = {
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
allowed_actions: ["stop-local-receiver"],
recommended_action: "stop-local-receiver",
actions: {
"stop-acquisition": {
allowed: false,
reason_codes: ["physical-command-reconciliation-required"],
target_source: "connection-supervisor",
required_transport_ref: null,
requires_live_gatt_validation: false,
automatic_retry: false,
},
},
facts: { retained_context_is_presence: false },
},
};
const guidance = presentation.connectionPolicyOperatorGuidance(
denied,
"stop-acquisition",
);
assert.deepEqual(guidance, {
reason: "Результат предыдущей физической команды K1 не подтверждён.",
nextAction: "Завершите локальный приём; физическое состояние K1 проверьте вручную.",
});
assert.doesNotMatch(`${guidance.reason} ${guidance.nextAction}`, /physical-command|stop-local/);
const allowed = structuredClone(denied);
allowed.connection_policy.allowed_actions.push("stop-acquisition");
allowed.connection_policy.actions["stop-acquisition"].allowed = true;
allowed.connection_policy.actions["stop-acquisition"].reason_codes = [];
assert.equal(
presentation.connectionPolicyOperatorGuidance(allowed, "stop-acquisition"),
null,
);
});
test("restart-recovery guidance offers an explicit read-only recovery", () => {
const deniedFresh = {
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
allowed_actions: ["observe-configured-device-network"],
recommended_action: "observe-configured-device-network",
actions: {
"observe-fresh-device-network": {
allowed: false,
reason_codes: ["reconciliation-target-not-observed"],
target_source: "fresh-scan",
required_transport_ref: "exact-durable-k1",
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
"observe-configured-device-network": {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: "exact-durable-k1",
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
facts: { retained_context_is_presence: false },
},
};
const durableGuidance = presentation.connectionPolicyOperatorGuidance(
deniedFresh,
"observe-fresh-device-network",
);
assert.deepEqual(durableGuidance, {
reason: "В свежем Bluetooth-поиске не найден K1, связанный с незавершённой записью.",
nextAction: "Нажмите «Переподключиться», чтобы проверить сохранённое подключение K1.",
});
assert.doesNotMatch(
`${durableGuidance.reason} ${durableGuidance.nextAction}`,
/observe-configured|durable-configured/,
);
deniedFresh.connection_policy.recommended_action = "observe-current-device-network";
assert.equal(
presentation.connectionPolicyOperatorGuidance(
deniedFresh,
"observe-fresh-device-network",
).nextAction,
"Нажмите «Переподключиться», чтобы проверить связь с тем же K1.",
);
});
test("replay ignores a stale failed live acquisition", () => {
const replay = {
source_mode: "replay",
phase: "replay",
rerun_grpc_url: "rerun+http://127.0.0.1:9876/proxy",
acquisition: {
acquisition_id: "old-live-acquisition",
state: "failed",
},
};
assert.equal(lifecycle.normalizeRuntimePhase(replay), "replaying");
assert.equal(lifecycle.effectiveAcquisition(replay), null);
assert.equal(
lifecycle.spatialSourceId(replay, replay.rerun_grpc_url),
`replay:${replay.rerun_grpc_url}`,
);
});
test("K1 configuration exposes all reviewed local connection directions", () => {
assert.equal(configuration.DEFAULT_CONNECTION_MODE, "bridge");
assert.equal(configuration.SUPPORTED_MOUNT_TYPE, "handheld");
assert.equal(configuration.SUPPORTED_GNSS_MODE, "none");
assert.deepEqual(
configuration.connectionModeOptions.map(({ value, disabled = false }) => ({ value, disabled })),
[
{ value: "bridge", disabled: false },
{ value: "quick-connect", disabled: false },
{ value: "direct-connect", disabled: false },
],
);
assert.deepEqual(
configuration.mountTypeOptions.map(({ value, disabled = false }) => ({ value, disabled })),
[
{ value: "handheld", disabled: false },
{ value: "vehicle-mounted", disabled: true },
{ value: "uav", disabled: true },
{ value: "backpack", disabled: true },
],
);
assert.deepEqual(
configuration.gnssModeOptions.map(({ value, disabled = false }) => ({ value, disabled })),
[
{ value: "none", disabled: false },
{ value: "rtk", disabled: true },
{ value: "ppk", disabled: true },
],
);
});
test("connection directions select distinct fail-closed topologies", () => {
assert.deepEqual(compatibility.profileSelectionForConnectionMode("bridge"), {
firmware_version: "3.0.2",
topology: "direct-lan",
verification: "live-device-info",
});
assert.equal(
compatibility.profileSelectionForConnectionMode("quick-connect").topology,
"device-ap",
);
assert.equal(
compatibility.profileSelectionForConnectionMode("direct-connect").topology,
"controller-hotspot",
);
});
test("a provisioned address is not presented as a verified device connection", () => {
assert.equal(lifecycle.normalizeRuntimePhase({
phase: "connected",
application_control_session: { state: "idle" },
}), "configuring");
assert.equal(lifecycle.normalizeRuntimePhase({
phase: "connected",
application_control_session: { state: "connection-ready" },
}), "configuring");
assert.equal(lifecycle.normalizeRuntimePhase({
...supervisedConnectionState({
leaseState: "configured-unverified",
controlAllowed: false,
}),
phase: "connected",
}), "connected");
});
test("a released acquisition failure stays exact in the acquisition panel without poisoning global runtime", () => {
const releasedFailure = {
phase: "error",
source_mode: "idle",
acquisition: {
state: "failed",
cleanup_pending: false,
},
application_control_session: {
state: "idle",
failure: {
network_change_admissible: true,
message: "control connection was lost after acknowledged stop",
},
},
};
assert.equal(lifecycle.isReleasedTerminalAcquisitionFailure(releasedFailure), true);
assert.equal(lifecycle.normalizeRuntimePhase(releasedFailure), "idle");
assert.equal(lifecycle.shouldSurfaceRuntimeActionError("live", releasedFailure), false);
assert.equal(lifecycle.shouldSurfaceRuntimeActionError("control", releasedFailure), false);
assert.equal(lifecycle.shouldSurfaceRuntimeActionError("scan", releasedFailure), true);
assert.equal(
lifecycle.authoritativeStateSupersedesRuntimeError(
{ action: "stop", runtimeId: "runtime-a", leaseGeneration: 4 },
releasedFailure,
),
true,
);
assert.equal(
lifecycle.authoritativeStateSupersedesRuntimeError(
{ action: "scan", runtimeId: "runtime-a", leaseGeneration: 4 },
releasedFailure,
),
false,
);
assert.equal(
lifecycle.isReleasedTerminalAcquisitionFailure({
...releasedFailure,
acquisition: { state: "failed", cleanup_pending: true },
}),
false,
);
assert.equal(
lifecycle.isReleasedTerminalAcquisitionFailure({
...releasedFailure,
application_control_session: {
state: "failed",
failure: { network_change_admissible: false },
},
}),
false,
);
});
test("poll and WebSocket state acceptance clear stale runtime banners after local release", async () => {
const runtimeSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts",
import.meta.url,
),
"utf8",
);
assert.match(runtimeSource, /authoritativeStateSupersedesRuntimeError\(\s*errorCorrelation\.current,\s*acceptedState/);
assert.match(runtimeSource, /openEventSocket\(acceptState/);
});
test("observed SCANNING recovery is a successful STOP-only connection outcome", async () => {
const recoveredScanning = {
...supervisedConnectionState({ mode: "bridge" }),
connection_mode: "bridge",
active_connection_mode: "bridge",
application_control_session: {
state: "scanning",
can_stop: true,
physical_command: {
requires_reconciliation: false,
resolved_active_recovery_required: true,
observed_session_state: "scanning",
},
},
};
assert.equal(lifecycle.isRecoveredPhysicalScanning(recoveredScanning, "bridge"), true);
assert.equal(
lifecycle.isRecoveredPhysicalScanning(recoveredScanning, "quick-connect"),
false,
);
const replayDuringPhysicalRecovery = {
...recoveredScanning,
source_mode: "replay",
compatibility: {
vendor_writes_enabled: true,
permitted_mode: "active-control",
},
acquisition: {
acquisition_id: "terminal-live-acquisition",
device_id: "original-k1",
device_session_id: "fresh-verified-session",
project_name: null,
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
control_mode: "plugin-commanded",
requested_streams: [],
target_host: "192.168.68.52",
evidence_policy: "disabled",
state: "failed",
state_revision: 9,
cleanup_pending: false,
result: {
recovery_only: true,
device_state: "scanning",
automatic_replay_allowed: false,
},
},
};
assert.equal(
lifecycle.requiresCanonicalStopAfterTerminalLocalFailure(replayDuringPhysicalRecovery),
true,
);
const recoveredStopTarget = physicalCommandConfirmation.activeStopTarget(
replayDuringPhysicalRecovery,
);
assert.ok(recoveredStopTarget);
assert.equal(recoveredStopTarget.acquisitionId, "terminal-live-acquisition");
assert.equal(recoveredStopTarget.deviceId, "original-k1");
assert.equal(recoveredStopTarget.fence.kind, "stop");
const runtimeSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts",
import.meta.url,
),
"utf8",
);
const provisioningSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/components/K1ProvisioningPipeline.tsx",
import.meta.url,
),
"utf8",
);
const acquisitionSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/components/K1AcquisitionPipeline.tsx",
import.meta.url,
),
"utf8",
);
assert.match(runtimeSource, /requireExactReadOnlyVerificationOutcome/);
assert.match(runtimeSource, /isRecoveredPhysicalScanning\(failedState, requestedConnectionMode\)/);
assert.match(provisioningSource, /isPhysicalStopRecoverySettling\(state\)/);
assert.match(
provisioningSource,
/const canScan = backendScanAllowed && !physicalStopRecoverySettling/,
);
assert.doesNotMatch(
provisioningSource,
/K1 продолжает сканирование|Завершаем остановку K1/,
);
assert.match(acquisitionSource, /recoveredPhysicalStop\s*\? "Требуется остановка"/);
assert.match(acquisitionSource, /terminalPhysicalStopObserved\s*\? "warning"/);
assert.match(acquisitionSource, /recoveredPhysicalStop \? "Сканирование продолжается"/);
assert.match(acquisitionSource, /Нажмите «Остановить сканирование» ниже или в пространственной сцене/);
assert.match(
acquisitionSource,
/canIssueCanonicalStop\(state, physicalStopIntentSpent\)/,
);
assert.match(
acquisitionSource,
/physicalStopInFlight\s*\? "Остановка устройства…"/,
);
assert.match(
acquisitionSource,
/: physicalStopPresented \? recoveredPhysicalStop \? "Остановить сканирование" : "Остановить устройство и запись"/,
);
assert.ok(
acquisitionSource.indexOf("terminalPhysicalStopObserved ? (")
< acquisitionSource.indexOf("<div className=\"scan-configuration-grid\">"),
"recovered SCANNING must render the STOP-only branch before project/START controls",
);
});
test("K1 provisioning mutations require the operator's fresh BLE candidate", () => {
const backendLease = {
selected_device_id: "stale-backend-lease-device",
connection_mode: "bridge",
devices: [
{
device_id: "fresh-scan-candidate",
name: "K1 candidate",
connectable: true,
},
],
};
assert.equal(
lifecycle.provisioningCandidateById(backendLease.devices, ""),
null,
);
assert.equal(
lifecycle.provisioningCandidateById(
backendLease.devices,
backendLease.selected_device_id,
),
null,
);
assert.equal(lifecycle.canSubmitProvisioningMutation({
devices: backendLease.devices,
selectedDeviceId: "expired-scan-candidate",
credentialsReady: true,
isBusy: false,
}), false);
assert.equal(lifecycle.canSubmitProvisioningMutation({
devices: backendLease.devices,
selectedDeviceId: "fresh-scan-candidate",
credentialsReady: true,
isBusy: false,
}), true);
});
test("K1 connection status is green only for a reachable matching lease", () => {
const legacyReachableLease = {
k1_ip: "192.168.68.50",
connection_mode: "bridge",
connection_verification: {
lease_state: "reachable",
network_reachability: "reachable",
},
};
const reachableLease = supervisedConnectionState();
assert.equal(lifecycle.isReachableConnectionLease(legacyReachableLease, "bridge"), false);
assert.equal(lifecycle.isReachableConnectionLease(reachableLease, "bridge"), true);
assert.equal(lifecycle.isReachableConnectionLease(reachableLease, "quick-connect"), false);
assert.equal(lifecycle.isReachableConnectionLease({
k1_ip: "192.168.68.50",
connection_mode: "bridge",
}, "bridge"), false);
assert.equal(lifecycle.isReachableConnectionLease({
k1_ip: "192.168.56.1",
connection_mode: "quick-connect",
connection_verification: {
status: "control-transport-lost",
lease_state: "disconnected",
network_reachability: "unreachable",
},
}, "quick-connect"), false);
for (const mutate of [
(state) => { state.connection_supervisor.observed.device_network.state = "unconfigured"; },
(state) => { state.connection_supervisor.observed.device_network.intent_id = "stale-intent"; },
(state) => { state.connection_supervisor.observed.device_network.transport_ref = null; },
(state) => {
state.connection_supervisor.observed.device_network.target = {
...state.connection_supervisor.observed.device_network.target,
ipv4: "192.168.68.99",
};
},
(state) => { state.connection_supervisor.observed.endpoint.intent_id = "stale-intent"; },
(state) => { state.connection_supervisor.observed.endpoint.host_path_epoch = 2; },
(state) => { state.connection_supervisor.observed.host_path.route_class = "default"; },
(state) => { state.connection_supervisor.observed.device_identity.intent_id = "stale-intent"; },
(state) => { state.connection_supervisor.observed.device_identity.host_path_epoch = 2; },
(state) => { state.connection_supervisor.observed.control_plane.host_path_epoch = 2; },
(state) => { state.connection_supervisor.observed.control_plane.session_id = null; },
(state) => {
state.connection_supervisor.observed.endpoint.target = {
...state.connection_supervisor.observed.endpoint.target,
ipv4: "192.168.68.99",
};
},
]) {
const stale = structuredClone(reachableLease);
mutate(stale);
assert.equal(lifecycle.isReachableConnectionLease(stale, "bridge"), false);
}
});
test("frontend connection authority fails closed without the backend lifecycle projection", () => {
const reachable = supervisedConnectionState();
assert.equal(lifecycle.isReachableConnectionLease(reachable, "bridge"), true);
const omitted = structuredClone(reachable);
delete omitted.connection_lifecycle;
assert.equal(lifecycle.isReachableConnectionLease(omitted, "bridge"), false);
assert.equal(
lifecycle.currentAppliedConnectionTopology(omitted, "bridge")?.status,
"configured-unverified",
);
const drifted = structuredClone(reachable);
drifted.connection_lifecycle.active_mode = "quick-connect";
assert.equal(lifecycle.isReachableConnectionLease(drifted, "bridge"), false);
});
test("backend topology distinguishes reachable authority from last-known address", () => {
const target = { ipv4: "192.168.56.1", port: 1883 };
const lastKnown = supervisedConnectionState({
mode: "quick-connect",
target,
leaseState: "lost",
controlAllowed: false,
deviceNetworkState: "unconfigured",
lastKnown: {
connection_mode: "quick-connect",
target,
logical_device_id: "device-k1-001",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
verified_at: "2026-08-06T11:59:00Z",
},
});
const configured = supervisedConnectionState({
mode: "quick-connect",
target,
leaseState: "configured-unverified",
controlAllowed: false,
});
const active = supervisedConnectionState({ mode: "quick-connect", target });
assert.deepEqual(lifecycle.backendConnectionTopology(lastKnown), {
connectionMode: "quick-connect",
status: "configured-offline",
source: "last-known",
endpoint: "192.168.56.1",
});
assert.deepEqual(lifecycle.backendConnectionTopology(configured), {
connectionMode: "quick-connect",
status: "configured-unverified",
source: "applied",
endpoint: "192.168.56.1",
});
assert.deepEqual(lifecycle.backendConnectionTopology(active), {
connectionMode: "quick-connect",
status: "active",
source: "applied",
endpoint: "192.168.56.1",
});
assert.equal(lifecycle.activeConnectionEndpointLabel(lastKnown), null);
assert.equal(
lifecycle.activeConnectionEndpointLabel(active),
"192.168.56.1",
);
assert.equal(lifecycle.backendConnectionTopology({}), null);
});
test("current BLE topology remains visible offline and supersedes durable history", () => {
const currentOffline = supervisedConnectionState({
mode: "bridge",
leaseState: "lost",
controlAllowed: false,
hostAvailable: false,
endpointState: "unreachable",
});
currentOffline.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: 2,
transport_ref: "ble-k1-old",
connection_mode: "quick-connect",
ipv4: "192.168.56.1",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
firmware_version: "3.0.2",
source: "ble-read-only-status",
observed_at_utc: "2026-08-06T11:00:00Z",
},
};
assert.deepEqual(lifecycle.backendConnectionTopology(currentOffline), {
connectionMode: "bridge",
status: "configured-offline",
source: "applied",
endpoint: "192.168.68.50",
});
assert.equal(lifecycle.backendConnectionTopology(currentOffline, "quick-connect"), null);
assert.equal(lifecycle.isReachableConnectionLease(currentOffline, "bridge"), false);
assert.equal(lifecycle.isConfiguredConnectionLease(currentOffline, "bridge"), true);
assert.equal(lifecycle.hasControlAuthority(currentOffline), false);
assert.equal(
lifecycle.normalizeRuntimePhase({ ...currentOffline, phase: "connected" }),
"configuring",
);
assert.equal(lifecycle.canonicalDeviceConnectivity(currentOffline), "offline");
});
test("durable semantic topology is configured-offline evidence, never authority", () => {
const durable = {
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: 4,
transport_ref: "ble-k1-001",
connection_mode: "quick-connect",
ipv4: "192.168.56.1",
compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2",
firmware_version: "3.0.2",
source: "ble-post-write-status",
observed_at_utc: "2026-08-06T12:00:00Z",
},
},
};
assert.deepEqual(lifecycle.backendConnectionTopology(durable), {
connectionMode: "quick-connect",
status: "configured-offline",
source: "durable",
endpoint: "192.168.56.1",
});
assert.equal(lifecycle.isConfiguredConnectionLease(durable, "quick-connect"), true);
assert.equal(lifecycle.isReachableConnectionLease(durable, "quick-connect"), false);
assert.equal(lifecycle.hasControlAuthority(durable), false);
assert.equal(lifecycle.normalizeRuntimePhase({ ...durable, phase: "connected" }), "configuring");
assert.equal(lifecycle.canonicalDeviceConnectivity(durable), "offline");
const hostProbed = structuredClone(durable);
hostProbed.configured_endpoint_probe = {
schema_version: "missioncore.xgrids-k1-configured-endpoint-probe/v1",
status: "reachable",
target_source: "durable-semantic-topology",
connection_mode: "quick-connect",
endpoint: "192.168.56.1",
transport_ref: "ble-k1-001",
intent_id: null,
semantic_revision: 4,
host_route_available: true,
host_route_class: "direct",
tcp_reachable: true,
identity_validation: "not-performed",
control_authority_granted: false,
ble_operation_performed: false,
network_mutation_performed: false,
automatic_retry: false,
observed_at: "2026-08-08T12:30:19Z",
reason_code: null,
};
assert.deepEqual(lifecycle.backendConnectionTopology(hostProbed), {
connectionMode: "quick-connect",
status: "configured-unverified",
source: "durable",
endpoint: "192.168.56.1",
});
assert.equal(lifecycle.isReachableConnectionLease(hostProbed, "quick-connect"), false);
assert.equal(lifecycle.hasControlAuthority(hostProbed), false);
for (const status of ["empty", "corrupt"]) {
const unavailable = structuredClone(durable);
unavailable.semantic_topology_store.status = status;
unavailable.semantic_topology_store.record = null;
unavailable.semantic_topology_store.configured_offline_evidence = false;
assert.equal(lifecycle.backendConnectionTopology(unavailable), null);
}
});
test("unresolved or corrupt durable mutation state remains a provisioning barrier", () => {
assert.equal(lifecycle.hasUnresolvedNetworkMutation({}), false);
assert.equal(lifecycle.hasUnresolvedNetworkMutation({ network_write_reconciliation: {} }), true);
assert.equal(lifecycle.hasUnresolvedNetworkMutation({
network_mutation_ledger: { status: "unresolved", mutation_allowed: false },
}), true);
assert.equal(lifecycle.hasUnresolvedNetworkMutation({
network_mutation_ledger: { status: "corrupt", mutation_allowed: false },
}), true);
assert.equal(lifecycle.hasUnresolvedNetworkMutation({
network_mutation_ledger: { status: "resolved", mutation_allowed: true },
}), false);
});
test("retained BLE context is never presence but can carry one backend-authorized recovery", () => {
const activeQuick = {
current_device_recovery: {
transport_ref: "exact-session-handle",
connection_mode: "quick-connect",
handle_available: true,
handle_retained: true,
advertised_now: false,
gatt_validated_recently: true,
},
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
allowed_actions: ["recover-current-device-network"],
actions: {
"recover-current-device-network": {
allowed: true,
reason_codes: [],
target_source: "retained-current-process",
required_transport_ref: "exact-session-handle",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
facts: {
retained_context_is_presence: false,
},
},
};
assert.equal(
lifecycle.currentDeviceTransportRef(activeQuick),
"exact-session-handle",
);
assert.deepEqual(lifecycle.retainedBleRecoveryTarget(activeQuick), {
transportRef: "exact-session-handle",
connectionMode: "quick-connect",
gattValidatedRecently: true,
});
assert.equal(
lifecycle.provisioningCandidateById([], "exact-session-handle"),
null,
);
assert.equal(
lifecycle.canSubmitProvisioningMutation({
devices: [],
selectedDeviceId: "exact-session-handle",
credentialsReady: true,
isBusy: false,
}),
false,
);
assert.equal(
lifecycle.connectionPolicyAllows(
activeQuick,
"recover-current-device-network",
),
true,
);
assert.equal(
lifecycle.connectionPolicyDecision(
activeQuick,
"recover-current-device-network",
).requires_live_gatt_validation,
true,
);
const freshlyObserved = {
device_id: "exact-session-handle",
name: "Lixel K1",
connectable: true,
};
assert.equal(
lifecycle.provisioningCandidateById(
[freshlyObserved],
"exact-session-handle",
),
freshlyObserved,
);
assert.equal(
lifecycle.canSubmitProvisioningMutation({
devices: [freshlyObserved],
selectedDeviceId: "exact-session-handle",
credentialsReady: true,
isBusy: false,
}),
true,
);
assert.equal(lifecycle.retainedBleRecoveryTarget({
current_device_recovery: {
...activeQuick.current_device_recovery,
advertised_now: true,
},
}), null);
});
test("browser refresh never adopts an existing backend K1 session as selection", () => {
const backendSession = {
selected_device_id: "ble-k1-001",
connection_mode: "bridge",
device_session: {
device_session_id: "device-session-001",
device_id: "logical-k1-001",
},
current_device_recovery: {
transport_ref: "ble-k1-001",
connection_mode: "bridge",
handle_retained: true,
},
};
assert.equal(
lifecycle.locallyInitiatedBleSessionTarget(backendSession, null, "bridge"),
null,
);
assert.equal(
lifecycle.locallyInitiatedBleSessionTarget(
backendSession,
"another-device",
"bridge",
),
null,
);
assert.equal(
lifecycle.locallyInitiatedBleSessionTarget(
backendSession,
"ble-k1-001",
"quick-connect",
),
null,
);
});
test("a pending local connect cannot bind the old matching backend session", () => {
const oldBackendSession = {
selected_device_id: "ble-k1-001",
connection_mode: "bridge",
device_session: {
device_session_id: "device-session-A",
device_id: "logical-k1-001",
},
current_device_recovery: {
transport_ref: "ble-k1-001",
connection_mode: "bridge",
handle_retained: true,
},
};
const oldTarget = lifecycle.bleSessionTargetForTransport(
oldBackendSession,
"ble-k1-001",
"bridge",
);
assert.equal(oldTarget?.key, "device-session-A:bridge:ble-k1-001");
assert.equal(
lifecycle.locallyInitiatedBleSessionTarget(
oldBackendSession,
null,
"bridge",
),
null,
"pending is not a successful local intent and grants no bind authority",
);
assert.equal(
lifecycle.acceptedBleSessionKeyAfterConnect(
oldBackendSession,
"ble-k1-001",
"bridge",
oldTarget.key,
),
null,
"the session that predated the click is not an accepted result",
);
});
test("a successful local connect binds only the new matching backend session", () => {
const backendSession = {
selected_device_id: "ble-k1-001",
connection_mode: "bridge",
device_session: {
device_session_id: "device-session-B",
device_id: "logical-k1-001",
},
current_device_recovery: {
transport_ref: "ble-k1-001",
connection_mode: "bridge",
handle_retained: true,
},
};
const acceptedSessionKey = lifecycle.acceptedBleSessionKeyAfterConnect(
backendSession,
"ble-k1-001",
"bridge",
"device-session-A:bridge:ble-k1-001",
);
assert.equal(acceptedSessionKey, "device-session-B:bridge:ble-k1-001");
assert.deepEqual(
lifecycle.locallyInitiatedBleSessionTarget(
backendSession,
"ble-k1-001",
"bridge",
{ requiredSessionKey: acceptedSessionKey },
),
{
transportRef: "ble-k1-001",
connectionMode: "bridge",
deviceSessionId: "device-session-B",
key: "device-session-B:bridge:ble-k1-001",
},
);
assert.equal(
lifecycle.locallyInitiatedBleSessionTarget(
{
...backendSession,
device_session: {
...backendSession.device_session,
device_session_id: "device-session-C",
},
},
"ble-k1-001",
"bridge",
{ requiredSessionKey: acceptedSessionKey },
),
null,
"a later session cannot silently replace the accepted session B",
);
assert.equal(
lifecycle.locallyInitiatedBleSessionTarget(
{ ...backendSession, device_session: null },
"ble-k1-001",
"bridge",
{ requiredSessionKey: acceptedSessionKey },
),
null,
);
assert.equal(
lifecycle.acceptedBleSessionKeyAfterConnect(
{ ...backendSession, device_session: null },
"ble-k1-001",
"bridge",
"device-session-A:bridge:ble-k1-001",
),
null,
"success without an exact returned session key is a clean reset",
);
assert.equal(
lifecycle.canAdmitProvisioningConnection({
policyAllowed: true,
targetSource: "fresh-scan",
hasSuccessfulLocalConnect: false,
localPrerequisitesReady: true,
}),
true,
"after the reset a fresh explicit scan selection can connect",
);
});
test("an arbitrary BLE result set never selects or connects a device", () => {
const devices = Array.from({ length: 20 }, (_, index) => ({
device_id: `ble-device-${String(index + 1).padStart(2, "0")}`,
name: `BLE device ${index + 1}`,
connectable: true,
}));
assert.equal(lifecycle.provisioningCandidateById(devices, ""), null);
assert.equal(
lifecycle.canSubmitProvisioningMutation({
devices,
selectedDeviceId: "",
credentialsReady: true,
isBusy: false,
}),
false,
);
});
test("connection policy remains authoritative when historical operations are present", () => {
const state = {
operations: [{
action: "network.provision",
status: "running",
operation_id: "historical-operation",
}],
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,
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
},
};
assert.equal(
lifecycle.connectionPolicyAllows(state, "provision-fresh-device"),
true,
);
assert.equal(
lifecycle.canAdmitProvisioningConnection({
policyAllowed: true,
targetSource: "fresh-scan",
hasSuccessfulLocalConnect: false,
localPrerequisitesReady: true,
}),
true,
);
});
test("legacy backend recovery evidence keeps exact UUID and mode outside UI admission", () => {
const decision = (allowed, target_source, required_transport_ref, required_connection_mode) => ({
allowed,
reason_codes: allowed ? [] : ["not-selected"],
target_source,
required_transport_ref,
required_connection_mode,
requires_live_gatt_validation: true,
automatic_retry: false,
});
const state = {
ble_discovery_generation: 7,
devices: [{
device_id: "fresh-policy-k1",
name: "Lixel K1",
connectable: true,
}],
network_mutation_ledger: {
status: "unresolved",
mutation_allowed: false,
},
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
allowed_actions: [
"observe-fresh-device-network",
"observe-current-device-network",
"observe-configured-device-network",
],
actions: {
"observe-fresh-device-network": decision(
true,
"fresh-scan",
"fresh-policy-k1",
"direct-connect",
),
"observe-current-device-network": decision(
true,
"retained-current-process",
"retained-policy-k1",
"quick-connect",
),
"observe-configured-device-network": decision(
true,
"durable-configured-state",
"durable-policy-k1",
"bridge",
),
},
facts: { retained_context_is_presence: false },
},
};
assert.deepEqual(
lifecycle.readOnlyConnectionObservationTarget(
state,
"different-browser-selection",
"bridge",
),
{
action: "observe-fresh-device-network",
deviceId: "fresh-policy-k1",
connectionMode: "direct-connect",
source: "fresh-scan",
serverBound: true,
expectedDiscoveryGeneration: 7,
},
);
state.devices = [];
state.connection_policy.allowed_actions = [
"observe-current-device-network",
"observe-configured-device-network",
];
state.connection_policy.actions["observe-fresh-device-network"] = decision(
false,
"fresh-scan",
"fresh-policy-k1",
"direct-connect",
);
assert.deepEqual(
lifecycle.readOnlyConnectionObservationTarget(
state,
"stale-browser-selection",
"direct-connect",
),
{
action: "observe-current-device-network",
deviceId: "retained-policy-k1",
connectionMode: "quick-connect",
source: "retained-current-process",
serverBound: true,
expectedDiscoveryGeneration: null,
},
);
assert.deepEqual(
lifecycle.serverBoundAppliedNetworkObservationTarget(state, "quick-connect"),
{
action: "observe-current-device-network",
deviceId: "retained-policy-k1",
connectionMode: "quick-connect",
source: "retained-current-process",
serverBound: true,
expectedDiscoveryGeneration: null,
},
);
state.network_mutation_ledger = {
status: "resolved",
mutation_allowed: true,
};
state.devices = [{
device_id: "durable-policy-k1",
name: "Lixel K1",
connectable: true,
}];
state.connection_policy.allowed_actions = [
"observe-fresh-device-network",
"observe-configured-device-network",
];
state.connection_policy.actions["observe-fresh-device-network"] = decision(
true,
"fresh-scan",
null,
null,
);
state.connection_policy.actions["observe-current-device-network"] = decision(
false,
"retained-current-process",
"retained-policy-k1",
"quick-connect",
);
assert.deepEqual(
lifecycle.readOnlyConnectionObservationTarget(
state,
"stale-browser-selection",
"direct-connect",
),
{
action: "observe-configured-device-network",
deviceId: "durable-policy-k1",
connectionMode: "bridge",
source: "durable-configured-state",
serverBound: true,
expectedDiscoveryGeneration: null,
},
);
assert.deepEqual(
lifecycle.serverBoundAppliedNetworkObservationTarget(state, "bridge"),
{
action: "observe-configured-device-network",
deviceId: "durable-policy-k1",
connectionMode: "bridge",
source: "durable-configured-state",
serverBound: true,
expectedDiscoveryGeneration: null,
},
);
});
test("legacy unresolved backend evidence never falls back to stale browser state", () => {
const state = {
devices: [],
network_mutation_ledger: {
status: "unresolved",
mutation_allowed: false,
},
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
allowed_actions: ["observe-configured-device-network"],
actions: {
"observe-configured-device-network": {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: "durable-policy-k1",
required_connection_mode: null,
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
facts: { retained_context_is_presence: false },
},
};
assert.equal(
lifecycle.readOnlyConnectionObservationTarget(
state,
"stale-browser-k1",
"quick-connect",
),
null,
);
});
test("local receiver cleanup never targets a replay session's retained acquisition", () => {
assert.deepEqual(lifecycle.localReceiverStopPlan({
source_mode: "replay",
acquisition: {
acquisition_id: "terminal-live-acquisition",
state: "completed",
cleanup_pending: false,
},
}), { kind: "compatibility" });
assert.deepEqual(lifecycle.localReceiverStopPlan({
source_mode: "idle",
acquisition: {
acquisition_id: " exact-cleanup-target ",
state: "failed",
cleanup_pending: true,
},
}), {
kind: "acquisition",
acquisitionId: "exact-cleanup-target",
});
assert.deepEqual(lifecycle.localReceiverStopPlan({
source_mode: "idle",
acquisition: {
acquisition_id: "released-terminal-acquisition",
state: "failed",
cleanup_pending: false,
},
}), { kind: "compatibility" });
});
test("local receiver policy denial distinguishes proven idle from active cleanup", () => {
assert.equal(lifecycle.isProvenLocalReceiverInactive({
source_mode: "idle",
acquisition: null,
}), true);
assert.equal(lifecycle.isProvenLocalReceiverInactive({
source_mode: "idle",
acquisition: {
state: "failed",
cleanup_pending: false,
},
}), true);
assert.equal(lifecycle.isProvenLocalReceiverInactive({
source_mode: "idle",
acquisition: {
state: "failed",
cleanup_pending: true,
},
}), false);
assert.equal(lifecycle.isProvenLocalReceiverInactive({
source_mode: "live",
acquisition: {
state: "acquiring",
cleanup_pending: false,
},
}), false);
assert.equal(lifecycle.isProvenLocalReceiverInactive({
source_mode: "replay",
acquisition: {
state: "completed",
cleanup_pending: false,
},
}), false);
});
test("trusted K1 recovery uses only one exact backend-owned device and mode", () => {
const state = {
physical_command: {
status: "unresolved",
requires_reconciliation: true,
resolved_active_recovery_required: false,
},
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
allowed_actions: ["observe-configured-device-network"],
actions: {
"provision-fresh-device": {
allowed: false,
reason_codes: ["physical-command-reconciliation-required"],
target_source: "fresh-scan",
required_transport_ref: "physical-k1",
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
"observe-configured-device-network": {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: "physical-k1",
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
facts: { retained_context_is_presence: false },
},
semantic_topology_store: {
record: {
transport_ref: "semantic-k1",
connection_mode: "quick-connect",
},
},
current_device_recovery: {
transport_ref: "process-k1",
connection_mode: "direct-connect",
},
};
assert.deepEqual(lifecycle.trustedConnectionBinding(state), {
deviceId: "physical-k1",
connectionMode: "bridge",
});
delete state.connection_policy.actions["provision-fresh-device"];
state.physical_command.requires_reconciliation = false;
assert.deepEqual(lifecycle.trustedConnectionBinding(state), {
deviceId: "semantic-k1",
connectionMode: "quick-connect",
});
state.semantic_topology_store.record.connection_mode = null;
assert.deepEqual(lifecycle.trustedConnectionBinding(state), {
deviceId: "process-k1",
connectionMode: "direct-connect",
});
state.current_device_recovery.connection_mode = null;
assert.equal(lifecycle.trustedConnectionBinding(state), null);
});
test("only an unresolved durable STOP blocks connection controls during backend cleanup", () => {
const unresolvedStop = {
source_mode: "live",
acquisition: {
state: "stopping",
cleanup_pending: true,
},
application_control_session: {
state: "awaiting-standby-confirmation",
physical_command: {
status: "unresolved",
requires_reconciliation: true,
record: {
action: "stop",
stage: "requested",
resolution: null,
},
},
},
};
assert.equal(lifecycle.isPhysicalStopRecoverySettling(unresolvedStop), true);
const boundedTimeout = structuredClone(unresolvedStop);
boundedTimeout.source_mode = "idle";
boundedTimeout.acquisition.state = "failed";
boundedTimeout.acquisition.cleanup_pending = false;
boundedTimeout.operations = [{
action: "acquisition.stop",
status: "timed_out",
}];
// The durable physical ledger remains intentionally unresolved, but all
// local work is released. The connection screen must leave the STOP loader
// and may start the separate bounded connection recovery path.
assert.equal(lifecycle.isPhysicalStopRecoverySettling(boundedTimeout), false);
const backendObservedStandby = structuredClone(unresolvedStop);
backendObservedStandby.application_control_session.state = "idle";
backendObservedStandby.application_control_session.physical_command.status = "resolved";
backendObservedStandby.application_control_session.physical_command.requires_reconciliation = false;
backendObservedStandby.application_control_session.physical_command.record.stage = "resolved";
backendObservedStandby.application_control_session.physical_command.record.resolution =
"stop-standby-observed";
assert.equal(
lifecycle.isPhysicalStopRecoverySettling(backendObservedStandby),
false,
);
const unresolvedStart = structuredClone(unresolvedStop);
unresolvedStart.application_control_session.physical_command.record.action = "start";
assert.equal(lifecycle.isPhysicalStopRecoverySettling(unresolvedStart), false);
});
test("physical recovery stays pinned to the original K1 across a multi-device BLE scan", () => {
const state = {
physical_command: {
status: "unresolved",
requires_reconciliation: true,
resolved_active_recovery_required: false,
},
ble_discovery_generation: 9,
devices: [
{ device_id: "nearby-other-k1", name: "Nearby K1", connectable: true },
{ device_id: "original-k1", name: "Original K1", connectable: true },
],
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
allowed_actions: ["scan-ble", "observe-fresh-device-network"],
actions: {
"provision-fresh-device": {
allowed: false,
reason_codes: ["physical-device-already-active"],
target_source: "fresh-scan",
required_transport_ref: "original-k1",
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
"observe-fresh-device-network": {
allowed: true,
reason_codes: [],
target_source: "fresh-scan",
required_transport_ref: "original-k1",
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
facts: { retained_context_is_presence: false },
},
};
assert.equal(lifecycle.requiresReadOnlyPhysicalRecovery(state), true);
assert.deepEqual(lifecycle.readOnlyPhysicalRecoveryBinding(state), {
deviceId: "original-k1",
connectionMode: "bridge",
});
assert.deepEqual(
lifecycle.readOnlyConnectionObservationTarget(
state,
"nearby-other-k1",
"quick-connect",
),
{
action: "observe-fresh-device-network",
deviceId: "original-k1",
connectionMode: "bridge",
source: "fresh-scan",
serverBound: true,
expectedDiscoveryGeneration: 9,
},
);
state.devices = [{ device_id: "nearby-other-k1", name: "Nearby K1", connectable: true }];
assert.equal(
lifecycle.readOnlyConnectionObservationTarget(
state,
"nearby-other-k1",
"quick-connect",
),
null,
"another nearby K1 must not become a fallback recovery target",
);
});
test("READY-classified STOP exits recovery UI while START follows backend authority", () => {
const readyPhysical = {
status: "resolved",
reason_code: null,
requires_reconciliation: false,
resolved_active_recovery_required: false,
observed_session_state: "ready",
record: {
action: "stop",
stage: "resolved",
resolution: "not-dispatched",
reconciled_physical_state: "standby",
},
};
const readySuccessor = {
physical_command: readyPhysical,
application_control_session: {
physical_command: readyPhysical,
},
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
allowed_actions: ["start-acquisition"],
actions: {
"start-acquisition": {
allowed: true,
reason_codes: [],
target_source: "durable-physical-command",
required_transport_ref: "original-k1",
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
"provision-fresh-device": {
allowed: false,
reason_codes: ["physical-command-reconciliation-required"],
target_source: "fresh-scan",
required_transport_ref: "original-k1",
required_connection_mode: "bridge",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
facts: { retained_context_is_presence: false },
},
connection_lifecycle: {
schema_version: "missioncore.xgrids-k1-connection-lifecycle/v1",
mode_selection: {
allowed: false,
reason_codes: ["connection-mode-selection-physical-state-unsafe"],
automatic_retry: false,
},
allowed_actions: ["start-acquisition"],
},
};
assert.equal(lifecycle.requiresReadOnlyPhysicalRecovery(readySuccessor), false);
assert.equal(lifecycle.connectionPolicyAllows(readySuccessor, "start-acquisition"), true);
assert.equal(
lifecycle.connectionPolicyAllows(readySuccessor, "provision-fresh-device"),
false,
"the exact successor binding remains pinned against network mutation",
);
assert.equal(
lifecycle.canSelectConnectionMode(readySuccessor),
false,
"the exact successor binding remains pinned against mode changes",
);
const unresolved = structuredClone(readySuccessor);
unresolved.application_control_session.physical_command.requires_reconciliation = true;
assert.equal(lifecycle.requiresReadOnlyPhysicalRecovery(unresolved), true);
const scanOver = structuredClone(readySuccessor);
scanOver.application_control_session.physical_command.requires_reconciliation = true;
scanOver.application_control_session.physical_command.resolved_scan_over_recovery_required = true;
assert.equal(lifecycle.requiresReadOnlyPhysicalRecovery(scanOver), true);
const reconciledActive = structuredClone(readySuccessor);
reconciledActive.application_control_session.physical_command.resolved_active_recovery_required = true;
reconciledActive.application_control_session.physical_command.observed_session_state = "scanning";
assert.equal(lifecycle.requiresReadOnlyPhysicalRecovery(reconciledActive), true);
const reopened = structuredClone(readySuccessor);
reopened.application_control_session.physical_command.resolved_active_recovery_required = true;
reopened.application_control_session.physical_command.reopened_physical_state_recovery_required = true;
assert.equal(lifecycle.requiresReadOnlyPhysicalRecovery(reopened), true);
});
test("only a newer authoritative reachable lease resolves connection errors", () => {
const error = {
action: "connect",
runtimeId: "runtime-a",
leaseGeneration: 4,
};
const reachableBridge = supervisedConnectionState({ generation: 5 });
assert.equal(
lifecycle.authoritativeReachableLeaseSupersedesError(error, reachableBridge),
true,
);
assert.equal(
lifecycle.authoritativeReachableLeaseSupersedesError(
{ ...error, action: "scan" },
reachableBridge,
),
false,
);
assert.equal(
lifecycle.authoritativeReachableLeaseSupersedesError(
error,
supervisedConnectionState({ generation: 4 }),
),
false,
);
assert.equal(
lifecycle.authoritativeReachableLeaseSupersedesError(
error,
{ ...reachableBridge, network_write_reconciliation: {} },
),
false,
);
assert.equal(
lifecycle.authoritativeReachableLeaseSupersedesError(
error,
{ ...reachableBridge, snapshot_runtime_id: "runtime-b" },
),
false,
);
});
test("connection-mode reset is explicit and CAS-fenced before the next flow", async () => {
const pipelineSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/components/K1ProvisioningPipeline.tsx",
import.meta.url,
),
"utf8",
);
const connectionSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/XgridsK1Connection.tsx",
import.meta.url,
),
"utf8",
);
assert.doesNotMatch(pipelineSource, /nextReachableConnectionModeSynchronization/);
assert.doesNotMatch(pipelineSource, /synchronizedLeaseKeyRef/);
assert.doesNotMatch(pipelineSource, /setConnectionMode\(/);
assert.match(connectionSource, /state\.desired_connection_mode/);
assert.doesNotMatch(connectionSource, /selectConnectionMode\(\{/);
assert.match(connectionSource, /desiredModeLocallyDirty\.current = mode !== state\?\.desired_connection_mode/);
assert.match(connectionSource, /setDesiredConnectionMode\(mode\)/);
const localModeChange = pipelineSource.slice(
pipelineSource.indexOf("const changeDesiredConnectionMode"),
pipelineSource.indexOf("const selectFreshDevice"),
);
const explicitModeCommit = pipelineSource.slice(
pipelineSource.indexOf("const commitDesiredModeForExplicitAction"),
pipelineSource.indexOf("const currentPreparingReconfigurationRequest"),
);
assert.match(localModeChange, /await selectConnectionMode\(\{/);
assert.match(localModeChange, /expected_revision: expectedRevision as number/);
assert.match(localModeChange, /reset_scenario: true/);
assert.match(localModeChange, /reset_id: resetId/);
assert.doesNotMatch(
localModeChange,
/scanWithResult\(|connect\(|verifyConnection\(|prepareConnection/,
);
assert.match(explicitModeCommit, /selectConnectionMode\(\{/);
assert.match(explicitModeCommit, /expected_revision: expectedRevision as number/);
assert.match(
pipelineSource,
/const repeatDeviceScan[\s\S]*?await commitDesiredModeForExplicitAction\(\)/,
);
assert.match(
pipelineSource,
/const submitConnect[\s\S]*?await commitDesiredModeForExplicitAction\(\)/,
);
});
test("connection-mode selector follows the authoritative backend admission", () => {
const ready = supervisedConnectionState({ connectionReady: true });
assert.equal(lifecycle.canSelectConnectionMode(ready), true);
const prepared = structuredClone(ready);
prepared.acquisition = {
acquisition_id: "acq-prepared",
state: "prepared",
project_name: "TEST001",
};
assert.equal(lifecycle.canSelectConnectionMode(prepared), true);
for (const reasonCode of [
"connection-mode-selection-control-state-unsafe",
"connection-mode-selection-acquisition-active",
"connection-mode-selection-physical-state-unsafe",
]) {
const blocked = structuredClone(ready);
blocked.connection_lifecycle.mode_selection = {
allowed: false,
reason_codes: [reasonCode],
automatic_retry: false,
};
blocked.connection_lifecycle.allowed_actions = ["start-acquisition"];
assert.equal(lifecycle.canSelectConnectionMode(blocked), false);
}
const drifted = structuredClone(ready);
drifted.connection_lifecycle.allowed_actions = ["start-acquisition"];
assert.equal(lifecycle.canSelectConnectionMode(drifted), false);
assert.equal(lifecycle.canSelectConnectionMode({}), false);
});
test("prepared project survives a mode draft and its cancellation", () => {
assert.equal(projectName.shouldHydratePreparedProject({
acquisitionId: "acq-prepared",
hydratedAcquisitionId: null,
modeSwitchRequired: false,
}), true);
let displayedProject = projectName.projectNameAfterConnectionModeSelection("TEST001");
assert.equal(displayedProject, "TEST001");
assert.equal(projectName.validateProjectName(displayedProject).error, null);
assert.equal(projectName.shouldHydratePreparedProject({
acquisitionId: "acq-prepared",
hydratedAcquisitionId: "acq-prepared",
modeSwitchRequired: true,
}), false);
displayedProject = projectName.projectNameAfterConnectionModeSelection("TEST001");
assert.equal(displayedProject, "TEST001");
assert.equal(projectName.validateProjectName(displayedProject).error, null);
assert.equal(projectName.shouldHydratePreparedProject({
acquisitionId: "acq-prepared",
hydratedAcquisitionId: "acq-prepared",
modeSwitchRequired: false,
}), true);
assert.equal(projectName.projectNameAfterConnectionModeSelection(null), "");
});
test("one in-flight provisioning call keeps its idempotency key internally", () => {
let created = 0;
const createUuid = () => {
created += 1;
return "11111111-1111-4111-8111-111111111111";
};
const first = lifecycle.provisioningIntentKey(null, createUuid);
const repeated = lifecycle.provisioningIntentKey(first, createUuid);
const failedOperation = {
status: "failed",
error: { safe_to_retry: false, side_effect_status: "unknown" },
};
const safePreWriteFailure = {
status: "failed",
error: { safe_to_retry: true, side_effect_status: "none" },
};
assert.equal(first, "network-provision:11111111-1111-4111-8111-111111111111");
assert.equal(repeated, first);
assert.equal(created, 1);
assert.equal(lifecycle.operationNeedsReconciliation(failedOperation), true);
assert.equal(
lifecycle.operationAllowsFreshProvisioningIntent(safePreWriteFailure),
true,
);
assert.equal(
lifecycle.operationAllowsFreshProvisioningIntent(failedOperation),
false,
);
});
test("read-only verification releases only a durably resolved matching write fence", () => {
const fence = {
operation_id: "op-ambiguous",
transport_ref: "k1-a",
};
const before = {
snapshot_runtime_id: "runtime-a",
network_write_reconciliation: fence,
};
const resolvedLedger = {
status: "resolved",
mutation_allowed: true,
operation_id: "op-ambiguous",
stage: "resolved",
resolution: "target-observed",
};
assert.equal(
lifecycle.readOnlyVerificationClearedReconciliation(
before,
{
snapshot_runtime_id: "runtime-restarted",
network_write_reconciliation: null,
network_mutation_ledger: resolvedLedger,
},
"k1-a",
),
true,
);
assert.equal(
lifecycle.readOnlyVerificationClearedReconciliation(
before,
{
network_write_reconciliation: null,
network_mutation_ledger: {
status: "empty",
mutation_allowed: true,
operation_id: null,
stage: null,
resolution: null,
},
},
"k1-a",
),
true,
);
assert.equal(
lifecycle.readOnlyVerificationClearedReconciliation(before, {}, "k1-a"),
false,
);
assert.equal(
lifecycle.readOnlyVerificationClearedReconciliation(
before,
{
network_write_reconciliation: fence,
network_mutation_ledger: {
...resolvedLedger,
status: "unresolved",
mutation_allowed: false,
stage: "observing",
resolution: null,
},
},
"k1-a",
),
false,
);
assert.equal(
lifecycle.readOnlyVerificationClearedReconciliation(
before,
{
network_write_reconciliation: null,
network_mutation_ledger: resolvedLedger,
},
"k1-b",
),
false,
);
assert.equal(
lifecycle.readOnlyVerificationClearedReconciliation(
before,
{
network_write_reconciliation: null,
network_mutation_ledger: {
...resolvedLedger,
operation_id: "op-different",
},
},
"k1-a",
),
false,
);
assert.equal(
lifecycle.readOnlyVerificationClearedReconciliation(
before,
{
network_write_reconciliation: null,
network_mutation_ledger: {
...resolvedLedger,
resolution: null,
},
},
"k1-a",
),
false,
);
});
test("each terminal explicit provisioning click starts a fresh operation identity", async () => {
const hookSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts",
import.meta.url,
),
"utf8",
);
const pipelineSource = await readFile(
new URL(
"../../../plugins/xgrids-k1/frontend/src/components/K1ProvisioningPipeline.tsx",
import.meta.url,
),
"utf8",
);
const connectRecovery = hookSource.slice(
hookSource.indexOf("const connect = useCallback"),
hookSource.indexOf("const verifyConnection = useCallback"),
);
const submitConnect = pipelineSource.slice(
pipelineSource.indexOf("const submitConnect = async"),
pipelineSource.indexOf("return (", pipelineSource.indexOf("const submitConnect = async")),
);
assert.match(
connectRecovery,
/observeProvisioningRequest\([\s\S]*?observedState = observation\.state[\s\S]*?const exactNetworkIntentCompleted = exactAppliedNetworkIntentCompleted\(/,
);
assert.match(
connectRecovery,
/const exactNetworkIntentCompleted = exactAppliedNetworkIntentCompleted\([\s\S]*?nextState = acceptSuccessfulConnectState\(nextState\)/,
);
assert.match(connectRecovery, /acceptedBleSessionKeyAfterConnect\(/);
assert.match(
connectRecovery,
/acceptedSessionKey:\s*networkIntentCompleted \? acceptedSessionKey : null/,
);
assert.match(submitConnect, /provisioningIntentKey\(null\)/);
assert.doesNotMatch(submitConnect, /provisioningIntentRef/);
assert.match(
submitConnect,
/const freshStartAllowed = result\.intentDisposition === "release"/,
);
assert.match(
submitConnect,
/setExplicitProvisioningDraft\(null\);[\s\S]*?setPassword\(""\);[\s\S]*?await connect\(/,
);
assert.match(submitConnect, /setSelectedDeviceSnapshot\(null\)/);
assert.doesNotMatch(pipelineSource, /Проверить K1 без записи/);
});
test("device mutations send explicit nested compatibility attestation", async () => {
const originalFetch = globalThis.fetch;
const calls = [];
const syntheticCredential = "x".repeat(32);
globalThis.fetch = async (path, init) => {
calls.push({ path, init });
return new Response(JSON.stringify({ state: { source_mode: "idle" } }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
};
const attestation = {
firmware_version: "3.0.2",
topology: "direct-lan",
verification: "live-device-info",
};
try {
await xgridsK1Api.connect({
expected_snapshot_runtime_id: "snapshot-runtime-test",
device_id: "ble-device",
ssid: "lab-network",
password: syntheticCredential,
connection_mode: "bridge",
compatibility_attestation: attestation,
idempotency_key: "network-provision:test",
expected_mode_revision: 4,
expected_discovery_generation: 9,
});
await xgridsK1Api.prepareAcquisition({
project_name: "Mission 01",
mount_type: "handheld",
gnss_mode: "none",
compatibility_attestation: attestation,
});
} finally {
globalThis.fetch = originalFetch;
}
assert.equal(calls.length, 2);
const provisioning = JSON.parse(calls[0].init.body);
const prepare = JSON.parse(calls[1].init.body);
assert.deepEqual(provisioning.input.compatibility_attestation, attestation);
assert.equal(provisioning.input.idempotency_key, "network-provision:test");
assert.equal(provisioning.input.expected_mode_revision, 4);
assert.equal(provisioning.input.expected_discovery_generation, 9);
assert.equal(
provisioning.input.expected_snapshot_runtime_id,
"snapshot-runtime-test",
);
assert.deepEqual(prepare.input.compatibility_attestation, attestation);
assert.equal(prepare.input.project_name, "Mission 01");
});
test("endpoint probing is separate from BLE refresh and read-only adoption", async () => {
const originalFetch = globalThis.fetch;
const calls = [];
globalThis.fetch = async (path, init) => {
calls.push({ path, init });
return new Response(JSON.stringify({ state: { source_mode: "idle" } }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
};
const attestation = {
firmware_version: "3.0.2",
topology: "direct-lan",
verification: "live-device-info",
};
try {
await xgridsK1Api.verifyConnection({
expected_snapshot_runtime_id: "snapshot-runtime-test",
device_id: "fresh-ble-device",
source: "fresh-scan",
compatibility_attestation: attestation,
expected_discovery_generation: 11,
});
await xgridsK1Api.verifyConnection({
expected_snapshot_runtime_id: "snapshot-runtime-test",
device_id: "durable-ble-device",
source: "durable-configured-state",
compatibility_attestation: attestation,
});
await xgridsK1Api.probeConfiguredEndpoint({
expected_snapshot_runtime_id: "snapshot-runtime-test",
});
} finally {
globalThis.fetch = originalFetch;
}
assert.equal(calls.length, 3);
assert.match(String(calls[0].path), /actions\/connection\.verify$/);
const adoption = JSON.parse(calls[0].init.body).input;
assert.deepEqual(adoption, {
expected_snapshot_runtime_id: "snapshot-runtime-test",
device_id: "fresh-ble-device",
source: "fresh-scan",
compatibility_attestation: attestation,
expected_discovery_generation: 11,
});
assert.equal("ssid" in adoption, false);
assert.equal("password" in adoption, false);
assert.equal("connection_mode" in adoption, false);
const durableAdoption = JSON.parse(calls[1].init.body).input;
assert.deepEqual(durableAdoption, {
expected_snapshot_runtime_id: "snapshot-runtime-test",
device_id: "durable-ble-device",
source: "durable-configured-state",
compatibility_attestation: attestation,
});
assert.equal("expected_discovery_generation" in durableAdoption, false);
assert.match(String(calls[2].path), /actions\/connection\.endpoint-probe$/);
assert.deepEqual(JSON.parse(calls[2].init.body), {
input: { expected_snapshot_runtime_id: "snapshot-runtime-test" },
});
});
test("connection verification accepts only the backend literal status and lease contract", () => {
const statuses = [
"not-probed",
"device-network-applied",
"device-network-applied-host-failed",
"adopted",
"host-route-mismatch",
"endpoint-unreachable",
"tcp-reachable-device-info-unverified",
"reachable",
"recovered",
"control-transport-lost",
"unreachable",
];
const leaseStates = ["disconnected", "configured-unverified", "reachable"];
assert.deepEqual([...XGRIDS_CONNECTION_VERIFICATION_STATUSES], statuses);
assert.deepEqual([...XGRIDS_CONNECTION_VERIFICATION_LEASE_STATES], leaseStates);
const exact = {
status: "not-probed",
lease_state: "disconnected",
lease_generation: 0,
supervisor_revision: 1,
endpoint_validation: "not-performed",
network_reachability: "unknown",
observed_at: null,
};
for (const status of statuses) {
assert.equal(isXgridsConnectionVerification({ ...exact, status }), true, status);
}
for (const lease_state of leaseStates) {
assert.equal(
isXgridsConnectionVerification({ ...exact, lease_state }),
true,
lease_state,
);
}
for (const malformed of [
{ ...exact, status: "configured" },
{ ...exact, lease_state: "lost" },
{ ...exact, lease_generation: -1 },
{ ...exact, supervisor_revision: 1.25 },
{ ...exact, network_reachability: "degraded" },
{ ...exact, observed_at: 123 },
Object.fromEntries(Object.entries(exact).filter(([key]) => key !== "status")),
Object.fromEntries(Object.entries(exact).filter(([key]) => key !== "lease_state")),
]) {
assert.equal(isXgridsConnectionVerification(malformed), false);
}
});
test("connection policy accepts the exact restart-recovery actions, sources and modes", () => {
assert.deepEqual([...XGRIDS_CONNECTION_POLICY_ACTIONS], [
"scan-ble",
"provision-fresh-device",
"prepare-select-device",
"prepare-change-network",
"cancel-reconfiguration",
"recover-current-device-network",
"observe-fresh-device-network",
"observe-current-device-network",
"observe-configured-device-network",
"inspect-configured-endpoint",
"inspect-host-network",
"probe-endpoint",
"verify-control-device-info",
"start-acquisition",
"stop-acquisition",
"stop-local-receiver",
"retire-unavailable-physical-target",
"acknowledge-data-loss",
]);
assert.deepEqual([...XGRIDS_CONNECTION_POLICY_TARGET_SOURCES], [
"none",
"fresh-scan",
"retained-current-process",
"durable-configured-state",
"configured-topology",
"connection-supervisor",
"local-runtime",
"local-prestart-handoff",
"local-reconfiguration-intent",
"durable-physical-command",
]);
const retainedDecision = {
allowed: true,
reason_codes: [],
target_source: "retained-current-process",
required_transport_ref: "9AE978F2-37A8-4B4B-9BCD-BD7010BB20D1",
required_connection_mode: "quick-connect",
requires_live_gatt_validation: true,
automatic_retry: false,
};
const durableDecision = {
...retainedDecision,
target_source: "durable-configured-state",
required_transport_ref: "0CA8AB68-E37B-46A2-B09F-C34B5C49428C",
required_connection_mode: "bridge",
};
const policy = {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
supervisor_revision: 17,
network_ledger_revision: 4,
recommended_action: "observe-current-device-network",
allowed_actions: [
"observe-current-device-network",
"observe-configured-device-network",
],
actions: {
"observe-current-device-network": retainedDecision,
"observe-configured-device-network": durableDecision,
},
facts: { retained_context_is_presence: false },
};
assert.equal(isXgridsConnectionPolicyDecision(retainedDecision), true);
assert.equal(isXgridsConnectionPolicy(policy), true);
const retirementDecision = {
allowed: true,
reason_codes: [],
target_source: "durable-physical-command",
required_transport_ref: "0CA8AB68-E37B-46A2-B09F-C34B5C49428C",
required_connection_mode: "bridge",
requires_live_gatt_validation: false,
physical_command_allowed: false,
physical_outcome: "unknown",
device_write_performed: false,
automatic_retry: false,
};
assert.equal(isXgridsConnectionPolicyDecision(retirementDecision), true);
assert.equal(isXgridsConnectionPolicy({
...policy,
recommended_action: "retire-unavailable-physical-target",
allowed_actions: ["retire-unavailable-physical-target"],
actions: {
"retire-unavailable-physical-target": retirementDecision,
},
}), true);
for (const malformedRetirement of [
{ ...retirementDecision, target_source: "durable-configured-state" },
{ ...retirementDecision, physical_command_allowed: undefined },
{ ...retirementDecision, physical_outcome: undefined },
{ ...retirementDecision, device_write_performed: undefined },
{ ...retirementDecision, requires_live_gatt_validation: true },
]) {
assert.equal(isXgridsConnectionPolicy({
...policy,
recommended_action: "retire-unavailable-physical-target",
allowed_actions: ["retire-unavailable-physical-target"],
actions: {
"retire-unavailable-physical-target": malformedRetirement,
},
}), false);
}
assert.equal(
isXgridsConnectionPolicyDecision({
...retainedDecision,
required_connection_mode: undefined,
}),
true,
"older decisions may omit the optional mode field",
);
for (const malformed of [
{ ...retainedDecision, target_source: "server-cache" },
{ ...retainedDecision, required_connection_mode: "automatic" },
{ ...retainedDecision, automatic_retry: true },
]) {
assert.equal(isXgridsConnectionPolicyDecision(malformed), false);
}
assert.equal(isXgridsConnectionPolicy({
...policy,
actions: {
...policy.actions,
"observe-current-device-network": {
...retainedDecision,
required_connection_mode: undefined,
},
},
}), false, "an allowed retained recovery must pin its mode");
assert.equal(isXgridsConnectionPolicy({
...policy,
actions: {
...policy.actions,
"observe-configured-device-network": {
...durableDecision,
target_source: "configured-topology",
},
},
}), false, "durable recovery cannot drift to an endpoint-only source");
});
test("connection reconfiguration accepts only the exact resumable v1 projection", () => {
const exact = {
schema_version: "missioncore.xgrids-k1-connection-reconfiguration/v1",
revision: 4,
intent_id: "connection-reconfigure-001",
intent: "change-network",
status: "fresh-scan-completed",
required_transport_ref: "BLE-DEVICE-001",
required_connection_mode: "bridge",
minimum_discovery_generation: 10,
fresh_discovery_generation: 10,
required_transport_observed: true,
prepared_at: "2026-08-10T12:00:00Z",
automatic_retry: false,
};
assert.equal(isXgridsConnectionReconfiguration(exact), true);
assert.equal(isXgridsConnectionReconfiguration({
...exact,
status: "idle",
intent: null,
intent_id: null,
required_transport_ref: null,
required_connection_mode: null,
minimum_discovery_generation: null,
fresh_discovery_generation: null,
required_transport_observed: null,
prepared_at: null,
}), true);
for (const malformed of [
{ ...exact, revision: -1 },
{ ...exact, intent: "cancel" },
{ ...exact, status: "scanning" },
{ ...exact, required_connection_mode: "bluetooth" },
{ ...exact, automatic_retry: true },
{ ...exact, intent_id: null },
]) {
assert.equal(isXgridsConnectionReconfiguration(malformed), false);
}
});
test("connection attempt phase distinguishes no write from an unknown write outcome", async () => {
assert.deepEqual([...XGRIDS_CONNECTION_ATTEMPT_PHASES], [
"network_applied",
"network_not_applied",
"network_outcome_unknown",
]);
for (const phase of XGRIDS_CONNECTION_ATTEMPT_PHASES) {
assert.equal(isXgridsConnectionAttemptPhase(phase), true, phase);
}
for (const phase of [
"network_write_failed",
"network_not_confirmed",
"outcome_unknown",
null,
]) {
assert.equal(isXgridsConnectionAttemptPhase(phase), false, String(phase));
}
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => new Response(JSON.stringify({
state: {
source_mode: "idle",
connection_attempt: {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
phase: "network_outcome_unknown",
automatic_retry: false,
},
},
}), {
status: 200,
headers: { "Content-Type": "application/json" },
});
try {
const state = await xgridsK1Api.getState();
assert.equal(state.connection_attempt.phase, "network_outcome_unknown");
} finally {
globalThis.fetch = originalFetch;
}
});
test("state API rejects an unreviewed connection attempt phase", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => new Response(JSON.stringify({
state: {
source_mode: "idle",
connection_attempt: {
schema_version: "missioncore.xgrids-k1-connection-attempt/v1",
phase: "network_write_failed",
automatic_retry: false,
},
},
}), {
status: 200,
headers: { "Content-Type": "application/json" },
});
try {
await assert.rejects(
xgridsK1Api.getState(),
(error) => error instanceof ApiError
&& error.message === "Локальный сервер вернул некорректное состояние.",
);
} finally {
globalThis.fetch = originalFetch;
}
});
test("state API rejects a drifted connection verification object at runtime", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => new Response(JSON.stringify({
state: {
source_mode: "idle",
connection_verification: {
status: "configured",
lease_state: "lost",
lease_generation: 1,
supervisor_revision: 2,
endpoint_validation: "not-performed",
network_reachability: "degraded",
observed_at: null,
},
},
}), {
status: 200,
headers: { "Content-Type": "application/json" },
});
try {
await assert.rejects(
xgridsK1Api.getState(),
(error) => error instanceof ApiError
&& error.message === "Локальный сервер вернул некорректное состояние.",
);
} finally {
globalThis.fetch = originalFetch;
}
});
test("state API rejects a drifted restart-recovery policy at runtime", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => new Response(JSON.stringify({
state: {
source_mode: "idle",
connection_policy: {
schema_version: "missioncore.xgrids-k1-connection-policy/v1",
supervisor_revision: 5,
network_ledger_revision: 3,
recommended_action: "observe-configured-device-network",
allowed_actions: ["observe-configured-device-network"],
actions: {
"observe-configured-device-network": {
allowed: true,
reason_codes: [],
target_source: "durable-configured-state",
required_transport_ref: "exact-k1",
required_connection_mode: "automatic",
requires_live_gatt_validation: true,
automatic_retry: false,
},
},
facts: { retained_context_is_presence: false },
},
},
}), {
status: 200,
headers: { "Content-Type": "application/json" },
});
try {
await assert.rejects(
xgridsK1Api.getState(),
(error) => error instanceof ApiError
&& error.message === "Локальный сервер вернул некорректное состояние.",
);
} finally {
globalThis.fetch = originalFetch;
}
});
test("host diagnostic guard rejects every unreviewed literal dimension", () => {
const exact = {
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,
};
assert.equal(isXgridsHostFailureDiagnostic(exact), true);
for (const malformed of [
{ ...exact, code: "PermissionError: private" },
{ ...exact, domain: "python-runtime" },
{ ...exact, impact: "unknown-impact" },
{ ...exact, operator_action: "run-private-shell-command" },
{ ...exact, automatic_retry: true },
{ ...exact, redacted: false },
]) {
assert.equal(isXgridsHostFailureDiagnostic(malformed), false);
}
});
test("failed network-profile writes close the UI session with a fresh explicit next step", () => {
const message = networkProvisionFailureMessage({
status: "failed",
error: { code: "BleakGATTProtocolError" },
});
assert.equal(
message,
"Bluetooth-периферия завершила сетевую операцию ошибкой. Команда могла быть принята K1; итог текущей попытки не подтверждён. Автоматический повтор команды K1 не отправлялся. Проверьте состояние K1 через «Переподключиться» или начните новое подключение через поиск Bluetooth.",
);
assert.doesNotMatch(message, /Bleak|GATT|ATT/i);
const attMessage = networkProvisionFailureMessage({
action: "network.provision",
status: "failed",
error: {
code: "BleakGATTProtocolError",
ble_att_error_code: 4,
ble_att_error_name: "INVALID_PDU",
},
});
assert.match(attMessage, /ATT 4 INVALID_PDU/);
assert.match(attMessage, /Автоматический повтор команды K1 не отправлялся/);
assert.match(attMessage, /Проверьте состояние K1 через «Переподключиться»/);
assert.match(attMessage, /новое подключение через поиск Bluetooth/);
const preWriteAttMessage = networkProvisionFailureMessage({
action: "network.provision",
status: "failed",
error: {
code: "BleakGATTProtocolError",
operation_stage: "baseline-read",
device_write_attempted: false,
side_effect_status: "none",
safe_to_retry: true,
ble_att_error_code: 4,
ble_att_error_name: "INVALID_PDU",
},
});
assert.match(preWriteAttMessage, /до команды изменения сети/);
assert.match(preWriteAttMessage, /Запись сетевого профиля не выполнялась/);
assert.doesNotMatch(preWriteAttMessage, /результат изменения сети неизвестен/i);
});
test("post-dispatch ambiguity resets the UI session without an automatic retry", () => {
const message = networkProvisionFailureMessage({
action: "network.provision",
status: "failed",
error: {
code: "network-provision-target-not-distinguishable-from-baseline",
device_write_attempted: true,
side_effect_status: "unknown",
safe_to_retry: false,
},
});
assert.equal(
message,
"После BLE-команды K1 вернул сетевой статус, неотличимый от исходного; итог текущей попытки подключения не подтверждён. Автоматический повтор команды K1 не отправлялся. Проверьте состояние K1 через «Переподключиться» или начните новое подключение через поиск Bluetooth.",
);
assert.doesNotMatch(message, /ручн|read-only|защитный барьер/i);
});
test("Bluetooth scan failures explain whether a device command was sent", () => {
const busy = discoveryScanFailureMessage({
action: "discovery.scan",
status: "failed",
error: { code: "ble-runtime-busy" },
});
const cleanupPending = discoveryScanFailureMessage({
action: "discovery.scan",
status: "failed",
error: { code: "ble-runtime-cleanup-pending" },
});
const timedOut = discoveryScanFailureMessage({
action: "discovery.scan",
status: "failed",
error: { code: "ble-discovery-timeout" },
});
assert.match(busy, /занят другой локальной операцией/);
assert.match(cleanupPending, /подтверждает отключение/);
assert.match(timedOut, /принудительно остановлен/);
assert.match(timedOut, /Команды K1 не отправлялись/);
});
test("connection recovery exposes safe operator-facing failure classes", () => {
const addressUnavailable = connectionVerificationFailureMessage({
action: "connection.verify",
status: "failed",
error: {
code: "connection-verify-address-unavailable",
side_effect_status: "none",
safe_to_retry: true,
},
});
const missingAdvertisement = connectionVerificationFailureMessage({
action: "connection.verify",
status: "failed",
error: { code: "connection-verify-device-not-rediscovered" },
});
const statusReadFailed = connectionVerificationFailureMessage({
action: "connection.verify",
status: "failed",
error: {
code: "connection-verify-status-read-failed",
operation_stage: "exact-uuid-scan",
side_effect_status: "none",
},
});
const exactUuidScanTimedOut = connectionVerificationFailureMessage({
action: "connection.verify",
status: "failed",
error: {
code: "connection-verify-exact-uuid-scan-timeout",
operation_stage: "exact-uuid-scan",
side_effect_status: "none",
},
});
const indistinguishableFromBaseline = connectionVerificationFailureMessage({
action: "connection.verify",
status: "failed",
error: {
code: "connection-verify-target-not-distinguishable-from-baseline",
side_effect_status: "none",
safe_to_retry: false,
},
});
const staleEndpoint = connectionVerificationFailureMessage({
action: "connection.verify",
status: "failed",
error: {
code: "connection-verify-mqtt-unreachable",
side_effect_status: "none",
safe_to_retry: true,
},
});
const bindingChanged = connectionVerificationFailureMessage({
action: "connection.verify",
status: "failed",
error: {
code: "application-connection-binding-lost",
side_effect_status: "none",
safe_to_retry: true,
},
});
const physicalProofTimedOut = connectionVerificationFailureMessage({
action: "connection.verify",
status: "failed",
error: {
code: "physical-command-reconciliation-proof-timeout",
side_effect_status: "none",
safe_to_retry: true,
},
});
assert.match(addressUnavailable, /K1 ответил/);
assert.match(addressUnavailable, /настройки устройства не менялись/);
assert.match(missingAdvertisement, /Mission Core не получил объявление/);
assert.match(missingAdvertisement, /Команды K1 не отправлялись/);
assert.doesNotMatch(missingAdvertisement, /питани|перезапуст|не работает|пропал/i);
assert.match(statusReadFailed, /Mission Core не завершил/);
assert.match(statusReadFailed, /команды не отправлялись/);
assert.doesNotMatch(statusReadFailed, /питани|перезапуст|не работает|K1 не ответил/i);
assert.match(exactUuidScanTimedOut, /точного сохранённого CoreBluetooth UUID/);
assert.match(exactUuidScanTimedOut, /не является выводом о состоянии устройства/);
assert.doesNotMatch(exactUuidScanTimedOut, /питани|перезапуст|не работает|K1 не ответил/i);
assert.match(staleEndpoint, /можно заново применить настройки общей сети/);
assert.match(staleEndpoint, /Команда Wi-Fi не отправлялась/);
assert.doesNotMatch(staleEndpoint, /новый поиск|read-only/i);
assert.match(bindingChanged, /нажмите «Подключиться заново»/);
assert.doesNotMatch(bindingChanged, /поиск Bluetooth/i);
assert.match(physicalProofTimedOut, /START и STOP не отправлялись/);
assert.match(physicalProofTimedOut, /нажмите «Подключиться заново»/);
assert.doesNotMatch(physicalProofTimedOut, /поиск Bluetooth/i);
assert.equal(
indistinguishableFromBaseline,
"K1 ответил, но приложение не смогло подтвердить, что прежние настройки сети были применены. Автоматического повтора и новой записи не было.",
);
assert.doesNotMatch(indistinguishableFromBaseline, /поиск Bluetooth|повторите запись/i);
});
test("scan and verify errors correlate only with the requested operation id", () => {
const state = {
operations: [
{
operation_id: "op-requested",
action: "discovery.scan",
status: "failed",
error: { code: "ble-discovery-timeout" },
},
{
operation_id: "op-other-tab",
action: "discovery.scan",
status: "failed",
error: { code: "ble-discovery-already-running" },
},
],
last_operation: {
operation_id: "op-other-tab",
action: "discovery.scan",
status: "failed",
},
};
assert.equal(
operationById(state, "discovery.scan", "op-requested")?.error?.code,
"ble-discovery-timeout",
);
assert.equal(operationById(state, "discovery.scan", "op-missing"), null);
});
test("host Wi-Fi failures close the attempt and require a fresh explicit connection", () => {
const operationTimeout = networkProvisionFailureMessage({
status: "failed",
error: { code: "host-wifi-operation-timeout" },
});
const missingNetwork = networkProvisionFailureMessage({
status: "failed",
error: {
code: "network-not-found",
side_effect_status: "confirmed",
safe_to_retry: false,
scan_attempt_count: 13,
scan_elapsed_ms: 17524,
},
});
const preWriteKeychain = networkProvisionFailureMessage({
status: "failed",
error: {
code: "keychain-authorization-required",
side_effect_status: "none",
safe_to_retry: true,
},
});
const postWriteKeychain = networkProvisionFailureMessage({
status: "failed",
error: {
code: "keychain-authorization-denied",
side_effect_status: "confirmed",
safe_to_retry: false,
},
});
assert.equal(
operationTimeout,
"Локальная операция подготовки Wi‑Fi не завершилась вовремя; итог текущей попытки подключения не подтверждён. Автоматический повтор команды K1 не отправлялся. Проверьте состояние K1 через «Переподключиться» или начните новое подключение через поиск Bluetooth.",
);
assert.doesNotMatch(operationTimeout, /получите пароль|пароль отсутствует/i);
assert.match(missingNetwork, /K1 принял команду Quick Connect/);
assert.match(missingNetwork, /13 проверок за 17\.5 с/);
assert.match(missingNetwork, /автоматического повтора не было/);
assert.match(preWriteKeychain, /Команда устройству не отправлялась/);
assert.match(postWriteKeychain, /Дополнительный пароль не запрашивался/);
});