How Priya finds things, how agents use the same backend, every term defined, and the principles worth stealing — with what I'd investigate next.
When Priya searches
Everything before this part built the system; this part opens its doors — first to Priya’s own questions, then to agents asking on their own. She types “clustering” and gets concepts ranked by meaning, not keywords. One query does it — real code from backend/app/knowledge/engine.py:
backend/app/knowledge/engine.pySELECT c.*, 1 - (c.embedding <=> :embedding) AS similarity ...WHERE 1 - (c.embedding <=> :embedding) >= :thresholdORDER BY similarity DESC LIMIT :kWhat. Embeddings beside the rows they describe; top-10 above a 0.7 cutoff, HNSW-indexed, joinable with certification and keyword filters.
Why. No vector service, no sidecar, no sync job — and cross-workload joins stay free in one round trip.
Tradeoff. The 1024-dimension contract: embedding size is baked into the column, so changing models migrates data. Split past single-node scale or with an independent search team — neither holds here.
First principle: co-locate what you correlate. Your turn: add one embedding column plus this query shape behind your existing search box before shopping for infrastructure.
You are here: Part 5 of 6 — the capstone. Parts 1–4 built the maps, math, API, and pipeline; this part connects everything Priya can ask — and everything agents can ask too. Part 6 then takes it all live.
Reading that query like an engineer
Four clauses, four jobs. SELECT with <=> computes cosine distance beside the row — no second system, no export. WHERE similarity >= :threshold (0.7) discards weak matches early instead of ranking noise. ORDER BY similarity DESC ranks what remains. LIMIT :k (10) caps work and screen space. Because the embedding lives in the same row, certification and keyword filters join in the same round trip — that join is the feature the sidecar architectures pay a sync job to imitate.
Two numbers carry contracts: 1024 (embedding width — change models, migrate data) and 0.7 (match floor — a product decision with an owner, per Part 2’s rule that magic numbers get names and dates). Your turn: find one magic number in your codebase without an owner. Assign it one today.
HNSW: the index that makes it fast
Without an index, every search compares against every row — fine at hundreds of concepts, hopeless at millions. HNSW (Hierarchical Navigable Small World) pre-builds shortcut layers over the vectors so a query descends greedily instead of scanning. Priya-sized data would survive a scan; the index is bought for headroom, honestly labeled as such.
The honest-scope rule again: match machinery to measured need. Under ~50 static graph nodes, sorted adjacency beats a graph database with an operator (Topic 4). Under thousands of vectors, HNSW beats a scan. In both cases the article states the crossover instead of pretending the heavy tool was always necessary.
When Priya asks “what first?”
Typed edges (prerequisite, enables, replaces, related) answer three questions: ancestors (what first), reverse lookup (what unlocks), depth-sorted paths minus mastered nodes. Kahn’s topological sort raises on cycles — a curriculum requiring A-before-B-before-A is broken by construction, and code should prove it. Match machinery to scale: under ~50 static nodes, sorted adjacency beats a graph database with an operator.
Walk one: Priya targets “Liquid Clustering”. Ancestors climb prerequisite edges (partitioning basics → file layout → clustering); mastered nodes drop out; the remainder depth-sorts into her reading order. The same walk powers “what unlocks” in reverse — finish clustering and the app can congratulate her with the exact doors it opened.
flowchart LR Q["Priya asks"] S["Search: meaning match"] G["Graph: what first"] A["Agents: same tools"] Q --> S Q --> G Q --> A
Search, graph, and agent tools are three doors into one backend — the Part-3 services doing the real work.
When agents ask instead of Priya
Same backend, third client: MCP tools (search, concept, path, progress, quiz, export) plus Obsidian vault exports. Mental model: client diversity tests service design — clean Part-3 services meant agents mapped to existing capabilities instead of demanding new endpoints. Design services so the third client is cheap; you won’t know what it is yet.
Agent safety, plainly: tools expose reads and quiz attempts — the same operations Priya’s screen performs, through the same auth and validation. No tool bypasses a gate Priya faces. The day an agent needs a capability Priya lacks (bulk export, admin reads), that tool gets its own auth review — capability and permission ship together, never apart.
Directing an AI agent at this knowledge layer
You are adding a knowledge capability (search, graph, or agent tool).
Goal: <one sentence>Constraints:- Co-locate before adding infrastructure (Topic 1): prove the query can't live in Postgres first.- New magic numbers get names, owners, and tests (Topic 2).- Agent tools wrap existing services; no new endpoints unless you prove the need (Topic 5).- Run make test-unit before finishing.
Before coding:1. State which of search/graph/agent answers this and why.2. Show the query or traversal on paper with real content.3. Then implement.Failure modes of knowledge systems
- Stale embeddings. Content edited, vectors not recomputed — meaning search lies quietly. Defense: the pipeline’s vectorize stage re-runs on publish (Part 4); edits outside the pipeline are the hole — close it by routing all writes through publish.
- Threshold rot. 0.7 was right for last year’s content; new topics drift. Defense: the cutoff has an owner and a review habit, not just a value.
- Dimension lock-in. New embedding model, old 1024-wide column. Defense: stated up front as the contract’s price (Topic 1 tradeoff) — migration planned, not discovered.
- Graph cycles. A-before-B-before-A curricula. Defense: Kahn’s sort raises; the error names the cycle.
- Agent overreach. A tool exposing more than its screen equivalent. Defense: capability parity review for every new tool.
Vocabulary (her words → our words)
- Concept — one learnable idea with explanations, examples, traps.
- Mastery (0–1, stored 0–1000) — measured command; 0.55 means “understanding”, 0.74 “application”.
- SM-2 card — a flashcard with an ease and a next-review date.
- Weak topic — weakness score above 0.4, with a typed reason.
- Stratified exam — fair paper: 40/40/20 difficulty mix, seeded shuffle.
- Idempotency receipt — proof a stage finished, so re-runs skip it.
- Dead-letter queue — where failed jobs wait to be understood.
- HNSW / tsvector — fast similarity index / keyword search index.
- MCP tool — one backend capability, callable by AI agents.
- JWT rotation — short access tokens plus renewable refresh tokens.
Exercises
- Search “clustering” and “partitioning”. Which results overlap? Explain why using the embedding column (same neighborhood) versus keywords (shared words).
- Draw the prerequisite ancestors of one concept three levels up. Then delete one edge — what breaks in the path?
- Lower the similarity cutoff to 0.5 in a scratch query. Count the junk. Restore 0.7 and write down why the owner was right.
- List every MCP tool beside its backing service. Any tool without one is a design smell — report it.
- Ask an AI agent to propose a new edge type with the Topic 6 prompt. Judge: does it prove Postgres can’t hold it?
What worked, what I’d change, what’s next
Worked: spec-first structure surviving a year; pure-function engine testable in milliseconds; one store serving three query kinds; gates deciding while models draft; sources of truth named per concern.
Changed already (resolved, evidenced): client-awarded XP → server-side (BUG-017). Untested math → 86 tests. Fixture rows polluting production-shape data → seed/teardown discipline. Each encoded — in code, tests, or process — so it teaches forever.
I’d change: write the dimension contract before the first embedding lands (discovered, not designed). Collapse the duplicate flat/integration test files into one layout. Promote the progress tracker from honest record to weekly ritual.
Investigate next: calibrating mastery weights against logged outcomes (judgment → evidence); hybrid keyword-plus-vector ranking with measured lifts; per-section time estimates from attempt timestamps. Each a small experiment — hypotheses first, numbers after. Your turn: pick one, write its hypothesis in one sentence, and name the measurement that would confirm it.
Principle worth keeping
Structured projects feel calm because every hard question was answered once, in writing, where the code can point at it. Tangled projects feel loud because those answers live in someone’s head — usually someone who left.
Series complete — what you can now build
You can rebuild this class of system — deterministic brain, served API, gated pipeline, searchable knowledge — for any study domain, and you can say why each piece exists, what breaks without it, and what you’d measure first. That was the promise in Part 1. The certificate at the end is Priya’s; the architecture is yours.