How content assets are discovered, described, embedded, verified and linked to journeys — and how that runs distributed across many machines writing into one shared store.
The platform keeps two concerns deliberately separate, connected only by the asset ↔ journey tag:
Curriculum-agnostic. Every asset that exists — video, image, interactive, document — with its provenance, media location and a machine-written brief of what it teaches. This is what the portal shows.
The learning structure the chapter-research side produces. The catalog never owns journeys; it only carries a tag from an asset (or asset part) to the journey / LO it covers.
Keeping them apart means the same asset can be reused across journeys, and the graph can evolve without rewriting the catalog.
A file used in slices — a book read a page at a time, a video referenced by timestamp — is an :Asset with :AssetPart children (PART_OF). The part is what gets tagged and embedded, so a single source can serve many journeys at different locators.
Discovery happens on many machines, none on a shared network. Every seat is an outbound-only HTTPS client of one central hub:
UPDATE … FOR UPDATE SKIP LOCKED, so two workers never collide.content_key, so re-runs never duplicate.populator token enqueues (content team, via the MCP); worker tokens claim and extract. Read (/ax/status) is open behind the login.| Table | Holds |
|---|---|
| ax_asset | one row per content-addressed asset — provenance, product, curriculum, grade, kind, title, chapter, media location, servable |
| ax_work | the work queue & claim lock — stage (pool→claimed→…→done), claimed_by, claim_expires, attempts |
| ax_brief | the Describe output — the structured brief JSON, a hash, and a pointer to the raw extract |
| ax_token | who may do what — worker / populator / admin bearer tokens |
Embedding, vector index and the journey tag land in a later migration (bge-m3 embeddings, a Neo4j graph with vector indexes). Briefs come first.
/ax/*), one origin, behind Cloudflare Access (ClassRoots login).pg; move embeddings to a self-hosted bge-m3 as the pool grows.