Add docs/adr/ with a chronological ADR set reconstructed from the project history (no orchestrator, one storage format, derived-state sync, SQL-over-SSH contract, WireGuard beneath SSH, IaC boundaries, non-root image, runtime data paths, bounded lake scans), an index README, and a template. Distinguish repo-local ADRs from ecosystem-wide ASRs. Expand AGENTS.md with a decision-records section and a runtime/operations guide (service URLs, rebuild workflow, CPU budget knobs). Reference the ADRs from README, CONTRIBUTING, and the affected design docs, and add an open question for T1 partition pruning.
1.9 KiB
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), and SSH already carries the trust
model (ADR-0005), 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 built, secured, and tested — "what you test is what flies".
- The SQL gate is safety-critical and is covered by unit tests
(
simulator/tests/test_sql_gate.py). - The explorer and the prototype's live mode are just another read-only
consumer of this same contract (
../04-swarm-sync.md). - Design principles 7 and 8 in
../../README.mdrestate this.