GodSpeed / Docs /PRD.md
Samyuktha24's picture
feat: implement sidebar component with navigation and recent queries
c0b5012

Godspeed β€” Product Requirements Document

Version: 0.1 MVP
Audience: Engineering teams, internal stakeholders
Last updated: 2026-05-11


1. Product Overview

Godspeed is an AI-powered knowledge copilot for engineering organisations. It gives every team member β€” from new hires to senior engineers β€” instant, accurate answers from the company's fragmented knowledge base: docs, tickets, Slack threads, code, incident reports, and runbooks.

Instead of searching across six tools, you ask one question. Godspeed retrieves, synthesises, and cites its sources, then visualises the knowledge graph so you can explore relationships between services, teams, and incidents.


2. Target Audience

Persona Age range Primary goal Technical level
End user / engineer 22 – 45 Get answers fast without asking colleagues Medium–high
New hire 22 – 30 Onboard to a large, unfamiliar codebase Low–medium
Analyst / team lead 28 – 50 Understand knowledge health, dependency risks, escalation patterns Medium
Admin / DevOps 25 – 50 Manage data sources, monitor system health, manage users High
Non-technical stakeholder 35 – 65 Search for policies, runbooks, team contacts Low

Design principles from the audience:

  • Professionals expect speed and no fluff. Results appear as they load β€” no waiting for the full answer.
  • 22-year-olds and 65-year-olds share the same interface. Interactions must be obvious without instructions.
  • Error messages are written for humans, not logs. Technical details go to system logs only.
  • Nothing disappears. Partial results, previous queries, and in-progress graph data all remain visible.

3. Core Features

3.1 Multi-agent Query System

What it does: When a user submits a query, a LangGraph-orchestrated agent pipeline fans out across multiple retrieval agents simultaneously, then synthesises results into a single coherent answer.

Agents:

  • doc_search β€” semantic search over ingested documents (Qdrant vector store + BM25 hybrid)
  • ticket_lookup β€” Jira/Linear ticket retrieval
  • live_docs β€” Confluence / GitHub wiki lookup
  • summariser β€” synthesis agent that fuses agent outputs, cites sources

User-visible behaviour:

  • Agent status badges appear as soon as the execution plan is ready
  • Each badge transitions: pending β†’ active (pulsing) β†’ done (βœ“ + confidence level)
  • Answer streams in token by token; user can read while agents are still running
  • If one agent fails, others continue and the answer is still produced with a note

Backend: POST /agent/query β€” SSE stream. Events: plan_ready, agent_started, agent_done, citations, answer_chunk, guardrail_result, done, error.

Retry behaviour: If the answer drops mid-stream, the partial text remains visible with a "connection dropped" warning and a Retry button. Retry re-runs the full pipeline from scratch β€” partial resumption requires backend changes (phase 2).


3.2 Real-time Knowledge Graph Visualisation

What it does: As the agent runs, a parallel WebSocket stream (WS /graph/stream) pushes graph nodes and edges that represent the knowledge entities relevant to the answer. The graph populates in real time β€” users see it build as the query runs.

