# How PROSPÆRO works

# How PROSPÆRO works

Edward built PROSPÆRO, the interview agent on edwardtadros.com, as a working example of how he ships agents: hybrid retrieval over a curated record of about fifty documents, a strict JSON output contract validated before anything renders, fail-closed guards on every write path, and a feedback loop that turns his reviewed answers into retrievable exemplars.

## Request path

1. The site is a single Cloudflare Worker with static assets. A question arrives from the page (`/api/compile`, streamed), from the public REST API (`/api/v1/ask`), from the hosted MCP server, or over A2A.
2. Retrieval: the knowledge base is about fifty markdown documents compiled at build time into a bundle with per-document embeddings (OpenAI text-embedding-3-small). At request time the query is embedded and scored against the documents in hybrid mode (vector similarity plus TF-IDF lexical scoring); if the embedding call fails the worker falls back to lexical only. Retrieval is tier-aware: anonymous callers and agents see public documents; verified visitors (work email plus code, or an invite link) see the private interview tier.
3. Exemplars: approved answers Edward has reviewed are retrieved the same way from a D1 table and passed to the model as examples; rejected answers are passed as warnings.
4. Generation: the system prompt (voice, interview rules, guardrails) plus a JSON request (question, retrieved knowledge, recent conversation history, examples) goes to the configured model through Cloudflare AI Gateway. Default text model is xAI Grok 4.6; Anthropic Sonnet is selectable; images come from xAI's image model; Haiku handles moderation and enrichment side tasks.
5. Validation: the model must return a JSON ModelOutput (coverage, reply, panel spec, optional follow-up) that validates against a JSON Schema and a set of design rules; SVG figures are sanitized against an allowlist. Invalid output triggers a repair pass, then a scripted fallback built from the retrieved text, so the page never renders unvalidated model output.
6. Coverage: the model reports answered / partial / none; a server-side backstop downgrades answers that admit the record is missing something, and the UI offers to send that question to Edward.

## What fails closed

Every write path is gated: contact and verification behind Turnstile and rate limits, owner tools behind a bearer token, generated images behind a per-session budget. Questions and answers are logged to D1 with coverage and rating; there is no inbound email processing and no automated action taken on Edward's behalf.

## Evaluation and testing

The repo carries about 550 vitest tests: contract validation, retrieval golden cases (interview questions that must surface specific documents in the top three), tier isolation (private documents never leak to anonymous callers), OAuth and MCP conformance, scrub tests that fail if an email or phone number appears in public copy, and exemplar regression fixtures. Deploys run the suite first.

## Agent interoperability

The site publishes llms.txt, an OpenAPI 3.1 description, an MCP server card, an A2A agent card, DNS-AID records with DNSSEC, and OAuth 2.1 with dynamic client registration and PKCE, so other agents can register, authenticate, and ask the dossier the same way a person does.
