Skip to content

Repository files navigation

CANON logo

CANON

Policy-governed intelligence for decisions that need proof.

Take organizational rules, retrieve the authoritative version, enforce constraints, and only then let AI answer.

React Live Demo TypeScript TanStack Vite Tailwind CSS Python Gemini Groq

Live Demo | Overview | Demo | Architecture | Run Locally | Deployment

Deployed CANON: canon.devayushrout.me


CANON homepage showing the policy-governed intelligence interface

Overview

CANON is a governance-gated policy intelligence system for teams that need internal policy answers with traceable evidence. It does not treat the model as the source of truth. Instead, it treats approved policy documents as the canonical authority and uses the model only after routing, retrieval, and governance checks have already narrowed the answer space.

The system is designed for organizational policy workflows where a generic chatbot would be risky: refund rules, access controls, support exceptions, security escalation, compliance-sensitive procedures, and versioned operating policies.

The current production path is a Vite + React 19 + TanStack frontend calling a Python API for policy intelligence. Groq handles classification/generation and Gemini handles embeddings from the Python layer. The repository has been cleaned so only the active frontend, Python API, policy corpus, docs, and evaluation tooling remain.

CANON can currently answer from the included markdown policy corpus, return sources and supporting clauses, refuse invalid or policy-disallowed requests, and escalate sensitive cases. It is still a project/demo system, not a substitute for legal, compliance, or human policy approval.

Demo

Live production demo: canon.devayushrout.me

CANON live policy console with sample questions and query input

Question
  -> intent detection
  -> owner routing
  -> Gemini embedding
  -> policy retrieval
  -> governance verdict
  -> source-backed answer or refusal

Example query:

Can support override the refund deadline?

Example response shape:

{
  "status": "SAFE",
  "verdict": "SAFE",
  "answer": "The answer is generated only from retrieved policy clauses.",
  "sources": ["data/raw_docs/policies/billing_and_refund_policy_v2.md"],
  "supporting_clauses": ["Relevant policy text used by the answer."],
  "confidence": "high",
  "context_used": 5,
  "hallucination_detected": false
}

At A Glance

Area Current State
Frontend React 19, TypeScript, TanStack Start-ready Vite app, TanStack Router, TanStack Query
UI Tailwind CSS v4, Radix UI primitives, shadcn-style components, Lucide icons
API Python FastAPI endpoint at POST /api/query
AI Layer Python calls Groq chat completions and Gemini embeddings
Retrieval Python retrieval over static JSON embeddings, with lexical local fallback
Data Markdown policy documents under data/raw_docs
Deployment Vercel production at canon.devayushrout.me
Status Portfolio-grade MVP with deterministic governance gates

Key Features

  • Policy-first answers: every answer is grounded in approved internal documents.
  • Owner-scoped retrieval: queries are routed to Finance, Operations, Security, or Support before evidence is used.
  • Version-aware evidence: latest policy versions win over stale source documents.
  • Explicit governance verdicts: responses are classified as SAFE, REFUSE_POLICY, REFUSE_INVALID, or ESCALATE.
  • Source-backed output: answers include source paths, supporting clauses, confidence, and grounding status.
  • No Node AI backend: Node is used only for frontend tooling; the intelligence runtime is Python.

Product Surface

CANON product section showing the decision trace and response contract

Workflow

CANON workflow section showing the evidence-gated policy pipeline

Architecture

CANON architecture section showing the internal governed answer path

Browser
  -> Vite React UI
  -> TanStack Query mutation
  -> Python POST /api/query
  -> Python Groq intent detection
  -> deterministic owner routing
  -> Python Gemini query embedding
  -> cosine retrieval over data/search-index.json
  -> owner/latest-version constraints
  -> Python Groq governance classification
  -> Python Groq answer or refusal generation
  -> lexical grounding check
  -> JSON response

The architecture is shaped around one rule: the model should not get to answer until the system has decided which policy owner applies, which documents are authoritative, whether the request is allowed, and whether the final answer stays close to the retrieved evidence.

Read the full architecture notes in docs/ARCHITECTURE.md.

Tech Stack

Layer Tools
UI React 19, TypeScript, Tailwind CSS v4
Routing TanStack Router
Data Fetching TanStack React Query
Components Radix UI primitives, shadcn-style local components
Charts/Icons Recharts, Lucide React
Build Vite with TanStack Start package alignment
API Python FastAPI
Classification Python calling Groq chat completions
Generation Python calling Groq chat completions
Embeddings Python calling Gemini Embedding API
Retrieval Python static JSON index, cosine similarity, lexical fallback
Source Data Markdown policy documents
Deploy Vercel static frontend plus Python serverless function

