feat(perception): integrate calibrated operator pipeline

Add calibrated K1 projection, recorded and near-live perception qualification, unified Rerun operator layers, bounded replay admission, audited viewer controls, worker experiments, and lab evidence.
This commit is contained in:
DCCONSTRUCTIONS
2026-07-23 00:23:28 +03:00
parent ada2a55ee6
commit b53d6d5a45
221 changed files with 55923 additions and 1357 deletions
@@ -23,8 +23,8 @@ import type { XgridsK1Controller } from "../runtimeContext";
const connectionCopy: Record<ConnectionMode, {
stepTitle: string;
ssidLabel: string;
ssidPlaceholder: string;
ssidLabel?: string;
ssidPlaceholder?: string;
buttonLabel: string;
safetyNote: string;
}> = {
@@ -36,18 +36,16 @@ const connectionCopy: Record<ConnectionMode, {
safetyNote: "K1 получит реквизиты существующей сети одним рассмотренным BLE-запросом без автоматического повтора.",
},
"quick-connect": {
stepTitle: "Подключитесь к точке доступа K1",
ssidLabel: "Название точки доступа K1",
ssidPlaceholder: "SSID сканера, например XGR-…",
buttonLabel: "Подключить этот Mac к K1",
safetyNote: "Введите SSID и пароль точки доступа вашего K1. Mac сменит текущую Wi‑Fi сеть одним CoreWLAN-запросом; недокументированный BLE-секрет не читается и K1 не получает BLE-запись.",
stepTitle: "Включите точку доступа K1 и подключитесь к ней",
buttonLabel: "Включить точку K1 и подключиться",
safetyNote: "Mission Core сначала проверит локальный device-scoped профиль выбранного K1. Если профиль отсутствует, операция остановится до BLE-записи. После preflight Mission Core отправит один рассмотренный AP-enable кадр и найдёт точный SSID выбранного устройства.",
},
"direct-connect": {
stepTitle: "Подключите K1 к хотспоту контроллера",
ssidLabel: "Название хотспота контроллера",
ssidPlaceholder: "SSID управляющего устройства",
buttonLabel: "Подключить K1 к хотспоту",
safetyNote: "Хотспот должен быть уже включён, а этот Mac — иметь к нему маршрут. K1 получит его реквизиты одним рассмотренным BLE-запросом.",
safetyNote: "Хотспот должен быть уже включён, а управляющее устройство — иметь к нему маршрут. K1 получит его реквизиты одним рассмотренным BLE-запросом.",
},
};
@@ -131,7 +129,8 @@ export function K1ProvisioningPipeline({
const provisioningIntentRef = useRef<string | null>(null);
const devices = state?.devices ?? [];
const isBusy = pendingAction !== null;
const credentialsReady = ssid.trim().length > 0 && password.length > 0;
const credentialsReady = connectionMode === "quick-connect"
|| (ssid.trim().length > 0 && password.length > 0);
const canConnect = powerConfirmed && selectedDeviceId.length > 0 && credentialsReady && !isBusy;
const modeCopy = connectionCopy[connectionMode];
const selectedModeConnected = Boolean(
@@ -170,10 +169,12 @@ export function K1ProvisioningPipeline({
if (!canConnect) return;
const idempotencyKey = provisioningIntentKey(provisioningIntentRef.current);
provisioningIntentRef.current = idempotencyKey;
const networkCredentials = connectionMode === "quick-connect"
? {}
: { ssid: ssid.trim(), password };
const succeeded = await connect({
device_id: selectedDeviceId,
ssid: ssid.trim(),
password,
...networkCredentials,
connection_mode: connectionMode,
compatibility_attestation: profileSelectionForConnectionMode(connectionMode),
idempotency_key: idempotencyKey,
@@ -181,6 +182,11 @@ export function K1ProvisioningPipeline({
if (succeeded) {
provisioningIntentRef.current = null;
setPassword("");
} else if (connectionMode === "quick-connect") {
// The backend has already persisted and reconciled the failed bounded
// attempt. A later click is a new explicit Quick Connect intent, not an
// automatic replay of the consumed operation key.
provisioningIntentRef.current = null;
}
};
@@ -252,15 +258,27 @@ export function K1ProvisioningPipeline({
status={selectedModeConnected ? "Адрес получен" : "Ожидает подключения"}
tone={selectedModeConnected ? "success" : "neutral"}
>
<div className="field-stack">
<TextField label={modeCopy.ssidLabel} hint="SSID" value={ssid} onChange={(event) => { setSsid(event.target.value); provisioningIntentRef.current = null; }} autoComplete="off" spellCheck={false} placeholder={modeCopy.ssidPlaceholder} />
<TextField label="Пароль Wi‑Fi" hint="Только в оперативной памяти" type="password" value={password} onChange={(event) => { setPassword(event.target.value); provisioningIntentRef.current = null; }} autoComplete="off" placeholder="Введите пароль" />
</div>
{connectionMode === "quick-connect" ? (
<div className="connection-summary">
<span>Канонический путь</span>
<strong>BLE включает AP → macOS подключает Mac к AP выбранного K1</strong>
</div>
) : (
<div className="field-stack">
<TextField label={modeCopy.ssidLabel ?? "Название сети Wi‑Fi"} hint="SSID" value={ssid} onChange={(event) => { setSsid(event.target.value); provisioningIntentRef.current = null; }} autoComplete="off" spellCheck={false} placeholder={modeCopy.ssidPlaceholder} />
<TextField label="Пароль Wi‑Fi" hint="Только в оперативной памяти" type="password" value={password} onChange={(event) => { setPassword(event.target.value); provisioningIntentRef.current = null; }} autoComplete="off" placeholder="Введите пароль" />
</div>
)}
<div className="connection-summary"><span>Устройство</span><strong>{deviceSummary?.name || selectedDeviceId || "Сначала выберите устройство"}</strong></div>
<Button width="full" variant="primary" icon={<Icon name="network" />} disabled={!canConnect} onClick={() => void submitConnect()}>
{pendingAction === "connect" ? "Подключаем…" : modeCopy.buttonLabel}
{pendingAction === "connect"
? connectionMode === "quick-connect" ? "Включаем точку и подключаем…" : "Подключаем…"
: modeCopy.buttonLabel}
</Button>
<p className="safety-note">{modeCopy.safetyNote} Пароль передаётся только локальному сервису, не сохраняется в браузере и удаляется из формы после успеха.</p>
<p className="safety-note">
{modeCopy.safetyNote}
{connectionMode === "quick-connect" ? " Это лабораторный путь для уже подготовленного хоста: credential provider должен существовать в системном хранилище заранее. На чистом Mac операция завершится до BLE-записи; браузер, API, журналы и evidence секрета не получают." : " Пароль передаётся только локальному сервису, не сохраняется в браузере и удаляется из формы после успеха."}
</p>
</WizardStep>
</div>
</GlassSurface>