Colophon
How this site works
A personal site, a directory of my projects, and a way to look more closely at the engineering behind them.
Architecture
This site, as a system
Pages come from a typed catalog. Ask and Contact are the only two ways out to a provider, and each is closed unless the server is configured to open it.
Select a part to see what it is responsible for and what it connects to.
Every part and connection, as text
- Browser Interface
Receives server-rendered HTML that reads without JavaScript. Hydration adds Ask, filters, the product theatre and these diagrams.
→ TanStack Start: page and server-function requests
- TanStack Start Service
Renders every route on the server, on Vercel, and checks the origin of every server-function call.
→ Content catalog: typed content
→ Ask boundary: a question and its scope
→ Contact boundary: a message
- GitHub External
Public repository data for /code, cached for an hour, with a build-time index as the fallback.
→ TanStack Start: public repository data
- Content catalog Data
Typed JSON validated with zod: projects, media, journeys and system flows. No page holds a fact of its own.
→ Retrieval corpus: indexed at deploy
- Ask boundary Gate
Answers with retrieved passages and their citations. A generated answer needs an explicit server switch; a provider key alone is not enough.
Trade-off: Quoted passages read less smoothly than a written answer, and cost nothing.
→ Retrieval: scoped search
→ Optional providers: only when generation is switched on (Authority boundary)
- Contact boundary Gate
Sends server email only when delivery and a challenge are both configured. Otherwise it opens an email draft and sends nothing.
→ Optional providers: only when delivery and challenge are configured (Authority boundary)
- Retrieval corpus Data
Built at deploy time from the content layer and the public source notes. It stays on the server; a check fails the build if it reaches a browser file.
Trade-off: A content change reaches Ask only with the next deploy.
→ Retrieval: passages
- Retrieval Service
BM25 keyword ranking in memory, scoped to one project when asked from its page. Vector ranking joins only when embeddings are switched on.
Trade-off: No database: a loop over a few hundred passages instead of a network hop and a bill.
- Optional providers External
A model, an email service and a challenge service. Each is unused unless configured.
Current modes
- Ask: retrieved passages, quoted with citations
- Contact: opens an email draft, sends nothing
Content with a source
The current project directory comes from a typed catalog. Each project has a dated source review, a clear stage and a longer technical dossier. A feature in a repository is not automatically a released feature, so those are separate claims.
Older engineering notes remain available at their original addresses. They are labeled as historical and cannot override a current project answer in Ask. Private code, personal app data and client-confidential material are not part of the public knowledge base.
Ask, without a database
Ask searches a small corpus assembled at build time. Keyword matching uses BM25. When embeddings are configured, a second ranking uses cosine similarity and the rankings are combined with reciprocal rank fusion. The corpus stays on the server rather than becoming part of the browser download.
A project question searches that project's sources. With no model provider, the endpoint returns retrieved excerpts with citations. Generated answers must finish and provide valid source references before they are shown. These checks do not prove every paraphrase is correct; the sources remain available for inspection.
Type and movement
Fraunces is the display face; Geist is the reading and interface face. Geist Mono is used sparingly for dates and technical labels. Warm paper and charcoal carry the layout, with restrained project colors. Light is the default and a saved theme preference wins.
Motion is used for transitions and small interaction cues, not to take over scrolling. Reduced-motion preferences remove movement. The introduction and project content remain visible without JavaScript.
Actual screens, with context
Project images come from rendered application screens. Preview and fixture captures are labeled rather than presented as evidence of a public release or real customer results. Images are cropped and resized without changing their contents, and a media manifest records each one's source, dimensions and checksum.
A project without a suitable public screenshot uses its real description and engineering details. There is no invented dashboard, synthetic activity chart or decorative success metric to fill the space.
The parts behind the page
The application uses TanStack Start, React, TypeScript, Vite and Tailwind. Server functions handle contact delivery, and the Ask endpoint has a separate streaming request boundary. There is no application database.
The repository contains content and request-contract tests, retrieval checks, a client-bundle guard and a browser verification script. A successful website test does not certify every application shown here. Review dates and the individual project limitations matter.
The same standard as everything else here
Nothing on this page is a claim you have to take on trust. The retrieval corpus, the two verify commands, the token system and every figure above are in the repository index, and the ask box will quote the relevant passage back at you with a citation if you ask it.