← All writing
·4 min read

Building this portfolio

Why the site ships with the same process I'd bring to a client engagement — PRD, ADRs, ROADMAP, process-gate, agent-readiness, the whole thing in the open.

A portfolio is supposed to show the work. The trouble is that showing the work usually means showing the surface: the typography, the case studies, the tagline. The decisions underneath are what matter, and they don't fit in a screenshot.

So this one is built differently. Same process I'd use on a paid client engagement, left in public view, every decision and trade-off legible to anyone who reads the repo.

The receipts

Why this way

I'm writing for two readers.

The MSME owner I might work with on Neev wants clarity. Can this person explain what they've built? Will it survive contact with the day? The home page and the case studies answer that, in plain English, with honest scope on what worked and what didn't.

The senior engineer I might work with on a platform team wants rigour. How do they handle change? How do they treat deprecations? Are they the kind of person who ships and forgets, or the kind who leaves a trail? The repo answers that.

Both readers can get what they came for without the other's material getting in the way. The portfolio is the entry point; everything under docs/ is the depth behind it.

The parts that were load-bearing

Next.js 16 over SvelteKit (ADR-0001). The Next + Turbopack + R3F ecosystem is where the Vercel-adjacent toolchain lives, and the Phase-4 agent-readiness work needed Route Handlers and middleware at the shape Next provides. SvelteKit is a fine framework. This wasn't the site for it.

Process-gate as pre-commit (ADR-0002). Three rules: code needs a CHANGELOG entry, structural changes need an ADR, epic-scale changes need a ROADMAP update. A shell script on simple-git-hooks enforces them. Cheap to write, load-bearing against drift.

MDX with server-only compilation and Shiki bundle isolation (ADR-0004). next-mdx-remote@6 compiles MDX inside React Server Components; Shiki never reaches the client bundle. pnpm analyze re-verifies the isolation every PR.

Content negotiation, Pattern A and Pattern B (ADR-0006). Every page has a .md alternate at /page.md (Pattern B, load-bearing) and responds to Accept: text/markdown at the canonical URL (Pattern A, additive). Passes isitagentready.com's content-negotiation check on both axes — and loses neither if one misbehaves.

The Wanderer crane port (slice 5.1c). 221 lines of vanilla Three.js in the reference design, ported directly into a useEffect-driven scene rather than R3F: the crane is a fixed-position full-document scene driven by document scroll, and wrapping that through R3F primitives reads worse than the direct port. Eight named POSES, IntersectionObserver-driven pose dispatch, damp lerp, scroll-velocity rotation, wing flap, pointer parallax. Bail-out to SVG fallback if the first frame takes more than 80 ms.

What's still to do

Launch isn't done. It's done enough to ship. The open follow-ups live in docs/ROADMAP.md — the honest list, with items like "tighten the JS bundle back toward 150 KiB once the bundle-analyzer audit identifies which preloaded chunk is blowing past the target," "write a real /api/docs page," and "run the isitagentready.com scan against prod and persist the screenshot to docs/agent-readiness-snapshots/."

None of those are in the "shouldn't launch without this" pile. They're the work that comes after launch, which is where most real engagements live anyway.

If any of this looks useful

Every file I've referenced is in the public repo. Clone it, read it, take what's useful. If you're starting a portfolio or a product and want the same process on it: [email protected].