part of the vulos suite

Everything
on one hub
you own.

Aql (Arabic عقلthe mind) is the software brain for your physical space. Cameras, lighting, robot mowers, IoT sensors, energy meters, climate, security and cleaning bots — and access control. The reach of a smart-home hub, pushed wider: autonomous robots and business fleets, under one hub that owns everything.

You own the box. It runs on your own machine — no cloud broker, no account, no telemetry. Access control is the first module that runs end to end today; the status ledger names every other line, built and unbuilt, without rounding up.

Hub
1 box
Cloud
0 brokers
Accounts
0 required
License
MIT or Apache-2.0
One hub, seven device kinds The Aql hub sits at the centre of a single orbit carrying seven device kinds — cameras, lighting, sensors, climate, energy, robots and access — each drawn at the same weight because the hub is built to own all of them. Access carries a terracotta accent and a travelling pulse to mark it as the one module that runs end to end today. Cameras Lighting Sensors Climate Energy Robots Access signed · tested
Vol. 01 — the one-hub issue — your box · your keys · no broker — Durban · Lagos · Lisbon
One control plane

One hub owns
everything.

A house or a whole facility under one roof: seven device kinds, one internal model, one audit log, one place to look. Underneath sits a driver-adapter seam — pluggable protocol adapters over a single model — so a new class of hardware is a driver, not a rewrite. Access control is the kind that runs end to end today; the engine behind the other six is designed and not written, and the ledger spells that out line by line.

Cameras planned

Live view, recording and event-driven alerting from IP cameras, feeding the same rules and the same audit log as everything else on the hub. Designed against the driver seam; no code yet.

onvif · rtsp

Lighting planned

The bread-and-butter surface — on, off, dim, scene, groups — behind the same one device model as everything else, so an automation can't tell a fixture from a fleet.

matter · zigbee · mqtt

Robots planned

Mowers, security patrol and cleaning bots as first-class fleet members with status, tasking and run history — the part a consumer smart-home hub never reaches for, and the reason this project exists.

zana native · generic http

Climate planned

Thermostats, valves, humidity and ventilation — setpoints and schedules that answer to the same rules engine as the lights and the gate, not to four vendor apps.

matter · mqtt · modbus

Energy planned

Meter and inverter ingestion, historical rollups and a source mix of solar, grid and battery — measured off real readings, not estimated. Nothing here is built yet.

modbus · inverter apis

Sensors planned

Motion, contact, temperature, humidity, water level, tamper — the inputs an automations runtime needs before it is worth having. Discovery and live state sit in the same engine phase.

matter · mqtt · zigbee · http

Access runs end to end

Gates, doors and barriers — the seventh kind, and the first one that is real all the way down: a paired controller pulses the relay on an Ed25519-signed command, verified against a key it pinned itself. It is the proof the rest of the hub is built against, not the whole of what the hub is for.

controller agent · conformance-tested
See the module
Chat as an input surface

Text a channel.
Act on a device.

Chat isn't the product — it's the input surface across the hub with the lowest possible friction. Nobody installs anything: someone messages a channel they already have open, the hub resolves who they are, runs your rules, and signs a command. Opening a gate is the verb that works today, because access is the module that's real; reaching the other six kinds this way is device-engine work.

The channel rails themselves are moving out of Aql and into Ephor, a separate, swappable component you run or point at. That move is in progress — so the honest line is the resident-facing one: text a channel, a device acts. Aql's side of it is fixed either way: the hub authorises and signs, and it is the only thing that decides.

  • The hub is the only authority — a channel is a transport, never a permission.
  • A sender resolves to a membership before anything physical is considered.
  • Rate limits and quotas are checked before anything physical moves.
  • Every action and every denial lands in an append-only audit log, in the same second.

A scripted conversation, not a live hub — but the shape is the real one: resolve the sender, disambiguate the access point, sign, reply with the audit id.

The first module that's real

Access control,
end to end.

