diff --git a/backlog/shared-stories.md b/backlog/shared-stories.md new file mode 100644 index 0000000..0e727f0 --- /dev/null +++ b/backlog/shared-stories.md @@ -0,0 +1,115 @@ +# Shared stories + +Stories that touch infrastructure shared by both Blocao (video) and Transcript Forensics (audio). Each one is implemented **once** and benefits both products. + +The Blocao backlog is the **source of truth** for the implementation details. The transcript backlog references these via `SHARED-XX.Y ↔ BL-XX.Y` mapping. + +--- + +## Mapping table + +| SHARED ID | Maps to Blocao ID | Title | Adaptation needed for transcript? | +|---|---|---|---| +| SHARED-00.1 | BL-00.1 | Monorepo structure | None | +| SHARED-00.2 | BL-00.2 | CI/CD pipeline | None | +| SHARED-00.3 | BL-00.3 | OpenWrt Image Builder | None | +| SHARED-00.4 | BL-00.4 | Balena fleet provisioning | Add whisper+pyannote container to compose | +| SHARED-00.5 | BL-00.5 | MQTT contract schemas | Add `aud//...` namespace | +| SHARED-01.1 | BL-01.1 | Wizard step 1 — Region | None | +| SHARED-01.2 | BL-01.2 | Wizard step 2 — Site identity | None | +| SHARED-01.3 | BL-01.3 | Wizard step 3 — WAN | None | +| SHARED-01.4 | BL-01.4 | Wizard step 4 — Camera VLAN | Probably skip for audio-only sites | +| SHARED-01.5 | BL-01.5 | Wizard step 5 — Hub auth | None | +| SHARED-01.6 | BL-01.6 | Wizard step 6 — Apply provisioning | None | +| SHARED-01.7 | BL-01.7 | Standalone mode | None | +| SHARED-02.1 | BL-02.1 | hai.uc RPCs | Add audio-related methods | +| SHARED-02.2 | BL-02.2 | Reverse proxy | Same path patterns | +| SHARED-02.3 | BL-02.3 | WAN view | None | +| SHARED-02.4 | BL-02.4 | VLAN matrix view | None | +| SHARED-02.5 | BL-02.5 | MQTT broker view | None | +| SHARED-02.6 | BL-02.6 | MQTT live tail | None | +| SHARED-02.7 | BL-02.7 | MQTT topic tree | None | +| SHARED-02.8 | BL-02.8 | GitOps view | None | +| SHARED-02.9 | BL-02.9 | Tailscale view | None | +| SHARED-02.10 | BL-02.10 | Services view | Includes audio containers | +| SHARED-02.11 | BL-02.11 | Logs view | None | +| SHARED-05.1 | BL-05.1 | Selftest engine — Cell | Whisper checks added in WDM-T-05.1 | +| SHARED-05.2 | BL-05.2 | Selftest engine — Router | None | +| SHARED-05.3 | BL-05.3 | HEALTH view | None | +| SHARED-05.4 | BL-05.4 | Run all tests | None | +| SHARED-05.5 | BL-05.5 | Health history | None | +| SHARED-05.6 | BL-05.6 | Quick-fix actions | None | +| SHARED-06.1 | BL-06.1 | Hub minimal | None | +| SHARED-06.2 | BL-06.2 | MQTT bridge router → hub | Add audio bridge policy | +| SHARED-06.3 | BL-06.3 | Sites Overview | Show audio sources alongside cameras | +| SHARED-06.4 | BL-06.4 | Cross-site forensic search | Extends to audio queries | +| SHARED-06.5 | BL-06.5 | Remote operate via Tailscale | None | +| SHARED-06.6 | BL-06.6 | Fleet provisioning | None | +| SHARED-07.1 | BL-07.1 | Evidence chain L1 | Manifest schema extended in WDM-T-07.1 | +| SHARED-07.2 | BL-07.2 | blocao verify CLI | Audio verification added in WDM-T-07.2 | +| SHARED-07.3 | BL-07.3 | Manifest hash chain | None | +| SHARED-07.4 | BL-07.4 | Operator audit log | Includes audio actions | +| SHARED-07.5 | BL-07.5 | Design tokens consolidation | None | +| SHARED-07.6 | BL-07.6 | UI patterns documentation | None | + +--- + +## Components shared across products (reuse list) + +The following code/components must be **product-agnostic**: + +### Console framework + +- SPA shell. +- Rail navigation pattern. +- Topbar with mode color. +- Compact ctx-strip pattern. +- Wizard mode (full-screen). + +### UI components + +- **Chat input with ghost-text autocomplete**: same pattern, different vocabulary backend. +- **Timeline with markers and swimlanes**: same structure, swimlanes are cameras for video / speakers for audio. +- **Player shell**: same controls, different visualization area (frame for video, waveform for audio). +- **Health test items**: same expandable detail pattern, different test set. +- **Pin-to-case button**: same flow. + +### Backend models + +- **Case model**: cases hold heterogeneous evidence types (clip, transcript_segment, etc). +- **Evidence pack export**: ZIP with manifests; supports any evidence type. +- **Manifest schema**: base fields shared, type-specific fields appended. +- **Operator audit log**: same append-only log, type-specific action codes. + +### Infrastructure + +- Router OpenWrt firmware (single image for both products). +- Cell base image (Balena), products plug containers in. +- MQTT broker config (same Mosquitto, namespaces separate). +- GitOps repos (same `site-config` + `fleet-config` pattern). +- Hub (single backend serving both products' fleet management). + +--- + +## Engineering principles for shared components + +1. **Interfaces first**. Define the contract (TypeScript types or JSON Schema) before implementing. +2. **Product code is in `apps/`, shared code is in `packages/`**. The chat component goes in `packages/ui-components/`. The transcript-specific vocabulary backend goes in `apps/transcript/`. +3. **No conditional product code in shared layers**. If the chat component needs different behavior for audio, that's a prop or strategy, not an `if (product === 'transcript')`. +4. **Shared component bumps are major**. Breaking changes to a shared component should be intentional and signaled. + +--- + +## Why this matters + +Without disciplined sharing, building two products costs almost twice as much as building one. With discipline, the second product costs ~30% the first, because most infrastructure is amortized. + +The Blocao + Transcript pair is the proof point. If we do this well, future products (e.g., access events forensics, IoT sensor forensics) cost even less because the platform layer is more mature. + +--- + +## Maintaining this document + +When closing a Blocao backlog story that has a SHARED counterpart, also tick the SHARED entry. When the implementation requires a transcript-specific adaptation, document it in `transcript-sprint-backlog.md` as `WDM-T-XX.Y`. + +If you find yourself wanting to write a new shared story not on this list, add it here first, then implement it.