8 decisions gate the pipeline build. Each has a recommended option. Your input shapes how content flows into Ask-ZuZu.
IN/. After processing, files move to OUT/. A new dedicated folder keeps Zuzu ingestion isolated from other HHE content.{course-slug}_{YYYY-MM-DD}_{type}.extcell-talk_2026-02-15_transcript.pdf, hbmg_2026-01-30_protocol.txt. Structured names let the pipeline extract metadata from the filename before the LLM even reads the content.17,251 chunks across 10 categories — all manually loaded. No automated pipeline. Three tier mismatches being resolved by the Tier Refactor.
Total chunks in ChromaDB
Automated pipelines
Member / Student / Certified
pie title ChromaDB Chunk Distribution (Current)
"tnc-hhc" : 7821
"hbmg" : 4406
"cohort" : 2016
"autoimmune" : 915
"brain-nervous" : 773
"10-steps" : 470
"gut-health" : 403
"detox" : 252
"microscopy" : 101
"hhp" : 94
| Category | Chunks | Current Tier | New Tier | Status |
|---|---|---|---|---|
| tnc-hhc | 7,821 | certified | student | MISMATCH FIX |
| hbmg | 4,406 | guest | member | OK |
| cohort | 2,016 | certified | certified | No config |
| autoimmune | 915 | level-1 | student | MISMATCH FIX |
| brain-nervous | 773 | level-2 | student | OK |
| 10-steps | 470 | level-2 | student | MISMATCH FIX |
| gut-health | 403 | level-1 | student | OK |
| detox | 252 | level-2 | student | OK |
| microscopy | 101 | certified | student | Needs review |
| hhp | 94 | certified | certified | OK |
Content producers drop files into a Google Drive folder. The pipeline polls every 15 minutes, processes uploads through format detection, LLM metadata extraction, semantic chunking, and batched ChromaDB writes.
sequenceDiagram
participant HHE as HHE Content
Producers
participant GD as G-Drive
IN/ Folder
participant POLL as Polling Service
(15-min cron)
participant PARSE as Format Detection
+ Parsing
participant LLM as Claude Sonnet
Metadata Extraction
participant CHUNK as Semantic
Chunker
participant CHROMA as ChromaDB
Batched Write
HHE->>GD: Drop PDF/TXT/DOCX
Note over GD: Named: {slug}_{date}_{type}.ext
POLL->>GD: List new files (Drive API v3)
GD-->>POLL: File list + metadata
POLL->>PARSE: Download + detect format
Note over PARSE: PDF: pdfminer.six
TXT: direct read
DOCX: python-docx
PARSE->>LLM: Raw text + filename
Note over LLM: Extract: course_slug
topic, source_type
author, date
LLM->>CHUNK: Structured text + metadata
Note over CHUNK: Section-boundary aware
Header hierarchy preserved
CHUNK->>CHROMA: Batched add_documents()
Note over CHROMA: tier + source_type
+ source_weight
+ recency_date + hash
CHROMA-->>POLL: Chunk count delta
Note over POLL: Move IN/ to OUT/
Log: file, chunks, summary
PDF via pdfminer.six, TXT direct read, DOCX via python-docx. Format detected from extension and content. Karen’s future book is DOCX-ready.
Extracts course_slug, topic classification, source type, author, and date. Filename convention provides baseline; LLM validates and enriches.
Chunks respect section headers and paragraph boundaries — not fixed-size sliding windows. Header hierarchy and cross-references preserved.
ALWAYS batched add_documents(). Critical: per-document writes take ~50s each (SQLite WAL). 40 docs batched = ~100s vs 33 minutes.
| Field | Type | Example | Purpose |
|---|---|---|---|
tier | enum | student | Access control (Member/Student/Certified) |
source_type | enum | transcript | Weight assignment + display |
source_weight | float | 1.0 | Retrieval ranking boost |
recency_date | date | 2026-03-01 | Recency decay scoring |
course_slug | string | cell-talk | Category routing |
author | string | Rachael | Attribution + weight |
content_hash | MD5 | abc123... | Dedup (no duplicate chunks) |
Current retrieval is pure cosine similarity. The new model adds recency and source authority weighting for more relevant results.
sequenceDiagram
participant USER as User Query
participant SEARCH as Semantic Search
(ChromaDB)
participant RANK as Weighted Ranker
participant FILTER as Tier Filter
(Member/Student/Certified)
participant RESP as Response Generator
USER->>SEARCH: Query text
SEARCH-->>RANK: Top-N candidates
with cosine scores
Note over RANK: combined = 0.6 * relevance
+ 0.2 * recency
+ 0.2 * source_weight
RANK->>RANK: Recency step function:
Current semester = 1.0
Previous semester = 0.8
Older = 0.5
RANK->>FILTER: Re-ranked candidates
Note over FILTER: User tier >= chunk tier?
Segment boost applied?
FILTER->>RESP: Filtered, ranked chunks
Note over RESP: High confidence: 4K-7K tokens
Low confidence: flag + cite sources
From Jan 30 consultation: pre-recorded, fact-checked content gets highest authority.
| Source Type | Weight | Rationale |
|---|---|---|
| Published book | 1.0 | Published, fact-checked |
| Pre-recorded lectures | 1.0 | Reviewed, edited content |
| Official protocols | 1.0 | HHE-approved guidance |
| Refined academic notes | 0.85 | Vince’s processed notes |
| Live call transcripts | 0.6 | Raw, unedited recordings |
Current Semester
Full weight
Previous Semester
Slightly reduced
Older
Still searchable
The HHE pipeline is modeled on the proven SecondAct-Interview ingestion system. Same stack, adapted metadata.
| Component | SecondAct-Interview | HHE Equivalent |
|---|---|---|
| Input format | DOCX (Q&A interviews) | PDF/TXT/DOCX (transcripts, protocols) |
| Parser | python-docx | pdfminer.six + python-docx + stdlib |
| LLM extraction | Claude Sonnet structured | Claude Sonnet metadata + topic |
| Embedding | text-embedding-3-small (1536-D) | Same |
| Vector store | ChromaDB PersistentClient (dual) | ChromaDB PersistentClient (single) |
| Batch writes | Single add_documents() — 17x speedup | Same pattern |
| Dedup | MD5 content hash | Same |
| Metadata | source, authority, year, content_type | tier, source_type, source_weight, recency_date |
Never call add_documents() per-item — ChromaDB SQLite WAL checkpoint takes ~50s per call. 40 docs per-item = 33 minutes; batched = ~100 seconds. This is a 17x performance difference.
New Python service deployed alongside existing HHE infrastructure on the VPS.
sequenceDiagram
participant GD as Google Drive
participant PM2 as PM2 Process Manager
(VPS)
participant ING as hhe-ingestion
(Python, 15-min cron)
participant CHROMA as ChromaDB
(Railway)
participant SUPA as Supabase
(VPS :54322)
participant PROXY as HHE-Kajabi-proxy-chat
(Railway :3100)
Note over PM2: Existing infrastructure
PM2->>ING: Trigger every 15 min
ING->>GD: Poll IN/ folder
GD-->>ING: New files
ING->>ING: Parse + Extract + Chunk
ING->>CHROMA: Batched writes
(3-tier metadata)
Note over CHROMA: member/student/certified
ING->>GD: Move IN/ to OUT/
Note over PROXY: Existing service (unchanged)
PROXY->>CHROMA: queryWithAccess()
PROXY->>SUPA: v_user_tier_calculation
Simple, familiar tooling. Co-located with Supabase. Python process managed by PM2 with 15-minute polling interval.
Real-time event-driven ingestion. Requires public webhook endpoint. Consider after pipeline is stable and content volume warrants instant processing.
Pipeline build depends on Amy’s decisions and the Tier Refactor completion. Estimated timeline after all blockers clear.
gantt
title HHE Ingestion Pipeline — Execution Timeline
dateFormat YYYY-MM-DD
axisFormat %b %d
section Blockers
Amy decisions (8 items) :crit, amy, 2026-03-01, 5d
Tier Refactor completion :crit, tier, 2026-03-01, 7d
G-Drive folder + credentials :crit, gdrive, after amy, 3d
section Pipeline Build
Python service scaffold :scaffold, after tier, 2d
G-Drive watcher + polling :watcher, after gdrive, 3d
Format parsers (PDF/TXT/DOCX) :parsers, after scaffold, 3d
LLM metadata extraction :llm, after parsers, 2d
Semantic chunker :chunker, after parsers, 2d
ChromaDB batched writer :writer, after chunker, 2d
section Integration
End-to-end pipeline test :test, after writer, 2d
First batch ingestion :batch, after test, 2d
Retrieval scoring upgrade :retrieval, after batch, 3d
Verification + QA :qa, after retrieval, 2d
section Deferred
Karen book ingestion :milestone, after qa, 0d
TypeSense migration planning :milestone, after qa, 0d