adacam/docs/research/adacam-audit-inconsistencies-2026-03-30.md

44 KiB
Raw Blame History

adacam Audit — Inconsistencies, Duplicates, and Gaps

Date: 2026-03-30
Auditor: Opus (deep audit sub-agent)
Sources reviewed: All workspace memory files, all daily notes (2026-03-01 through 2026-03-30), all docs/ files, BEE-CAMERA.md, bee-security-audit.md, bee-ssh-diagnostic-report.md, bee-tunnel-state.md, adacam-odc-redis-consumer-plan.md, hivemapper-audit-2026-03-14.md
Gitea access: Unavailable (SSH key not present at /root/.ssh/id_ed25519_unraid)


1. Inconsistencies

1.1 adacam-odc port number — CRITICAL

  • adacam-master-audit.md (2026-03-29): Port 5000
    "Port: 5000 | adacam_odc.py | ODC API (HTTP)"
  • adacam-bug-report-2026-03-29.md: Port 5500 (explicitly noted as "not 5000")
    "adacam-odc.service | ✅ Running | API on port **5500** (not 5000)"
  • 2026-03-26.md daily note: "adacam-odc: running port 5500, preview DISABLED"
  • adacam-recovery-plan-2026-03-30.md (verify step 4): curl -s http://localhost:5500/api/1/health
  • adacam-diagnostic-2026-03-29.md: Mentions localhost:5500 in one place, port 5000 in Flask description
  • 2026-03-24.md: Built adacam_odc.py "Flask on port 5000"
  • RESOLUTION: Port was originally coded as 5000 but changed to 5500 at some point between initial deployment (Mar 24-25) and Mar 26. The 5500 is correct (most recent live observations, recovery plan, bug report). The master audit is WRONG on this point. The reason for the port change is NOT documented anywhere.

