add expanded master report v2.0 (12 agents)

This commit is contained in:
kayos 2026-03-22 11:26:26 -07:00
parent b2e3a3a360
commit 471e9bb271

View file

@ -0,0 +1,748 @@
# ADAMaps Project — Comprehensive Technical Report
**Date:** 2026-03-22
**Version:** 2.0 (Expanded Edition)
**Prepared by:** Kayos (OpenClaw Agent)
**For:** Jacob Hayes (Cobb)
**Classification:** Internal — Sulkta Cooperative
---
## Executive Summary
This document is the **single source of truth** for the ADAMaps decentralized road mapping platform and Hivemapper Bee liberation project. It consolidates research from 12 Opus deep-dive agents covering hardware, firmware, AI/ML, security, connectivity, and recovery procedures.
### Project Status
| Component | Status | Notes |
|-----------|--------|-------|
| **Unit 1 Bee** | ✅ Liberated | SSH working, adacam services running |
| **Unit 2 Bee** | ⚠️ Locked out | SSH key auth failed, recovery artifact v5+ pending |
| **ADAMaps API** | ✅ Deployed | Flask on Rackham:5001, PostGIS on Lucy |
| **Varroa App** | ✅ Working | Store-and-forward architecture functional |
| **Truck Bee WiFi** | ⚠️ Unstable | Too far from router, HTTP agent deployed |
| **SSH Tunnel** | ❌ Broken | OpenSSH relay bug on Keembay platform |
### Critical Findings
1. **Detections stored in FILES**, not SQLite — `/data/recording/landmarks/*.json`
2. **odc-api is bloat** — 14% CPU, can be eliminated
3. **SSH reverse tunnel relay is broken** — platform bug, not config
4. **HTTP Agent API works** — deployed at `/data/adacam/agent.py:8080`
5. **USB bridge enables recovery**`192.168.197.55` via USB-C
6. **/opt is READ-ONLY** — all writes must go to `/data/`
7. **Mender OTA has no local signature verification** — custom artifacts work
---
## Table of Contents
1. [Hardware Architecture](#1-hardware-architecture)
2. [Firmware & OS](#2-firmware--os)
3. [Partition Layout & Persistence](#3-partition-layout--persistence)
4. [Data Pipeline](#4-data-pipeline)
5. [AI/ML Pipeline](#5-aiml-pipeline)
6. [Sensor Integration](#6-sensor-integration)
7. [ADAMaps Backend](#7-adamaps-backend)
8. [Mobile Integration](#8-mobile-integration)
9. [Connectivity Options](#9-connectivity-options)
10. [Security Analysis](#10-security-analysis)
11. [Liberation Procedures](#11-liberation-procedures)
12. [Recovery Procedures](#12-recovery-procedures)
13. [SSH Tunnel Diagnostics](#13-ssh-tunnel-diagnostics)
14. [Service Reference](#14-service-reference)
15. [File System Reference](#15-file-system-reference)
16. [Credentials & Keys](#16-credentials--keys)
17. [Recommendations](#17-recommendations)
18. [Appendices](#18-appendices)
---
## 1. Hardware Architecture
### 1.1 Intel Keem Bay SoC
| Component | Specification |
|-----------|---------------|
| **SoC** | Intel Keem Bay (ARM64) |
| **CPU** | 4x ARM Cortex-A53 cores |
| **VPU** | Intel Movidius Myriad X (16 SHAVE cores) |
| **Peak Performance** | ~4 TOPS (INT8) |
| **Memory** | 4GB LPDDR4 (1.34GB CMA reserved for VPU) |
| **Storage** | eMMC with A/B partitions |
| **Process** | 10nm |
### 1.2 Camera System
| Component | Details |
|-----------|---------|
| **Primary Sensor** | Sony IMX412 (12MP) |
| **Native Resolution** | 4056×3040 |
| **Working Resolution** | 2028×1024 |
| **Frame Rate** | 30 FPS |
| **Stereo Sensors** | OV9282 (1MP mono) × 2 |
| **Pipeline** | Luxonis DepthAI |
### 1.3 Network Interfaces
| Interface | Purpose | IP Address |
|-----------|---------|------------|
| wlp1s0f0 | WiFi AP | 192.168.0.10/24 |
| wlp1s0f1 | WiFi Client | DHCP (192.168.0.155) |
| wwan0 | LTE Modem | DHCP when SIM present |
| br0 | USB Bridge | 192.168.197.55/28 |
| usb0/usb1 | USB Gadget | Bridged to br0 |
### 1.4 LTE Modem
| Property | Value |
|----------|-------|
| **Chip** | Telit LN920 |
| **USB ID** | 1bc7:1201 |
| **Type** | LTE Cat 4 |
| **Interfaces** | 5x ttyUSB + wwan0 (QMI/NCM) |
---
## 2. Firmware & OS
### 2.1 System Overview
| Property | Value |
|----------|-------|
| **Kernel** | 5.10.32-intel-standard (aarch64) |
| **Distro** | meta-intel-ese Reference Distro 1.0 (Yocto/Dunfell) |
| **Init System** | systemd |
| **Python** | 3.8 |
| **Node.js** | v14.x |
| **Shell** | /bin/sh (busybox) |
| **Firmware Build** | 20250903011853 |
### 2.2 Mender OTA System
```json
{
"ServerURL": "https://docker.mender.io",
"UpdatePollIntervalSeconds": 1800,
"RetryPollIntervalSeconds": 300,
"InventoryPollIntervalSeconds": 28800,
"TenantToken": "dummy"
}
```
**Key Points:**
- Polls every 30 minutes for updates
- **No local signature verification** — custom artifacts work
- Uses custom `dm-verity-update` module (not standard Mender)
- Does NOT call state scripts
---
## 3. Partition Layout & Persistence
### 3.1 Full Partition Table
| Partition | Name | Size | Purpose |
|-----------|------|------|---------|
| p1 | capsule | 32MB | UEFI capsule |
| p2/p3 | env-main/redund | 512KB | U-Boot environment |
| p4 | boot_a | 256MB | Kernel Slot A |
| p5 | system_a | 3GB | Root FS Slot A |
| p6 | syshash_a | 128MB | dm-verity hash A |
| p7 | boot_b | 256MB | Kernel Slot B |
| p8 | system_b | 3GB | Root FS Slot B |
| p9 | syshash_b | 128MB | dm-verity hash B |
| p10 | factory | 64MB | Factory calibration |
| **p11** | **data** | **52GB** | **Persistent data** |
### 3.2 What Survives Updates
| Location | Survives? | Notes |
|----------|-----------|-------|
| `/` (rootfs) | ❌ | Replaced by A/B update |
| `/etc` (overlay) | ✅ | Upper dir in `/data/overlay/current/` |
| `/data/*` | ✅ | Never touched by OTA |
| `/home/root` | ✅ | Bind mount from /data |
| `/opt/*` | ❌ | Read-only, part of rootfs |
### 3.3 Overlay Filesystem
```
overlay on /etc type overlay (
lowerdir=/rootfs/etc,
upperdir=/data/overlay/current/,
workdir=/data/overlay/workdir/
)
```
**Critical Understanding:** Any write to `/etc` goes to `/data/overlay/current/`. This survives ALL firmware flashes. This is how Unit 2 got locked out — hardened sshd_config in overlay.
---
## 4. Data Pipeline
### 4.1 End-to-End Flow
```
Camera (IMX412) → depthai_gate → VPU (YOLOv8-nano) → map-ai.py
/data/recording/landmarks/*.json
adacam-forwarder → ADAMaps API
```
### 4.2 Detection Storage
**Location:** `/data/recording/landmarks/`
**Format:** JSON files (NOT SQLite)
```json
{
"id": 2945056,
"class_label": "road_sign",
"overall_confidence": 0.847,
"lat": 33.841234,
"lon": -118.391234,
"timestamp": 1746377552043,
"bounding_box": {"x1": 1234, "y1": 456, "x2": 1456, "y2": 678},
"image_path": "/data/recording/cached_observations/xxx.jpg",
"speed_mph": 35.2,
"heading_deg": 127.4
}
```
### 4.3 Detection Classes
| ID | Label | Description |
|----|-------|-------------|
| 0 | road_sign | Traffic signs |
| 1 | lane_marking | Road lines |
| 2 | traffic_light | Signals |
| 3 | face | Privacy (blur) |
| 4 | license_plate | Privacy (blur) |
| 5 | road_marker | Mile markers |
| 6 | construction | Construction signs |
| 7 | vegetation | Overgrown blocking |
**Confidence threshold:** 0.3 minimum
### 4.4 Storage Limits (folder-purger)
| Directory | Limit | Contents |
|-----------|-------|----------|
| gps | 190 MB | GPS tracks |
| imu | 343 MB | IMU data |
| ml_metadata | 19 MB | Detection metadata |
| raw | 4.8 MB | Raw H.265 |
| unprocessed_framekm | 7.5 GB | Pending uploads |
---
## 5. AI/ML Pipeline
### 5.1 VPU Performance
| Metric | Value |
|--------|-------|
| **VPU Utilization** | 98% (bottleneck) |
| **Inference Time** | ~45ms/frame (FP16) |
| **Effective FPS** | 8-12 FPS |
| **JPEG I/O** | ~27ms/frame |
### 5.2 Models
| Model | Size | Purpose |
|-------|------|---------|
| privacy.blob | 9.5MB | Face/plate detection |
| ObjectDetectionUS.blob | 9MB | US road signs |
| ObjectDetectionEU.blob | 9MB | EU road signs |
| classifySpeedLimit.blob | 10MB | Speed value OCR |
| classifyTurnRule.blob | 10MB | Turn restrictions |
### 5.3 Custom Model Deployment
**Yes, possible:**
1. Train YOLOv8 with matching architecture
2. Export ONNX → compile OpenVINO → `.blob`
3. Replace in `/opt/map-ai/models/` (requires overlay or re-flash)
4. Update hash in metadata JSON
5. Restart map-ai.service
---
## 6. Sensor Integration
### 6.1 Redis Keys
| Key | Type | Purpose |
|-----|------|---------|
| GNSSFusion30Hz | JSON | 30Hz fused GPS |
| ImuFusion10Hz | JSON | 10Hz fused IMU |
| MagnetometerData | JSON | Compass heading |
| MAP_AI_READY | string | AI status flag |
### 6.2 Sensor Hardware
| Sensor | Device | Rate |
|--------|--------|------|
| GPS (u-blox) | /dev/ttyS2 | 1-10Hz |
| IMU | /dev/spidev0.0 | 100-200Hz |
| Magnetometer | via IMU SPI | 10-50Hz |
### 6.3 GPS Assistance
**MGA Offline:** `/data/mgaoffline.ubx`
Reduces TTFF from 30-60s to 1-5s.
---
## 7. ADAMaps Backend
### 7.1 Architecture
```
Bee → adacam-forwarder → api.adamaps.org (Rackham:5001)
PostGIS (Lucy:5432 via VPN)
```
### 7.2 API Endpoints
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | /api/health | No | Health check |
| GET | /api/stats | No | Detection counts |
| POST | /api/ingest | X-AdaMaps-Key | Ingest batch |
| POST | /api/images | X-AdaMaps-Key | Upload images |
### 7.3 Ingest Payload
```json
POST /api/ingest
Header: X-AdaMaps-Key: adamaps-ingest-2026
{
"device_id": "dashcam-4A928016A02C1046",
"detections": [
{
"ts": 1746377552043,
"lat": 33.841234,
"lon": -118.391234,
"class_label": "road_sign",
"overall_confidence": 0.847
}
]
}
```
### 7.4 Database Schema
```sql
CREATE TABLE detections (
id SERIAL PRIMARY KEY,
device_id TEXT NOT NULL,
detected_at TIMESTAMPTZ,
lat DOUBLE PRECISION,
lon DOUBLE PRECISION,
geom GEOMETRY(Point, 4326),
sign_type TEXT,
confidence DOUBLE PRECISION,
image_path TEXT,
raw_json JSONB
);
CREATE INDEX detections_geom_idx ON detections USING GIST(geom);
```
---
## 8. Mobile Integration
### 8.1 Pairing Protocol
1. Phone connects to Bee's AP manually
2. `GET /pair` returns serial, version
3. Token derived locally: `SHA256("adacam-api-{serial}-token")[:32]`
4. No token exchange — both sides compute independently
### 8.2 adacam-api Endpoints
| Endpoint | Auth | Description |
|----------|------|-------------|
| /pair | No | Pairing info |
| /api/1/landmarks/last/:n | No | Recent detections |
| /api/1/wifi/connect | Yes | Configure WiFi |
| /api/1/ssh/toggle | Yes | Enable/disable SSH |
| /api/1/wigle/config | Yes | WiGLE wardriving |
### 8.3 App Architecture
- Store-and-forward design
- Room database for offline buffering
- Explicit network binding for dual-network handling
- WorkManager for uploads when internet available
---
## 9. Connectivity Options
### 9.1 Interface Summary
| Interface | Status | Use Case |
|-----------|--------|----------|
| WiFi AP | ✅ Working | Phone pairing |
| WiFi Client | ✅ Working | Home network |
| LTE | ✅ Ready | Needs SIM |
| USB Bridge | ✅ Working | Recovery access |
| Bluetooth LE | ❌ Disabled | Not compiled in kernel |
| WireGuard | ❌ Disabled | Not compiled in kernel |
### 9.2 USB Bridge Access
**Critical for Unit 2 recovery:**
1. Connect USB-C cable
2. Set host IP: `192.168.197.49/28`
3. SSH to `192.168.197.55`
### 9.3 LTE Modem
When SIM inserted:
- `lte-init.py` detects and configures APN
- `wwan0` interface comes up
- Routes adjusted based on metric
---
## 10. Security Analysis
### 10.1 Phone-Home Mechanisms
| Mechanism | Service | Risk |
|-----------|---------|------|
| Mender OTA | mender-client | 🔴 Critical |
| Beekeeper Plugin | beekeeper-plugin | 🔴 Critical |
| mitmproxy Routing | mitmproxy | 🟠 High |
| Model Zoo | model-zoo | 🟡 Medium |
| odc-api | odc-api | 🟡 Medium |
### 10.2 Device Fingerprints
| Type | Value |
|------|-------|
| Serial | 2P021849 |
| IMEI | 351369652127410 |
| SIM ICCID | 89148000010586417818 |
| WiFi MAC | b8:f4:4f:c7:a3:55 |
### 10.3 Blocking Strategy
**Services to disable:**
```bash
systemctl stop beekeeper-plugin mender-client mitmproxy model-zoo odc-api
systemctl disable beekeeper-plugin mender-client mitmproxy model-zoo odc-api
```
**Domains to block in /etc/hosts:**
```
127.0.0.1 docker.mender.io hivemapper.com api.hivemapper.com beemaps.com
```
---
## 11. Liberation Procedures
### 11.1 Script History
| Version | Status | Key Change |
|---------|--------|------------|
| v0.1-0.3 | ❌ Broken | Wrote to read-only paths, SSH lockout |
| v0.4 | ✅ Safe | Removed SSH hardening |
| v0.5 | ✅ Current | All writes to /data, SSH keys to /home/root/.ssh |
### 11.2 SSH Lockout Root Cause (Unit 2)
1. v0.3 wrote `PasswordAuthentication no` to `/etc/ssh/sshd_config`
2. This went to `/data/overlay/current/ssh/sshd_config`
3. Script failed at `mkdir /root/.ssh` (read-only)
4. No authorized_keys written
5. Device rebooted → **Permission denied (publickey)**
### 11.3 Safe Liberation (v0.5)
```bash
ssh root@192.168.0.10 'bash -s' < liberate-v0.5.sh
```
**What it does:**
- Kills Hivemapper services
- Writes SSH keys to `/home/root/.ssh/` (safe path)
- Installs adacam services
- Creates `/data/adacam/liberated` marker
---
## 12. Recovery Procedures
### 12.1 Recovery Artifacts Built
| Artifact | Approach | Result |
|----------|----------|--------|
| v1-v4 | State scripts | Failed — Mender fork ignores state scripts |
| v5+ | Patched usb-updater in system.img | **Current approach** |
### 12.2 v5+ Recovery Method
**Key insight:** `/usr/bin` is NOT overlaid. Changes in system.img take effect.
**How it works:**
1. Modified `/usr/bin/usb-updater` with SSH recovery code prepended
2. Flash via USB
3. On boot, usb-updater has recovery code
4. Next USB insertion triggers recovery:
- Writes open sshd_config to overlay
- Writes authorized_keys
- Restarts sshd
### 12.3 USB Bridge Recovery
**Alternative recovery path:**
1. Connect USB-C cable
2. Configure host: `192.168.197.49/28`
3. SSH to `192.168.197.55`
4. Clear overlay: `rm /data/overlay/current/ssh/sshd_config`
5. Write keys: `/home/root/.ssh/authorized_keys`
6. Reboot
---
## 13. SSH Tunnel Diagnostics
### 13.1 Problem Summary
SSH reverse tunnel establishes but **does not relay data**. Banner never received.
### 13.2 Evidence
| Test | Result |
|------|--------|
| Raw TCP from Lucy:2222 | Zero bytes received |
| Standalone sshd on 2223 | Same banner timeout |
| Local SSH on Bee | ✅ Works |
| Tunnel port on Lucy | ✅ Appears |
### 13.3 Root Cause
Likely OpenSSH bug or kernel network stack issue specific to Intel Keembay. Socket activation is NOT the cause (ruled out with standalone sshd test).
### 13.4 Workarounds
| Option | Status |
|--------|--------|
| HTTP Agent API | ✅ Deployed at :8080 |
| chisel tunnel | Needs ARM64 binary |
| Move truck closer | Pending |
### 13.5 HTTP Agent API
**Deployed to:** `/data/adacam/agent.py`
**Port:** 8080
**Auth:** `X-Agent-Key: bee-agent-sulkta-2026`
**Endpoints:**
- `GET /status` — Health check
- `POST /shell` — Execute command
- `GET /landmarks` — Get detection files
---
## 14. Service Reference
### 14.1 Services to KEEP
| Service | Purpose |
|---------|---------|
| depthai_gate | Camera + VPU |
| map-ai | Detection processing |
| redis | Sensor data store |
| redis-handler | Sensor fusion |
| hostapd | WiFi AP |
| sshd | Remote access |
| usb-updater | Recovery path |
### 14.2 Services to KILL
| Service | Reason |
|---------|--------|
| odc-api | Bloated, read files directly |
| mitmproxy | Hivemapper exfil |
| beekeeper-plugin | Control plane |
| hivemapper-data-logger | Uploader |
| mender-client | OTA (blocks liberation) |
| here-plugin | HERE Maps |
| model-zoo | Hivemapper models |
### 14.3 New ADAMaps Services
| Service | Port | Path |
|---------|------|------|
| bee-agent-api | 8080 | /data/adacam/agent.py |
| adacam-forwarder | — | /data/adacam/ |
| bee-tunnel | — | systemd service |
---
## 15. File System Reference
### 15.1 Key Paths on Bee
```
/data/ # Writable, survives OTA
├── adacam/ # ADAMaps config
│ ├── agent.py # HTTP agent API
│ ├── config.json
│ └── liberated # Liberation marker
├── recording/
│ ├── landmarks/ # Detection JSON ← KEY
│ ├── cached_observations/ # Detection images ← KEY
│ ├── framekm/ # Video bundles
│ └── odc-api.db # SQLite (sensors only)
├── overlay/current/ # /etc overlay
├── ssh/
│ └── bee_tunnel_key # Tunnel SSH key
└── mgaoffline.ubx # GPS assistance
/opt/ # Read-only
├── map-ai/ # ML Python code
├── odc-api/ # Node.js API (kill)
└── dashcam/bin/ # Binary tools
/home/root/.ssh/ # Bind mount from /data
└── authorized_keys # SSH keys (safe path)
```
---
## 16. Credentials & Keys
### 16.1 API Keys
| Service | Key |
|---------|-----|
| ADAMaps Ingest | `X-AdaMaps-Key: adamaps-ingest-2026` |
| Bee Agent API | `X-Agent-Key: bee-agent-sulkta-2026` |
| Gitea | `33a9eb57b58c262f4434c12028bc3a30b1ff7021` |
### 16.2 SSH Keys
**OpenClaw (kayos@openclaw):**
```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQxwJU91TCxds34P18D3xRbu7rxlrgTUoml/H8nxeDK
```
**Bee tunnel (root@keembay):**
```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5ckRf/4SA84JOrmJtElHBT3dU9RC2Le5GBfqhWWVc8
```
### 16.3 IP Addresses
| Device | LAN IP | VPN IP |
|--------|--------|--------|
| Lucy | 192.168.0.5 | 192.168.254.112 |
| Rackham | 142.44.213.229 | 192.168.254.1 |
| Bee AP | 192.168.0.10 | — |
| Bee Client | 192.168.0.155 | — |
| Bee USB | 192.168.197.55 | — |
---
## 17. Recommendations
### 17.1 Immediate Actions
1. **Move truck closer** — Fix WiFi stability
2. **Test HTTP agent through tunnel** — May work even if SSH doesn't
3. **If tunnel fails** — Deploy chisel as alternative
4. **Test USB bridge recovery on Unit 2** — Direct access without WiFi
### 17.2 Architecture Improvements
1. **Eliminate odc-api** — Read landmark files directly (saves 14% CPU)
2. **Deploy bee-agent-api as systemd service** — Persistent remote access
3. **Implement WiFi→LTE failover** — When SIM inserted
4. **Block all Hivemapper domains** — Complete isolation
### 17.3 Long-Term
1. **Custom firmware image** — Bake in all changes
2. **Own signing keys** — Lock out Hivemapper OTA
3. **LTE tunnel** — Persistent connectivity when mobile
4. **ADAMaps mobile map** — MapLibre with detection overlay
---
## 18. Appendices
### A. Document Sources
| Document | Topic |
|----------|-------|
| hivemapper-bee-technical-architecture.md | Hardware/firmware |
| ADAMAPS-TECHNICAL.md | Backend API |
| BEE_DATA_PIPELINE.md | Data flow |
| bee-ssh-diagnostic-report.md | Tunnel issues |
| UPDATE-AND-RECOVERY.md | Mender OTA |
| bee-security-audit.md | Phone-home blocking |
| AI_ML_PIPELINE.md | VPU/models |
| LIBERATION-HISTORY.md | Scripts + recovery |
| MOBILE-INTEGRATION.md | Varroa app |
| CONNECTIVITY.md | LTE/USB/WiFi |
| REDIS-SENSOR-INTEGRATION.md | Sensors |
### B. Gitea Repos
| Repo | Purpose |
|------|---------|
| Sulkta-Coop/adamaps | Backend API, schema |
| Sulkta-Coop/adacam | Liberation scripts, security |
| Sulkta-Coop/adacam-api | On-device API |
| Sulkta-Coop/varroa | Android app |
### C. Quick Commands
**Liberation (safe):**
```bash
ssh root@192.168.0.10 'bash -s' < liberate-v0.5.sh
```
**Kill Hivemapper:**
```bash
systemctl stop beekeeper-plugin mender-client mitmproxy model-zoo odc-api
systemctl disable beekeeper-plugin mender-client mitmproxy model-zoo odc-api
```
**Start HTTP agent:**
```bash
python3 /data/adacam/agent.py &
```
**USB recovery access:**
```bash
# On host: sudo ip addr add 192.168.197.49/28 dev usb0
ssh root@192.168.197.55
```
---
## Changelog
| Date | Version | Changes |
|------|---------|---------|
| 2026-03-22 | 1.0 | Initial report (4 agents) |
| 2026-03-22 | 2.0 | Expanded edition (12 agents) |
---
**End of Report**
*Generated 2026-03-22 by Kayos for Sulkta Cooperative*
*This document is the single source of truth for the ADAMaps/Bee project.*