ResolveAI is a production-minded support operations workspace that pairs human judgment with grounded AI assistance. Agents can review customer context, approved knowledge, and a structured response draft without allowing AI to send messages or cross tenant boundaries.
AI support demos often optimize for a fast response while hiding the difficult parts: authorization, prompt injection, knowledge provenance, failure handling, cost control, and human accountability. ResolveAI makes those constraints part of the product and the architecture.
- Responsive support inbox and conversation workspace
- Tenant authorization before ticket or AI access
- Approved knowledge attached to each ticket
- Deterministic local AI provider for zero-configuration demos
- OpenAI Responses API provider with strict structured output
- Prompt boundary escaping and untrusted-content instructions
- Citation allow-listing and mandatory human review
- Per-actor generation rate limiting
- PostgreSQL ticket repository with forced row-level security
- Transaction-scoped tenant context that cannot leak through the connection pool
- Correlated structured logs without customer content
- Unit and PostgreSQL integration tests, CI, and production Docker image
No AI-generated message is sent automatically.
flowchart LR
Browser[Next.js workspace] --> Route[Draft API route]
Route --> Auth[Tenant authorization]
Auth --> Store{Ticket repository}
Store --> DemoStore[Deterministic fixtures]
Store --> Postgres[(PostgreSQL + RLS)]
Store --> Service[Draft domain service]
Service --> Prompt[Prompt boundary]
Prompt --> Provider{AI provider}
Provider --> Demo[Deterministic demo]
Provider --> OpenAI[OpenAI Responses API]
Service --> Guard[Citation and review guard]
Guard --> Browser
Redis[(Redis / jobs)] -. production rate limits .-> Route
The framework boundary is deliberately thin. Authorization and post-generation
guardrails live in the domain service and are independently testable. See
docs/architecture.md and the architecture decisions in
docs/decisions.
This repository treats operability and AI quality as implementation concerns, not deployment afterthoughts:
docs/api.openapi.yamldefines the shipped HTTP contract, rate-limit behavior, and correlation identifiers.docs/threat-model.mdmaps assets, trust boundaries, abuse cases, mitigations, and accepted risks.docs/runbook.mdcovers provider degradation, rate-limit incidents, tenant-isolation alarms, rollback, and evidence preservation.docs/evaluation-strategy.mddefines offline quality and safety gates for the retrieval milestone.- Provider tests verify strict structured output, storage controls, stable error classification, and runtime schema rejection.
- PostgreSQL integration tests run migrations against a real database and prove same-tenant hydration, cross-tenant isolation, fail-closed context, and pooled transaction cleanup.
These artifacts describe the current slice honestly. Production authentication, Redis, retrieval, and cloud infrastructure remain milestones with explicit acceptance criteria rather than appearing as shipped features.
Requirements: Node.js 20.9 or newer.
cp .env.example .env.local
npm install
npm run devOpen http://localhost:3000. The app uses a deterministic provider unless
OPENAI_API_KEY is set, so the complete review workflow works without external
services or API spend.
To exercise the durable ticket store:
docker compose up -d postgres
npm run db:migrate
npm run db:seed
TICKET_STORE=postgres npm run devThe application role, tenant policies, schema, and indexes are created by the checksum-verified migration runner. Seed data is synthetic and idempotent.
To enable the live AI provider:
OPENAI_API_KEY=your-key
OPENAI_MODEL=gpt-5.6-terraKeep real credentials in environment or secret storage; never commit them.
npm run lint
npm run typecheck
npm test
npm run test:integration
npm run buildCI runs the same checks against PostgreSQL 17 for pushes and pull requests.
| Concern | Decision | Tradeoff |
|---|---|---|
| AI integration | Vendor-neutral provider interface | Small abstraction cost; deterministic tests and easier fallback |
| Model output | Strict schema plus runtime validation | Less model flexibility; predictable application behavior |
| Grounding | Citation IDs intersected with approved context | Unsupported sources are dropped, not silently trusted |
| Delivery | Human approval is mandatory | More agent effort; no autonomous customer-facing mistakes |
| Demo identity | Header adapter behind an explicit boundary | Easy local use; intentionally unsuitable for production auth |
- Organization identity is resolved before ticket lookup.
- The domain service repeats tenant authorization as defense in depth.
- Customer messages and knowledge are treated as untrusted model input.
- Model output must match a strict schema and is validated again at runtime.
- Citations not present in the approved ticket context are removed and flagged.
- Generated text is always marked for review; this slice has no send endpoint.
- The live provider uses a privacy-preserving safety identifier and disables API response storage.
The demo request headers are not production authentication. The next milestone
replaces them with verified session claims. See SECURITY.md.
The repository intentionally distinguishes shipped behavior from designed behavior. Planned milestones include PostgreSQL persistence and row-level security, Redis-backed queues and rate limits, document ingestion and retrieval, evaluation datasets, audit events, OpenTelemetry, and cloud infrastructure.
See docs/roadmap.md for acceptance criteria and the
operations runbook for current incident procedures.
Licensed under the MIT License.