One of the seven kinds is finished: gates, doors and barriers, from the intent all the way to the relay. It earns the space below by being real — a paired controller, signed commands, an audit chain and an offline path, all conformance-tested. Between the intent and the motor sit your rules, and an Ed25519 signature nothing on the network can forge: only the signature, the expiry and the nonce decide.

  1. 01

    An intent arrives

    Someone texts open, or taps it in the console. However it arrives, the transport authenticates itself first and the hub trusts none of it on its own — an intent is a request, and it is about to be judged.

  2. 02

    Your rules decide

    The hub resolves the sender to a membership, then checks the access point, the open cooldown, the hourly cap and any per-location quota. The verdict — either way — is appended to the audit log. Geofencing and recurring time windows are designed, not shipped.

  3. 03

    A signed command goes out

    An Ed25519-signed envelope — nonce, issued-at, expiry no more than 60 seconds wide — reaches the controller, which dialled out to the hub, so no inbound port is ever open at the gate. It verifies against the pinned key, fail-closed, and pulses the relay.

Access control · when the line is down

The gate still
opens.

A hub that answers only when the line is up isn't yours. Aql pre-issues a short-lived, signed grant of your rights; near the door, the app proves it to the controller directly, over LAN or Bluetooth. No connectivity, no hub, no third party in the loop.

  1. 1
    Earlier, online The hub signs a grant: which access points, until when, bound to the app's own keypair. Default TTL is seven days, refreshed on every online launch — so a revocation converges within the TTL, and instantly on the normal path.
  2. 2
    At the door, offline The app finds the controller itself — mDNS on the same LAN, or BLE GATT when there is no network at all — and asks to open.
  3. 3
    Challenge The controller replies with a 128-bit random nonce, valid for 30 seconds and usable exactly once.
  4. 4
    Proof The app signs the grant together with that nonce using its own key. A recorded exchange is worthless afterwards; possession of the grant alone is worthless too.
  5. 5
    Verify, then open The controller checks the grant's signature against its pinned hub key, then expiry, rights, and the nonce signature — fail-closed, in that order — and pulses the relay. The audit event is queued locally and uploaded when the line comes back.

Status — honestly

  • Real and conformance-tested. The grant wire format, the hub's issuance endpoint, and the controller's verification are all built and checked against the fixtures in proto/vectors/.
  • LAN works today. The reference controller advertises itself over mDNS and serves the grant exchange over LAN.
  • BLE is half-done. The framing codec and the open→challenge→proof→result session are implemented and unit-tested at ATT MTUs 23, 185 and 512; the radio itself still needs validation on real hardware.
  • The app doesn't do it yet. Requesting, storing and presenting a grant is not built — so this path does not run end to end for a real person today. Both ends of it are ready and waiting for the app.

Aql sits in parallel with your existing gate hardware, never in series with it — the local button and any code-required fail-safe egress keep working on their own, and are never something this replaces. Full status →

You own the box

No broker.
No account.

One Go binary and one SQLite file, on hardware you can point at: a VPS, a Pi behind the couch, a box in the plant room. There is no Aql service to sign up for, nothing phones home, and nothing in the binary charges anyone anything. The only private thing about your hub is its own config.

  • Bring your own channel Chat is a component you point the hub at, not a service we run — and the rails are moving to Ephor while this lands. Whichever side carries them, the accounts and credentials are yours: your workspace, your bot token, your business number. Nobody bills you through us, because there is no us in the path.
  • No public URL? Still a full install Controllers dial out to the hub unconditionally, so a Pi on the LAN with no inbound port is a complete access installation — CGNAT and a closed router are non-issues. What needs a URL is reaching the console from outside, and whichever chat rails you run that receive webhooks rather than dialling out.
  • TLS is yours, on purpose The binary ships zero TLS and zero ACME code, and refuses to bind a non-loopback address unless you tell it TLS is terminated upstream. Put a reverse proxy or any tunnel you already trust in front — Caddy, nginx, cloudflared, Tailscale Funnel. Less rope, fewer ways to serve a login page in cleartext.
  • Nothing to pay, nothing to report No billing code, no tiers, no licence server, no analytics beacon, no account with us — because there is no "us" in the runtime path. Your costs are your box and your own channel credentials.
