Skip to content

Architecture Decision Records

Architecture Decision Records (ADRs) capture the consequential design choices behind OpenCCU-Loom — the decision, its context, and its consequences — so future readers can understand why the code looks the way it does.

Who this page is for

Contributors and developers who need the rationale behind a design choice. ADRs are immutable once landed: a superseded decision gets a new ADR rather than an edit to the old one.

The table below catalogues every ADR. Each links to the record on GitHub.

# Title Summary
0001 License: MIT The source is licensed MIT.
0002 Multi-CCU as a first-class feature One daemon serves many CCUs, scoped by central_name, from 0.1.0.
0003 Embed openccu-data metadata artifacts Translations, easymodes, and profiles are embedded from openccu-data.
0004 Python decorators ↔ Go cross-cutting How decorator-based concerns from the Python reference map to Go.
0005 Visibility as outbound filter Visibility is applied as an outbound filter on REST and MQTT.
0006 Naming conventions for REST + MQTT Shared naming rules across the REST and MQTT surfaces.
0007 Strong model: Source interface A single Source interface backs both reads and writes.
0008 AggregatedState default-flip Flips the AggregatedState default and removes the legacy path.
0009 Service-method command topics Service-method command topics in HA Discovery.
0010 Discovery payload from the model HA-Discovery payload construction moves into the model.
0011 MQTT topic & payload architecture The topic and payload structure for the MQTT plane.
0012 Matter bridge: pure-Go The Matter bridge is implemented in pure Go, no CGo SDK.
0013 Matter wire-protocol design rules Wire-protocol rules learned from chip-tool commissioning bring-up.
0014 Parameter ignore / un-ignore mechanics How parameters are ignored and un-ignored.
0015 Split Ignored from NoCreate Separates Ignored from NoCreate in DataPointUsage.
0016 Custom-DP-aware UI rendering UI rendering is aware of custom data points.
0017 Logging and diagnostics The logging and diagnostics model.
0018 Health tracker parity The health tracker mirrors aiohomematic.
0019 Persistent VALUES cache A persistent VALUES cache with a wire-DP lifecycle.
0020 External-client wire contract The wire contract external clients depend on.
0021 mDNS self-advertisement mDNS self-advertisement for LAN auto-discovery.
0022 WebSocket resume cursor + kind The WebSocket resume cursor and envelope kind discriminator.
0023 HmIP-Wired is a ProductGroup HmIP-Wired is modeled as a ProductGroup, not an interface.
0024 Instance vs CCU identity Daemon-instance vs CCU identity, and the two interface ids.
0025 MCP server as a north-bound adapter The MCP server is a north-bound adapter.
0026 MCP dev-mode A build-tag-gated MCP introspection surface.
0027 Encrypt config secrets at rest Config secrets are encrypted at rest.
0028 Contract digest & version guard A contract digest and version guard couple API-schema changes to the types-repo release.
0029 Tier-model teardown for Unit.Stop Unit.Stop tears down subsystems in tiered order.
0030 Event-bus dispatch striping: rejected Per-central isolation already meets the goal; dispatch striping is rejected.
0031 IM opcode dispatch seam A testable gate and per-opcode seam are extracted from handleIMOpcode.
0032 Sigma resumption extraction Sigma-resumption extraction is already satisfied; the finding is corrected.
0033 Groups cluster stays a stub The minimal Groups-cluster stub is a deliberate, matter.js-conformant divergence.
0034 Adapter package taxonomy internal/central/adapter stays one package with a documented taxonomy.
0035 Hub refresh-set extraction The refresh-coordination sub-component is extracted from HubCoordinator.
0036 Matter Bridge decomposition The CommissioningSession/IMEngine facade split is deferred.
0037 OTLP span exporter A pluggable span exporter ships a lean OTLP/HTTP exporter, not the OTel-gRPC SDK.
0038 Cross-stack CI gate The cross-stack model-snapshot parity gate runs in nightly CI.
0039 Subscribe dispatch seam Cohesive sub-helpers are extracted from handleSubscribeRequest.
0040 Measurement history Measurement history is stored in embedded SQLite with an opt-in push exporter.
0041 Persist auth sessions Auth sessions persist in SQLite as a save-through cache.
0042 Clear CCU cache and re-pull Clearing CCU-derivable caches and re-pulling is a first-class operation.
0043 CCU as an authentication provider Login can be delegated to a CCU's own user database.
0044 Single-port onboarding + HA Ingress auth Onboarding runs on a single port with HA Ingress auth passthrough.
0045 Login + onboarding into the SPA Login and first-run onboarding live in the Svelte SPA.
0046 SSDP CCU discovery CCUs are discovered on the LAN via active SSDP/UPnP.
0047 North-bound bridge registry North-bound bridges are Services owned by a Registry.
0048 chip-tool ↔ godevccu send/receive matrix A hermetic per-DP-type Matter send/receive suite runs chip-tool against godevccu.
0049 Matter one endpoint per device Matter exposes one endpoint per physical device by default.
0050 MQTT transport → shared go-mqtt module The in-tree MQTT transport is extracted into the external shared go-mqtt module.
0051 North-bound authorization model Role-based MinRole gating unified across REST + WS, plus backup-at-rest sealing.
0052 Daemon-level alarm MQTT topics The alarm engine publishes panel state/commands on daemon-level topics, not per-central ones.
0053 CCU metadata via go-openccu-data Embedded OCCU extracts come from the versioned go-openccu-data module instead of a hand-synced copy.
0054 Remote ingress proxy add-on OpenCCU-Loom Remote: HA Ingress panel for remote instances via token injection instead of the local-only Ingress passthrough.