5.7 KiB
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/<source_id>/... 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-configpattern). - Hub (single backend serving both products' fleet management).
Engineering principles for shared components
- Interfaces first. Define the contract (TypeScript types or JSON Schema) before implementing.
- Product code is in
apps/, shared code is inpackages/. The chat component goes inpackages/ui-components/. The transcript-specific vocabulary backend goes inapps/transcript/. - 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'). - 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.