Keep the 45-byte pose frame consistent across docs, simulator, and prototype, clarify MinIO is not peer sync, and state clearly that the repo is a from-scratch platform sketch with options rather than mandates.
47 lines
2.3 KiB
Markdown
47 lines
2.3 KiB
Markdown
# ADR-0004: Read-only SQL-over-SSH as the peer query contract; no debug API
|
|
|
|
## Status
|
|
|
|
Accepted (2026-07-08). Supersedes the earlier sketch of a bespoke query service.
|
|
|
|
## Context
|
|
|
|
Beyond the 5 Hz broadcast, a peer (or an engineer on the bench) sometimes needs
|
|
to *ask* a drone a richer question: "show me your detections in the last minute
|
|
near this position". Inventing a service for this means a new port, a new
|
|
protocol, an auth layer, and a second code path that only runs during
|
|
debugging — the classic "works on the bench, untested in flight" trap.
|
|
|
|
## Options
|
|
|
|
| Option | Pros | Cons |
|
|
| --- | --- | --- |
|
|
| A — Custom query microservice + REST API | Flexible | New port/protocol/auth to secure; a debug-only path that never flies |
|
|
| B — Read-only DuckDB SQL over an SSH forced command | Reuses SSH trust + the query language already on both ends; identical path on bench and in flight | SQL must be gated to read-only |
|
|
|
|
## Decision
|
|
|
|
Peer data access is **read-only DuckDB SQL executed through an SSH forced
|
|
command**. SQL is already the query language on both ends
|
|
([ADR-0002](ADR-0002-one-storage-format.md)), and SSH already carries the trust
|
|
model ([ADR-0005](ADR-0005-wireguard-beneath-ssh.md)), so no new service, port,
|
|
or protocol is invented. A **SQL gate** rejects anything that writes
|
|
(`COPY`, `INSERT`, `ATTACH`, pragmas). There is **no separate debug API**: an
|
|
engineer debugging on the ground runs the identical query through the identical
|
|
wrapper, permissions, and output format a peer drone would use.
|
|
|
|
## Consequences
|
|
|
|
- One access path is designed for flight and bench — "what you test is what
|
|
flies".
|
|
- The statement gate in the PoC (`simulator/explorer/server.py`, covered by
|
|
`simulator/tests/test_sql_gate.py`) is a **first layer**: keyword allow/deny
|
|
over HTTP for the explorer. Production still needs the remaining layers in
|
|
[04 — Swarm sync](../04-swarm-sync.md) (forced-command key, read-only OS user,
|
|
engine hardening, resource caps) and a real SQL parser rather than keywords
|
|
alone.
|
|
- The explorer and the prototype's live mode are *stand-in consumers* of the
|
|
same read-only contract over HTTP today; the proposed flight path is
|
|
SQL-over-SSH ([`../04-swarm-sync.md`](../04-swarm-sync.md)).
|
|
- Design principles 7 and 8 in [`../../README.md`](../../README.md) restate this.
|