CEREBRAL STRATUM Help

Session Planning

This document tracks focused 1-hour work sessions for CEREBRAL STRATUM. Each item is scoped to be achievable (or meaningfully advanced) in a single sitting. Sessions are linked to the YouTrack CEREBRALSTRATUM project at youtrack.blueguardian.co.

Current State (as at 2026-05-17)

Repo

State

Next milestone

cerebralstratum-backend

4 services scaffolded; organisations, devices, users, locations resources exist

Device registration flow wired to Keycloak; Kafka telemetry consumer

cerebralstratum-frontend

KMP migration active; React web app + shared/ KMP module + Compose targets

FleetDashboardView expect/actual; Grafana embed integration

cerebralstratum-firmware

Rust, ESP32-S3; UUID management + MQTT client stub only

First live CAN frame → MQTT publish loop

cerebralstratum (parent)

ADRs complete (ADR-0001–0003); ECS/RDS migration proposed

Infrastructure Terraform; Keycloak ECS cutover

infra

OpenShift cluster configs

Terraform modules for ECS + RDS (ADR-0003 Phase 1)

Session Backlog

Sessions are grouped by area and roughly ordered by dependency. Mark sessions complete by moving them to Completed.

Identity & Infrastructure

[INFRA-S01] Provision RDS for Keycloak (ADR-0003 Phase 1)

Terraform: db.t4g.micro PostgreSQL 16, Single-AZ, private subnet, gp3 20GB, deletion protection enabled, 7-day backup retention. Store credentials in Secrets Manager. Validate connectivity from EC2 bastion.

Outcome: RDS instance exists; keycloak DB and user created; credentials in Secrets Manager; connectivity confirmed. ADR: ADR-0003 Phase 1 YouTrack: CEREBRALSTRATUM project

[INFRA-S02] ECS Task Definition for Keycloak + cloudflared

Author the ECS task definition (Fargate, ARM64, 0.5 vCPU / 1 GB) with Keycloak + cloudflared sidecar containers as per ADR-0003. Deploy ECS service (desired count: 1). Configure cloudflared route: auth.blueguardian.co → http://localhost:8080.

Depends on: INFRA-S01 (RDS endpoint required for KC_DB_URL) Outcome: Keycloak reachable at auth.blueguardian.co; admin console behind Zero Trust Access policy. ADR: ADR-0003 Phase 3

[INFRA-S03] Database migration: containerised → RDS

Export Keycloak DB from EC2-hosted container (pg_dump -Fc), restore into RDS (pg_restore). Validate realm config, client registrations, and LDAP federation settings post-restore.

Depends on: INFRA-S01 Outcome: RDS instance has all realm data; IdM LDAP federation confirmed working. ADR: ADR-0003 Phase 2

[INFRA-S04] Keycloak ECS cutover and EC2 decommission

Validate all Zero Trust applications authenticate via ECS-hosted Keycloak. Validate private_key_jwt device auth flows (backend ADR-0001). Remove Keycloak + PostgreSQL containers from EC2 instance. Evaluate IdM instance right-sizing.

Depends on: INFRA-S02, INFRA-S03 Outcome: EC2 no longer runs Keycloak or PostgreSQL; single authoritative Keycloak on ECS. ADR: ADR-0003 Phase 4

Backend

[BE-S01] Device registration endpoint — platform registration phase

Implement POST /devices in device-registrar: accept device public key, register device client in Keycloak (Keycloak Admin REST API), publish device.platform.registered event to Kafka. Wire up JPA persistence in DeviceEntity.

Outcome: Device can register with the platform; Kafka event emitted; device client exists in Keycloak. ADR: cerebralstratum-backend ADR-0001

[BE-S02] Device registration endpoint — user association phase

Implement POST /devices/{deviceId}/associate in device-registrar: validate user identity (JWT), assign device to user's Keycloak group, publish device.user.associated Kafka event. Include idempotency guard.

Depends on: BE-S01 Outcome: Devices can be associated with users; association event published.

[BE-S03] Kafka telemetry consumer in primary backend

Add a Kafka consumer for device telemetry topic (device.telemetry.raw). Deserialise GPS + CAN payload, persist to locations table via EntityManagerLocationRepository. Implement schema-per-tenant routing (resolve tenant from device → organisation mapping).

