# Knowledge assistant: retrieval-only demonstration

This is a deterministic retrieval demonstration using four short fictional documents marked approved within the demo. There is no live language model, embedding service, vector database, external system, or generated answer. “Approved” is fictional document metadata, not approval from a real organisation.

Run with Python 3.9+:

```sh
python3 test_retrieval.py
python3 retrieve.py "How do I invite a teammate?"
python3 retrieve.py "Are monthly invoices due in 14 or 30 days?"
python3 retrieve.py "Where is customer data hosted?"
```

## Included sources

| Document | Fictional approval date | Topic |
| --- | --- | --- |
| KB-001 | 2026-08-20 | Team invitations |
| KB-002 | 2026-08-26 | Email support hours |
| KB-003 | 2026-08-27 | Invoices due after 30 calendar days |
| KB-004 | 2026-08-28 | Invoices due after 14 calendar days |

KB-003 and KB-004 intentionally conflict. Both remain approved, and neither explicitly supersedes the other. The retriever returns both quotations and abstains. It does not silently prefer the more recent document.

## How it works

The script reads the local Markdown metadata and source paragraphs. It tokenises a question, applies four small plural normalisations, and ranks manually labelled fact groups by overlap with their curated retrieval terms. One matching term is enough to retrieve a candidate; this is a deliberately narrow example. A tied top score prompts abstention. No matching term returns `unknown` with no evidence.

For a selected fact group, distinct normalised statements cause `conflict`. This is a conservative string check within a manually assigned fact key, not general semantic contradiction detection. A single consistent statement returns `evidence_found` with document ID, title, date, relative path and exact source quotation. This is retrieved evidence only: even for “Can I get support on Saturday?”, the program returns the staffing policy rather than generating or interpreting a yes/no answer.

## Actual result

`test_retrieval.py` ran the five declared questions in `questions.json`. All 5 fixed functional cases passed: 3 return evidence, 1 abstains for a conflict, and 1 abstains for missing information. Tests check the expected status, source IDs, abstention flag, absence of generation, and quotation presence in source text. Full outputs are in `results.json`; a readable transcript is in `transcript.md`.

These cases are intentionally small and selected by the demo author. They are not an accuracy, latency, ROI or model-quality benchmark. Keyword overlap can retrieve irrelevant evidence and miss paraphrases. Hand-authored fact grouping limits conflict checks. Production retrieval would need broader evaluation, permissions, document ownership, lifecycle rules, observability and an appropriately grounded generation layer.

`prompt.md` is an optional drafted contract for a future grounded generation step. It was not executed. All code is standard-library Python and operates only on local files. The test writes `results.json`; the command optionally writes the explicitly supplied `--output` path.

`grounding-prompt.md` is a website-friendly duplicate of the optional unexecuted prompt.
