Production map

Small demo. Production shape.

The demo is static, so it runs anywhere and needs no key. The parts that matter in production keep the same shape: chunk schema, citation object and test set.

No server · no database · no key
Production path
PDF / DOCXParse + chunkEmbeddingspgvectorTop-k + rerankClaudeAnswer + citations
Demo partProduction partWhy the change is small
JSON chunks in data/documents.tspgvector rows in SupabaseSame fields: chunk id, document id, page, text. Add an embedding column and an index.
BM25 in lib/retrieve.tsEmbedding search, top 20, then a rerankThe retrieve() contract stays: a question goes in, five passages with scores come out.
Authored answers in data/answers.tsClaude API call with a citation-first promptThe prompt receives the same passages and must return { text, citations }. A citation check rejects a page that is not in the context.
Static export on Cloudflare PagesNext server on a Node host plus Supabase AuthPages, routes and components stay. Add a session, row-level security and two API routes.
Browser state on /documentsIngestion job: parse, chunk, embed, upsertThe table columns stay. The job writes file status, chunk count and the last index time.
The demo runs on Cloudflare Pages as static files. No server, no database, no key.
The hard question

Contracts that contradict each other

A contract is evidence, not a row to overwrite. The assistant keeps every version and makes the rule visible.

1Keep both clauses. The older contract stays in the index and in the answer. The archive never hides a signed version.
2Group by clause. Notice period, deposit, fees and pets each become a comparable field with a number and a date.
3Apply a rule, not a guess. The later signature date governs by default. A clause can name a different rule, and that rule wins.
4Show both values. The answer carries a Conflict badge, both sources and the rule that was applied.
5Log the decision. A person can review the conflict and add a note. The note becomes part of the audit trail.

What is real here

✓Retrieval. 45 chunks, BM25 scoring and page metadata, in the browser.
✓Citations. Document title, page and the exact passage, in a drawer.
✓Conflict handling. Two deposits, one later signature, both clauses visible.
✓Evaluation. 12 citation tests, 10 pass and 2 known gaps.
The answer text is authored in this demo. The Claude API writes it in production from the passages that the retrieval step returns.

Access and teams

Access control is out of the demo. In production, Supabase row-level security maps a user to a team, and a team maps to a document set. Files use signed URLs.

Login, upload rights and delete rights are separate roles. The admin page shows the actions; the production API checks the role before each write.

The next step

Connect a small real corpus first: 20 to 50 documents, a test set and a score. Then add the ingestion queue and the team rules.