Depends on: BE-S01 (device → organisation mapping needed for tenant resolution) Outcome: Telemetry from device arrives in correct tenant's PostgreSQL schema.

[BE-S04] Grafana embed URL generation

Implement server-side Grafana embed URL signing in backend service. Scoped to authenticated user's fleet (organisation filter). Return signed URL via REST endpoint consumed by the frontend FleetDashboardView (backend ADR-0002).

Outcome: Frontend can render a scoped Grafana dashboard per authenticated user.

Frontend

[FE-S01] Audit KMP shared module vs React web app — identify migration gaps

Walk through webApp/ and shared/commonMain/ side-by-side. Catalogue which domain models and API clients exist only in React (TypeScript) vs. which have been migrated to KMP shared/. Produce a gap list as a Writerside topic.

Outcome: Written gap analysis; prioritised list of shared module work remaining.

[FE-S02] FleetDashboardView expect/actual for web target

Implement expect class FleetDashboardView in shared/commonMain/. actual for jsMain: React component rendering Grafana embed URL (fetched from backend). Wire up Coroutines StateFlow for loading/error/success states.

Depends on: BE-S04 (backend endpoint needed for full integration, but stub URL works for UI) Outcome: Grafana fleet dashboard renders in web app via KMP shared abstraction.

[FE-S03] Device list view — KMP shared model

Define Device domain model in shared/commonMain/ with @JsExport. Implement DeviceRepository expect/actual: REST client in jsMain, stub in jvmMain. Wire up device list in composeApp (Android/Desktop) and webApp React.

Outcome: Device list rendered across web and Compose targets from shared model.

Firmware

[FW-S01] CAN frame capture via TWAI (ESP32-S3)

Implement TWAI driver initialisation and a receive loop in Rust (esp-idf-hal TWAI bindings or direct ESP-IDF FFI). Log raw CAN frames to serial. Goal: confirm hardware path works before any network integration.

Outcome: Raw CAN frames (at minimum ignition/RPM/speed from OBD-II) visible in serial monitor. ADR: cerebralstratum-firmware ADR-0001

[FW-S02] OBD-II PID decoder

Implement PID request/response for standard OBD-II PIDs: speed (0x0D), RPM (0x0C), engine coolant temp (0x05), throttle position (0x11). Emit decoded values as a Rust struct. Include VIN request (service 09 PID 02).

Depends on: FW-S01 Outcome: Decoded telemetry struct populated from live CAN bus; no hardcoded values.

[FW-S03] Device authentication — private_key_jwt flow to Keycloak

Generate a device key pair (stored in NVS). On boot, request an OAuth2 token from Keycloak using private_key_jwt grant (backend ADR-0001). Cache token with TTL; refresh before expiry. This is the auth prerequisite for all network telemetry.

Depends on: INFRA-S02 (Keycloak on ECS must be live and reachable) Outcome: Device obtains and refreshes a valid access token from Keycloak.

[FW-S04] MQTT telemetry publish loop (LTE path)

Integrate esp-idf-mqtt to publish decoded telemetry (FW-S02) to Eclipse Hono MQTT adapter. Use device access token from FW-S03 for authentication. Publish at 1 Hz on LTE; implement QoS 1 with local queue for reconnect resilience.

Depends on: FW-S02, FW-S03 Outcome: Live telemetry visible in Hono/Kafka from a device on the bench.

[FW-S05] NTN CoAP fallback path

Implement the NTN transport path: detect LTE link loss, switch to BG95-S5 NTN mode, serialise a 29-byte CBOR snapshot, send via CoAP POST to Hono. Restore LTE path when signal recovers.

Depends on: FW-S04 Outcome: Telemetry continues (at reduced frequency) when LTE is unavailable. ADR: cerebralstratum-firmware ADR-0001 — NTN payload policy section

Completed

Session

Date

Notes

ADR migration — all repos

2026-05-17

Migrated all Obsidian ADRs into repo-specific Writerside; created cerebralstratum parent repo ADRs; scaffolded firmware Writerside from scratch

Last modified: 26 May 2026