feat(k1): wire canonical control session to UI
This commit is contained in:
@@ -21,7 +21,7 @@ Each gate produces evidence and an explicit GO, PAUSE or BLOCKED result.
|
||||
| Stage 7 observation archive | GO (point/pose/telemetry contract) — durable catalog, recovery, capture-clock-bounded RRD preparation, archived metric time series, saved-session timeline and atomic playback are implemented |
|
||||
| Stage 7 recorded cameras | GO (contract), acceptance pending — acquisition-owned fMP4 archive and player are implemented/tested; one real archived K1 camera plus point-cloud session has not passed playback yet |
|
||||
| Plugin isolation | GO (laboratory control plane) — vendor backend/frontend and optional scene controls are plugin-owned; manifest/runtime descriptor parity, versioned handshake, lifecycle health and transport correlation fail closed while execution remains in-process |
|
||||
| K1 application control | PAUSE (accepted START followed by `ALGORITHM_ERROR`) — first live attempt stopped before START on a batch-3 correlation failure; a second attempt correlated all 10 pre-START requests plus START but collapsed UI stages into 365 ms and omitted the retained post-START/control-session lifecycle. The collapsed path and standalone START/STOP are disabled. An uninstalled offline executor now uses explicit UI checkpoints plus live DeviceStatus gates; no further physical write is authorized yet |
|
||||
| K1 application control | OPERATOR ACCEPTANCE READY — the failed collapsed path and standalone START/STOP remain disabled. Plugin v0.5.0 installs one continuous control-session owner behind separate connection, workspace, project, START, STOP and steady-green UI actions. No wall-clock transition, automatic retry, navigation-triggered command or repository-test equipment I/O exists. A full operator-run physical cycle and native-project verification remain open |
|
||||
| Stage 8 product storage | PAUSE — retention, replication, encryption, capacity monitoring and long-run browser/WASM stress remain deployment gates |
|
||||
|
||||
USB project copying remains optional ground truth rather than a blocker for the
|
||||
|
||||
@@ -260,7 +260,7 @@ operator power cycle restored steady green.
|
||||
This disproves the earlier assumption that byte-matched pre-START payloads plus
|
||||
a correlated START acknowledgement are sufficient acceptance. The legacy
|
||||
collapsed `run_bootstrap()` executor now rejects before emission. Its
|
||||
replacement is an uninstalled acceptance-only session owner. It requires the
|
||||
replacement is an operator-driven acceptance session owner. It requires the
|
||||
observed connection, workspace-entry and project-prompt checkpoints instead of
|
||||
wall-clock floors, sends the immediate post-START ModelingStatus read, services
|
||||
the same MQTT socket until live `SCANNING + project + init_ready`, then emits the
|
||||
@@ -270,9 +270,10 @@ standby. System-error and DeviceStatus reports are decoded into redacted safety
|
||||
state; a fault forbids further automatic action. Standalone START/STOP are
|
||||
disabled. MQTT keepalive/report processing also continues while the operator is
|
||||
between UI actions; the 15–120-second command permit is created at the actual
|
||||
START or STOP confirmation, not at connection time. This path is
|
||||
synthetic-test-only and remains outside facade/UI, so it
|
||||
does not authorize a new physical attempt.
|
||||
START or STOP confirmation, not at connection time. Plugin v0.5.0 now exposes
|
||||
this path through separate plugin-owned UI actions. Repository tests use only
|
||||
in-memory transports; physical execution occurs only from an explicit operator
|
||||
click against an already selected direct-LAN K1.
|
||||
|
||||
The one-time Keychain administration command uses `security -w` as the final
|
||||
argument so Apple's own TTY prompt receives the authority. Mission Core never
|
||||
|
||||
+28
-27
@@ -115,44 +115,45 @@ directly and use their sibling metadata receive timestamps when present.
|
||||
complete visible-device list.
|
||||
4. Enter the existing router SSID/password and explicitly authorize the reviewed
|
||||
provisioning write. The backend does not retry the write automatically.
|
||||
5. Enter the required project name. Mission Core NFKC-normalizes and trims it,
|
||||
rejects control/surrogate characters or more than 96 characters, and stores
|
||||
it as local display metadata rather than a path. The read-only profile does
|
||||
not send it to K1.
|
||||
6. When K1 reports a non-AP private address, choose **Подготовить локальный
|
||||
приём данных**. The stronger “initiate device work” wording appears only for
|
||||
a future profile that actually authorizes a vendor write.
|
||||
7. Wait until the UI reports that the local Rerun bridge is ready. No manual
|
||||
viewer URL is needed.
|
||||
8. Open **Наблюдение → Пространственная сцена**. The K1 plugin's optional scene
|
||||
block shows the local preparation/acquisition phase and stop action.
|
||||
9. Double-click the physical K1 button to start scanning. Real point frames and
|
||||
pose/trajectory updates then appear in the embedded viewport.
|
||||
5. Confirm operator presence, closed LixelGO, storage/power and steady green;
|
||||
choose **Подключить управление K1**. This emits only connection operations
|
||||
1–6 and then waits indefinitely for the next UI action.
|
||||
6. Choose **Открыть рабочее пространство K1** for operation 7.
|
||||
7. Enter the required project name and choose **Сохранить проект и подготовить
|
||||
локальный приём**. Mission Core normalizes it, prepares evidence reception
|
||||
and releases only operations 8–10; the name itself is not sent yet.
|
||||
8. After the project step is ready, choose **Запустить сканирование K1** once.
|
||||
The project name is carried by canonical START. Mission Core opens
|
||||
**Наблюдение → Пространственная сцена** and shows calibration while the same
|
||||
control socket waits for `SCANNING + project + init_ready`.
|
||||
9. Real point frames and pose/trajectory updates then appear in the embedded
|
||||
viewport. Do not use the physical button or open LixelGO during this cycle.
|
||||
10. When K1 emits `ModelingReport`, the same plugin block shows its current scan
|
||||
time, route distance and speed. These are device reports, not values inferred
|
||||
from a browser timer or accumulated across a device counter reset.
|
||||
11. Double-click K1 again to stop physical scanning and wait for steady green,
|
||||
then choose **Остановить локальный приём** in the scene or device workflow
|
||||
so capture, camera archive and summaries are finalized. That UI action does
|
||||
not stop K1 on the active profile.
|
||||
11. Choose **Остановить устройство и запись** in the scene. The
|
||||
plugin-commanded path emits one canonical STOP on the original socket,
|
||||
waits for live unbound READY, and asks the operator to confirm the constant
|
||||
green indicator before capture, camera archive and summaries are finalized.
|
||||
|
||||
Each new live run creates a direct child below `MISSIONCORE_EVIDENCE_DIR`, or
|
||||
`.runtime/mission-core/evidence/sessions/` by default, with raw MQTT frames,
|
||||
per-message metadata and a hash summary. Repository-level
|
||||
`sessions/*_viewer_live` is legacy import-only evidence and is never selected by
|
||||
the current writer. The connector subscribes to the fixed report-topic
|
||||
allowlist and does not publish an application request or modeling command.
|
||||
the current writer. The data connector remains subscribe-only. Application
|
||||
requests are isolated in the separate canonical control-session owner and can
|
||||
be emitted only by explicit staged UI actions.
|
||||
|
||||
The recovered command substrate is intentionally inert. It byte-matches the ten
|
||||
The recovered command substrate byte-matches the ten
|
||||
observed pre-START requests plus START/STOP, correlates DeviceInfo and modeling
|
||||
responses, and classifies live device states without importing MQTT or
|
||||
publishing anything. One private application-level OpenAPI authority is kept
|
||||
responses, and classifies live device states before any command transition. One
|
||||
private application-level OpenAPI authority is kept
|
||||
separate from the transient vendor ID/serial returned by the BLE-selected K1.
|
||||
The fixed Keychain loader, bounded execution lease and dormant facade
|
||||
orchestrator now exist. No emission method or live MQTT sink is installed, and
|
||||
an acceptance-only transport exists outside the facade. Keychain provisioning,
|
||||
physical START/STOP and durable save completion remain open, so
|
||||
`vendor_writes_enabled` is false and the physical-button workflow is canonical.
|
||||
The fixed Keychain loader and dormant shadow coordinator remain available for
|
||||
inspection. Plugin v0.5.0 additionally installs a continuous interactive MQTT
|
||||
owner: operations 1–6 at connection, 7 at workspace entry, 8–10 at project
|
||||
preparation, then separately permitted START and STOP. Physical START/STOP and
|
||||
durable native-project completion still require operator acceptance.
|
||||
|
||||
## Automatic Rerun source and lifecycle
|
||||
|
||||
|
||||
@@ -138,21 +138,20 @@ after explicit operator attestation of firmware `3.0.2` and direct-LAN topology,
|
||||
and records the basis as `operator-attested`. That claim is not device-derived
|
||||
proof. The profile independently records observation, decode, replay,
|
||||
physical-verification and write evidence. Loading it cannot authorize a
|
||||
transport mutation. Application-command publishing remains disabled; the
|
||||
separately reviewed BLE Wi-Fi provisioning write retains its own explicit
|
||||
operator gate.
|
||||
transport mutation. BLE Wi-Fi provisioning and application control retain
|
||||
separate explicit operator gates.
|
||||
|
||||
An exact but inert K1 application-control substrate now lives inside the vendor
|
||||
An exact K1 application-control substrate now lives inside the vendor
|
||||
plugin. It byte-matches the retained ten-request pre-START dialogue plus
|
||||
START/STOP, correlates live DeviceInfo/modeling responses and maps bounded
|
||||
device-status values into an observation-only state machine. The OpenAPI value
|
||||
device-status values into a fail-closed state machine. The OpenAPI value
|
||||
is one private application-level authority; vendor ID and serial come from the
|
||||
BLE-selected live K1 and are cross-checked against status. No MQTT publisher
|
||||
exists. A fixed Keychain loader, bounded lease and dormant facade orchestrator
|
||||
are present, but there is no emission method or live MQTT sink. Keychain item
|
||||
provisioning and stable-artifact proof after STOP remain unresolved. A separate
|
||||
acceptance-only transport is not imported by the facade, so
|
||||
`vendor_writes_enabled=false` remains authoritative.
|
||||
BLE-selected live K1 and are cross-checked against status. Plugin v0.5.0 owns a
|
||||
single interactive MQTT session from connection through STOP/standby, with one
|
||||
explicit UI action per recorded lifecycle boundary and no automatic retry. A
|
||||
fixed Keychain loader and dormant shadow coordinator remain present. Stable
|
||||
physical proof after STOP remains unresolved; write capability is exposed only
|
||||
while that interactive socket owner is active.
|
||||
|
||||
## Semantic lifecycle
|
||||
|
||||
|
||||
@@ -66,13 +66,16 @@ performs no implicit stop.
|
||||
|
||||
K1 project names are required, NFKC-normalized and trimmed, rejected for control
|
||||
or surrogate characters or more than 96 Unicode characters, and sent to the
|
||||
backend as local display metadata. The active profile has
|
||||
`vendor_writes_enabled=false`, so its
|
||||
backend as local display metadata. At the time of this ADR the active profile
|
||||
had `vendor_writes_enabled=false`, so its
|
||||
buttons and scene control say that they prepare/stop local reception. Before an
|
||||
acquisition exists, device-start wording is gated by active-control capability;
|
||||
after start, calibration/device-stop wording additionally requires a
|
||||
plugin-commanded acquisition mode.
|
||||
|
||||
The application-control portion is superseded by ADR 0012 and plugin v0.5.0;
|
||||
the plugin ownership and host-boundary decisions remain unchanged.
|
||||
|
||||
Plugin CSS is imported with the contribution and scoped below
|
||||
`.xgrids-k1-plugin`. A plugin cannot add global navigation, route ownership or
|
||||
unscoped global selectors.
|
||||
|
||||
@@ -110,8 +110,8 @@ shadow arm/disarm/state actions and redacted snapshots. The coordinator has no
|
||||
request-emission method and the installed sink is explicitly uninstalled; this
|
||||
runtime wiring does not widen write authority.
|
||||
|
||||
`application_mqtt.py` and `application_acceptance.py` provide the next, still
|
||||
uninstalled physical-acceptance boundary. The MQTT type repeats the retained
|
||||
`application_mqtt.py` and `application_acceptance.py` provide the reviewed
|
||||
physical-acceptance boundary. The MQTT type repeats the retained
|
||||
3.1.1 session (`clean_session=false`, keepalive 60), subscribes only to exact
|
||||
known response topics, admits only reviewed request topics and QoS2/retain-false
|
||||
envelopes, and consumes explicit bootstrap ordinals/modeling actions before the
|
||||
@@ -134,8 +134,18 @@ MQTT through explicit STOP and waits for live READY plus operator-confirmed
|
||||
standby. Fault/status observations are redacted and any fault forbids automatic
|
||||
continuation. The socket remains serviced during operator/UI waits, and each
|
||||
short action permit is created at its button confirmation rather than at
|
||||
connection time. These types are synthetic-test-only, not imported by the facade,
|
||||
declared as plugin actions or represented by UI controls.
|
||||
connection time.
|
||||
|
||||
Plugin v0.5.0 installs this boundary through
|
||||
`application_session.py`. One background owner is the only thread allowed to
|
||||
touch the control MQTT client. REST/UI actions release exactly one checkpoint:
|
||||
session open (1–6), workspace entry (7), project preparation (8–10), START, STOP
|
||||
and steady-green confirmation. Preparing local reception happens before the
|
||||
START event is released. After STOP, local capture remains owned until live
|
||||
unbound READY and explicit visual confirmation. Page close, model switching,
|
||||
polling and service state reads cannot emit START/STOP; model switching is
|
||||
blocked while the socket is open. Repository tests replace the transport with
|
||||
in-memory fakes and perform no equipment I/O.
|
||||
|
||||
`MacOSKeychainApplicationAuthorityProvisioner` invokes Apple's interactive
|
||||
`security add-generic-password ... -w` prompt with `-w` last. The private value
|
||||
|
||||
Reference in New Issue
Block a user