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

130 lines
7.5 KiB
Markdown

# 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.