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

69 lines
2.9 KiB
Markdown

# 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
- `topics`**max 3**, each `{ id (kebab-case), label, type (concept|role|process), description }`
- `relations`**max 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.**