Files
NODEDC_MISSION_CORE/docs/audits/2026-09-07-k1-private-installer-r2.md

7.5 KiB

K1 private installer and onboard package boundary R2

The owner narrowed the acceptance scope to the current K1 and a transferable installer for supported onboard hosts. A second scanner and other firmware versions are explicitly deferred. The reviewed application material may travel with this private installer; it is not committed to source or made public.

Evidence and decision

ADR 0012 and the retained LixelGO static/wire analysis distinguish the embedded application value from each scanner's live vendor ID and serial. A per-device packet dump is not part of the reviewed connection flow. We nevertheless claim only the currently accepted scanner/FW 3.0.2, not untested fleet-wide support. The current XGRIDS release notes also identify a communication-protocol change at 3.0.2 paired with LixelGO 1.2.0; compatibility remains version-scoped.

Autonomy here means installation on Ubuntu 24.04 amd64 without a Mac, Keychain, typed key or new capture. The private K1 package supplies the same reviewed material; its installer encrypts that material using the destination host's systemd credential facility. Normal Ubuntu repositories may be needed for OS dependencies. This is not an air-gapped distribution of Ubuntu itself.

Implementation

Node 0.8.0 no longer owns the K1 Python runtime, Linux wheel bundle, service, polkit rule or credential importer. These moved to the optional mission-core-xgrids-k1 package owned under plugins/xgrids-k1/packaging. Its dependencies and Debian migration metadata are explicit. Existing runtime, journal, identity and encrypted-credential paths are retained. Removal preserves durable state; package transitions keep the existing idle/safe-worker gate.

The code-only package is 0.1.0; the prepared private edition is 0.1.0+private.1. Private material enters the engineering builder through memory/stdin and is present only in a root-owned 0600 package member. The .deb itself is a private 0600 artifact, not an encrypted distributable. Public provenance records only profile identity, material presence and hashes of public files. The installed worker uses the encrypted systemd credential, never the package member as a plaintext runtime fallback. Identical reinstall is idempotent; a different existing credential requires explicit rotation. No raw value reaches argv, environment, browser state, Ops or source files.

The onboard source payload now has an executable 85-module allowlist instead of copying every one of 459 Python modules. Changed imports fail packaging until reviewed. The Core/LAB factory moved into composition.py with identical AST; neither its behavior nor the device dialogue changed. Laboratory public exports became lazy so importing one historical migration predicate does not load laboratory runners and downstream compute jobs. Existing export names and resolved objects are retained.

Validation before private release

  • 138 installer, isolated-payload, application-authority, Node bridge, session, laboratory and composition checks passed. The synthetic installer checks encryption invocation, reinstall, refusal to rotate, invalid inputs, permissions, symlinks, private/public payload separation and no overwrite.
  • 775 additional plugin runtime, acquisition lifecycle, restart rehydration and laboratory API checks passed, with no errors, failures or skips.
  • Ruff and whitespace checks passed for changed runtime/new packaging modules.
  • Node TypeScript, production UI and Go binary/package build passed. No second backend or Docker workload was started.
  • The isolated runtime test uses the declared source payload and verifies all loaded K1/Core modules originate there. It reads idle state and closes the runtime; no BLE discovery, provisioning, MQTT, START/STOP or hardware test is performed. The local Mac lacks optional aiortc; full Node media import is a Linux installation acceptance, not a result claimed by this test.

Exact release hashes, installed package versions, credential readiness and hardware acceptance are recorded after the private build and board update.

Remaining architecture scope

This is a separately installable onboard package, not completion of the entire plugin migration. Local Core still uses an in-process runtime and a statically composed frontend. The facade still needs internal decomposition, and some shared session/viewer code remains a declared plugin dependency. No other Rerun profile, camera producer or recovery state transition was changed here. Hardware acceptance uses the UI with cache cleared before every test, as requested. A second scanner, new firmware or different host platform is not accepted by packaging and software regression alone.

Vendor reference: https://www.xgrids.com/intl/support/download?page=K1

Release and installation acceptance

Source commit d8cc5367c4f55973d5688a0627298cf5137649a6 is published to origin/main. Both package provenances bind that exact commit. The private release directory is private/releases/mission-core-node-k1-20260907; it contains the two packages, install and SHA256SUMS and is excluded from Git.

Package Bytes SHA-256
mission-core-node_0.8.0_amd64.deb 109813216 7ec59efe5b5ee6e48771f7302281d28fd96dd6d425678ddfaeff18f8fd79773e
mission-core-xgrids-k1_0.1.0+private.1_amd64.deb 318106524 ec28e0fd83db88ec37903734ae4779aea4d716fe47905ab978a64d420513b1ea

The authorized build read the existing fixed application Keychain item in memory and supplied it to the private package builder. No separate raw-key transfer was used. The earlier rejected direct-import proposal was not run. The prepared package was transferred over the previously trusted Mini SSH identity into a mode-0700 release directory with mode-0600 packages. Every transferred checksum matched. APT simulation selected one upgrade and one new package, with no removals.

The owner entered the normal Ubuntu administrator password in the installer window. Installation returned exit 0. On 2026-09-07 at 08:49 UTC, the Mini started Node 0.8.0 and K1 0.1.0+private.1. The private package's postinst successfully prepared the host-encrypted material before starting the worker. Both services are active/running with NRestarts=0; Bluetooth and NetworkManager are active. Installed package provenance matches the release.

The installed source tree has exactly the declared 85 Python modules; the old laboratory/execution.py is absent after Debian migration. The new full Linux worker, including its media imports, starts and supplies fresh/available/idle state to Core. This closes the full Linux import check that the Mac synthetic test could not perform. The original ndc-rover-006 identity and binding are preserved. Canonical Core port 8000 remains operational. No device command was sent as part of packaging and installation acceptance.

Five R2 structured blocks were added to Ops K1 card #3, retaining all 34 prior blocks and its historical state. Node card #76 received progress comment e4f1fc04-be54-4172-ada7-9c672db4681a; its frozen 26-block baseline was not changed. Installer preparation is accepted separately from physical K1 authentication, Bridge/live through both UIs, Ubuntu outage/reboot recovery and installation on a second board. Those physical checkers remain open.

The owner subsequently confirmed the K1 is powered and Chrome cache was cleared for a Core Fleet UI test. Read-only observations are retained under private/acceptance/k1-node080-20260907-core-ui, with UTC/monotonic timestamps, operator notes and hashes. Starting that test does not itself establish a successful hardware connection.