Dependencies
Policy (ADR-0011): shipped artifacts may depend on permissive or LGPL (dynamically linked) components only — no GPL. Dev-only tools are unrestricted. Adding a dependency requires adding its row here in the same PR. The devcontainer Dockerfile mirrors these groups with comments.
Agent (libfjarr) — ships on robots
Section titled “Agent (libfjarr) — ships on robots”| Dependency | Version (Ubuntu 26.04 LTS, ADR-0022; re-verified in slice 2.9) | Purpose | License | Ships |
|---|---|---|---|---|
| GStreamer core + base/good/bad plugins | 1.28.2 | pipelines, RTP, WebRTC; gstreamer1.0-plugins-base-apps for gst-device-monitor-1.0, which fjarr-agent setup and drivers detect run to find cameras (docs/26), a package dependency since 2026-09-28 | LGPL-2.1 (dynamic) | yes |
libx265 (pulled by Ubuntu’s gstreamer1.0-plugins-bad for its x265enc) | 26.04 | nothing: present on disk, never loaded by the agent. x265enc is an encoder, encoders are never autoplugged, and the agent’s encoder is explicit (VA-API, openh264). Recorded 2026-09-28, when the image’s GPL guard was sharpened | GPL-2.0 | present, not a dependency: the rule (ADR-0011) is about what enters the agent’s process. The image guard fails on x264enc, avdec_*, libx264 and libxvidcore instead, which are what decodebin or a GPL encoder would load |
gstreamer1.0-nice (libnice) | 0.1.23 | ICE for webrtcbin; the agent also links libnice directly (libnice-dev at build) to give it the local addresses to gather from, without the tunnel interface (docs/23, #34) | LGPL-2.1/MPL | yes |
gstreamer1.0-alsa | 1.28.2 | alsasrc: fjarr.audio reads a robot’s microphones through ALSA, as a system service with no desktop session (docs/23#audio, M3.5); Opus itself is gstreamer1.0-plugins-base’s opusenc, over libopus (BSD-3-Clause) | LGPL-2.1 (dynamic) | yes |
gstreamer1.0-pipewire | 1.6.2 | Wayland capture (pipewiresrc) | MIT | yes |
| libva + intel-media-driver (iHD; amd64 only — arm64 uses mesa’s VA drivers) | 2.22 / 26.1 | VA-API H.264 encode | MIT | yes (driver from distro) |
| libx11 / libxtst / libxfixes / libxrandr / libxi | 26.04 | X11 backend | MIT/X11 | yes — in fjarr-desktop-x11 only (ADR-0021) |
| libei | 1.5.0 | Wayland input injection | MIT | yes — in fjarr-desktop-wayland only |
| libxkbcommon | 1.13.1 | keymap lookup for typing text through the robot’s layout (docs/23) | MIT | yes — in fjarr-desktop-wayland only |
| libpipewire | 1.6.2 | capture: backend module E reads each capture’s stream itself, frames and the cursor’s metadata (slice 3.5, docs/23); fjarr-desktop-session narrows each handed connection to its capture’s node (docs/23). gstreamer1.0-pipewire is no longer used by the agent. The modules load their own client configuration (/usr/share/fjarr/pipewire-client.conf, in fjarr-agent so both desktop packages can share it) with libpipewire-0.3-modules’ client modules, not pipewire-bin’s client.conf: that package brings GPL-3 readline (2026-10-06). The desktop’s sound (M3.5 3.5.2): both modules read the speakers through it, and fjarr-x11-session narrows the X11 kiosk’s connection as the GNOME helper does (ADR-0034) | MIT | yes — in fjarr-desktop-wayland, fjarr-desktop-session and fjarr-desktop-x11 |
| libevdev | 1.13.6 | uinput helper | MIT-ish (X11) | yes (in fjarr-inputd) |
| libdbus / sd-bus | 26.04 | portal negotiation | AFL-2.1/GPL dual → use LGPL path; verify at M2 | yes — in fjarr-desktop-wayland only |
| nlohmann-json | 3.11 | envelopes, config | MIT | yes |
GStreamer nvcodec plugin (nvh264enc, plugins-bad) | 1.28 | the nvcodec encoder family for discrete NVIDIA cards (ADR-0025, M2.6) | LGPL-2.1 (dynamic) | yes (optional) |
NVIDIA driver libraries (libnvidia-encode, libcuda) | the host’s driver | what nvcodec loads at runtime; never linked or redistributed by us — the machine’s own driver install provides them, exactly as the Intel VA driver is | proprietary, not shipped | no |
NVIDIA L4T GStreamer (nvv4l2h264enc) | JetPack | the nvv4l2 encoder family on Jetson (M2.6); from NVIDIA’s own repository on the board, arm64 only | NVIDIA SDK terms, not shipped | no |
openh264 (openh264enc, plugins-bad) | 2.4 | the explicit encoder = "software" path (CI, no-GPU dev, portable robots) — never a silent fallback (docs/23) | BSD-2 | yes (optional) |
| libsoup-3 (+ glib-networking) | 3.6 | WS/HTTP signaling client (ADR-0017) and the introspection server (docs/24) | LGPL-2.1 (dynamic) | yes |
toml++ (tomlplusplus) | 3.4 (header-only) | fjarr.toml config (docs/23) | MIT | yes |
| nlohmann json-schema-validator | 2.3 (no Ubuntu package: pinned via CMake FetchContent, built into libfjarr) | capability config validation against config_schema | MIT | yes |
GStreamer gstreamer.supp (valgrind suppressions, vendored at agent/tests/valgrind/) | 1.28.2 source tree | make agent-memcheck (docs/23 memory ladder, nightly) | LGPL-2.1-or-later (a data file; never linked) | no — dev only |
python3-gi + gir1.2-gst-rtsp-server-1.0 + gstreamer1.0-rtsp | 26.04 | the lab’s RTSP camera simulator (docker/lab/rtsp-sim.py, the rtsp-sim compose service) for fjarr.camera’s rtsp track | LGPL-2.1 (PyGObject, gst-rtsp-server) | no — dev image and CI only |
gstreamer1.0-libav (avdec_h264) | 1.28 | receive-side H.264 decode in fjarr-opsim (docs/23) — the dev image and CI only. It had crept into the shipped agent image, where decodebin would autoplug it for RTSP; removed 2026-09-28, and the image guard now fails on it | LGPL-2.1 (Ubuntu’s ffmpeg build enables GPL parts) | no — a test tool; never linked into libfjarr, fjarr-agent or a demo |
libsystemd (sd_notify) | 26.04 | READY/WATCHDOG supervision — required by the packaged agent (ADR-0019 addendum) | LGPL-2.1 (dynamic) | yes |
| GoogleTest | 1.17 | C++ unit/loop tests | BSD-3 | dev-only |
| mutter, PipeWire, WirePlumber, GTK 4, libei (Ubuntu 26.04 packages) | 50.1 / 1.6 / 0.5 / 4.22 / 1.5 | the desktop fixture’s headless GNOME session (docker/desktop-fixture, M3 slice 3.0): the compositor under test, its screencast plumbing, the test window, EIS | GPL-2.0+ (mutter), MIT (PipeWire, WirePlumber, libei), LGPL-2.1+ (GTK) | no — a test image only; never in a shipped artifact |
| wl-clipboard (Ubuntu 26.04 package) | 2.2 | the desktop fixture’s robot side of the clipboard tests (M3 slice 3.5): wl-copy copies on the robot, wl-paste pastes there, behind the fixture’s oracle | GPL-3.0 | no — a test image only; never in a shipped artifact |
python3-xlib, x11-xserver-utils (xrandr, xhost), xauth (Ubuntu 26.04 packages) | 0.33 / 7.7 / 1.1 | the X11 fixture’s robot side (robot-sim with SIM_FIXTURE=1, M3 slice 3.7): the test window that logs input, carving and removing RandR monitors, the xhost grant, an enforced access control | LGPL-2.1+ (python-xlib), MIT (the X utilities) | no — a test image only; never in a shipped artifact |
| PipeWire, WirePlumber, dbus (Ubuntu 26.04 packages, in robot-sim) | 1.6 / 0.5 / 1.16 | the X11 fixture’s kiosk sound (M3.5 slice 3.5.2, ADR-0034): the kiosk account’s session bus and sound server, a null sink as its speakers, pw-play as the application that plays | MIT (PipeWire, WirePlumber), GPL-2.0+ or AFL-2.1 (dbus) | no — a test image only; never in a shipped artifact |
| xclip (Ubuntu 26.04 package) | 0.13 | the X11 fixture’s robot side of the clipboard tests (M3 slice 3.7c): copies text and a PNG on the robot and pastes them there, through plugd_x11.py | GPL-2.0 | no — a test image only; never in a shipped artifact |
FFmpeg dev packages, with libx264 and libxvidcore (pulled by Ubuntu’s libgstreamer-plugins-base1.0-dev and -bad1.0-dev) | 26.04 | nothing of Fjarr’s: they arrive on any machine that builds against GStreamer, so on an embedder’s build machine with libfjarr-dev. libfjarr links GStreamer, never FFmpeg, and the robot runtime packages (fjarr-agent, fjarr-tools) do not bring them (make deb-install-test checks) | GPL-2.0 | no — build machine only |
debhelper, devscripts, equivs, fakeroot (the package builder, docker/deb-builder) | 26.04 | building the .debs (docs/26#releases, ADR-0031) | GPL-2.0+ (build tools; nothing of theirs is in a package) | no — build only |
| Vendor camera SDKs (ZED, RealSense, Jetson multimedia, GigE vendors…) | per vendor | never a libfjarr dependency — each ships as its own GStreamer plugin package fjarr-gst-<vendor> per architecture (ADR-0020) | per vendor (checked per package) | optional, separate packages |
Forbidden: gstreamer1.0-plugins-ugly (x264enc) | — | — | GPL | never (doctor-enforced) |
Setup tool (fjarr-setup) — ships in fjarr-agent
Section titled “Setup tool (fjarr-setup) — ships in fjarr-agent”The installer commands fjarr-agent hands over
(docs/26): a Rust binary at
/usr/lib/fjarr/fjarr-setup, no GStreamer, nothing of it in the agent’s process.
| Dependency | Version | Purpose | License | Ships |
|---|---|---|---|---|
| cliclack | 0.5 | the prompts (every one has a flag); the one prompt library once fjarr-connect moves off dialoguer | MIT | yes |
| toml_edit | 0.22 | /etc/fjarr/fjarr.toml edited in place, comments and order kept — it is the customer’s file | MIT/Apache-2.0 | yes |
| drm | 0.15 | fjarr-agent display: the DRM connectors, their state, and the PATH property that says a connector hangs off a DisplayPort chain, so a chain’s root, which reads as disconnected, is never taken for a free connector (docs/26) | MIT | yes |
| clap, anyhow, libc, serde, serde_json, tokio | as the operator client | the CLI, errors, getpwnam/getuid/isatty, the change record, the netlink runtime | MIT/Apache-2.0 | yes |
fjarr-netdev (rtnetlink) | in-tree | the same device code fjarr-connect uses: the persistent tun, its address, the routing table for the range check | MIT (rtnetlink) | yes |
Signaling (fjarr-signaling / fjarr-server) — ships as sidecar/Cloud
Section titled “Signaling (fjarr-signaling / fjarr-server) — ships as sidecar/Cloud”| Dependency | Version | Purpose | License | Ships |
|---|---|---|---|---|
| Rust toolchain | 1.98.0 (pinned; bumped from 1.89.0 in slice 4.5e because webrtc-rs 0.21 uses Ipv4Addr::from_octets, stabilised after 1.89) | build | MIT/Apache-2.0 | build-only |
| tokio | 1.x | async runtime | MIT | yes |
axum (+ ws) | 0.8 | HTTP + WebSocket | MIT | yes |
| tracing / tracing-subscriber | 0.1/0.3 | structured logs | MIT | yes |
| serde / serde_json | 1.x | envelopes | MIT/Apache-2.0 | yes |
| futures-util | 0.3 | WS stream/sink combinators | MIT/Apache-2.0 | yes |
| jsonwebtoken | 9 | session-grant verification (HS256 at M1) | MIT | yes |
| hmac + sha1 + sha2 | 0.12/0.10 | TURN ephemeral creds (SHA1, coturn format), webhook signatures (SHA256) | MIT/Apache-2.0 | yes |
| base64 | 0.22 | TURN credential encoding | MIT/Apache-2.0 | yes |
| subtle | 2 | constant-time token comparison | BSD-3 | yes |
| uuid (v7) | 1.x | event/session ids | MIT/Apache-2.0 | yes |
Operator client (fjarr-connect) — ships in fjarr-tools (planned, M4.5)
Section titled “Operator client (fjarr-connect) — ships in fjarr-tools (planned, M4.5)”Versions are pinned when the binary is implemented; these rows exist so the licence question is settled before the code is written (ADR-0024). The robot side of the tunnel adds no dependency at all — a TUN device is the kernel plus two ioctls.
| Dependency | Version | Purpose | License | Ships |
|---|---|---|---|---|
| webrtc-rs | pinned at implementation | peer connection + data channels, no media | MIT/Apache-2.0 | yes |
| tokio | 1.x | async runtime | MIT | yes |
| libc | 0.2 | the virtual interface, with no wrapper crate: TUNSETIFF plus one unbuffered read and write per packet is three calls, and a TUN crate would bring its own I/O model to sit beside tokio’s. Interface, address and route setup shells out to ip, which is on every host that has a TUN device (slice 4.5e; the macOS utun path is the same three calls against a different socket family) | MIT/Apache-2.0 | yes |
| rtnetlink (with netlink-packet-core / -route / -utils, netlink-proto, netlink-sys, nix) | 0.23 | the interface’s address, MTU and per-robot routes, in process. A file capability is not inherited by a child, so shelling out to ip cannot work under the setcap install docs/27 promises — and speaking netlink here also means the binary needs no iproute2 on the host (slice 4.5e) | MIT | yes |
| clap | 4.x | the CLI surface | MIT/Apache-2.0 | yes |
| getrandom | 0.3 | the 128-bit state of the loopback login (docs/27#logging-in), from the OS on every platform; it replaced a Linux-only libc::getrandom so the binary builds where the shell runs. Already in the tree under rand | MIT/Apache-2.0 | yes |
| windows-sys | 0.61 | Windows only: the console modes and size behind fjarr-connect shell’s raw mode (docs/27#shell); on Unix that is termios through libc. Already in the tree under tokio | MIT/Apache-2.0 | yes |
| dialoguer | 0.11 | the robot picker — type to filter, enter to connect (docs/27#what-it-feels-like) — rather than a hand-rolled terminal UI (slice 4.5f). To be replaced by cliclack, the setup tool’s prompt library, once its filter mode is confirmed to serve the picker (docs/26#the-setup-tool) | MIT | yes |
| toml, dirs | 0.8, 6 | ~/.config/fjarr/config.toml and the 0600 credential cache beside it (slice 4.5f) | MIT/Apache-2.0 | yes |
| reqwest (rustls) | 0.12 | the operator API calls — robots, grants, login codes (docs/09#operator-api); already in the tree for the server’s webhooks | MIT/Apache-2.0 | yes |
fjarr-protocol (this repo) | workspace | shared signaling message types — the reason wire drift is a compile error. Its own crate since slice 4.5e, so an operator client links the types without the server’s axum/hyper/HMAC stack (ADR-0024) | AGPL-3.0 | yes |
| reqwest (rustls) | 0.12 | webhook delivery | MIT/Apache-2.0 | yes |
| tokio-tungstenite | 0.24 | the operator’s signaling socket (fjarr-connect, slice 4.5e), wss:// through its rustls-tls-webpki-roots feature: the rustls (ring) and webpki-roots reqwest already brings; also the e2e test WS client | MIT | yes (it was dev-only until fjarr-connect shipped one) |
| futures-util | 0.3 | stream/sink combinators on that socket | MIT/Apache-2.0 | yes |
| anyhow | 1.x | error context in the operator client, where a failure is a message to a developer rather than a value to match on | MIT/Apache-2.0 | yes |
| tracing, tracing-subscriber | 0.1 / 0.3 | the operator client’s logging | MIT | yes |
Web (@fjarr/core, @fjarr/react) — ships to customer bundles
Section titled “Web (@fjarr/core, @fjarr/react) — ships to customer bundles”| Dependency | Version | Purpose | License | Ships |
|---|---|---|---|---|
| TypeScript | ^5.9 | build | Apache-2.0 | build-only |
| React (peer dep) | ≥ 19 | @fjarr/react only | MIT | peer |
| (M2+) xterm.js | — | terminal view | MIT | yes |
@fjarr/core runtime deps | none (design goal) | keep the core dependency-free | — | — |
| vitest | ^5 | unit tests (core, react) | MIT | dev-only |
| happy-dom | ^20 | DOM for @fjarr/react hook tests | MIT | dev-only |
| @testing-library/react | ^16 | hook/component tests | MIT | dev-only |
| @xterm/xterm + @xterm/addon-fit | ^5.5 / ^0.10 | the terminal renderer in <TerminalView> (docs/06 fjarr.terminal) | MIT | yes (@fjarr/react/terminal entry with optional peer dependencies, imported only when the component mounts — a dashboard with no terminal pays nothing) |
d3-graphviz (+ its d3-selection, d3-transition peers) + @hpcc-js/wasm | ^5 (^3) / ^2 | DOT rendering in <PipelineGraph> and the on-robot viewer (docs/24) | BSD-3 (ISC) / Apache-2.0 | yes (@fjarr/react/pipelines entry with optional peer dependencies; the viewer app’s static files served from introspect.viewer_dir, docs/24) |
@playwright/test (+ pinned Chromium image) | 1.63.0 (pinned) | browser lab harness and e2e (docs/25; rows below) | Apache-2.0 | dev-only |
Vite + @vitejs/plugin-react | ^8 / ^5 | serves the lab page (web/e2e/app) | MIT | dev-only |
Demos, website, tooling — never shipped
Section titled “Demos, website, tooling — never shipped”| Dependency | Version | Purpose |
|---|---|---|
| Vite | ^8 | demo-dashboard dev/build |
| Astro + Starlight | ^7 / ^0.42 | website + docs rendering |
| pnpm (via corepack) | 10.x | JS workspace |
| markdownlint-cli2, lychee | latest | docs gates |
| ajv | ^8 | protocol schema conformance gate (make protocol-check) |
| CMake/Ninja/ccache, clang-21 suite | 26.04 | C++ build/lint |
| valgrind, heaptrack | 3.26 / 1.5 | nightly memcheck and allocation profiling of the agent (docs/15 memory safety; GPL tools, dev-only, never linked) |
@playwright/test (@fjarr/e2e, never published) | 1.63.0 (pinned; the browser image tag follows it) | browser lab harness and fjarr-lab (Apache-2.0) |
mcr.microsoft.com/playwright:v1.63.0-noble (container) | 1.63.0 | the lab’s headless Chromium with CDP (docs/25) |
| openssh-client | 26.04 | the operator end of the tunnel lab: make tunnel-ssh / tunnel-scp run through it over fjarr0 (docs/27 gate, slice 4.5c). BSD-2/ISC, dev image only — nothing in a shipped artifact links or invokes it |
openssh-server (fjarr-robot-services container) | 26.04 | the ssh daemon the tunnel gate reaches, in a sidecar on the robot’s network namespace. BSD-2/ISC, dev-only fixture: on a real robot this is the integrator’s own package and the agent never knows about it |
docker-cli, docker-compose-v2 (dev image) | 26.04 | docker-outside-of-docker: the lab drives the compose stack from dev (Apache-2.0) |
iproute2 (tc, dev image) | 26.04 | netem media-path profiles inside the robot container (GPL-2.0 tool, dev-only, never linked) |
| coturn (container) | 4.6 | dev/self-host TURN (BSD-3) |
mkosi, systemd-ukify, systemd-repart, systemd-boot-efi, OVMF, qemu-system-x86 (docker/ota-build) | Ubuntu 26.04 (mkosi 26, systemd 259) | building the x86 test images and rehearsing them in a VM (M8 slice 8.0, docs/32). LGPL-2.1+ (mkosi, systemd), BSD-2 (OVMF), GPL-2.0 (QEMU, a tool); what the images contain is the recipe’s own list |
SWUpdate, EFI Boot Guard (efibootguard, its 0.22 loader pinned by hash) | 2025.12 / 0.19 tools (Ubuntu 26.04), 0.22 loader | the x86 Ubuntu A/B recipe’s slot writer and boot loader (ADR-0040). SWUpdate 2025.12 is also the Jetson Yocto test image’s slot writer (docs/32), built by meta-swupdate with the spike layer’s defconfig (-B none, CMS signatures, raw handler, zstd; no Lua, web server or downloader). GPL-2.0-only, libebgenv included: run as tools by the applier, never linked into Fjarr; they are in images built from the recipes, not in Fjarr’s packages |
desync, xdelta3, bsdiff, zchunk, diffoscope (spikes/ota-delta) | 1.1.4 (upstream binary, checksum verified) / 26.04 | the 8.0 delta harness, chunks against binary diffs. BSD-3 (desync, bsdiff, zchunk), GPL-2.0+ (Ubuntu’s xdelta3), GPL-3.0+ (diffoscope); harness only — a diff decoder on robots would be upstream xdelta 3.1+ (Apache-2.0) or zstd (BSD) |
kas, kas-container (image ghcr.io/siemens/kas/kas:5.5, the script pinned by SHA-256) | 5.5 | builds the Jetson Yocto test image (M8 slice 8.0, docs/32, spikes/ota-jetson/yocto). MIT; a build tool, never shipped |
| Yocto layers: poky (OE-core, bitbake), meta-openembedded (meta-oe), meta-tegra (OE4T), meta-swupdate | scarthgap: poky 3a3d07f, meta-oe 0f00f8b, meta-tegra 6d7cc8f (L4T 36.5.2), meta-swupdate 25c9be8 | the Jetson Yocto recipe’s base (Q1, Q2). Metadata MIT (OE-core, meta-oe, meta-tegra, meta-swupdate), bitbake GPL-2.0; what an image contains carries each recipe’s own licence (kernel GPL-2.0, systemd LGPL-2.1+, SWUpdate GPL-2.0). Recipes, not images: Fjarr ships no image |
NVIDIA Jetson Linux (L4T) BSP and public sources: flash, backup and BCT tools (l4t_initrd_flash.sh, l4t_backup_restore.sh, tegrabct_v2), nvbootctrl, edk2-nvidia UEFI and L4TLauncher, the NVMe A/B partition XML | 36.4.4 and 36.5.2 (SHA-256 in spikes/ota-jetson/board/checks.lock) | flashing, backing up and building the ZED Box Mini’s firmware; nvbootctrl is run by the Jetson applier. NVIDIA proprietary (tools, MB2 common file, partition XML), BSD-3-Clause (MB1 pinmux/GPIO files), BSD-2-Clause-Patent (edk2-nvidia), GPL-2.0 (kernel). Fetched by hash and never redistributed: the layer carries only Fjarr’s changes |
Stereolabs stereolabs-zedbox-mini driver package, ZED Box Mini device-tree tarballs (36.4.4, 36.5) | 1.4.4 for L4T 36.5.2 (SHA-256 in spikes/ota-jetson/board/stereolabs.lock, checks.lock) | the board package’s reference and, later, the camera drivers (docs/18 #45, #47). Stereolabs’ terms (no licence stated); fetched by hash at build time, maintainer scripts never run, never redistributed |
Fjarr’s timer-tegra186 watchdog backport (a patch in spikes/ota-jetson/yocto) | for NVIDIA’s linux-jammy l4t-r36.5.2 (e6b364044e43) | the Yocto image’s kernel, compared in D2b. GPL-2.0-only, like the file it changes; applied by the recipe to a kernel Fjarr does not ship |
Board check tools image (spikes/ota-jetson/board/Dockerfile: device-tree-compiler, cpp, patch, dpkg, python3, shellcheck) | Ubuntu 26.04 | the board package’s checks (BCT and device-tree diffs, the driver pin). GPL-2.0+/BSD-2 (dtc), GPL-3.0+ (cpp, patch, dpkg, shellcheck), PSF (Python); tools only |
L4T flash container fjarr-l4t-flash (ubuntu:22.04 by digest with L4T’s l4t_flash_prerequisites.sh packages: qemu-user-static, nfs-kernel-server, sshpass, abootimg, xmlstarlet, device-tree-compiler, …) and its minimal rootfs (63 Ubuntu 22.04 arm64 packages, flash/rootfs-debs.lock) | 22.04 | running NVIDIA’s flash, backup and restore tools from the lab mini-PC (Q6, phase C). GPL-2.0 (QEMU, nfs-utils, sshpass, abootimg), MIT (xmlstarlet), mixed (the rootfs packages); lab only, never shipped |
nfs-kernel-server, rpcbind, nfs-common on the lab mini-PC (spikes/ota-jetson/flash/host-setup.sh, undone by --undo) | Ubuntu 26.04 | the box’s flash initrd mounts the L4T tree over NFS. GPL-2.0; a lab host change, never shipped |
device-tree-compiler, bmaptool on the lab mini-PC (spikes/ota-jetson/flash/host-setup.sh, undone by --undo) | Ubuntu 26.04 | meta-tegra’s initrd-flash, run natively for D1 (it mounts the box’s disks through the host’s udisks): its tegraflash calls dtc, its make-sdcard writes the slot images with bmaptool. GPL-2.0+/BSD-2 (dtc), GPL-2.0 (bmaptool); a lab host change, never shipped |
| Jetson network rescue: NVIDIA’s L4T kernel and modules, systemd-stub and ukify, BusyBox, OpenSSH, gdisk, e2fsprogs, nvme-cli, efibootmgr, dosfstools, util-linux, zstd; dnsmasq on the mini-PC; QEMU and AAVMF for the bench | 5.15.148-tegra, 259.5, 1.30.1, 8.9p1 (Ubuntu 22.04 arm64); dnsmasq 2.92; QEMU 10.2.1, AAVMF 2025.11 (the full list in spikes/ota-jetson/rescue/README.md, Licences) | the lab’s network rescue UKI and its off-box bench (docs/32, “Three rescue layers”). GPL-2.0 (kernel, BusyBox, gdisk, e2fsprogs, nvme-cli, efibootmgr, QEMU), GPL-2.0/3.0 (dnsmasq), GPL-3.0+ (dosfstools), LGPL-2.1+ (systemd-stub, ukify), BSD (OpenSSH, zstd), BSD-2-Clause-Patent (AAVMF); lab only, never shipped |
shellcheck (koalaman/shellcheck:stable container; Ubuntu’s in the spike’s tool images) | 0.11.0 | lint for the spikes’ shell scripts. GPL-3.0-or-later; a check, never shipped |
Lab script host tools: curl, jq, GnuPG (gpg, AES-256 for the backup’s second copy), rsync, util-linux flock, python3, OpenSSH client; nmap optional (probe-host.sh) | Ubuntu 26.04 | spikes/ota-jetson lab scripts on the workstation and the mini-PC (the lock, the plug’s RPC, the backup and its encrypted copy). curl (MIT-style), jq (MIT), GPL-3.0+ (GnuPG, rsync), GPL-2.0 (util-linux), PSF (Python), BSD (OpenSSH), NPSL (nmap); tools only |
| Xvfb/openbox/x11vnc/noVNC (robot-sim) | 26.04 | fake robot desktop |
| Docker + Compose v2 | ≥ 24 | the environment itself |
Version discipline
Section titled “Version discipline”Toolchains are pinned (rust-toolchain.toml, packageManager field,
Dockerfile base images by tag). Distro libraries float within Ubuntu 26.04
LTS. Cargo.lock and pnpm-lock.yaml are committed. Upgrades are ordinary
PRs with a dependencies-row diff; base-image bumps get a changelog note.