lectio / docs /PHASES.md
adesh01's picture
feat: Lectio β€” HF Space deployment
14fda63

Implementation Phases

Phased build plan for the Christianity-focused AI Assistant. Each phase has a goal, concrete tasks, the files it touches, and an exit criterion. See ARCHITECTURE.md for the full design.

Status legend: βœ… done Β· 🟑 in progress Β· ⬜ not started


Phase 0 β€” Project Setup βœ…

Goal: Reproducible backend skeleton, tooling, and config.

  • βœ… uv project, Python 3.12 pin, pyproject.toml + uv.lock
  • βœ… FastAPI app, /health + /chat stub
  • βœ… structlog (console dev / JSON prod) with request-id middleware
  • βœ… pydantic-settings config (env-driven), .env.example
  • βœ… .gitignore, README, git initialized + initial commit

Exit: uv run uvicorn app.main:app boots, /health returns 200. βœ…


Phase 1 β€” Data Layer & Corpus 🟑

Goal: Postgres + pgvector populated with grounded source text.

  • βœ… docker-compose.yml β€” pgvector/pg16 on host port 5433
  • βœ… schema.sql β€” bible_verses, history_docs, conversations + HNSW/GIN indexes
  • βœ… core/db.py β€” psycopg3 pool, pgvector registration, extension bootstrap
  • βœ… scripts/init_db.py β€” idempotent schema apply
  • βœ… core/embeddings.py β€” bge-base loader, embed_passages / embed_query
  • 🟑 scripts/ingest_bible.py β€” KJV (66 books) ingest + embeddings (in progress)
  • 🟑 scripts/ingest_history.py β€” parse creeds1.pdf, chunk, embed β†’ history_docs (in progress)
  • ⬜ Deuterocanon ingest from KJV-with-Apocrypha.json β†’ tag catholic/orthodox

Exit: bible_verses fully populated (~31k rows); history_docs has creeds + council facts; semantic search returns sane neighbors.