1.2 Where detections are stored — multi-phase confusion

  • 2026-03-22 morning (deep research Opus): Detections are in /data/recording/landmarks/*.json files. SQLite has no landmarks table.
    "Critical: Detections NOT in SQLite. Detections flow: map-ai → Redis (ephemeral) → odc-api in-memory cache → REST API"
  • 2026-03-22 afternoon: Corrected — detections ARE in /data/recording/odc-api.db SQLite table landmarks. image_name column points to /data/recording/cached_observations/.
  • 2026-03-24 (adacam-odc build): "Key finding: map-ai writes directly to SQLite — odc-api never touched landmark writes"
  • 2026-03-26 (debug session): "map-ai does NOT write directly to SQLite on this firmware — drove with odc-api dead, count frozen. odc-api IS the SQLite writer." Also notes GPS pipeline was dead at same time.
  • 2026-03-29 (adacam-pipeline-map.md): StoreLandmarksNode (inside map-ai) writes directly to SQLite. Root cause of frozen count = GPS logger disabled, NOT odc-api.
  • 2026-03-29 (adacam-master-audit.md): StoreLandmarks.py is called from map-ai pipeline → writes to odc-api.db.
  • RESOLUTION: map-ai's StoreLandmarksNode writes directly to SQLite (/data/recording/odc-api.db, landmarks table). The 2026-03-26 "experiment" was confounded — the GPS logger (hivemapper-data-logger) was also dead at that time, which starves LocateLandmarkNode of GPS data → StoreLandmarksNode has nothing to write. The observation that "count froze when odc-api was dead" was a coincidence, not causation. odc-api does NOT write to the landmarks table.

1.3 bee-security-audit.md device identity — UNDOCUMENTED

  • bee-security-audit.md (dated 2026-03-22): Serial 2P021849, IMEI 351369652127410, Firmware 20250903011853
  • adacam-master-audit.md (Truck Bee, confirmed): Serial 2P007435, IMEI 351369652125828, Firmware 20260309193836
  • RESOLUTION: The bee-security-audit.md is NOT the Truck Bee. Based on serial numbers and IMEI, it was either: (a) the Brick Bee (dashcam-81B2B81681545109) analyzed before it got bricked, OR (b) a different unit entirely. Firmware build date 20250903011853 is Sept 3, 2025 — pre-liberation, stock firmware. The Truck Bee's current firmware is 20260309193836 (March 9, 2026). This mismatch is never documented anywhere in the workspace. The security audit describes pre-liberation services (mitmproxy, beekeeper-plugin) which are now blocked/disabled on Truck Bee. The Brick Bee's device ID dashcam-81B2B81681545109 ≠ the security audit's serial 2P021849 — the relationship between these identifiers is unclear.

1.4 sshd binding on Truck Bee — confusing evolution

  • MEMORY.md: "adacam SSH only accessible on AP interface (192.168.0.10)"
  • bee-tunnel-state.md (2026-03-11): "sshd.socket: active, listening on [::]:22 (dual-stack, accepts IPv4+IPv6)"
  • 2026-03-22.md (early): "sshd on Bee is socket-activated, binds ONLY to 192.168.0.10 (AP interface)"
  • 2026-03-22.md (later, after deep recon): "sshd.socket already listens on ALL interfaces (ListenStream=22, no IP binding)"
  • RESOLUTION: sshd.socket listens on all interfaces at OS level. However, the Bee's client WiFi IP (192.168.0.155) is not reachable from home LAN — it's a private subnet the Bee advertises but returns traffic incorrectly due to the dual-subnet routing conflict. Effectively, SSH is only reliably accessible via the AP interface (192.168.0.10) or via a working tunnel. MEMORY.md is operationally correct even if technically incomplete.

1.5 hivemapper-data-logger: kill vs keep

  • 2026-03-22 KEEP/KILL lists: hivemapper-data-logger listed under KILL (thought to be phone-home telemetry)
  • 2026-03-29 adacam-pipeline-map.md: Confirmed root cause of zero detections — it was disabled (likely between Mar 22 and Mar 24) and is the GPS/IMU backbone. Re-enabled.
  • When it was disabled: The daily notes say it was disabled "at some point on Mar 24" but there is NO entry in any daily note showing who disabled it or when. The 2026-03-22 kill list may have caused someone to disable it during an undocumented session. This is a change log gap.
  • RESOLUTION: hivemapper-data-logger.service must STAY ENABLED. It reads GPS (/dev/ttyS2) and IMU (/dev/spidev0.0), publishes to Redis (GNSSFusion30Hz, ImuFusion10Hz). Without it, map-ai cannot geo-locate detections and writes nothing.

1.6 adacam-odc.service port in adacam-master-audit.md Listening Ports table

  • The master audit's "Listening Ports" table shows port 5000 for adacam_odc.py
  • But the same audit shows adacam-odc.service as active
  • By March 26 (confirmed) the service runs on 5500
  • The master audit port table is outdated/wrong on this single point.

1.7 wifi-client.service status — currently unknown

  • 2026-03-29.md: "wifi-client.service created + enabled" then "rollback still pending Opus diagnostic result"
  • adacam-bug-report-2026-03-29.md: "The service file /etc/systemd/system/bee-tunnel.service no longer exists" but bee-tunnel is described separately from wifi-client
  • adacam-recovery-plan-2026-03-30.md (Fix #1): wifi-client.service is the LIKELY ROOT CAUSE of hostapd being broken. Says to stop, disable, and remove it.
  • 2026-03-30.md daily: "Camera AP is broadcasting but rejecting WiFi connections ('connection failure') — full connection rejection, hostapd likely broken." Recovery plan Fix #1 = remove wifi-client.service.
  • RESOLUTION: wifi-client.service was created during the 2026-03-29 session as a HARD RULE violation (made without Cobb's approval). It is believed to still be present on the device and is the likely cause of the current hostapd breakage. Status: UNREMOVED as of time of camera going offline (2026-03-30 ~09:52 PDT). This needs to be the FIRST fix applied when camera access is restored.

1.8 resolv.conf state — uncertain

  • 2026-03-29.md: "Reverted the resolv.conf symlink in session" (restored symlink to systemd-resolved)
  • adacam-diagnostic-2026-03-29.md: DNS broken because systemd-resolved has no link-specific DNS config
  • adacam-bug-report-2026-03-29.md: DNS resolution confirmed broken
  • RESOLUTION: The resolv.conf symlink was restored (good), but the UNDERLYING DNS issue (systemd-resolved not resolving) is still present. DNS fix (DNS=8.8.8.8 in systemd-resolved config) was proposed but NOT applied (requires Cobb approval). This is an open issue.

1.9 WiFi routing fix — applied but not persisted

  • 2026-03-30.md: "Applied routing fix to the camera (4 ip route/ip rule commands) — these were runtime only, NOT persisted. Power cycle clears them."
  • Camera was subsequently power-cycled and the routing fix is now GONE.
  • adacam-recovery-plan-2026-03-30.md: Says to add fix to /data/persist/install.sh for persistence.
  • RESOLUTION: The routing fix was applied once, then lost on power cycle. Not persisted. Needs to be reapplied AND added to install.sh.

1.10 BEE-CAMERA.md describes stock firmware (stale document)

  • BEE-CAMERA.md (dated 2026-03-13) describes stock Hivemapper firmware services (odc-api Node.js, camera-bridge, preview mode through camera-bridge restart, etc.)
  • Current Truck Bee has NONE of this — odc-api is dead, camera-bridge is disabled in adacam-odc code, adacam-odc is the service
  • The document is valuable as a hardware/technical reference but misleading if read as current state
  • Action: Should be prefaced with a "HISTORICAL — stock firmware only" note

1.11 adacam_odc.py port 9001 conflict (now resolved but underdocumented)

  • 2026-03-26: "Port conflict theory: datalogger HTTP default :9001, camera-bridge was on :9001 — likely crashed datalogger at some point."
  • adacam_odc.py camera bridge changed 9001→9002 (commit bd0c4cff008c), then camera bridge code disabled entirely (commit 76b177a8e0e8)
  • This is the plausible reason hivemapper-data-logger was crashing — it binds to :9001 and camera-bridge was fighting it
  • This causal chain is NOT documented anywhere as the confirmed cause of the GPS logger crash

2. Duplicates

The following files cover substantially the same ground and should be consolidated:

File Coverage Notes
adacam-master-audit.md Comprehensive device state (2026-03-29) Most detailed current-state doc
adacam-project-state.md (previous version) Device state Prior Opus-written summary
adacam-pipeline-map.md Detection pipeline + root cause GPS logger root cause focus
adacam-diagnostic-2026-03-29.md DNS diagnostic DNS focus, largely covered by bug report
adacam-sitrep.md Summary status (2026-03-29) Short summary of bug report
adacam-bug-report-2026-03-29.md Comprehensive issue list Best structured issue tracker
BEE-CAMERA.md Hardware/firmware reference Only useful for HW technical depth; stock firmware description
bee-security-audit.md Security analysis (stock firmware) Pre-liberation, different device (2P021849)
docs/ADAMAPS-MASTER-REPORT-FINAL.md March 22 synthesis Superseded; Rackham primary/Lucy backup is correct
docs/ADAMAPS-MASTER-REPORT.md March 22 synthesis Older, superseded
docs/ADAMAPS-MASTER-REPORT-EXPANDED.md Expanded synthesis Also March 22 era, superseded
2026-03-22.md daily Session log Contains all historical pipeline discoveries
2026-03-29.md daily Session log Contains most comprehensive current-state summary

Recommendation: adacam-project-state.md (this audit's output) is the single source of truth going forward. All others are source material.


3. Missing Information

3.1 Why/when hivemapper-data-logger was disabled

  • We know it was disabled "at some point on Mar 24"
  • No session note records explicitly disabling it
  • Likely: the 2026-03-22 kill list led someone to disable it, but no log entry exists
  • This is a change log gap

3.2 Port change from 5000 to 5500 in adacam-odc

  • Code was originally written to bind port 5000
  • By 2026-03-26 it was running on 5500
  • No commit or note explains why the port changed
  • The Gitea commit bd0c4cff008c changed camera bridge from 9001→9002, 76b177a8e0e8 disabled camera bridge — neither changes the Flask port

3.3 wifi-client.service content

  • The service file was created during the 2026-03-29 session
  • The exact content of /etc/systemd/system/wifi-client.service is NOT recorded anywhere
  • The recovery plan notes it may be "running wpa_supplicant or ip commands against wlp1s0f0" — but this is speculation
  • Impact: Without knowing exact content, it's harder to confirm it's the hostapd culprit

3.4 Original /etc/systemd/wifi-client.service (pre-our-version)

  • Recovery plan (2026-03-30) says "check if wifi-client.service is enabled" implying it might have been a PRE-EXISTING service on the device
  • There is no record of what the original service file contained before we created a new one
  • This distinction matters for recovery

3.5 Wigle/config API (mentioned 2026-03-24)

  • "Cobb mentioned a Bee-side custom API — Something related to Wigle and other configs on the Bee"
  • Never investigated or documented
  • Unknown if this still exists, what it does, or what endpoints/port it uses

3.6 Brick Bee (Device 2) device identity

  • SSID: dashcam-81B2B81681545109
  • Serial number: unclear — bee-security-audit.md has 2P021849 but that file's relationship to Device 2 is unconfirmed
  • Assembly UUID: unknown
  • IMEI of Device 2: unknown (may be 351369652127410 from security audit)
  • Current firmware version: unknown
  • Physical location: unknown — 2026-03-22 notes show it was at "home" for recovery attempts; current location not stated

3.7 UART pad locations on Hivemapper Bee PCB

  • Recovery plan mentions UART as path #6 for SSH recovery
  • bee-ssh-diagnostic-report.md says "Physical pins at 0x20180000"
  • 2026-03-22.md says "UART access to U-Boot would let us modify env-main (p2)"
  • But no actual pad/pin locations on the physical Bee PCB are documented
  • "Research the Hivemapper Bee teardown community" = deferred, never done

3.8 adamaps-persist.service / install.sh current content

  • The service runs /data/persist/install.sh at boot
  • It was updated during 2026-03-29 cleanup to remove bee-tunnel/bee-collector references
  • But the exact CURRENT content of install.sh is not re-recorded anywhere post-cleanup
  • The recovery plan mentions it will install SSH key, mask mender, block hosts — but the new exact content is unknown

3.9 /data/persist/install.sh — does it still run correctly?

  • 2026-03-29 notes: adamaps-persist.service "failed at boot" due to RTC sync timing issue
  • 2026-03-30 notes: Still failing, "pam_nologin" persisting suggests possible boot hang
  • Whether install.sh is executing properly is unknown

3.10 GPS device path ambiguity

  • 2026-03-26 notes: "GPS on /dev/ttyS2 per prepare-gps.sh. Also /dev/ttyUSB0-4 present from LTE modem — GPS may actually be on one of those."
  • master-audit.md confirms: "GPS: u-blox @ /dev/ttyS2"
  • datalogger default path was /dev/ttyAMA1 (doesn't exist) — but prepare-gps.sh sets it to ttyS2
  • RESOLUTION (mostly): GPS IS on /dev/ttyS2 per prepare-gps.sh. But the exact invocation of datalogger with ttyS2 is unclear.

4. Stale / Outdated Documents

Document Issue Recommended Action
bee-tunnel-state.md Last updated 2026-03-11. bee-tunnel.service was REMOVED from device on 2026-03-29. Now describes a non-existent service. Archive or mark OBSOLETE
BEE-CAMERA.md Describes stock Hivemapper firmware stack (odc-api, camera-bridge, preview via camera-bridge, etc.). Device no longer runs any of this. Add "HISTORICAL — stock firmware" header
bee-security-audit.md Describes pre-liberation stock firmware (beekeeper-plugin enabled, mitmproxy running, mender-client running). These are all blocked/masked on current device. Also describes a different device (2P021849, not 2P007435). Add clear "PRE-LIBERATION, Device 2P021849" header
adacam-sitrep.md Snapshot from 2026-03-29 16:55 PDT — superseded by master audit and bug report Archive
adacam-odc-redis-consumer-plan.md Plan to add Redis BLPOP consumer to adacam-odc. This plan was superseded by the finding that map-ai writes directly to SQLite, making Redis IPC unnecessary. MEMORY.md confirms "Redis = only MAP_AI_READY health flag. No detection IPC to replicate." Archive as SUPERSEDED — redis consumer not needed
docs/hivemapper-bee-technical-architecture.md Research doc from 2026-03-22 describing stock firmware architecture Tag as "stock firmware reference"
docs/ADAMAPS-MASTER-REPORT.md / FINAL.md / EXPANDED.md All from 2026-03-22 era, pre-liberation, superseded by master audit Archive
Early adacam-forwarder-v2.py (in adamaps repo, Gitea) Superseded by adacam-odc integrated forwarder Note as deprecated

5. Change Log Gaps

Events that happened but are not captured with timestamps/authors in any change log:

Date Event Gap
~2026-03-22 to Mar 24 hivemapper-data-logger.service disabled No session note records who disabled it or when. The 2026-03-22 kill list recommended killing it, but no execution log exists.
2026-03-24 to 2026-03-26 adacam-odc.service port changed from 5000 to 5500 No commit note, no daily note records this change
2026-03-25 (inferred) odc-api.service killed (finally) Daily note says "odc-api killed" with kill command documented, but commit history unclear
2026-03-29 session wifi-client.service created and enabled Documented as happening, but the exact service file content is not recorded
2026-03-29 (attempted) resolv.conf overwritten, then partially reverted Documented but rollback completion uncertain
2026-03-30 morning WiFi routing fix applied (4 ip commands) Applied by Opus agent per daily note, but not in any change log. Lost on power cycle.
2026-03-30 wpa_supplicant run directly on Pi wlan0 Documented in daily note — but this is what corrupted Pi WiFi driver, not the camera

6. Contradictions Between Gitea Docs and Workspace Memory

Since Gitea is inaccessible from this environment (SSH key missing), this section is based on cross-referencing what the daily notes describe being committed vs. what current state docs say.

6.1 Gitea docs/RECON.md

  • Committed 2026-03-29 per daily notes
  • "Schema, architecture, pipeline — any agent reads this first now"
  • This file's content is not in workspace; may duplicate parts of adacam-master-audit.md
  • Cannot verify without Gitea access

6.2 Gitea docs/MASTER-AUDIT-2026-03-29.md

  • Committed 2026-03-29 (commit a8289028)
  • Mirror of memory/adacam-master-audit.md
  • The port 5000 error in the master audit is ALSO in Gitea at this commit

6.3 adacam_odc.py (Gitea services/adacam-odc/)

  • Last known commit chain: multiple commits through 2026-03-26
  • Port may be 5500 in code (commit not explicitly recorded as port change)
  • Camera bridge code disabled per commit 76b177a8e0e8
  • USB tethering monitor fully implemented per commit 1f1694f01c5c (2026-03-25)
  • Cannot confirm latest commit state without Gitea access

7. Summary Matrix

Category Count Severity
Port number (5000 vs 5500) 1 High — affects all API calls
Detection write path confusion 1 Resolved in this audit
bee-security-audit device mismatch 1 Medium — affects Device 2 identity
wifi-client.service unknown state 1 Critical — likely causing current hostapd break
Routing fix not persisted 1 High — lost on power cycle
hivemapper-data-logger disable/re-enable gap 1 Medium — change log gap
Stale documents 6 Low-Medium
Missing info items 10 Various
Change log gaps 7 Medium

8. adacam ↔ ADAMaps Interface Inconsistencies

This section documents inconsistencies, gaps, and contradictions between what adacam-odc is documented to do and what the ADAMaps API expects, plus internal ADAMaps documentation inconsistencies.


8.1 Detection payload field names: mismatch between sender and receiver

adacam-odc sends (from codebase audit 2026-03-23, v1 forwarder):

{
    'id': str(row['id']),           # camera's local SQLite ID
    'ts': int(row['ts']),
    'lat': float(row['lat']),
    'lon': float(row['lon']),
    'class_label': row['class_label'],
    'overall_confidence': float(row['confidence']),
    'device_id': config['device_id'],
}

ADAMaps DB stores:

  • sign_type (not class_label)
  • confidence (not overall_confidence)
  • detected_at (derived from ts)

RESOLUTION: The ADAMaps /api/ingest endpoint maps class_labelsign_type and overall_confidenceconfidence internally. This IS handled, but it's an implicit contract that's not documented anywhere. If anyone changes either side without updating the other, silent data loss occurs.


8.2 Extended fields: ADAMaps DB has columns that adacam-odc may not send

ADAMaps detections table has (after migration 004, 2026-03-24): cam_lat, cam_lon, cam_heading, azimuth, attributes JSONB, map_feature_id, bbox_x1/y1/x2/y2

adacam-odc SQLite source table HAS all of these (confirmed from odc-api.db schema): cam_lat, cam_lon, cam_heading, azimuth, attributes, x1/y1/x2/y2

Whether adacam-odc's forwarder ACTUALLY sends them: UNKNOWN.

  • adamaps/bee/adacam-forwarder.py (the OLD standalone forwarder) had extended fields added in commit referenced in MEMORY.md 2026-03-24
  • But that old forwarder was SUPERSEDED by adacam-odc's integrated Thread 2
  • Whether Thread 2 in adacam-odc sends extended fields is not documented explicitly
  • The 2026-03-22 adacam-codebase-audit-2026-03-23.md audit flags this as a gap and recommends adding them
  • Impact: Cropping endpoint /api/images/{filename}?crop={sign_id} only works if bbox coords reach ADAMaps. Phase 2 speed sign optimization only works if attributes JSON is forwarded. Currently likely missing both.

8.3 Image upload: detection_id linkage is ambiguous

adacam-odc image upload flow:

  1. Ingest detections → POST /api/ingest → response: {"inserted": N, "device_id": "..."}
  2. Upload image → POST /api/images with detection_id field

The problem: The ingest response does NOT return the ADAMaps-assigned sequential IDs (1 to 14523 range). The forwarder uses the camera's LOCAL SQLite ID (e.g., 229787) as the detection_id in the image upload.

ADAMaps's /api/images route must then look up the detection by raw_json->>'id' = "229787", NOT by detections.id. Whether the current app.py does this correctly is undocumented in workspace files. If it matches by detections.id (sequential), all 2,941 uploaded images are pointing to wrong detection records.

What is documented: 2026-03-22 notes state "4285 detections with images linked" — suggesting the linkage WAS working. But the exact matching logic in app.py is not described in any workspace file.


8.4 docs/ADAMAPS-TECHNICAL.md is comprehensively outdated (2026-03-22)

This file is in /root/.openclaw/workspace/docs/ADAMAPS-TECHNICAL.md. Almost every section is wrong:

Field ADAMAPS-TECHNICAL.md says Actual (2026-03-30)
On-device service adacam-api.service on port 5000 adacam-odc.service on port 5500
On-device data path /data/adacam/adacam.db /data/recording/odc-api.db
VPN type WireGuard OpenVPN
DB location Lucy (Postgres via VPN) Rackham (primary), Lucy (replica)
Agent auth X-Agent-Wallet: addr1... header Ed25519 crypto auth, API key
Agent DB table agent_stats agent_registry
On-device persistence service bee-tunnel.service Removed (2026-03-29)
Forwarder Separate adacam-forwarder.py Merged into adacam-odc.py Thread 2
Detection data source /data/adacam/adacam.db /data/recording/odc-api.db landmarks table
AGENT_API_LIVE False (code ready, not live) True (flipped 2026-03-23)
ADAMaps stats No data 14,523 detections, 1,833 signs, 108 verified

Recommended action: Delete or archive this file. The authoritative current state is in memory/adacam-project-state.md (this audit's output).


8.5 VPN type: WireGuard vs OpenVPN — confirmed in multiple places

  • docs/ADAMAPS-TECHNICAL.md: WireGuard, Bee → 192.168.254.x VPN IP
  • 2026-03-22.md (Cobb correction, v3.0 report): "VPN: OpenVPN (not WireGuard). Server: Lucy (Docker container). Client: Rackham (native)"
  • docs/ADAMAPS-MASTER-REPORT-FINAL.md: Corrected VPN section
  • RESOLUTION: OpenVPN is correct. The Bee does NOT have a VPN connection to Lucy/Rackham. VPN is only between Lucy and Rackham. Bee connects to ADAMaps only via adacam-odc forwarder over public internet.

8.6 API container port inconsistency

  • docs/ADAMAPS-TECHNICAL.md: "Port 5001 (internal), reverse-proxied via ISPConfig to api.adamaps.org"
  • adamaps-docs-update-2026-03-30.md: Docker-compose maps "127.0.0.1:5001:5000" — container internal port 5000, external 5001
  • RESOLUTION: Both are consistent: Flask runs on 5000 inside the container, Apache proxies external 5001 → container. No conflict, just needs to be read correctly.

8.7 odc-api detection write path: three conflicting answers

This is the most complex inconsistency and affects the fundamental architecture understanding. Completely new dimension found in this extended audit that the prior adacam-only audit partially resolved:

Date Source Claim
2026-03-22 (morning) Pipeline research Detections NOT in SQLite — in JSON files + Redis ephemeral
2026-03-22 (afternoon) Live recon Detections ARE in odc-api.db SQLite landmarks table
2026-03-24 odc-api source audit map-ai writes directly to SQLite — odc-api never touched landmark writes
2026-03-25 Drive session observation 1,763 new detections captured (while odc-api was being killed)
2026-03-26 Runtime observation odc-api IS needed — masking it stopped new landmark writes (Redis consumer theory)
2026-03-26 adacam-odc-redis-consumer-plan.md Plan to build Redis consumer in adacam-odc to replace odc-api
2026-03-26 map-ai.py source EXTERNAL_MODEL queues ONLY active when isHerePluginEnabled — always 0 with here-plugin disabled
2026-03-29 Master audit + pipeline map Root cause of frozen count = hivemapper-data-logger disabled (GPS dead), NOT odc-api

RESOLUTION (authoritative, based on source code and final root cause analysis):

  1. map-ai.py's StoreLandmarksNode writes directly to SQLite at /data/recording/odc-api.db
  2. Redis EXTERNAL_MODEL_OUTPUT_QUEUE is used ONLY by the ExternalModelsRouterNode, which runs ONLY when isHerePluginEnabled or isTest. With here-plugin disabled, these queues are always 0.
  3. odc-api has a TypeORM Redis consumer but it's dormant when here-plugin is disabled
  4. The 2026-03-26 "masking odc-api broke detection pipeline" was a mis-attribution — the real cause was GPS logger being disabled
  5. adacam-odc-redis-consumer-plan.md is SUPERSEDED — the Redis consumer it proposes would consume an always-empty queue

8.8 api/app.py vs app.py — duplicate file in adamaps repo (RESOLVED)

  • adacam-codebase-audit-2026-03-23.md: "api/ - (Duplicate? Check if this is the live one)"
  • adamaps-docs-update-2026-03-30.md: "api/app.py differs but is NOT deployed (legacy file, docker-compose service not running)"
  • RESOLUTION: Main /opt/adamaps/app.py is the live service. api/app.py is a legacy/development copy. Not a problem operationally but should be removed from the repo to avoid confusion.

8.9 ADAMaps detection count frozen at 14,523 since March 25

  • Live stats (2026-03-29 audit): 14,523 detections, same count noted in project-status.md
  • Root cause: WiFi routing conflict blocks camera's internet access → adacam-odc forwarder can't reach api.adamaps.org → no new uploads since ~Mar 23-25
  • Not documented anywhere in ADAMaps-side docs — looks like a live system at full operation, but data collection has been frozen for 5+ days as of Mar 30
  • map-ai has continued writing detections to camera SQLite (last seen Mar 24); these detections exist on camera but haven't been forwarded

8.10 adacam-api repo: exists but was never archived

  • adacam-cross-verify-2026-03-24.md: "Archive adacam-api repo on Gitea" (pending)
  • docs/ADAMAPS-TECHNICAL.md: Describes adacam-api as an active service
  • No workspace file confirms archiving was completed
  • The repo Sulkta-Coop/adacam-api likely still exists on Gitea as an active-looking repo
  • Impact: Future agents might read ADAMAPS-TECHNICAL.md, see adacam-api described, try to deploy or reference it, and conflict with the deployed adacam-odc

8.11 WiGLE integration: in adacam-api but status in adacam-odc unknown

  • adacam-api had 4 WiGLE endpoints + separate wigle.db SQLite
  • adacam-cross-verify-2026-03-24.md (deploy notes): "WiFi/SSH/config/pairing endpoints merged from adacam-api"
  • But no explicit confirmation that WiGLE routes were included in the merge
  • WiGLE data never flows to ADAMaps — it uploads to WiGLE.net separately
  • Gap: Whether adacam-odc currently has /api/1/wigle/* endpoints is unknown

8.12 Honeypot canaries in ADAMaps DB — not in adacam forwarder

From 2026-03-22 session notes: 5 canary detections planted in ADAMaps DB (IDs 1225612260, device honeypot-canary) at fictional coordinates. These are for detecting data scraping/theft.

Not documented in any adacam-side file. Only in the 2026-03-22 daily note.

Impact: Any query against ADAMaps data that returns device_id=honeypot-canary is an alert trigger. adacam-odc does not interact with these (camera device ID is fvhL2I-iCT). No action needed, but the canaries should be noted.


9. Updated Summary Matrix

Category Count Severity
Port number (5000 vs 5500) 1 High
Detection write path confusion 1 Resolved in this audit
bee-security-audit device mismatch 1 Medium
wifi-client.service unknown state 1 Critical
Routing fix not persisted 1 High
hivemapper-data-logger disable/re-enable gap 1 Medium
odc-api Redis consumer theory (SUPERSEDED) 1 Resolved
Extended fields not forwarded (cam_heading, attributes, bbox) 1 High — crops broken, Phase 2 partially manual
image detection_id linkage ambiguity 1 Medium — may be causing image-detection mismatches
docs/ADAMAPS-TECHNICAL.md completely outdated 1 High — will mislead future agents
VPN type documented wrong 1 Low (now resolved)
api/app.py legacy duplicate 1 Low
Detection count frozen at 14,523 (not documented) 1 Info
adacam-api repo not archived 1 Low
WiGLE routes in adacam-odc unknown 1 Low
adacam-odc-redis-consumer-plan superseded 1 Medium — plan should be archived
Stale documents 7 Low-Medium
Missing info items 10 Various
Change log gaps 7 Medium

Audit complete. See adacam-project-state.md for the consolidated authoritative state document.


GITEA AUDIT — 2026-03-30

Auditor: Opus (Gitea audit sub-agent, methodical senior engineer mode)
Date: 2026-03-30
Method: Gitea HTTP API (http://192.168.0.5:3001) — curl/Python, no SSH
Repos examined:

  • Sulkta-Coop/adacam (primary) — all files read
  • Sulkta-Coop/adamaps (primary) — forwarder, ingest API, bee/ dir read
  • Sulkta-Coop/adacam-api — metadata only (confirmed archived)

G1 — PORT NUMBER — CRITICAL RESOLUTION

Finding: The Gitea repo contains two conflicting statements about the port:

Document Committed Says
services/adacam-odc/adacam_odc.py (line: PORT = int(os.environ.get("PORT", 5000))) Always Default 5000
services/adacam-odc/adacam-odc.service (Environment=PORT=5000) Always 5000
docs/RECON.md (commit 91d26e436e, 2026-03-29 17:06) 2026-03-29 5000. Explicitly: "Does not use port 5500 (that was a wrong guess — ignore it)"
docs/ADAMAPS-STATUS-REPORT-2026-03-26.md (commit 4d7154fd, 2026-03-26) 2026-03-26 5500. Explicitly: "adacam-odc is deployed and running on port 5500. odc-api is unmasked and running on port 5000 (still needed for detection pipeline)" and in Milestones: "odc-api permanently moved to port 5000, adacam-odc on 5500"

The RECON.md (newer commit, same day as the master audit) is internally inconsistent with the 2026-03-26 status report that is also in the same Gitea repo. The RECON.md was evidently written based on the committed code (PORT=5000 default), not based on live observation of the running device.

Verdict: The device is running on PORT=5500. The service on the device has been modified to use PORT=5500 (either in the service file on /data partition, or the environment variable is overridden). The committed Gitea service file shows PORT=5000 but this was never deployed — or was overridden on the device.

The RECON.md statement "5500 was a wrong guess" is INCORRECT. The 2026-03-26 status report explicitly documents the intentional change to 5500 as a completed milestone. RECON.md was written from committed code without checking the running device.

Action required:

  1. Update services/adacam-odc/adacam-odc.service in Gitea to Environment=PORT=5500
  2. Remove the incorrect note from docs/RECON.md
  3. Workspace project-state.md port field is CORRECT (5500) — no change needed there

G2 — data/persist/install.sh — NOT IN GITEA

Finding: The file /data/persist/install.sh is NOT committed to the Gitea repo at all. It does not appear in the git tree. It exists only on the device.

The docs/MASTER-AUDIT-2026-03-29.md (committed at 18:05 on 2026-03-29) documents the OLD install.sh content in section 11 under "Key Source Files":

/data/persist/install.sh — Persistence mechanism: Runs at boot from /data partition. Installs SSH keys. Creates bee-tunnel service. Blocks Mender/Hivemapper/HERE.

This is the pre-cleanup version (bee-tunnel was removed later in the same session, ~evening of 2026-03-29). The MASTER-AUDIT was committed at 18:05, before the bee-tunnel removal. So the Gitea document is now outdated for install.sh.

Appendix A of MASTER-AUDIT also lists bee-tunnel.service as "restart" (Auto-restarting, exit code 255) and bee-collector.service as "dead" — these reflect state BEFORE they were removed.

Current install.sh state: Unknown without device access. Per workspace project-state.md, it was updated on 2026-03-29 to remove bee-tunnel/bee-collector references. The WiFi routing fix is NOT in install.sh (as of 2026-03-30; it was applied runtime-only and lost on power cycle — open TODO).

Action required: Once camera access is restored:

  1. Verify current /data/persist/install.sh content
  2. Add WiFi routing fix (4 ip rule commands) to install.sh
  3. Commit the current install.sh to Gitea for version tracking

G3 — ADAMaps INGEST API — FULLY CONFIRMED

Finding: Gitea code (both adacam_odc.py forwarder and adamaps/app.py ingest handler) fully confirms the API contract:

Endpoint: POST https://api.adamaps.org/api/ingest
Auth: Header X-AdaMaps-Key: adamaps-ingest-2026
Payload format:

{
  "device_id": "fvhL2I-iCT",
  "detections": [
    {
      "id": "229787",
      "ts": 1742950000000,
      "lat": 33.8677,
      "lon": -118.3776,
      "class_label": "regulatory-speed-sign",
      "overall_confidence": 0.847,
      "device_id": "fvhL2I-iCT",
      "bbox_x1": 120.0,  "bbox_y1": 80.0, "bbox_x2": 240.0, "bbox_y2": 180.0,
      "cam_lat": 33.8678, "cam_lon": -118.3777, "cam_heading": 109.0,
      "azimuth": 45.0, "map_feature_id": 12345,
      "width": 120.0, "height": 100.0,
      "speed_label": 25, "speed_label_conf": 0.99,
      "attributes": {"speed_label": 25, "speed_label_conf": 0.99}
    }
  ]
}

All optional fields (bbox, cam_heading, azimuth, attributes, speed_label) ARE forwarded when non-null — confirmed in fetch_new_detections_for_forwarding() query and the detection dict-building loop. Workspace section 13.3 marks these as "Unknown" — this is INCORRECT.

Config key name inconsistency: The code uses config["adamaps_key"] and config["adamaps_api"]. Workspace section 6 shows old config format with "api_key" and "api_url". In practice this is non-breaking (code falls back to hardcoded defaults "adamaps-ingest-2026" and "https://api.adamaps.org"), but the documentation in project-state.md section 6 is wrong.


G4 — IMAGE-DETECTION LINKAGE — RESOLVED

Finding: adamaps/app.py at line 1066:

cur.execute("""
    UPDATE detections SET image_path = %s
    WHERE device_id = %s AND raw_json->>'id' = %s
""", (image_url, device_id, str(detection_id)))

The image upload endpoint matches by raw_json->>'id' (the camera's local SQLite ID sent as detection_id in the image upload form). This WORKS because adacam-odc stores the original SQLite id in the raw_json JSONB column when the detection is ingested.

Workspace audit item 8.3 ("image detection_id linkage ambiguity") is RESOLVED — the linkage IS correct and working. The 2,941 successfully linked images confirm this.


G5 — BRICKED BEE INFO — ALL KNOWN DATA CONFIRMED, NO NEW DATA

Gitea docs/BRICK-BEE-RECOVERY-RESEARCH.md (last updated 2026-03-22) contains:

Field Value
SSID dashcam-81B2B81681545109
What happened liberate.sh v0.3 ran, wrote PasswordAuthentication no to /data/overlay/current/ssh/sshd_config BEFORE writing SSH keys → locked out
Recovery attempts v1-v8, all failed. Mender cannot touch /data partition
Next planned step UART serial console (Cobb finding screwdrivers), OR wipe overlay via artifact
Serial/IMEI NOT documented in any Gitea file
Physical location Not stated (was at home during recovery attempts)

No serial number or IMEI for the Brick Bee exists in any Gitea document. The workspace project-state.md serial 2P021849 and IMEI 351369652127410 (from bee-security-audit.md, marked "unconfirmed") are the only available identifiers — this Gitea audit does NOT confirm or deny them. They remain "unconfirmed" in workspace docs.

MASTER-AUDIT-2026-03-29.md adds nothing new about the Brick Bee beyond confirming Device 1 (Truck Bee) serial 2P007435.


G6 — adacam-api REPO — ARCHIVED (OPEN TODO IS STALE)

Finding: Sulkta-Coop/adacam-api has archived: True, last updated 2026-03-14.

Workspace project-state.md section 13.11 P3 item: "adacam-api Gitea repo not archived" is ALREADY DONE. Close this todo.


G7 — INTERNAL GITEA INCONSISTENCY: RECON.md vs STATUS-REPORT-2026-03-26.md

Both documents are committed to Sulkta-Coop/adacam but directly contradict each other on the port:

  • docs/ADAMAPS-STATUS-REPORT-2026-03-26.md: "adacam-odc on 5500" (Milestone: completed)
  • docs/RECON.md (committed later on same day 2026-03-29): "Port: 5000. Does not use port 5500."

The RECON.md explicitly refutes what the 2026-03-26 status report documented as a completed intentional change. This creates confusion for any future agent reading Gitea. RECON.md needs correction.


G8 — EXTENDED FIELDS STATUS — WORKSPACE SECTION 13.3 IS WRONG

Finding: Gitea services/adacam-odc/adacam_odc.py forwarder code at lines ~850-940 clearly shows ALL extended fields are forwarded when present:

Field Workspace says Gitea confirms
bbox_x1/y1/x2/y2 Unknown Forwarded if non-null
cam_lat, cam_lon Unknown Forwarded if non-null
cam_heading Unknown Forwarded if non-null
azimuth Unknown Forwarded if non-null
map_feature_id Unknown Forwarded if non-null
attributes (JSONB) Unknown Parsed + forwarded if present
speed_label / speed_label_conf Unknown Forwarded if non-null

The workspace audit finding "Extended fields not forwarded" (section 9 summary matrix, High severity) is INCORRECT for the current committed code. These fields ARE forwarded. The codebase audit from 2026-03-23 was based on the OLD separate adacam-forwarder-v2.py, not the current adacam_odc.py. The combined service was built later (2026-03-24) and DID include extended fields.


G9 — adamaps/bee/RETIRED.md — FORWARDER STATUS CONFIRMED

Finding: Sulkta-Coop/adamaps/bee/RETIRED.md confirms:

adacam-forwarder.py and adacam-forwarder.service are superseded by the forwarder thread built into adacam-odc.

The old standalone forwarder is explicitly retired. This matches workspace state. The adacam-odc.py forwarder thread is the ONLY active forwarder.


FILES READ (complete list)

Repo File Summary
adacam services/adacam-odc/adacam_odc.py Main combined service: Flask API (PORT=5000 default, device runs 5500) + forwarder thread. All extended fields forwarded.
adacam services/adacam-odc/adacam-odc.service Systemd unit: Environment=PORT=5000. Confirmed mismatch with running device.
adacam services/adacam-odc/deploy.sh Deploy script: stops odc-api, bee-collector, here-plugin etc. Deploys to /data/adacam/. Health checks at localhost:5000.
adacam services/adacam-odc/README.md Architecture docs: Flask API on port 5000, forwarder thread to api.adamaps.org
adacam docs/RECON.md (commit 91d26e436e, 2026-03-29) Port 5000, calls 5500 "wrong guess" — INCORRECT. Good network/DNS diagnostics.
adacam docs/MASTER-AUDIT-2026-03-29.md (commit a8289028a9, 2026-03-29) Comprehensive device state snapshot. Accurate for 2026-03-29 pre-cleanup. Port 5000 (wrong), bee-tunnel/collector shown as disabled (pre-removal).
adacam docs/ADAMAPS-STATUS-REPORT-2026-03-26.md Port 5500 confirmed. Detection pipeline debug. map-ai.py captured.
adacam docs/BRICK-BEE-RECOVERY-RESEARCH.md (2026-03-22) Brick Bee SSID, root cause, recovery attempts v1-v8, UART next step. No serial/IMEI.
adacam docs/adacam-pipeline-map.md Visual pipeline map. ADAMaps endpoints: /api/ingest, /api/images.
adacam docs/adacam-codebase-audit-2026-03-23.md Audit based on OLD separate forwarder (pre-odc). Extended fields marked missing — superseded.
adacam docs/ADAMAPS-MASTER-REPORT-FINAL.md (2026-03-22) Canonical report from March 22. Device 2 locked out. ADAMaps on Rackham:5001.
adacam docs/BEE-ACCESS-PLAN.md (2026-03-22) Network topology, AP/client routing, SSH access procedure. References wpa_supplicant directly — HARD RULE VIOLATION (brcmfmac breakage on 2026-03-30). Outdated.
adacam docs/PROJECT_STATUS.md (2026-03-16) Early status doc. Partition layout, Mender format. Historical.
adacam CVE-LOG.md 3 CVEs filed: /api/1/cmd unauthenticated RCE (MCID15663720), hardcoded WiFi password, beekeeper-plugin RCE platform. 90-day window expires 2026-06-07.
adacam README.md Repo overview. References adacam-api repo (now archived).
adacam (git log, 20 entries) Commit history. Most recent: a8289028 (2026-03-29 master audit), 91d26e436e (2026-03-29 RECON.md).
adamaps bee/RETIRED.md adacam-forwarder superseded by adacam-odc.
adamaps bee/adacam-forwarder.py Old standalone forwarder. Now retired. Config uses adamaps_api + adamaps_key keys (same as odc).
adamaps app.py (key sections) Ingest endpoint (line 891), image upload (line 1033), auth via X-AdaMaps-Key. Image linkage via raw_json->>'id'.
adacam-api (metadata only) Confirmed archived: True, 2026-03-14.

SUMMARY OF CORRECTIONS NEEDED

Item Current state Correct state Action
RECON.md port statement Says 5000, calls 5500 "wrong guess" Device runs on 5500 Fix RECON.md in Gitea
adacam-odc.service PORT PORT=5000 PORT=5500 (matches running device) Update service file in Gitea
Workspace section 13.3 extended fields All "Unknown" All forwarded if non-null Updated in project-state.md (below)
Workspace section 6 config keys api_key, api_url adamaps_key, adamaps_api Updated in project-state.md (below)
Workspace image linkage (8.3) "Unknown/ambiguous" Confirmed working via raw_json->>'id' Updated in project-state.md (below)
Workspace P3 todo: "adacam-api not archived" Open Already archived since 2026-03-14 Close this todo
BEE-ACCESS-PLAN.md wpa_supplicant reference Shows wpa_supplicant direct use Hard rule violation — use nmcli Update Gitea docs

Gitea audit complete: 2026-03-30. Sources: HTTP API, all files in adacam + adamaps repos.