← Back to assistant

ResumeIQ

Architecture

ResumeIQ is a retrieval-grounded AI app built by Peter Doucette. It turns approved professional materials into contextual answers and keeps those answers inside disclosure rules so unsupported claims do not slip through. Ask about Peter's background, projects, skills, or career path, or ask how ResumeIQ itself was built, tested, and deployed.

Stack: Next.js · TypeScript · Vercel AI SDK · OpenRouter · structured retrieval · conversation-state · guardrails · automated evaluation

Purpose

Visitors chat against Peter's Public professional materials. Substantive answers come from Approved Claims in a structured knowledge corpus. If Public claims do not support a statement, the assistant says so or refuses.

Operating rules

  1. Retrieval-grounded answers only. Factual claims come from Approved Claims, not from model memory.
  2. Disclosure tiers. Only Public-approved content can appear in Visitor answers. Unclear approval fails closed.
  3. Professional scope first. General-knowledge and other off-topic asks are refused before generation. The assistant steers back to approved career experience, projects, skills, and qualifications.
  4. Evaluation before wider sharing. Automated grounding, refusal, scope, and retrieval checks must pass before the behavior is treated as ready to share more broadly.

System layout

Visitor messages hit the Next.js UI, then POST /api/chat. The turn processor runs guardrails, checks professional scope, retrieves Public Approved Claims, builds a grounding-constrained system prompt, and streams tokens through the Vercel AI SDK via OpenRouter.

Visitor request path
LayerResponsibility
UINext.js chat with optional opening chips, contextual follow-ups, and résumé / contact / architecture links. CRT theme is locked.
Chat APITurn orchestration: strategy, guardrails, professional-scope gates, retrieval, prompt composition, streaming generation, conversation-state headers
KnowledgeMarkdown under knowledge/ with disclosure frontmatter. Production uses metadata-aware lexical retrieval (CLAIM_RETRIEVAL_ADAPTER=stub). Hybrid embedding retrieval runs when an embedding API key is configured.
ModelOpenRouter via Vercel AI SDK for generation only. The model is never the source of biographical truth.
HardeningPrompt-injection resistance, professional-scope filtering, refusal precedence, payload size caps, best-effort IP rate limiting on chat endpoints

Request lifecycle

Each turn builds a turn strategy (intent, retrieval query shaping, response mode). Guardrails can stop prohibited, confidential, injection, or unsupported hire-score requests before retrieval. A professional-scope gate refuses clear general-knowledge asks when there is no in-scope intent or active topic thread. After retrieval, a relevance gate blocks weak unknown-intent hits so unrelated profile chunks cannot unlock model prior knowledge. When retrieval succeeds, an answer plan guides how evidence is woven into the reply. The system prompt binds audience mode, depth, covered claim ids, session summary, voice rules, and the retrieved Public claims block. Some modes run a lightweight grounding verifier and one repair rewrite when numeric claims drift from retrieved evidence.

Turn processing

Retrieval shapes the query from the visitor text, searches the Public corpus, can prefer a named project document, then applies novelty preferences so later turns favor unused evidence. Soft profile fallback is allowed only for in-scope exploration. Zero-hit off-topic queries return an empty claim set.

Retrieval selection

Knowledge

Professional materials live as structured Markdown with YAML frontmatter: document id, disclosure tier, confidence, audiences, competencies, and explicit non-claims. The loader builds a Public corpus for Visitors from profile, timeline, skills, projects, FAQ, and related Approved Sources. Retrieval can prefer a project document when the visitor names a known subject (for example ResumeIQ, DACI, or WedFlix). Media-production and institutional eras are both Public content the retriever can serve.

If Public claims do not support a statement, the assistant says the information is unavailable or refuses. Restricted and Confidential registers stay out of the Visitor retrieval path.

Disclosure gate

Conversation controls

Conversation state tracks active topic, used chunk ids, and asked follow-up keys so later turns avoid repeating the same evidence. Soft follow-up suggestions (at most two) appear under the latest reply when they deepen the current subject. Opening chips are optional examples: five high-level starters, including how ResumeIQ was built and what the job title does not capture. Visitors can ignore chips and type freely.

Conversation controls

Bounds and hardening

Guardrails enforce refusal precedence for prohibited topics, prompt injection, confidential material, and hire-score requests. Professional-scope filtering refuses general-knowledge and other off-topic asks and redirects Visitors to approved career materials. Chat payloads are size-capped; depth is forced server-side; generation uses a token budget. Rate limiting is best-effort per IP on chat endpoints.

Refusal precedence
Professional scope filter

Checking behavior

Quality is checked with an automated harness (npm run eval) covering privacy and refusal suites, injection cases, professional-scope cases, and retrieval-intelligence checks (subject prefer, novelty, answer-plan shape, verifier behavior, opener pool, ResumeIQ routing). Wider sharing expects zero Critical and zero Major failures on those suites.

Evaluation gate

Parts list

Next.js and TypeScript on Vercel; Vercel AI SDK for streaming chat; OpenRouter as the model provider; structured lexical retrieval over Markdown Approved Claims; conversation-state helpers; guardrails; professional-scope checker; automated evaluation. Hybrid embedding retrieval when an embedding API key is configured.

Ask the assistant about ResumeIQ →