- Introduced "Pension Scheme & Benefits" detailing secondary employment benefits and pension specifics. - Created "Roles & Accountabilities" outlining the Holacracy role structure and responsibilities within Respellion. - Added "Security" section covering GDPR compliance and workplace safety protocols. - Established "Spending and Contracting" policy detailing expense categories and submission processes. - Documented "Who We Are" to define Respellion's identity, services, and operational model under Holacracy and ISO 9001.
3.1 KiB
3.1 KiB
Ingestion spec: source documents → knowledge graph
Turns admin-uploaded text into topics and relations using Claude. Runs
entirely client-side; there is no ingestion service.
- UI:
src/components/admin/UploadZone.jsx(Admin → Sources tab) - Pipeline:
src/lib/extractionPipeline.js - Tool/schema:
emit_knowledge_graph(src/lib/llmTools.js) validated byextractionResultSchema(src/lib/llmSchemas.js)
Upload
- Accepted formats:
.txtand.md, max 5 MB per file. - Drag-and-drop or click-to-browse. Unsupported files are skipped with a toast.
- The queue tracks each file:
pending → processing → done / failed / cancelled. - Progress is polled every ~2s from the
sources.progressfield ({ current, total, message }), shown as "Chunk N/total". - Orphan detection: sources stuck in
processingfor >5 minutes (e.g. a closed tab) can be marked failed or deleted.
Pipeline: processSourceText(textContent, sourceName, { signal })
- Create source record with
status='processing'. - Chunk the text (
chunkText): target ~8000 chars per chunk with ~800 chars overlap, splitting on sentence/paragraph boundaries (hard-splitting oversized sentences). Overlap preserves cross-boundary context. - Known-topics hint (
buildKnownIdsHint): up to the 200 most recent existing topics are listed so the model reuses existing ids instead of duplicating them. - Per-chunk extraction via
callLLM:- tier
standard,maxTokens: 8192,timeoutMs: 180_000 - forced
toolChoiceonemit_knowledge_graph - rate-limited (~20 req/min, burst 2) to protect quota across many chunks
- system prompt instructs: ≤15 topics per chunk; topic
type∈ {concept,role,process};learning_relevance∈ {core,standard,peripheral,exclude}; relationtype∈ {related_to,depends_on,part_of,executed_by}
- tier
- Update progress before each chunk.
- Merge (
mergeKnowledgeGraph): topics keyed byid(new data updates existing, butlearning_relevanceis preserved whenrelevance_lockedis true); relations de-duplicated on(source, target, type). Persisted viadb.saveTopics/db.saveRelations. - Finalize:
status='completed', orfailed(error) /cancelled(abort).
Aborting via the signal stops the run and marks the source cancelled.
Output shape (emit_knowledge_graph)
{
"topics": [ { "id", "label", "type", "description", "learning_relevance" } ],
"relations":[ { "source", "target", "type" } ]
}
theme, complexity_weight, and difficulty are not set here — they are
added later by the curriculum enrichment step (see docs/curriculum-spec.md).
Gotchas
- If extraction logs a truncation (
LLMTruncatedError,stop_reason: max_tokens), tighten the per-chunk topic cap before raisingmax_tokens. - A source already
completedis not re-processed; delete it to force re-analysis. - There are no embeddings produced here — R42 retrieval is computed at query time
with TF-IDF over
topics.