Agent handoff — state as of 2026-06-23¶
Working notes for agents (and humans) picking up AryaOS and the snstac fleet. Supersedes the 2026-05-16 handoff in portal.md.
Current known-good build¶
- Latest successful dev image:
v2026.06.23.212757-abe8e41bf5e2-dev - Release URL: https://github.com/snstac/aryaos/releases/tag/v2026.06.23.212757-abe8e41bf5e2-dev
- GitHub Actions run:
28056974502 - Source commit:
abe8e41bf5e2(Publish image releases via gh) - Image verification:
58 ok, 0 failed - Notes: this is a dev/lab image with
aryaos-dev-labSSH key, passwordlesspisudo, and no first-boot password expiry. Do not use it as a field release.
Recent build blockers fixed:
sikw00fcot.servicewas missing AryaOS site config inheritance. Root cause was a brokensedexpression instage-charontakthat used/as the delimiter while matching/etc/default/<svc>. Fixed in81ca548with a path-safeawkinsert. Keep siteEnvironmentFile=/etc/aryaos/aryaos-config.txtbefore the service-specific/etc/default/<svc>line.- GitHub release publishing failed on immutable releases because
softprops/action-gh-releasepublished the prerelease before uploading the image asset. Fixed inabe8e41by usinggh release create, which creates a draft, uploads assets, then publishes. sikw00fcotdepends onpython3-pymavlink; that package is now published from https://github.com/snstac/python3-pymavlink and indexed by https://snstac.github.io/packages.
The big picture¶
AryaOS is the master consumer of the PyTAK stack. Three pillars landed in June 2026:
- Everything installs from the signed apt repo — https://snstac.github.io/packages,
built by snstac/packages from each product's
latest GitHub release (repos listed in its
products.txt). No vendored sensor binaries remain in this repo; the only vendored artifacts are trust anchors (shared_files/aryaos/snstac-packages/, FlightAware repo deb). - Cockpit is the single admin surface — nine standalone
cockpit-*plugin repos/debs (adsbcot, aiscot, aiscatcher, dronecot, lincot, gps, charontak, gpstak, aryaos).cockpit-aryaos("AryaOS Site") manages the site-wide layer:/etc/aryaos/aryaos-config.txt(siteCOT_URLetc.) and one-shot TAK TLS cert upload to/etc/aryaos/tls(key0640 root:tak-certs; group reconciled byaryaos-firstboot.shevery boot). Per-tool plugins edit/etc/default/<svc>. - CI builds dev images by default — every push to
mainproduces av<ts>-<sha>-devprerelease with lab access baked (dev SSH key, pi NOPASSWD, no password expiry) for burn-and-test. Hardened release images require dispatching the Pi-gen workflow with thereleaseinput checked.scripts/verify-image.shloop-mounts every built image and asserts ~58 facts (packages, units, files, and the lab/release security contract) before anything publishes.
Architecture invariants (don't break these)¶
- Site-config inheritance: every gateway unit loads
EnvironmentFile=-/etc/aryaos/aryaos-config.txtbefore its own/etc/default/<svc>— site sets defaults, per-service values override. The injection happens in each stage's chroot script (sed after[Service]); drop-in files would invert the precedence (drop-ins parse after the unit file). - CoT routing hub:
adsbcot,aiscot,dronecot,lincot, and other local PyTAK feeders should keepCOT_URL=udp+wo://127.0.0.1:28087. Charontak listens onudp+ro://127.0.0.1:28087and owns the external egress lanes: default Mesh SAudp+wo://239.2.3.1:6969, optional TAK Server, and other tools. Do not point each feeder independently at the same TAK Server except for deliberate legacy/debug bypass. - apt pinning:
install-sensor-debs.shpinsrelease o=snstacat 995 because stage-adsbcot pins trixie at 990 and Debian ships an SDR-less readsb that must never win. readsb is alsoapt-mark hold(statushold ok installed— verify-image accepts both hold and install). - Exactly one
EXPORT_IMAGEstage, last in everySTAGE_LIST(PR validation enforces).ARYAOS_CI_TRIM_WORK=1(CI only) deletes stale stage rootfs trees — pi-gen full-copies per stage and 72 GB arm64 runners can't hold ~15 copies (the fleet has 72 GB and 145 GB VMs; never rely on runner luck).increase-runner-disk-sizeis broken on arm64 runners — keep it false. - Release publication on immutable-release repos: use
gh release createfor releases with image assets. Do not go back tosoftprops/action-gh-releaseunless it is configured to keep the release draft until after asset upload.
Bluetooth PAN¶
AryaOS now includes a local-only Bluetooth PAN/NAP service for phone-to-box IP
connectivity without network egress. The service is aryaos-bt-pan.service; helper
source is shared_files/dhbridge/aryaos-bt-pan-nap; docs are in
bluetooth-pan.md.
Defaults in /etc/aryaos/aryaos-config.txt:
BT_PAN_ENABLED=1
BT_PAN_BRIDGE=pan0
BT_PAN_ADDRESS=10.44.0.1
BT_PAN_PREFIX=24
BT_PAN_DHCP_START=10.44.0.20
BT_PAN_DHCP_END=10.44.0.60
BT_PAN_DHCP_LEASE=12h
Expected behavior:
- AryaOS registers a BlueZ Network Access Point on
hci0and createspan0. - Paired phones get a DHCP lease on
10.44.0.0/24; AryaOS is10.44.0.1. - No NAT or forwarding is enabled. This is only for reaching AryaOS local services,
for example
https://10.44.0.1:9090/. - Phone OS support varies. Android vendor builds differ; iOS is usually restrictive for arbitrary Bluetooth PAN client use.
Hardening + one-click updates (new, 2026-07-02)¶
See security.md for the full posture. Summary of what landed:
- firewalld enabled with an explicit allowlist in the default zone
(
shared_files/aryaos/firewalld/); AntSDR link pinned to the trusted zone viazone=trustedinaryaos-antsdr.nmconnection. Operators use Cockpit → Networking → Firewall. If a new service opens a port, add a firewalld service XML + zone entry + verify-image assert, or it will be unreachable. - fail2ban (sshd jail), sshd drop-in (
50-aryaos.conf, password auth deliberately stays on), sysctl hardening, unattended-upgrades (Debian security only; snstac origin commented out by design). - Per-device web TLS:
aryaos-firstboot.shregenerates the snakeoil key and/etc/lighttpd/ssl/snakeoil-combined.pemonce per device (marker/etc/aryaos/.web-tls-regenerated). Firstboot also stoppedchown -R node-red /etc/aryaos— Node-RED now owns only the config file, and/etc/aryaos/tlsisroot:tak-certs 0750with the key0640. - One-click updates:
/usr/local/sbin/aryaos-update {check|apply|status} aryaos-update.service(oneshot, survives browser close), driven by the Software updates card in cockpit-aryaos ≥ 1.1 (falls back tosystemd-run+ plain apt on pre-2.1 images). JSON state in/var/lib/aryaos/update-*.json.- aryaos-overlay 2.1 is built by CI and attached to releases as a deb
asset, so units can upgrade the overlay itself once
snstac/aryaosis in the packages repoproducts.txt(see open items — sequencing matters). - New verify-image asserts cover all of the above; runtime checks are in
scripts/aryaos-test/tests/09-security.sh.
GPSTAK (new, 2026-06-12)¶
gpstak package → /usr/bin/gpstak: feeds onboard GNSS to TAK
devices per https://ampledata.org/network_gps.html — CoT position events to COT_URL
(default udp+broadcast://255.255.255.255:4349, ATAK's External or Network GPS) and
raw-NMEA passthrough for WinTAK (NMEA_TARGETS). Reads gpsd's JSON socket; pytak for
transport (so PYTAK_TLS_* applies). Ships disabled; managed in Cockpit → GPSTAK
(cockpit-gpstak). Verified live on the dev
Pi. Source and Debian/RPM release packaging live in https://github.com/snstac/gpstak.
Fleet state (all on pytak >= 7.3.0, releasing versioned debs)¶
| Repo | Release | Notes |
|---|---|---|
| pytak | 7.3.11 | capability line: cert enrollment, tak://, wss://, marti://, pytak dp, +wo/+ro, MQTT |
| adsbcot 9.1.0, aprscot 8.0.0, inrcot 5.2.1, cotproxy 1.0.1 | Jun 2026 | pipelines modernized (lincot-style ci.yml) |
| aiscot 7.1.4, dronecot 2.1.3, djicot 1.2.0, lincot 1.2.3, charontak 0.1.13, sikw00fcot 1.0.0 | Jun 2026 | charontak ≥ 0.1.13 no longer ships its cockpit plugin in-deb; sikw00fcot is SiKW00F MAVLink fan-out to CoT |
| python3-pymavlink | 2.4.49-1 | packaged for AryaOS so sikw00fcot can install cleanly; pure-Python fallback path, depends on python3 and python3-lxml |
| readsb | 3.16.15-2 | synced to wiedehopf dev; build debs in debian:trixie containers because Ubuntu builds depend on librtlsdr2, uninstallable on Debian |
| dhbridge | 0.3.3 | public now; ≥ 0.3.2 required for Pi 5 (sysfs has no address attr); /etc/default/dhbridge masks dhbridge.ini keys (issue #3) |
| AIS-catcher fork | 0.68 | release workflow runs upstream build-debian.sh as root; upstream CI workflows disabled on the fork |
| kraktak 10.1.1, windtak 1.0.0, takline 0.1.1 | Jun 2026 | kraktak release decoupled from its best-effort docker job |
| cockpit-* ×9 | 1.0.0+ | Cockpit plugins use the dark AryaOS/GPSTAK visual style; watch for regressions to white-on-white UI |
LINCOT / Host Beacon¶
AryaOS expects LINCOT v1.3.1+ for dynamic host remarks and gpsd-derived CoT accuracy.
/etc/default/lincot sets GPS_INFO_CMD="gpspipe --json -n 5" and
REMARKS_EXTRA_CMD=/usr/local/sbin/aryaos-lincot-remarks. The helper emits CPU/load,
RAM, swap, disk, temperature, uptime, and Pi throttle state. LINCOT maps gpsd TPV
altHAE/eph/epx/epy/epv to CoT hae/ce/le.
AryaOS also sets COT_DETAIL_XML_CMD=/usr/local/sbin/aryaos-cot-detail so the LINCOT
host beacon carries a structured <__aryaos> detail block. aryaos-neighbord.service
listens on Mesh SA multicast (239.2.3.1:6969) and writes /run/aryaos/neighbors.json
for /cgi-bin/aryaos-neighbors and the landing-page neighbor table.
Recurring gotchas (each cost a build this month)¶
gh release uploadfails on fresh tags —gh release view || gh release createfirst.- Immutable GitHub releases reject assets uploaded after publication. Use
gh release create <tag> <asset> ..., not a create-then-upload flow that publishes first. dpkg-deb -c | grep | head→ SIGPIPE kills dpkg-deb underset -e.dh_installtreats destinations as directories (foo.confbecomes a dir).- stdeb deb names default to
python3-<name>withoutstdeb.cfgPackage3:. - A single private/release-less repo in
products.txtkills the whole publish ("release not found"); publishes racing a just-pushed tag fail the same way. - This repo has
core.fileMode=false—git update-index --chmod=+xfor scripts. - GitHub GraphQL intermittently 401s here; use REST (
gh api) with retries.
Dev lab¶
Known lab hosts recently used:
pi@aryaos-dev-pi/pi@172.17.2.158: original default dev Pi; may be unreachable depending on current lab network.192.168.0.199: ADS-B box used for readsb/adsbcot/gpsd/dashboard checks.192.168.0.13: UAS-mode box with AntSDR and BlueMark DroneScout bridge DS100.
Use the lab SSH key in shared_files/aryaos/ssh/ where possible. Integration suite:
ARYAOS_SSH=pi@<host> ./scripts/aryaos-test/run.sh
After flashing the latest dev image, first checks should include:
systemctl status charontak lincot adsbcot aiscot dronecot sikw00fcot/cgi-bin/aryaos-portal-statusand/admin/aryaosgpsddata on GPS-capable unitsreadsband/run/adsb/aircraft.jsonon ADS-B units- AntSDR Ethernet reachability and dronecot feed behavior on UAS units
- Bluetooth pairing plus
aryaos-bt-pan.service/pan0on Bluetooth-capable units
Open items / next handoff tasks¶
- Hardening burn-in (2026-07-02): flash the first post-hardening dev
image and run the integration suite (esp.
09-security.sh). Watch for firewalld regressions: comitup hotspot onboarding, Bluetooth PAN DHCP, Mesh SA neighbor discovery, AntSDR → dronecot, Docker-published CloudTAK ports, Node-RED/AIS-catcher dashboards. Then, after the first release with thearyaos-overlay_*_all.debasset exists, addsnstac/aryaosto packagesproducts.txt(adding it earlier breaks the whole publish —gh release downloadfails on a release with no deb assets). - Flash and test the latest dev image: burn
v2026.06.23.212757-abe8e41bf5e2-dev, then run the integration suite against the current lab ADS-B and UAS boxes. Pay special attention tosikw00fcot, Charontak inheritance, and the new Bluetooth PAN service. - Bluetooth PAN live validation: pair an Android phone to AryaOS, confirm it
receives
10.44.0.20-60, confirmhttps://10.44.0.1:9090/works, and confirm no unwanted NAT/default-route behavior is introduced. - AntSDR operational follow-through: keep the AntSDR path focused on
alphafox02/antsdr_dji_droneid; do not rely on DroneScout containers for this setup. Verify the matching Ethernet interface comes up and that dronecot consumes the AntSDR output. - Release hygiene: for dev builds, verify published prereleases have the image asset attached. Delete empty prereleases immediately if publish fails after tag creation.
- takline + windtak are private — the packages publish token can't read them;
flip public (
gh repo edit snstac/<r> --visibility public --accept-visibility-change-consequences), then add toproducts.txt. - Archive
spotcot(pre-pytak-5, dormant since 2022) andcockpit-sdrconnect(unmodified cockpit-dronecot clone, no releases). - Delete stray fork
snstac/AIS-catcher-1(accidental duplicate). - adsbcot PyPI job needs a trusted publisher configured on PyPI (release works regardless; the job just reads red).
- Possible next plugins: charontak lane editor (structured
charontak.iniUI — current plugin is a raw editor), kraktak/windtak/aprscot pages; backport SIGPIPE fixes everywheredpkg-deb -c | headsurvives. - Node-RED runtime check after the worldmap 5.x / tfr2cot 2.0 major bumps (palette installs now go through the npm 11 override).