MIT or Apache-2.0 · every line
your-box ~ $
# one binary, one SQLite file
git clone https://github.com/vul-os/aql
cd aql/hub && go build -o ../aql-hub ./cmd/hub

# loopback by default — this binary serves plain HTTP
../aql-hub -listen 127.0.0.1:8080 -data ./data

# TLS is yours: a reverse proxy, or any tunnel you trust
caddy reverse-proxy --to 127.0.0.1:8080

✓ hub up        console + API on 127.0.0.1:8080
✓ signing key   ./data (ed25519, 0600, first boot)
✓ audit log     ./data (sqlite, one file to back up)

pre-1.0 — flags and paths can still move · see docs → run your hub

What's real

The whole truth,
on one page.

Aql is early, and early projects that oversell are how people end up with a gate that doesn't open. So here is the ledger: what is built and tested, and what is still only a design. One of the seven device kinds is finished and the engine behind the other six has not started — that is the whole shape of the project right now. Nothing anywhere on this page is called real unless it appears in the left column.

Built & tested real

  • The hub. One Go binary, one SQLite file: accounts, members, invites, locations, access points, device pairing and the controller registry — 60 HTTP routes, 183 tests green across 8 packages.
  • Signed commands. Ed25519 envelopes carrying a nonce and an expiry capped at 60 seconds. The controller pins the hub's key at pairing and verifies fail-closed, in a fixed order.
  • The reference controller. Its own Go module, 45 tests green: dials out, pins the hub's key, verifies in a fixed order. The last inch is not proven — the GPIO relay driver is still a stub, and no build in this repo has driven real hardware.
  • Offline-grant issuance. The hub issues a signed 7-day grant through the same authorization gates as a live open, and the controller's eleven-step verification is built and tested.
  • Conformance vectors. 61 vectors and 68 checks in proto/, consumed by both implementations and by an independent verifier that trusts neither.
  • Chat as an input surface. A message resolves to a member, passes the open path and becomes a signed command — and the per-channel rails are moving out to Ephor. That move is in progress, so read this as the behaviour being real, not as a claim about which binary carries an adapter this week.
  • Rules and audit. Open cooldown, hourly caps, optional per-location quotas — and a SHA-256 hash-chained, append-only log of every open, denial, pairing and config change, verifiable from a cold backup.
  • Temporary access grants. A dated window for a named person, with an optional use cap, revocable, refunded on a rate-limit denial.
  • A cross-module test harness. Boots the real hub and controller binaries and drives the open path over the wire, adversarial cases included.

Not built yet planned

  • The device engine. The driver-adapter seam and every adapter behind it — Matter, MQTT, Zigbee, ONVIF, Modbus, generic HTTP — is designed, not written. No protocol driver of any kind exists in the repo.
  • The automations runtime. No when → do rule executes against live device state. Where the engine even lands — the Go hub or the Rust core — is not committed.
  • Energy metering. No meter or inverter ingestion, no historical rollups, no source mix.
  • The camera pipeline. No live view, no recording, no camera-driven alerting.
  • Lighting, climate, sensors and robot tasking. Six of the seven kinds have status in the design and nothing underneath them.
  • The phone half of offline access. The app does not request, store or present a grant — the one gap between a tested protocol and a working feature.
  • Geofencing and recurring windows. Documented designs, no code. The cleaner-every-Tuesday case is not solved yet.
  • One-time PIN and QR passes. Designed. Today's temporary access needs to know who you're granting it to.
  • Mobile builds and first-class Zana support. On the roadmap, in no binary.

This ledger is written against ROADMAP.md and ARCHITECTURE.md in the repo, and the repo runs a docs-versus-code claim check in CI. If you find something here that the code doesn't do, that's a bug worth an issue.

The other half

Aql is the brain.
Zana is the body.

Zana is the open-hardware companion project: designs for the machines a hub like this is worth having — robot mowers, sensor nodes, security and cleaning bots. Open designs, so the thing in your garden isn't a black box either.

