docs: refactor docs structure and tighten assistant instruction policy

shrink root README into a landing page with a docs map and focused contributor guidance
add TV_POWER_RUNBOOK as the canonical TV power rollout and canary runbook
add CHANGELOG and move project history out of README-style docs
refactor src README into a developer-focused guide (architecture, runtime files, MQTT, debugging)
prune redundant older HDMI docs and keep a canonical HDMI_CEC_SETUP path
update copilot instructions to a high-signal policy format with strict anti-shadow-README design rules
align references across docs to current files, scripts, and TV power behavior
This commit is contained in:
RobbStarkAustria
2026-04-01 10:01:58 +02:00
parent fb0980aa88
commit 82f43f75ba
20 changed files with 2228 additions and 2267 deletions

View File

@@ -0,0 +1,83 @@
# Server Handoff: TV Power Coordination
## Purpose
Implement server-side MQTT power intent publishing so clients can keep TVs on across adjacent events and power off safely after schedules end.
## Source of Truth
- Shared full plan: TV_POWER_COORDINATION_TASKLIST.md
## Scope (Server Team)
- Scheduler-to-intent mapping
- MQTT publishing semantics (retain, QoS, expiry)
- Conflict handling (group vs client)
- Observability for intent lifecycle
## MQTT Contract (Server Responsibilities)
### Topics
- Primary (per-client): infoscreen/{client_id}/power/intent
- Optional (group-level): infoscreen/groups/{group_id}/power/intent
### Delivery Semantics
- QoS: 1
- retained: true
- Always publish UTC timestamps (ISO 8601 with Z)
### Intent Payload (v1)
```json
{
"schema_version": "1.0",
"intent_id": "uuid-or-monotonic-id",
"issued_at": "2026-03-31T12:00:00Z",
"expires_at": "2026-03-31T12:10:00Z",
"target": {
"client_id": "optional-if-group-topic",
"group_id": "optional"
},
"power": {
"desired_state": "on",
"reason": "event_window_active",
"grace_seconds": 30
},
"event_window": {
"start": "2026-03-31T12:00:00Z",
"end": "2026-03-31T13:00:00Z"
}
}
```
## Required Behavior
### Adjacent/Overlapping Events
- Never publish an intermediate off intent when windows are contiguous/overlapping.
- Maintain continuous desired_state=on coverage across adjacent windows.
### Reconnect/Restart
- On scheduler restart, republish effective retained intent.
- On event edits/cancellations, replace retained intent with a fresh intent_id.
### Conflict Policy
- If both group and client intent exist: per-client overrides group.
### Expiry Safety
- expires_at must be set for every intent.
- Server should avoid publishing already-expired intents.
## Implementation Tasks
1. Add scheduler mapping layer that computes effective desired_state per client timeline.
2. Add intent publisher with retained QoS1 delivery.
3. Generate unique intent_id for each semantic transition.
4. Emit issued_at/expires_at and event_window consistently in UTC.
5. Add group-vs-client precedence logic.
6. Add logs/metrics for publish success, retained payload age, and transition count.
7. Add integration tests for adjacent events and reconnect replay.
## Acceptance Criteria
1. Adjacent events do not create OFF gap intents.
2. Fresh client receives retained intent after reconnect and gets correct desired state.
3. Intent payloads are schema-valid, UTC-formatted, and include expiry.
4. Publish logs and metrics allow intent timeline reconstruction.
## Operational Notes
- Keep intent publishing idempotent and deterministic.
- Preserve backward compatibility while clients run in hybrid mode.