Files: backend/app/core/{db,embeddings,schema.sql}, backend/scripts/*


Phase 2 β€” Retrieval Layer βœ…

Goal: Denomination-aware scripture + history retrieval functions.

  • βœ… core/retrieval.py β€” search_scripture(query, denomination, k) with canon filter
  • βœ… search_history(query, denomination, k) (validated once history_docs populated)
  • βœ… Retrieval confidence scoring (top cosine similarity, threshold in config)
  • βœ… Reference lookup verse_exists(book, chapter, verse) for citation validation

Exit: Given a query + denomination, returns ranked verses honoring canon membership; confidence reflects match quality. βœ…


Phase 3 β€” LLM Integration βœ…

Goal: Gemini client wrapper with grounded prompting.

  • βœ… core/llm.py β€” google-genai client, main (gemini-2.5-pro) generation
  • βœ… Module-level singleton + _reset_client() auto-retry on closed httpx session
  • βœ… core/prompts.py β€” system prompt templates, denomination framing, build_user_prompt
  • βœ… Structured output helpers (generate_json with response_schema)

Exit: Wrapper takes prompt + retrieved context, returns grounded text; honors "cite only retrieved verses" instruction. βœ…


Phase 4 β€” Safety & Router Node βœ…

Goal: Block unsafe input before retrieval; classify intent in one call.

  • βœ… core/safety.py β€” Stage 1 regex (adversarial templates, explicit hate)
  • βœ… Stage 2 Gemini Flash call returning {safe, intent, confidence}
  • βœ… Intents: scripture | theology | history | image | general | blocked
  • βœ… Low-confidence / general β†’ fallback to plain responder

Exit: Adversarial + hateful prompts blocked pre-retrieval; intent routed correctly on the eval set. βœ…


Phase 5 β€” Agent Graph βœ…

Goal: Wire the LangGraph StateGraph from ARCHITECTURE.md Β§4–6.

  • βœ… agent/state.py β€” AgentState TypedDict with all fields
  • βœ… agent/nodes.py β€” 9 nodes: Input, SafetyRouter, ScriptureRAG, HistoryRAG, Theology, Image, ImageValidator, Validator, Responder
  • βœ… agent/graph.py β€” conditional edges, compile, get_graph() lru_cache singleton
  • βœ… Per-node latency capture into state.latency_ms

Exit: Graph runs end-to-end for all intents. βœ…


Phase 6 β€” Grounding & Hallucination Control βœ…

Goal: Catch fake citations and paraphrase drift.

  • βœ… Citation validator: extract Book Ch:Verse, verify vs corpus, strip + log fakes
  • βœ… Semantic drift check: embed response, compare max-sim across retrieved set
  • βœ… Drift disclaimer injection when drift high despite strong retrieval
  • βœ… Populate hallucinated_refs, drift_warning in state

Exit: Fake-verse and paraphrase-misquote eval cases pass (no invented refs). βœ…


Phase 7 β€” Conversation Memory βœ…

Goal: Bounded, relevant context β€” no full-history dump.

  • βœ… Persist each turn to conversations with per-turn embedding
  • βœ… Window strategy (≀20 turns β†’ last 10) and semantic strategy (>20 β†’ top-5)
  • βœ… Denomination-switch guard: inject canon/framing-changed system note

Exit: Long sessions stay within budget; denomination switch updates framing without stale assumptions. βœ…


Phase 8 β€” Image Generation βœ…

Goal: Safe Christian-themed image flow with two-pass moderation.

  • βœ… Image prompt rewrite into safe Christian-art form
  • βœ… Imagen 3 call via google-genai (base64 data URI)
  • βœ… ImageValidator node re-checks rewritten prompt before generation
  • βœ… Return image URL/bytes + safety metadata

Exit: Policy-violating image prompts blocked at raw and post-rewrite stages. βœ…


Phase 9 β€” API Integration βœ…

Goal: Replace /chat stub with the compiled graph.

  • βœ… /chat invokes graph, returns response + citations + flags
  • βœ… Session handling, request-id propagation into graph state
  • βœ… asyncio.run_in_executor wraps synchronous graph for async FastAPI

Exit: End-to-end API call produces grounded, cited, moderated responses. βœ…


Phase 10 β€” Frontend βœ…

Goal: Minimal chat UI (UI polish explicitly not graded).

  • βœ… Next.js 15 + Tailwind CSS chat interface
  • βœ… Denomination selector (Protestant/Catholic/Orthodox pills)
  • βœ… Citation rendering: verified (amber) + hallucinated (red) badges
  • βœ… Image display in chat bubble
  • βœ… Wire to backend /chat

Exit: Usable demo chat with denomination toggle and visible citations. βœ…


Phase 11 β€” Evaluation βœ…

Goal: Reproducible eval harness over the dataset in ARCHITECTURE.md Β§13.

  • βœ… eval/dataset.json β€” 20 cases: fake-verse, adversarial, hallucination, image, history, denomination, theology, scripture
  • βœ… eval/run_eval.py β€” run cases through graph, score PASS/PARTIAL/FAIL, color report, exit code 1 on FAIL
  • βœ… --id and --category filters for targeted runs
  • βœ… Result: 16 PASS / 2 PARTIAL / 2 FAIL (historical FAILs fixed by Phase 1 history ingest)

Exit: Single command runs the eval set and prints a scored report. βœ…


Phase 12 β€” Deployment ⬜

Goal: Credible hosted demo.

  • ⬜ Backend β†’ Hugging Face Spaces (or container host)
  • ⬜ DB β†’ NeonDB (pgvector); push corpus
  • ⬜ Frontend β†’ Vercel
  • ⬜ Env/secrets wiring (GEMINI_API_KEY)

Exit: Public URL serves the assistant against hosted DB.


Phase 13 β€” Deliverables 🟑

Goal: Wrap up assignment artifacts.

  • βœ… docs/ARCHITECTURE.md β€” full system design with all decisions
  • βœ… docs/HLD.md β€” Mermaid diagrams + component table
  • βœ… docs/SYSTEM_DESIGN.md β€” formal SDD with requirements, flows, trade-offs
  • βœ… README.md β€” setup, run, eval instructions
  • ⬜ 5–8 min walkthrough script/recording
  • ⬜ Final eval run after full corpus ingest (target β‰₯18/20 PASS/PARTIAL)

Exit: Demo + repo + note + walkthrough ready to submit.


Critical Path

Phase 1 (corpus) β†’ Phase 2 (retrieval) β†’ Phase 3 (LLM) β†’ Phase 4 (safety/router)
β†’ Phase 5 (graph) β†’ Phase 6 (grounding) β†’ Phase 9 (API) β†’ Phase 11 (eval)

Phases 7 (memory), 8 (image), 10 (frontend) are parallelizable once the graph (Phase 5) exists. Phases 12–13 are last.