The two are deliberately not welded together. Aql is meant to control anyone's hardware; Zana devices are simply the ones designed against it first. First-class Zana adapters are a roadmap item — no Zana-specific code is in Aql today.

Aql software
Zana hardware
Common questions

The things
people ask first.

Isn't this just Home Assistant?+

Same instinct — your devices, your box, nothing in the middle — and Home Assistant is a mature project with hundreds of integrations working today, which Aql very much is not. The difference in intent is the reach: the reach of a smart-home hub pushed wider, so autonomous robots and business fleets are first-class citizens rather than consumer gadgets, and every actuation is a signed envelope a device verifies against a key it pinned itself — which is what lets a hub command hardware across a network it doesn't trust. If you want a full smart home working this weekend, use Home Assistant. If that wider reach and the signed-command model are what you're after, this is that project, early.

What actually works today?+

One of the seven device kinds, end to end: access — gates, doors and barriers. A chat message or a click in the console resolves to a member, passes your rate limits and quotas, and becomes an Ed25519-signed command that a paired controller verifies against a pinned key and acts on, with every verdict audited. The engine behind the other six kinds — the drivers, the automations runtime, energy, cameras, robot tasking — is designed and unbuilt. The ledger above is the complete list, both columns.

So when do the other six kinds work?+

There are no dates, because none of it is scheduled — this is an open-source project being built in the open, not a product with a release plan. What the shape does tell you: access control was finished first because it is the case where getting it wrong is worst, and the pieces it forced into existence — one device model, a pairing ceremony, signed commands, an append-only audit chain, a controller that trusts nothing — are the same pieces every other kind needs. The device engine is the next phase, and the honest state of it is: not started. The roadmap is phase-by-phase and says so.

Do I need an account, or a cloud?+

Neither. There is no Aql service to sign up for and no broker between you and your hardware. You run the binary; it keeps its state in one SQLite file on your disk and generates its own signing key on first boot. Nothing phones home, and there is no billing code in the binary at all. The one outside dependency is optional and yours: if you want chat as an input surface, the workspace, the bot token or the business number behind it is your own account with that provider, billed by them, never by us.

What happens when the internet is down?+

The design answer is a pre-issued signed grant that the app proves to the controller over LAN or Bluetooth — no connectivity, no hub, no third party. The honest answer today: both ends of that exchange are built and conformance-tested, LAN/mDNS works, the BLE session is implemented and unit-tested but its radio still needs hardware validation — and the app does not yet request or present a grant, so the path doesn't run end to end for a real person. Separately, none of this ever sits in series with your gate: the local button and any code-required fail-safe egress keep working on their own. Full status.

Does everyone need to install an app?+

No — that's the whole point of chat as an input surface. People message the hub from an app they already have open. The only installs are the controller at the door, the hub on your box, and optionally the desktop app for administration.

What hardware does the access path work with?+

Any gate, door or barrier with a dry-contact relay input, which is most of them, driven by a Pi-class board running the reference controller agent on Wi-Fi or a 4G SIM. It only ever dials out, so CGNAT and closed ports are a non-issue. The two surfaces that still want real hardware in front of them are the GPIO relay driver and the BLE radio — everything above them is tested.

Is it secure enough for a real site?+

The core is built to be: Ed25519-signed commands with a nonce and an expiry no wider than 60 seconds, verified fail-closed in a fixed order against a key the controller pinned at pairing — so a hostile network, a hijacked DNS record or a malicious tunnel can't forge an open. Every inbound transport authenticates before it is read, tenancy is scoped in the database layer, the audit log is hash-chained and append-only, and the binary refuses to bind a public interface in cleartext. It is also young code that has not been externally audited; read the security chapter and decide for yourself.

What's Zana?+

The open-hardware half of the same idea — designs for robot mowers, sensor nodes and security or cleaning bots. Aql controls any hardware; Zana devices are the ones designed against Aql first. First-class support is a roadmap item, not code in the binary today. github.com/vul-os/zana.