Technical reference for the system itself. Data source: _pipeline\admin-registry.yaml — add entries there. No secrets live in this repo; entries record where access lives, never values.

Architecture

Circle.so LMSplatform.outskill.comOtter.aifallback captureScheduled taskdaily 21:00Chrome + extensionauthed API harvestDownloads stagingbundle file-dropsPython pipelineorganize / fetch / runFFmpegHLS download + verifyV: media archivevideo / vtt / docsClaude Fable 5knowledge extractionYAML records_CLASSES (git)build_site.pypage generation_site pageshome / toc / searchSQLite FTS5+vecplanned indexOllama Qwen3planned embeddings

Solid = live; dashed = planned.

Technology stack

Grouped by what each part is for, with a plain-English line on what the technology actually is — the stack as a lesson, not a list.

The data itself

ComponentTechnologyStatusWhat this tech isRole here
Content recordsYAML + JSON SchemaliveYAML is a structured text format humans can read directly — labeled fields and lists, like a very tidy outline. JSON Schema is a rulebook that checks each file has the right fields.One file per session, git-versioned in _CLASSES. The ONLY permanent commitment; every page and index is rebuildable from these.
Course registrycourses.yaml + courseconf.pyliveA single YAML file listing every course (its URL, id, media folder) plus a small Python helper that reads it.Scripts take --course KEY; no ids or paths hardcoded anywhere.

Getting content in

ComponentTechnologyStatusWhat this tech isRole here
Ingestion adapterChrome + Claude-in-Chrome + Circle internal APIliveCircle is the platform Outskill's LMS runs on; its 'internal API' is the data feed the LMS's own pages use. The Claude browser extension rides your logged-in Chrome session to call it — same access you have, automated.Fetched data leaves the browser as file-drops to Downloads; nothing needs your password stored anywhere.
SchedulerCowork task 'catalyst-ingest'liveCowork's built-in scheduled tasks — a to-do that runs itself on a timer while Claude Desktop is open.Daily 21:00 check for new postings + posting-lag tracking.

Processing & archiving

ComponentTechnologyStatusWhat this tech isRole here
Pipeline scriptsPython 3.14 (_pipeline)livePlain Python programs — organize / fetch_transcripts / fetch_materials / run_recordings / build_site.Idempotent: safe to re-run any time; per-course state files remember what's already done.
Video archiverFFmpeg 8.1.2 (HLS -c copy)liveFFmpeg is the Swiss-army knife of video tools. HLS is the chunked streaming format sites deliver video in; '-c copy' means FFmpeg stitches the chunks into a normal .mp4 without re-encoding — fast and lossless.Downloads signed streams, verifies with ffprobe, always runs detached.
Media archiveV:\_CLASSES-medialiveA plain drive folder holding every recording, transcript, and handout.16 GB and growing. Deliberately NOT in git and NOT OneDrive — too big, no need to sync.

Knowledge extraction

ComponentTechnologyStatusWhat this tech isRole here
Extraction modelClaude Fable 5 (Cowork)liveThe AI doing the reading and writing: full transcript in, structured teaching records out.~85-90k tokens/session with the enriched schema; corrects ASR garbles; flags point-in-time claims.

Publishing

ComponentTechnologyStatusWhat this tech isRole here
Site generatorbuild_site.pyliveOne Python script that turns the YAML records into every page you're reading — nothing here is hand-edited HTML.Design locked to the approved Basecamp-5 reference page; 'edit data, not html'.

Search & memory (planned)

ComponentTechnologyStatusWhat this tech isRole here
Search indexSQLite + FTS5 + vector extplannedSQLite is a database that lives in a single file, built into nearly everything. FTS5 is its full-text engine (find any phrase, fast). A vector extension adds meaning-based lookup on top.Will cover full transcripts, not just extracted records. Vector extension choice deliberately open: benchmark sqlite-vec / sqlite-vector / vec1 on the real corpus.
EmbeddingsQwen3-Embedding-4B via OllamaplannedAn embedding model turns text into lists of numbers that capture meaning, so 'similar ideas' can be found even when no words match. Ollama runs such models locally — your data never leaves the machine.Runs on the RTX 3080 Ti (12 GB).
Local serviceNode v24 + shortcutplannedNode runs JavaScript outside the browser — here, a tiny local web server.Will serve the search UI and smooth recording seeks; the static pages keep working standalone without it.

Access & authentication

SystemHow auth worksNotes
Outskill LMS (Circle.so) - platform.outskill.comPaul's Chrome profile session cookie. No stored credential; if logged out, log back in via Chrome and the pipeline works again.Internal API requires the authed browser. assets-v2.circle.so files are public hash-URLs (no auth).
Pilot Institute LMS - lms.pilotinstitute.comPaul's Chrome profile (Logto OIDC). API calls need BOTH `Authorization: Bearer <localStorage.access_token>` and `X-Tenant-Id: er8hu0`. Note localStorage also holds a 43-char `logto_access_token` which is NOT the API token - using it returns 401.Custom LMS, not Circle. REST at learn-api.pilotinstitute.com; quizzes at quizbank-api.pilotinstitute.com; video on Bunny.net Stream (library 400978). Signed MP4/HLS URLs expire ~1h (vs Circle's ~24h). Lesson pages do NOT freeze the renderer here.
Otter.aiPaul's Chrome profile session. Fallback source only.Generic speaker labels; suspected 4h cap; likely dropped once posting-lag pattern is confirmed.
NotebookLMGoogle account in Chrome. No API - uploads stay manual drag-and-drop.
Claude (Cowork)Claude Desktop login. Fable 5 used for extraction; usage drawn from plan's weekly limits.

Configuration registry

ItemWhereWhy
Chrome automatic downloads policyHKCU\Software\Policies\Google\Chrome\AutomaticDownloadsAllowedForUrls = https://platform.outskill.com + https://lms.pilotinstitute.comAllows the harvest's multi-file Blob drops to Downloads. Set by Paul 2026-08-15 (reg add). lms.pilotinstitute.com added by Paul 2026-08-16 (CL-013, done). STILL PENDING: community.livingwithpixels.com (CL-014). Each unlisted origin fails the same way - the first drop lands, every later one is silently swallowed, and a page reload does NOT clear it. Treat 'add the origin' as step one of onboarding any new platform.
Course registry_pipeline\courses.yaml (loader: courseconf.py)One entry per course - baseUrl, courseId/classId, mediaDir, manifest/state filenames, evergreen flag. Every pipeline script takes --course KEY, so adding a course is a registry edit not a code edit. Added 2026-08-16. NOTE manifestDir: courses whose manifest lives in mediaDir (part-107) MUST declare it, or the path resolves to Catalyst's manifest.json.
Python interpreterpy -3.14 (C:\Users\pberg\AppData\Local\Python\pythoncore-3.14-64)The bare `python` on PATH is 3.13 and has NO pyyaml. Every pipeline script must be run as `py -3.14`.
Scheduled task: catalyst-ingestCowork > Scheduled (SKILL.md under Documents\Claude\Scheduled\catalyst-ingest)Daily 21:00 ingest cycle + posting-lag tracking. Runs only while Claude Desktop is open.
PathsLibrary/git: C:\Users\pberg\OneDrive\Documents\_AI\_CLASSES | Media: V:\_CLASSES-media | Pipeline: _CLASSES\_pipeline | Site: _CLASSES\_siteMedia deliberately OUTSIDE OneDrive and git (16+ GB, growing).

Technical notes

Open questions