Ionosphere.tv
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add ionosphere.tv design spec

Semantically enriched AT Protocol conference video archive.
Pannacotta-pattern architecture: source lexicons → lenses →
internal lexicons → appview → SSG render. First corpus is
ATmosphereConf 2026 VODs from Streamplace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Blaine Cook 6177e92f

+203
+203
docs/superpowers/specs/2026-03-30-ionosphere-design.md
··· 1 + # Ionosphere: Semantically Enriched Conference Video Archive 2 + 3 + ## Overview 4 + 5 + Ionosphere is an AT Protocol-native video archive that transforms conference talk recordings into a browsable, semantically enriched knowledge base. Conference talks become richly annotated documents with synchronized transcripts, concept cross-references, speaker profiles, and a navigable knowledge graph. MTV meets the British Library and Wikipedia. 6 + 7 + The first corpus is ATmosphereConf 2026 (126 VOD records from Streamplace, ~100 schedule events). 8 + 9 + **Domain:** ionosphere.tv 10 + **NSID namespace:** `tv.ionosphere.*` 11 + 12 + ## Architecture 13 + 14 + Follows the pannacotta pattern: diverse source lexicons -> lenses -> internal lexicons -> appview -> render. Uses RelationalText for the document model and `pub.layers.annotation` for semantic enrichment layers. panproto for schema versioning. 15 + 16 + ### Source Data 17 + 18 + - **`place.stream.video`** records from `did:plc:rbvrr34edl5ddpuwcubjiost` (stream.place), served from PDS at `iameli.com`. 126 VOD records, 1080p HLS CMAF playback via `vod-beta.stream.place/xrpc/place.stream.playback.getVideoPlaylist?uri=<at-uri>`. 19 + - **`community.lexicon.calendar.event`** records from `did:plc:3xewinw4wtimo2lqfy5fm5sw` (atmosphereconf.org). ~100 schedule events with title, description, room, type, category, speakers (handle + name), start/end times. 20 + 21 + ### Domain Lexicons 22 + 23 + - **`tv.ionosphere.talk`** — Title, speaker refs, track/room, start/end times, video ref (AT URI to `place.stream.video`), transcript as RelationalText document with word-level temporal facets, source schedule ref. 24 + - **`tv.ionosphere.speaker`** — Name, AT Protocol handle/DID, bio, affiliations, talk refs. 25 + - **`tv.ionosphere.concept`** — Knowledge entity: name, aliases, description, Wikidata ref. Created by LLM enrichment, curated by humans. 26 + - **`tv.ionosphere.event`** — Conference-level metadata: name, dates, location, tracks/rooms, schedule ref. Supports multiple conferences. 27 + 28 + ### Annotation Facet Types 29 + 30 + Defined in the format-lexicon (`formats/tv.ionosphere/ionosphere.lexicon.json`), not as AT Protocol record lexicons. These are RelationalText feature types used within documents. 31 + 32 + - **`speaker-segment`** — featureClass: block. Marks a speaker turn within the transcript. 33 + - `speakerUri`: AT URI to `tv.ionosphere.speaker` record 34 + - `startTime`: number (nanoseconds from video start) 35 + - `endTime`: number (nanoseconds from video start) 36 + 37 + - **`concept-ref`** — featureClass: inline. Links a text span to a concept. 38 + - `conceptUri`: AT URI to `tv.ionosphere.concept` record 39 + 40 + - **`speaker-ref`** — featureClass: inline. Links a mention of a person to a speaker record. 41 + - `speakerUri`: AT URI to `tv.ionosphere.speaker` record 42 + 43 + - **`talk-xref`** — featureClass: inline. Cross-reference to another talk. 44 + - `talkUri`: AT URI to `tv.ionosphere.talk` record 45 + 46 + - **`link`** — featureClass: inline. External URL reference. 47 + - `url`: string (URI) 48 + - `title`: string (optional) 49 + 50 + - **`timestamp`** — featureClass: meta. Word-level timing for video sync. 51 + - `startTime`: number (nanoseconds from video start) 52 + - `endTime`: number (nanoseconds from video start) 53 + 54 + ## Data Layer: Progressive Enhancement 55 + 56 + Each stage enriches but does not gate. A talk with no transcript still renders with schedule metadata and video. A transcript without LLM enrichment still plays with timestamps. Concepts get richer as more talks reference them. Records arrive independently and the view gets progressively richer. 57 + 58 + ### Stage 1: Ingest & Correlate 59 + 60 + Pull `place.stream.video` and `community.lexicon.calendar.event` records. Correlate by fuzzy title matching + time overlap. Filter noise (lunch breaks, test streams, duplicates). Produce one `tv.ionosphere.talk` per real talk, linking to both source records. Manual overrides for tricky matches. 61 + 62 + ### Stage 2: Transcribe 63 + 64 + Download audio from each VOD via HLS endpoint. Run through transcription service with word-level timestamps. Output: plain text + word timing array. Transcription provider evaluated at implementation time (Whisper, Deepgram, AssemblyAI — compare cost/quality on samples first). 65 + 66 + ### Stage 3: Document Assembly 67 + 68 + Convert transcript + timestamps into a RelationalText document. Facets include: 69 + - `timestamp` facets on every word/word-group (temporal anchoring) 70 + - `speaker-segment` facets marking speaker turns 71 + 72 + Speaker diarization (identifying who speaks when within a single audio stream) is deferred for v1. Single-speaker talks get one `speaker-segment` for the entire transcript. Multi-speaker sessions (panels, Q&A) default to one segment per scheduled speaker, with manual refinement as a curation task. Diarization can be added as a later enrichment stage without changing the document model. 73 + 74 + ### Stage 4: LLM Enrichment 75 + 76 + Pass transcript through an LLM to identify and annotate: 77 + - Concept mentions -> create/link `tv.ionosphere.concept` records 78 + - Speaker/person mentions -> link to `tv.ionosphere.speaker` records 79 + - Cross-references to other talks -> `talk-xref` facets 80 + - External links/references mentioned verbally -> `link` facets 81 + 82 + Annotations stored as `pub.layers.annotation` layers with source metadata. 83 + 84 + ### Stage 5: Appview Indexing 85 + 86 + SQLite materialization from annotation layers: 87 + - `talks` — title, speaker, times, document JSON, video ref 88 + - `talk_concepts` — join table 89 + - `talk_speakers` — join table 90 + - `talk_crossrefs` — join table 91 + - `concepts` — vocabulary table 92 + - `speakers` — vocabulary table 93 + 94 + ### Stage 6: Render 95 + 96 + Next.js SSG. Video streams from Streamplace at runtime. Transcript sync is client-side JS. Data baked at build time from appview SQLite. 97 + 98 + ### Appview Role 99 + 100 + The appview serves two purposes: (1) a build-time data layer that the Next.js SSG reads from to generate static pages, and (2) a development server for iterating on data and testing. The shipped site is fully static — the appview does not need to run in production. It can be promoted to a live service later if needed (e.g., for search, real-time updates, or API consumers). 101 + 102 + ## Frontend & Playback 103 + 104 + ### Global Timestamp State 105 + 106 + The video player broadcasts current playback time. Every annotation has temporal bounds from word-level timestamps. Components subscribe to global time and activate/deactivate themselves autonomously. No central controller — each annotation is a reactive entity, same pattern as pannacotta's ingredient quantity scaling. 107 + 108 + ``` 109 + VideoPlayer -> currentTime (global state) 110 + | 111 + TranscriptView (Pretext-rendered) 112 + +-- word spans: scroll-to + highlight on match 113 + +-- concept-ref chips: glow/activate on match 114 + +-- speaker-segment blocks: current speaker indicator 115 + +-- talk-xref chips: activate when mentioned 116 + ``` 117 + 118 + Click a word in the transcript -> seek video. Click a concept -> navigate to concept page. Bidirectional. 119 + 120 + ### Page Types 121 + 122 + - **Talk page** — video + synced transcript + sidebar (metadata, speakers, concepts) 123 + - **Speaker page** — bio, all talks, concept co-occurrences 124 + - **Concept page** — description, Wikidata link, all talks mentioning it, timeline of mentions 125 + - **Browse/index** — by day, track, category, concept, speaker. The research librarian view. 126 + - **Home** — conference overview, featured/recent talks 127 + 128 + ### SSG 129 + 130 + All pages statically generated. Video streams from Streamplace at runtime. Transcript sync is client-side JS. Data baked from appview SQLite at build time. 131 + 132 + ## Project Structure 133 + 134 + ``` 135 + ionosphere/ 136 + +-- package.json # pnpm workspace root 137 + +-- pnpm-workspace.yaml 138 + +-- tsconfig.json 139 + +-- lexicons/ 140 + | +-- tv/ionosphere/ 141 + | +-- talk.json 142 + | +-- speaker.json 143 + | +-- concept.json 144 + | +-- event.json 145 + +-- formats/ 146 + | +-- tv.ionosphere/ 147 + | +-- ionosphere.lexicon.json # facet type definitions 148 + | +-- lenses/ 149 + | | +-- schedule-to-talk.lens.json # calendar.event -> tv.ionosphere.talk 150 + | | +-- transcript-to-document.lens.json # raw transcript -> RelationalText doc 151 + | +-- ts/ # annotation, enrichment utilities 152 + +-- apps/ 153 + | +-- ionosphere/ # Next.js SSG frontend 154 + | | +-- src/ 155 + | | +-- app/ 156 + | | | +-- talks/ 157 + | | | +-- speakers/ 158 + | | | +-- concepts/ 159 + | | | +-- components/ 160 + | | | +-- VideoPlayer.tsx 161 + | | | +-- TranscriptView.tsx 162 + | | | +-- AnnotationChips.tsx 163 + | | | +-- TimestampProvider.tsx 164 + | | +-- lib/ 165 + | +-- ionosphere-appview/ # Hono server, SQLite, indexer 166 + | +-- src/ 167 + | +-- appview.ts 168 + | +-- db.ts 169 + | +-- ingest.ts 170 + | +-- correlate.ts 171 + | +-- transcribe.ts 172 + | +-- enrich.ts 173 + | +-- indexer.ts 174 + | +-- routes.ts 175 + +-- scripts/ 176 + | +-- ingest.ts # CLI: pull source data 177 + | +-- transcribe.ts # CLI: run transcription 178 + | +-- enrich.ts # CLI: run LLM enrichment 179 + +-- data/ # cached source data, transcripts 180 + ``` 181 + 182 + ### Dependencies 183 + 184 + - `relational-text` — document model, facets, annotation layers 185 + - `@atproto/api` — AT Protocol client 186 + - `hono` — HTTP server for appview 187 + - `better-sqlite3` — appview storage 188 + - `next` — SSG frontend 189 + - Pretext — transcript layout (integration TBD based on available API) 190 + - panproto — schema versioning 191 + 192 + ## Transcription 193 + 194 + Provider to be evaluated at implementation time. Candidates: 195 + - **Whisper (local)** — free, good quality, word-level timestamps via whisper.cpp or faster-whisper. Requires GPU for reasonable speed. 196 + - **Deepgram** — fast, good word-level timestamps, ~$0.0043/min (Nova-2). ~$0.50 for the full corpus. 197 + - **AssemblyAI** — good diarization, word-level timestamps, ~$0.01/min. ~$1.20 for the full corpus. 198 + 199 + Decision deferred — will compare on a few sample talks first. 200 + 201 + ## Enrichment 202 + 203 + LLM-assisted annotation generates first-pass semantic layers. Humans refine via a curation interface (design TBD, not in initial scope). Each annotation layer carries source metadata (algorithm, model, version, timestamp) so provenance is transparent.