Files
learning-platform/docs/r42-spec.md
RaymondVerhoef 07af2783dc
All checks were successful
On Push to Main / test (push) Successful in 1m33s
On Push to Main / publish (push) Successful in 1m31s
On Push to Main / deploy-dev (push) Successful in 2m3s
Add comprehensive documentation for key organizational aspects
- 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.
2026-05-27 08:24:56 +02:00

2.9 KiB

R42 spec: the in-app chatbot

R42 is a knowledge-base-grounded assistant available on every screen. It runs client-side and is grounded by local TF-IDF retrieval — no vector database.

  • UI: src/components/chat/ChatLauncher.jsx, ChatWindow.jsx, useChat.js
  • Prompt/tool: src/components/chat/prompts.js
  • Retrieval/validation: src/components/chat/rag.js + src/lib/retrieval.js
  • KB writes: src/lib/kbStore.js

Conversation

  • The brand mark (src/components/ui/Mark.jsx) renders R42 in idle / typing / error states.
  • Messages persist per user in localStorage under chat:thread:{userId}, capped at 50 messages. Only roughly the last 12 turns are sent to the API; older context is truncated with a notice.
  • A greeting message seeds an empty thread.
  • Each turn calls callLLM (fast/standard Claude tier — low latency matters for chat).

Grounding (RAG via TF-IDF)

buildKbContext in rag.js:

  1. Build / reuse the TF-IDF index over topics (src/lib/retrieval.js).
  2. Retrieve the top 10 topics for the user's message.
  3. Always include topics whose id or label appears verbatim in the message.
  4. Include relations only when both endpoints are in the retrieved set.
  5. For explicitly mentioned topics, inject up to ~1200 chars of their generated content.
  6. Append a short KB hash so the cached context busts when topics change.

The system prompt (prompts.js) is assembled as cacheable blocks: a stable preamble (role, tasks, style, "answer only from the KB"), the KB context block, and a per-turn tail with the user's name and admin/non-admin flag.


Proposing knowledge-graph edits

R42 may call propose_graph_delta with:

  • reason — one sentence
  • topicsmax 3, each { id (kebab-case), label, type (concept|role|process), description }
  • relationsmax 5, each { source, target, type (related_to|depends_on|part_of|executed_by) }

validateDelta (rag.js) dedupes by topic id and case-folded label, rejects relations with missing endpoints or self-references, and enforces the 3/5 caps. Invalid deltas are dropped.

A confirmation chip appears inline:

  • Admin → Yes: kbStore.applyDelta writes topics/relations to PocketBase immediately.
  • Non-admin → Yes: kbStore.appendSuggestion queues a pending entry in kb:suggestions (localStorage) for admin review.

Admins review the queue in src/components/admin/SuggestionsQueue.jsx (approve re-runs applyDelta; reject marks it rejected). kbStore dispatches respellion:kb-updated after writes so the D3 graph and queue refresh.


Quiz integrity

src/pages/Testen.jsx sets quiz:active:{userId}=true on quiz start and clears it on every non-quiz phase and on unmount, dispatching a respellion:quiz-state event. ChatLauncher hides the FAB while this flag is set, so users cannot consult R42 mid-quiz. Never bypass this.