case study

An AI-native portfolio on self-hosted infrastructure

The problem

A static resume cannot show how I frame, govern, and operate AI systems. It lists claims and leaves the reader to trust them. I wanted a portfolio a reviewer could interrogate directly, with the system itself as the evidence.

What I built

This site. The primary interface is an AI chat grounded in a curated profile corpus through retrieval-augmented generation (RAG), the pattern where a model answers from retrieved source material instead of from memory. The corpus lives in Qdrant, a vector database. Answers come from a local model served by Ollama on my own hardware, so no visitor question leaves the lab for a hosted AI provider.

The rest of the stack is self-hosted too: single sign-on through Authentik, per-host TLS through a Caddy reverse proxy, and a live telemetry strip on the homepage fed by the same lab the site runs on. The site also exposes a Model Context Protocol (MCP) endpoint, so a visitor can connect their own AI agent and interrogate the portfolio from their side of the table.

The trust boundary

A public chat backed by a small local model is a prompt-injection target, so the design treats every render path as public. Three defenses run in series:

  • Deterministic input screening runs before any model call. It classifies a question as on topic, off topic, or an injection attempt without a model in the loop, so the classifier itself cannot be prompted.
  • Content is tiered. The foundation document is private tier by default, and public rendering passes through a central redaction denylist that replaces protected client and employer names with generic equivalents.
  • Model output is scrubbed on the way out. A streaming egress filter holds back enough of the stream to guarantee a protected name can never be emitted, even when a visitor plants that name inside their own question hoping the model will repeat it.

Why self-hosted

I could have stood this up on a hosted app platform in an afternoon. Hosting it on someone else's stack would undercut the point. The site is the portfolio: the identity provider, the proxy, the vector store, the model runtime, and the MCP server are the same systems the chat describes, and a visitor is using them rather than reading about them.

Limits

The chat answers from the curated corpus and declines the rest. Questions are logged server-side for quality and abuse review. The model is a small local one, chosen on purpose; operating well within its limits is part of the demonstration.