Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
4f08136
feat(pipeline): v1.1.0 core ingestion pipeline, auto-lock state, and …
Sep 6, 2026
03b2e1d
chore(release): merge v1.1.0 core ingestion pipeline & policy engine …
Sep 6, 2026
b117942
feat(security): v1.2.0 AES-256-GCM encryption, salted PIN hashing, an…
Sep 6, 2026
4b4fd1a
chore(release): merge v1.2.0 security & hardware safety into develop
Sep 6, 2026
0fd10a3
feat(ingress): v1.3.0 frontend SSE streaming, HA ingress base path in…
Sep 6, 2026
1884693
Merge branch 'feature/v1.3.0-frontend-streaming-and-ingress' into dev…
Sep 6, 2026
aceac1e
test(hardening): eliminate test theatre and enforce closed-loop SSE a…
Sep 6, 2026
3805101
feat(ui): pop in-modal validation error on invalid PIN and enforce 4-…
Sep 6, 2026
4b991f4
chore(release): bump version to 1.4.0 and update changelog
Sep 6, 2026
65034ad
chore(release): merge feature/v1.4.0-pin-validation-and-test-hardenin…
Sep 6, 2026
4732e24
docs: add design spec and implementation plan for pluggable entity tr…
Sep 6, 2026
13f01ee
feat(core): add ITransport abstractions and capability interfaces
Sep 6, 2026
9c6f1ef
feat(data): add system_settings persistence and configuration fallbac…
Sep 6, 2026
c4b4e4d
feat(engine): implement ZWaveWebSocketTransport with JSON-RPC server …
Sep 6, 2026
8cc47fc
feat(engine): integrate ITransportRegistry with door operations and h…
Sep 6, 2026
a411178
feat(web): add SettingsController and interactive UI settings manager…
Sep 6, 2026
d06b6fd
chore(release): bump version to 1.5.0 and update changelog for plugga…
Sep 6, 2026
29ffebc
ci: configure develop trigger and ASPNETCORE_URLS for smoke health ch…
Sep 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
branches: [ main, develop ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down Expand Up @@ -100,8 +100,10 @@ jobs:
run: dotnet build --configuration Release

- name: Start server & probe health
env:
ASPNETCORE_URLS: "http://localhost:8150"
run: |
dotnet run --project src/CodeMaster.Web/CodeMaster.Web.csproj --configuration Release &
dotnet run --project src/CodeMaster.Web/CodeMaster.Web.csproj --configuration Release --no-build &
APP_PID=$!
echo "Server started with PID $APP_PID"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
branches: [ main, develop ]
schedule:
- cron: '0 6 * * 1'

Expand Down
6 changes: 3 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisLevel>latest</AnalysisLevel>
<Version>1.0.0</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<Version>1.5.0</Version>
<AssemblyVersion>1.5.0.0</AssemblyVersion>
<FileVersion>1.5.0.0</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
49 changes: 49 additions & 0 deletions addon/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,55 @@

All notable changes to the CodeMaster Home Assistant Add-on will be documented in this file.

## [1.5.0] - 2026-09-06

### Added
- Pluggable Hardware Entity Transports: Introduced `ITransport`, `ILockTransport`, `IKeypadTransport`, and `ISensorTransport` interfaces with central `ITransportRegistry`.
- Direct Z-Wave JS Server WebSocket Transport (`ZWaveWebSocketTransport`): Connects directly to `zwave-js-server` via JSON-RPC, eliminating the requirement to enable the MQTT gateway in Z-Wave JS UI.
- Native Hardware Detection: Validated against physical mesh hardware: Node 18 (August Smart Lock Pro), Node 39 (Schlage BE469ZP Touchscreen Deadbolt), and Node 40 (Ring Keypad v2).
- Dynamic System Settings Persistence: SQLite `system_settings` table backing `SettingsController` (`GET/PUT /api/settings`, `POST /api/settings/test-connection`) with container environment variable fallbacks and live hot-reconnection.
- Interactive Settings View & Zustand Store: Real-time segmented transport selector, live WebSocket connection latency & node diagnostic probe, and MQTT credential management.
- Smart Door Setup Wizard: Auto-populates discovered Z-Wave locks and keypads directly from the active WebSocket session.

## [1.4.0] - 2026-09-06

### Added
- In-modal PIN validation error alert banner (`role="alert"`) and visual border highlighting in `UserManagement` UI with auto-dismiss on keystroke.
- Strict 4–8 numeric digit PIN validation in REST API (`UsersController.SetPin`) and MCP tool (`codemaster__create_guest_pin`).
- Closed-loop test harness assertions replacing trivial checks: live SSE event delivery stream tests, hardware slot error handling, and non-numeric credential rejection tests.

### Fixed
- Fixed SSE event serialization formatting (`s_sseJsonOptions`) using camelCase naming policy and string enum serialization for real-time frontend streaming.

## [1.3.0] - 2026-09-06

### Added
- Real-time live activity audit streaming via Server-Sent Events (`EventSource`) at `/api/logs/stream` integrated with Zustand `useAuditStore`.
- Home Assistant dynamic Ingress reverse-proxy integration with automated `<meta name="base-path">` and `<base href>` runtime HTML injection.
- Home Assistant Add-on `/data/options.json` configuration ingestion mapping `mqtt_host`, `mqtt_port`, `mqtt_username`, and `mqtt_password` directly to engine options.
- Manual lock/unlock audit event dispatch to `INotificationDispatcher` (Apprise) with typed client constructor resolution.

## [1.2.0] - 2026-09-06

### Added
- Authenticated AES-256-GCM `ICredentialEncryptionService` protecting sensitive PIN credentials at rest with dynamic key derivation and transparent legacy plaintext fallback.
- Cryptographically salted PIN hashing with constant-time equality verification (`PinSecurityHelper.VerifyPinHash`) preventing timing attacks.
- Physical Lock Code Revocation on user deletion and MCP revocation (`ClearUserHardwareSlotsAsync`) clearing active lock deadbolt slot codes.
- Timezone-aware access policy evaluation supporting arbitrary `TimeZoneId` mappings (e.g. `America/Chicago`) for localized recurring schedules.

## [1.1.0] - 2026-09-06

### Added
- Hosted `MqttInboundConsumerService` for reliable continuous consumption and processing of the bounded MQTT channel.
- Automatic Door Policy Assignments in `UsersController.Create` and `SavePolicy` with multi-door targeting.
- Automated Home Assistant MQTT Discovery entity registration and unregistration on door lifecycle events.
- Live real-time lock state and contact sensor telemetry reconciliation via `UpdateDoorStates`.

### Fixed
- Fixed auto-lock countdown calculation to expose live remaining seconds via dynamic expiration timestamp.
- Added numeric PIN validation (`All(char.IsAsciiDigit)`) in `HardwareSlotSyncWorker` preventing raw hashes being sent to physical locks.
- Fixed `HardwareSlotRepository.ClearSlotAsync` marking slots as Synced instead of PendingSync.

## [1.0.0] - 2026-09-06

### Added
Expand Down
2 changes: 1 addition & 1 deletion addon/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: "CodeMaster"
description: "Universal Access Control & Lock/Keypad Synchronization Engine"
version: "1.0.0"
version: "1.5.0"
slug: "codemaster"
arch:
- amd64
Expand Down
Binary file modified docs/screenshots/01-dashboard-doors.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/02-users-and-schedules.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/03-activity-audit-log.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/04-door-setup-wizard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/05-mobile-responsive.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 89 additions & 0 deletions docs/superpowers/plans/2026-09-06-codemaster-remediation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# CodeMaster Remediation & Production Hardening Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Transform CodeMaster from a vibe-coded prototype into an enterprise-grade access control engine by resolving all critical pipeline disconnects, data orphan bugs, security/encryption gaps, hardware sync safety issues, and frontend streaming limitations across 3 minor releases (v1.1.0, v1.2.0, v1.3.0).

**Architecture:**
1. Build `MqttInboundConsumerService` consuming `MqttInboundChannel` to process keypad events, lock states, and sensor changes in real time.
2. Fix policy assignment links (`AccessAssignments`) and schedule evaluation.
3. Introduce AES-256-GCM reversible encryption for hardware slot codes and salted PIN hashing.
4. Enforce physical lock clearance on user deletion/revocation.
5. Provide genuine SSE streaming in the React UI, dynamic Ingress basePath resolution, and HA `/data/options.json` support.

**Tech Stack:** .NET 10, C# 13, Dapper, SQLite (WAL), System.Threading.Channels, MQTTnet, React 19, TypeScript, Vitest, Playwright.

---

## Global Constraints
- Target .NET 10 (`net10.0`), C# 13, `<Nullable>enable</Nullable>`.
- Container immutability: all changes build into Docker images cleanly.
- Verify release version synchronization with `python3 verify_release.py --ci --skip-tests`.
- Maintain >= 80% test coverage with zero ESLint warnings (`npm run lint`).
- Only mock when absolutely necessary and ensure mock data matches realistic hardware payloads.

---

## Release Set 1: Core Pipeline & Policy Engine (v1.1.0)
Branch: `feature/v1.1.0-pipeline-and-policy-engine`

### Task 1.1: Build `MqttInboundConsumerService` Background Worker
- [ ] Implement `src/CodeMaster.Engine/Services/MqttInboundConsumerService.cs` as a `BackgroundService` that reads from `_inboundChannel.Reader.ReadAllAsync(stoppingToken)`.
- [ ] Route keypad events to `RingMqttKeypadProvider` and `BuiltInLockKeypadProvider`.
- [ ] On valid keypad entry, call `AccessPolicyEvaluator`, unlock door, update auto-lock state, write `AccessLog`, and broadcast event.
- [ ] Route lock telemetry and door contact states to `DoorOperationService.UpdateDoorStates`.
- [ ] Register `MqttInboundConsumerService` in `Program.cs` and add `codemaster/#` to `MqttOptions.SubscribedTopics`.

### Task 1.2: Auto-Lock Countdown Tracking & State Machine Lifecycle
- [ ] Enhance `AutoLockStateMachine` to track expiration timestamp and `RemainingSeconds`.
- [ ] Update `DoorOperationService.GetRemainingAutoLockSecondsAsync` to query state machine.

### Task 1.3: Fix Policy Assignment in `UsersController.SavePolicy` & `UserManagement.tsx`
- [ ] Modify `SavePolicy` in `UsersController.cs` to assign user to policy and selected/all doors via `AccessAssignment`.
- [ ] Update `useUserStore.ts` and `UserManagement.tsx` to handle door assignments.

### Task 1.4: Hardware Slot Sync Guard & Status Reset
- [ ] Ensure `HardwareSlotSyncWorker.cs` never sends hashed values to physical locks.
- [ ] Fix `HardwareSlotRepository.ClearSlotAsync` to reset `SyncStatus` to `Synced`.

### Task 1.5: Automated Home Assistant Discovery & Release v1.1.0
- [ ] Publish Home Assistant discovery messages on door registration and MQTT connect.
- [ ] Add unit and closed-loop tests verifying the pipeline.
- [ ] Bump version to 1.1.0 and merge to `develop`.

---

## Release Set 2: Cryptographic Security & Hardware Safety (v1.2.0)
Branch: `feature/v1.2.0-security-and-hardware-safety`

### Task 2.1: AES-256-GCM Reversible Encryption Service
- [ ] Implement `ICredentialEncryptionService` using AES-256-GCM.
- [ ] Store authenticated encrypted ciphertext in `EncryptedValue`.

### Task 2.2: Salted PIN Hashing & Constant-Time Verification
- [ ] Generate secure random salts for PIN hashes.
- [ ] Use constant-time equality check (`CryptographicOperations.FixedTimeEquals`).

### Task 2.3: Physical Lock Clearance on Revocation/Deletion
- [ ] When deleting a user in `UsersController` or revoking in MCP `DoorTools`, clear physical lock slots via `lockProvider.ClearSlotCodeAsync`.

### Task 2.4: Timezone Awareness in Access Schedules & Release v1.2.0
- [ ] Support local timezone in `AccessPolicy.IsActiveAt` before checking time/day windows.
- [ ] Bump version to 1.2.0 and merge to `develop`.

---

## Release Set 3: Frontend Live Streaming, Ingress & Integration (v1.3.0)
Branch: `feature/v1.3.0-frontend-streaming-and-ingress`

### Task 3.1: Live SSE Event Streaming in Frontend
- [ ] Connect `EventSource('/api/logs/stream')` in `useAuditStore.ts` and update `LiveEventFeed.tsx`.

### Task 3.2: Dynamic Home Assistant Ingress Base-Path Support
- [ ] Inject `X-Ingress-Path` into `index.html` via ASP.NET middleware.
- [ ] Update `apiClient.getBasePath()` to support Ingress subpaths.

### Task 3.3: Home Assistant OS `options.json` & Apprise Options Fix
- [ ] Load optional `/data/options.json` in `Program.cs`.
- [ ] Fix `AppriseOptions` binding and trigger notifications on access events.
- [ ] Bump version to 1.3.0 and merge to `develop`.
Loading
Loading