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. |
Related reading¶
- Architecture — how these decisions show up in the package layout.
SPECIFICATION.md— the design intent the ADRs implement.- Matter parity contract — the binding rules for the Matter-side ADRs (0012, 0013, 0031, 0033, 0036, 0039, 0048, 0049).