# Risk Register Assessment date: 2026-07-13 ## Verified Defects | ID | Finding | Evidence | Impact | Next action | |---|---|---|---|---| | VD-001 | First-boot web credential behavior is documented inconsistently. | `include/config.h` says first-boot AP forces password change; `src/web_server.cpp` serves `/wifi` behind current credentials and does not enforce a first-boot password change. | Operators may deploy with default `admin/admin` longer than intended. | Design an explicit credential-onboarding flow in a separate security task. | | VD-002 | `Requirements.md` referenced payload schema v3 while code, README, and tests use schema v4. | `payload_codec.cpp` uses `kSchema = 4`; `test_payload_codec` validates schema v4 vectors. | Contract documentation could mislead future protocol work. | Updated schema references to v4 in this harness task. | | VD-003 | `docs/TESTS.md` referenced old `lilygo-t3...` environments. | Current `platformio.ini` has `production`, `debug`, and `test`. | Developers could run non-existent verification commands. | Replaced with current compile-only and on-device commands. | | VD-004 | PlatformIO static analysis currently fails outside repository-owned firmware logic. | Default `pio check -e production --fail-on-defect=high` fails when cppcheck reaches `toolchain-xtensa-esp32/.../bits/c++config.h:520`; `--skip-packages` avoids that header but still reports high defects under `.pio/libdeps/production/ArduinoJson/.../Variant/ConverterImpl.hpp`. | The canonical verification command is strict and correctly returns non-zero until analyzer scope/policy is explicitly decided. | Resolve in a separate tooling task; do not silently add skips, suppressions, or dependency changes just to obtain a passing check. | ## Probable Risks | ID | Finding | Evidence | Impact | Next action | |---|---|---|---|---| | PR-001 | Direct `lib_deps` are version-ranged, not exact. | `platformio.ini` uses `^` ranges. | New installs may resolve different library versions. | Apply exact pins in a separate dependency-only commit after review. | | PR-002 | PlatformIO Core version is not locked by the repository. | Local `pio --version` is `6.1.18`; CI installs the expected version but local shells may differ. | Local and CI behavior can drift. | Keep expected core version documented and update only in a dedicated tooling task. | | PR-003 | Static analysis coverage depends on PlatformIO's available check tools. | `pio check` is available, but tool availability can vary by runner cache/network. | CI may fail for tool setup rather than firmware defects. | Keep output visible; add pinned analyzer packages only if needed later. | | PR-004 | `.vscode/extensions.json` had pre-existing local modifications. | `git status --short` reported it modified before this task. | Review may mix user-local editor changes with harness work if committed together. | Keep it out of this task unless the user explicitly asks. | ## Missing Tests | ID | Gap | Existing partial coverage | Next action | |---|---|---|---| | MT-001 | No native host test environment yet. | Transport logic is close to pure logic but still includes `Arduino.h`. | Follow staged extraction plan in `docs/engineering/test-matrix.md`. | | MT-002 | ACK sender-side validation is not directly unit-tested as production code. | Some ACK-related behavior is documented and indirectly covered by compile checks. | Extract ACK parse/validation into a small pure helper, then add native or embedded tests. | | MT-003 | Retry timeout calculation is not directly unit-tested. | Sender stats and constants exist; behavior is runtime-coupled. | Extract timeout calculation before adding tests. | | MT-004 | SD history parser is not covered by a dedicated test suite. | Web input and CSV contracts are documented; compile checks cover buildability. | Extract current/legacy CSV line parsing to a pure helper. | | MT-005 | Web POST validation is not covered beyond helper sanitizers. | `test_html_escape` covers escaping, URL encoding, and device ID sanitization. | Add focused tests when web parsing is extracted. | ## Missing Documentation | ID | Gap | Next action | |---|---|---| | MD-001 | No measured hardware power baseline is recorded in this branch. | Record current, light-sleep-off, and light-sleep-on measurements in a separate HIL/power task. | | MD-002 | No Gitea runner inventory is recorded. | Document runner labels and container prerequisites in CI operations notes once the runner exists. | | MD-003 | No sanitized HIL local config example exists yet. | Add `hil_tests/config.example.yaml` when pytest harness scaffolding starts. | ## Security Decisions | ID | Current decision | Status | Recommendation | |---|---|---|---| | SD-001 | AP password default is `changeme123`. | Confirmed. | Replace with per-device provisioning in a separate approved task. | | SD-002 | Web defaults are `admin/admin`. | Confirmed. | Add forced first-boot credential change in a separate approved task. | | SD-003 | Credentials are stored in Preferences. | Confirmed. | Assess NVS encryption, flash encryption, and credential rotation separately. | | SD-004 | LoRa packets are not cryptographically authenticated. | Confirmed. | Design message authentication and replay handling separately; preserve current wire contract until approved. | | SD-005 | Replay protection is limited to batch IDs, duplicate tracking, sender IDs, and ACK rate limiting. | Confirmed. | Add explicit threat model before changing protocol. | | SD-006 | OTA, firmware signing, secure boot, and flash encryption are not configured in this project. | Confirmed by source/config search; hardware fuse state unknown. | Decide production boot-chain policy in a separate security task. | ## Hardware-Dependent Questions | ID | Question | Why it matters | Proposed verification | |---|---|---|---| | HQ-001 | Does GPIO14 role selection remain stable with SD SCK reuse on receiver boot? | `main.cpp` releases the role pin before SD uses GPIO14. | HIL boot-role and SD mount tests. | | HQ-002 | Does chunked light sleep preserve 1 Hz meter UART capture on real meters? | Power behavior depends on UART timing and FreeRTOS scheduling. | Sender HIL with smart-meter UART simulator and real meter. | | HQ-003 | Are ACK windows sufficient at worst-case RSSI/SNR and duplicate retries? | LoRa airtime and receiver delay depend on RF environment. | Paired-board RF soak tests with ACK loss injection. | | HQ-004 | Is SD logging reliable across missing, full, and corrupt cards? | Runtime currently treats SD as optional but history depends on it. | HIL SD fault injection. | | HQ-005 | Are heap and stack margins acceptable during web history queries and long LoRa batches? | ESP32 memory pressure is hardware/runtime dependent. | Long-duration HIL with heap/stack telemetry. |