Why This Exists

CANON exists because policy Q&A should not behave like an unconstrained chatbot. The system separates the decision path into explicit stages: detect what the user is asking, scope the policy owners, retrieve authoritative documents, apply governance rules, generate only from retrieved evidence, and return an answer with sources.

The current implementation keeps the browser app light and pushes the intelligence runtime into Python. Embeddings are generated through Gemini, model reasoning runs through Groq, and retrieval uses a static JSON index plus deterministic fallbacks so the project remains understandable and deployable.

Run Locally

Clone the repository:

git clone https://github.com/ayushcodes13/canon.git
cd canon

Install dependencies:

pnpm install
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Create a local environment file:

cp .env.example .env.local

Build the retrieval index:

pnpm run build:index

Start the Python API:

pnpm run dev:api

Start the frontend in another terminal:

pnpm run dev

Then open the local Vite URL printed by the dev server.

Environment Variables

GROQ_API_KEY=
GEMINI_API_KEY=
GROQ_MODEL=llama-3.3-70b-versatile
GEMINI_EMBEDDING_MODEL=gemini-embedding-001
VITE_API_BASE_URL=

Never commit real secrets. Keep .env.local untracked and configure production secrets directly in the hosting provider.

Project Structure

frontend/
  index.html
  src/
    components/ui/
    lib/
    screens/
    sections/
    main.tsx
    router.tsx
    styles.css

api/
  index.py
  main.py
  pipeline.py
  build_search_index.py

data/
  raw_docs/
  search-index.json

docs/
  ARCHITECTURE.md
  DOMAINS.md
  assets/

Engineering Decisions

  • Use the requested frontend stack: React 19, TypeScript, TanStack Router, TanStack Query, Vite, Tailwind v4, Radix-style UI, Lucide icons, and Recharts now own the browser app.
  • Keep AI in Python: intent detection, retrieval, governance, generation, and grounding are all behind api/main.py.
  • Use hosted embeddings: Gemini embeddings keep the production index path lightweight and deployment-friendly.
  • Keep retrieval simple: the document set is small, so a static JSON vector index is easy to build, inspect, and deploy.
  • Gate before generation: governance classification happens before answer generation, not after.
  • Expose uncertainty: confidence, grounding warnings, context count, and sources are part of the response contract.
  • Remove inactive surfaces: retired demo code and unused binary indexes are kept out of the production repository so future work starts from the active architecture.

Limitations

  • The best results require valid Groq and Gemini API keys.
  • Without keys, the Python API uses deterministic local fallback logic for development only.
  • The current index is generated from local markdown files, not a live document management system.
  • There is no authentication or role-based access control yet.
  • The grounding check is lexical and lightweight, not a formal proof system.
  • It is a portfolio-grade MVP and still needs security review before real organizational use.

Roadmap

  • Add a persistent document ingestion dashboard.
  • Add authentication and role-aware policy access.
  • Add policy owner approval workflows.
  • Add richer evaluation tests for refusals, escalations, and grounding.
  • Add durable production logging for audit trails.
  • Keep the public Vercel demo and custom domain current with releases.
  • Add a clean free subdomain such as canon-policy.pages.dev or canon.is-a.dev.

Screenshots

CANON live homepage screenshot

CANON live console screenshot

CANON live workflow screenshot

CANON live architecture screenshot

Deployment

Live production deployment:

https://canon.devayushrout.me

CANON is configured for a single Vercel project. Vercel builds the Vite frontend, generates the Gemini embedding index during deployment, and routes /api/* to the Python FastAPI app through api/index.py.

For local frontend-only verification:

pnpm run build

For Vercel production builds:

pnpm run build:vercel

Run the Python API locally:

python3 -m uvicorn api.main:app --host 0.0.0.0 --port 8000

On Vercel, set GROQ_API_KEY and GEMINI_API_KEY before deploying. GEMINI_API_KEY is required to generate the semantic retrieval index; without it, the build skips index generation and the API falls back to lexical retrieval. VITE_API_BASE_URL can stay unset for same-origin Vercel deployment because the frontend calls /api/query.

License

This project is released under the Apache License 2.0. See LICENSE.

About

A governed RAG system for enterprise SaaS internal compliance & IT operations support.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages