Public beta scope: AD workflows have real-system path validation, but NOBA is still under active verification. Treat compliance evidence and self-healing claims as evaluation surfaces unless the source and configured state are shown. Read validation boundaries.
← All posts

Honesty, Live Tests, and a Rust Agent — What Shipped Between beta.5 and beta.24

2026-04-14

The last blog post went up on April 2nd when AD integration shipped. Since then we've cut twenty beta releases. This is what actually changed, and why most of it is about doing less talking and more proving.

Honesty-first engineering

A chunk of the work between beta.17 and beta.20 wasn't new features — it was pulling overclaims out of the UI and fixing scoring logic that was silently marking unknown evidence as green. The Trust Center used to award points for audit and maintenance rows we couldn't actually verify; it doesn't anymore. Workflow runs used to return a null run handle, so operators couldn't trace or cancel them; they now return a real run_id. SIEM forwarding used to drop batches on failure without telling anyone; it now re-enqueues and exposes drop/retry/backoff counters.

WebAuthn registration went from trusting the client to actually validating attestation format, rpIdHash, authenticator flags, and COSE algorithm constraints. SAML IdP certificate revocation checks now enforce configured CRL and OCSP policy, with a strict mode available for fail-closed deployments. Backup metadata used to report placeholder table and row counts; it now reports real values from PostgreSQL and MySQL.

The rule we settled on: if evidence is missing, failed, or unwired, it counts as unknown, not green. Marketing copy stays bounded to what the live code and live tests can actually prove.

Zero placeholder integration modules

NOBA's healing dispatch sits on top of integration modules — one per platform — each exposing an execute_op() contract. For a long time a lot of those modules were placeholders that returned structured-looking errors without actually talking to anything. That era is over.

Across beta.23 we replaced the last three security placeholders (CrowdSec, Fail2ban, Wazuh), closed out the surveillance category (Frigate, Blue Iris, Shinobi, ZoneMinder), retrofitted seven pre-existing modules (Proxmox, TrueNAS WebSocket, Pi-hole, UniFi, Home Assistant, qBittorrent, n8n) with the same contract, and shipped the last of the file-sync and NAS coverage. Thirty-eight integration modules, every single one exposing Contract C1 dispatch. No placeholders remain.

Live infrastructure testing — for real this time

beta.22 delivered the part that makes the honesty and the contract discipline stick: a live-infrastructure test harness. Instead of mocked connectors, integration tests now run against real running instances, capture evidence files, and fail on whatever the real API actually does.

The list of platforms that have been run against real deployments since beta.22:

Live testing found real bugs that mocks couldn't: a CrowdSec User-Agent validation gate, a TrueNAS WebSocket helper that called a non-existent function and always returned an error, and a MariaDB reserved-word quoting drift in the schema introspection path. All fixed in the same releases that expanded the coverage.

A Rust-native agent, with Windows support

beta.24 ships a full Rust rewrite of the remote agent. One 2.8 MB musl static binary, built across five crates: core (WebSocket, config, command dispatch, self-update), metrics (CPU, memory, disk, network via sysinfo), terminal (PTY via portable-pty), local healing policy evaluation, and RDP capture.

The RDP layer deserves its own paragraph because Windows remote-control on a locked desktop is ugly. Capture runs through a priority list: kernel framebuffer first (works on Linux virtual consoles without any compositor), then Wayland via native wlr-screencopy-unstable-v1 (no portal, no user prompt), then X11 SHM, then on Windows a combined DXGI + GDI path. Input injection goes through XTest on X11 and Windows SendInput on the Windows path.

The Windows desktop-transition fix in this release is a real one. DXGI IDXGIOutputDuplication and GDI device contexts are desktop-bound at creation, and no amount of per-frame SetThreadDesktop will re-bind them — hitting Win+L, logging out, or logging back in used to freeze the whole browser session. The capture thread now polls the input-desktop name and rebuilds the backend end-to-end when it changes, and the supervisor tracks LogonUI.exe presence to respawn the session helper under the correct Windows token family (user token on the interactive desktop, Winlogon token on Secure Desktop). Keyboard focus also used to get lost during that rebuild; the RDP view now binds key events at the window level instead of the canvas, so the brief frame-pause doesn't strand anyone typing into nothing.

Self-update verifies SHA-256 and Ed25519 before swapping the binary. The agent protocol now has a protobuf schema (proto/noba_agent.proto) with JSON fallback for legacy Python agents; commands are sent as protobuf to Rust agents and JSON to the legacy ones, so the transition doesn't break anyone's existing deployments.

Windows agent deployment that actually works

Before beta.24, the DeployModal's Windows tab told customers to cross-compile the agent from source. That was fine for developers and useless for everyone else. The Windows tab now generates a real PowerShell install bootstrap that downloads noba-agent.exe from the server, registers it as a Windows service, and writes C:\ProgramData\noba-agent\config.json. agent-build.yml cross-compiles the Windows binary alongside the Linux one in CI.

A few other things

Try it

NOBA Enterprise is at v2.1.0-beta.24, in open beta. Download builds are at /download — the download page reads the version directly from R2, so you always get the latest.

curl -sSL https://www.nobacmd.com/install.sh | bash

Or grab the .deb / .tar.gz directly from the download page and run it behind your own reverse proxy. Tell us what breaks.

Comments

No comments yet. Be the first.

Comment posted.