Node types (colour coded):

  • Service β€” blue (#3b82f6)
  • Library β€” green (#22c55e)
  • Incident β€” red (#ef4444)
  • Team β€” orange (#f97316)

Edge types: DEPENDS_ON, CAUSED_BY, OWNED_BY, MENTIONS, REFERENCES, HAS_CHUNK, DOCUMENTS

Interactions:

  • Hover a node β†’ tooltip with name and label
  • Click a node β†’ side panel with related documents and "Ask about this node" shortcut
  • Node count and edge count displayed below the graph as it builds
  • WS auto-reconnects up to 5 times with exponential backoff if the connection drops. After max retries a "Try again" button is shown β€” reconnecting re-runs the full Neo4j snapshot so any data updated since last load appears automatically.
  • A "↻ Refresh graph" control is available after a successful load, letting users pull in freshly ingested data without re-running their query.

Architecture note: The graph stream is a global Neo4j snapshot (MATCH (n) WHERE NOT n:Chunk) β€” it is not scoped to the current query or to the user's team. Every connection/reconnect fetches fresh live data. Team-scoped graph filtering is a phase 2 item.

Desktop layout: Graph always visible in the right column (380px) alongside the answer. Graph canvas mounts the moment a query is submitted and starts populating with the first node/edge β€” no loading screen.

Mobile: Graph and Answer are in separate tabs. Graph tab is the default. Answer tab is grey/disabled until the first SSE event arrives (nothing to show yet). Tab unlocks and becomes clickable once data is available.


3.3 Answer Streaming & Citations

What it does: The answer streams in as the synthesiser agent produces tokens. Citations appear as expandable source cards below the answer.

Citation fields: source name, source type (doc/ticket/wiki), relevance score, reranker score, chunk preview.

Related docs: When more than 3 citations exist, overflow documents appear in a "Related documents" section below citations.

Guardrail: If the synthesiser's confidence is low, a yellow "This answer may not be fully accurate" banner appears with a suggestion to verify sources before acting.


3.4 Feedback System

What it does: After each completed answer, the user can rate the response. Feedback is stored in Redis and can be surfaced to admins for quality monitoring.

User flow (πŸ‘ path):

  1. User clicks πŸ‘ β†’ POST /api/query/{queryId}/feedback with { sentiment: "helpful" }
  2. Toast: "Feedback recorded β€” thank you"
  3. Button replaced with "πŸ‘ Marked as helpful"

User flow (πŸ‘Ž path):

  1. User clicks πŸ‘Ž β†’ inline form expands asking "What was wrong?"
  2. Optional free-text field for context
  3. Two options: "Not helpful" (sentiment: not_helpful) or "Flag as hallucination" (sentiment: hallucinated)
  4. On submit: toast + confirmation text
  5. On cancel: form collapses, buttons remain

Data stored: gs:feedback:{queryId} key in Redis with sentiment + text, TTL 30 days.


3.5 Query History & Workspace

What it does: Every completed query (success or failure) is stored in Redis and available in the workspace. Users can browse, expand, and replay past queries.

History endpoint: GET /api/workspace/history?page=N&limit=20 β†’ paginated list.

History item fields: query text, brief answer summary, timestamp, success/failure dot, duration.

Replay: "Ask again β†’" re-submits the exact query text to the agent pipeline.

Sidebar integration: The 6 most recent queries appear in the collapsible left sidebar for quick replay without navigating to the History page.


3.6 Collapsible Sidebar Navigation

What it does: A fixed left sidebar on desktop (β‰₯1024px) provides navigation, recent query history, notifications, theme toggle, and account management. Collapses to icon-only mode (56px) to maximise content space.

Collapsed state: Icons only, tooltips on hover, avatar initial for user section. Expanded state (240px): Full labels, ⌘K badge on Ask, 6 recent queries, user name + email, sign out.

Navigation links: Home, Ask (⌘K), History, Analytics, Admin (admin role only).

Sidebar state is persisted to localStorage via zustand. Mobile uses the original top NavBar.


3.7 Analytics Dashboard

Four tabs accessible to analysts and admins:

Tab Data source What it shows
Queries Redis gs:queries list Total queries, unique users, avg response time, success rate, daily trend chart
Knowledge Health Neo4j node counts Coverage/freshness/accuracy per domain (Service, Library, Incident, Team), radar chart
Dependencies Neo4j nodes Service/library nodes with version comparison, outdated/breaking change flags
Escalations Redis gs:escalations Open/in-progress/resolved escalations table, filter by status
Export All of the above CSV download of query events by date range

Date range filter: 7d / 30d / 90d / all.


3.8 Admin Panel

Three tabs visible to admin role only:

Tab Feature
System Status Live health cards for Neo4j, Redis, Qdrant β€” each shows OK/error state
Data Sources Toggle integrations on/off (Jira, Confluence, GitHub, Slack), seeded from env vars, state persisted in Redis
System Logs Live WebSocket log tail (WS /ws/logs) β€” filter by level, search, pause/resume, 500-line ring buffer
Ingest Trigger graph ingest or file upload for ingestion pipeline

3.9 Authentication

Session-cookie-based auth backed by Redis. Two configurable personas via env vars (DEMO_EMAIL, ADMIN_EMAIL).

  • Login: POST /api/auth/login β†’ sets gs_session cookie (HttpOnly, SameSite=Lax, 8h TTL)
  • Session validated on app mount via POST /api/auth/refresh β€” stale localStorage is cleared if server rejects
  • Logout: POST /api/auth/logout β†’ deletes session from Redis, clears cookie
  • cookie_secure = true must be set in prod to enable Secure flag on the cookie

3.10 Error Handling β€” User-Facing Language

All error messages visible to users are written in plain language. Technical details (stack traces, error codes, Redis keys) go to the structured JSON log (/ws/logs) only.

Scenario User sees
Query timeout (>30s) "The query took too long to respond. This can happen when agents are under heavy load. Try again in a moment." + Retry button
Answer cut off mid-stream "Answer may be incomplete β€” connection dropped mid-stream." + Retry button
Graph stream lost "Having trouble loading the knowledge graph β€” trying again (X of 5)…"
Low-confidence answer "This answer may not be fully accurate. Verify against the cited sources before acting on it."
Login failed "Invalid credentials" (no detail that reveals which field is wrong)
Redis unavailable on login "Session store unavailable β€” try again shortly" (503)
Feedback failed "Could not submit feedback" toast
No results "No results found for [query]" with suggested reformulations

4. Navigation & Layout

Desktop (β‰₯ 1024px)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ [Sidebar 240px / 56px]  β”‚  Main content (flex-1)        β”‚
β”‚                          β”‚                               β”‚
β”‚  Godspeed (logo)  [<]    β”‚  SearchBox                    β”‚
β”‚                          β”‚                               β”‚
β”‚  Home                    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  Ask          ⌘K         β”‚  β”‚ Answer col  β”‚ Graph colβ”‚   β”‚
β”‚  History                 β”‚  β”‚             β”‚  (380px) β”‚   β”‚
β”‚  Analytics               β”‚  β”‚ Agent badgesβ”‚          β”‚   β”‚
β”‚  Admin (admin only)      β”‚  β”‚ Answer text β”‚  Force   β”‚   β”‚
β”‚  Notifications           β”‚  β”‚ Citations   β”‚  Graph   β”‚   β”‚
β”‚                          β”‚  β”‚             β”‚          β”‚   β”‚
β”‚  ── Recent ──            β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  > last query 1          β”‚                               β”‚
β”‚  > last query 2          β”‚                               β”‚
β”‚                          β”‚                               β”‚
β”‚  [Moon] Dark mode        β”‚                               β”‚
β”‚  [avatar] Jane  [β†’]      β”‚                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mobile (< 1024px)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Godspeed     πŸ””  πŸ‘€  [β˜€]  β”‚  ← NavBar
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ SearchBox                β”‚
β”‚                          β”‚
β”‚ [  Graph  |  Answer  ]   β”‚  ← Tab bar (Answer disabled until SSE data)
β”‚                          β”‚
β”‚ [  Force graph canvas ]  β”‚  ← Graph tab (default)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

5. Known Gaps & Planned Improvements

End User

  • No "save answer" / bookmark feature β€” users can't pin answers for later reference
  • No copy-as-markdown button on the answer card
  • Follow-up questions don't carry conversation context β€” each is a fresh query
  • Knowledge graph has no "fit to screen" / zoom reset button
  • No keyboard navigation within the force graph
  • Suggested topics on Home page are static β€” don't adapt to user history or role
  • No "explain like I'm new" mode for adjusting answer depth

New Hire

  • No guided onboarding flow / interactive tour
  • No progress tracking (topics explored, questions asked this week)
  • Suggested queries don't differentiate between new users and experienced ones
  • No "getting started" checklist or recommended first queries

Analyst

  • Knowledge health freshness and accuracy values are hardcoded (0.85, 0.90) β€” not derived from real data
  • No time-period comparison in analytics (e.g., this week vs. last week)
  • No per-agent performance breakdown (which agent has the most low-confidence results?)
  • Export only covers query events β€” no export of graph data or health scores

Admin

  • No user management UI (add users, change roles, deactivate accounts) β€” credentials are env-var only
  • No audit log UI (who queried what, when)
  • Data source sync status is static β€” no live progress when a sync is running
  • No webhook configuration UI
  • No rate limiting on the query endpoint
  • freshness and accuracy in knowledge health need real calculation logic (last ingestion timestamp, validation pipeline)

Cross-cutting

  • Share Results feature sends only the query text β€” not the graph state or answer
  • No persistent "projects" or "collections" to group related queries
  • Notifications (WS /ws endpoint) exist but no backend events push to them yet
  • PDF export in Analytics is a stub (returns plain text fallback)
  • No dark-mode persistence of the force-graph canvas background β€” always transparent

8. Phase 2 β€” Team Projects & Shared Wikis

Current state (MVP): Query history (gs:queries) is a single global Redis list. All logged-in users see all queries. The graph snapshot is global β€” not filtered by team. team_id is passed to agent queries for retrieval context but is not used for access control or grouping anywhere in the system.

Phase 2 scope:

Feature What it needs
Team projects Project CRUD (name, description, team_id), associate queries with a project, project-scoped history view
Shared wikis Per-project document collections, invite team members to a project, read-only sharing links
Team-scoped history /api/workspace/history?team_id={id} filter; Redis history key per team (gs:queries:{team_id})
Team-scoped graph /graph/stream?team_id={id} β€” filter Neo4j nodes by team property
Access control Role Γ— team matrix (who can read/write which projects); currently roles are global not team-scoped
Per-team ingestion Confluence space key per team, GitHub org filter per team, stored in data sources config

What already exists that supports phase 2:

  • user.team_id and user.team on the User object
  • team_id passed to every agent query β€” the agent uses it for retrieval filtering already
  • team property on Neo4j Service/Library nodes (set by ingestion pipeline)
  • team_id stored on each query event in Redis

6. Tech Stack Summary

Layer Technology
Frontend React 18, TanStack Router, TanStack Query, Zustand, Tailwind CSS, Radix UI
Agent orchestration LangGraph 0.2.x, Gemini 2.5 Pro/Flash via langchain-google-genai
Vector search Qdrant (local: host+port; hosted: QDRANT_URL + QDRANT_API_KEY)
Graph store Neo4j 5.x async driver
Session / analytics store Redis (aioredis)
Embeddings BAAI/bge-large-en via FlagEmbedding
Reranker BAAI/bge-reranker via FlagEmbedding
PII masking GLiNER (local, zero egress)
API server FastAPI 0.115, uvicorn
Document parsing docling 2.x, PyMuPDF, pdfplumber, python-docx

7. Environment Variables Reference

Variable Required Default Purpose
VITE_API_BASE_URL βœ“ β€” Frontend β†’ backend HTTP base URL
VITE_WS_BASE_URL βœ“ β€” Frontend β†’ backend WebSocket base URL
REDIS_URL βœ“ redis://localhost:6379/0 Redis connection string
DEMO_EMAIL β€” demo@godspeed.local Demo user email
DEMO_PASSWORD β€” demo Demo user password
ADMIN_EMAIL β€” admin@godspeed.local Admin user email
ADMIN_PASSWORD β€” admin Admin user password
CORS_ORIGINS βœ“ prod http://localhost:5173,... Comma-separated allowed origins
COOKIE_SECURE βœ“ prod false Set true behind HTTPS
QDRANT_URL hosted "" Qdrant Cloud cluster URL
QDRANT_API_KEY hosted "" Qdrant Cloud API key