How this was built.
How I built this site with Claude Code, and what it taught me about loop engineering.
The market has shifted.
Two shifts are happening at once. Senior roles are compressing, with flatter orgs expecting senior people to build, not delegate. And hiring has changed: a portfolio that shows the work now carries more than a résumé that lists it.
So I built one.
Two reasons. The first was to get hands-on with Claude Code and find out what "loop engineering" actually means by experimenting, not by reading about it. The second was simpler: proof that shows instead of tells. The site is what fell out. A real portfolio, six pages of hand-written HTML and CSS I directed but didn't type line by line.
Here's how it came together, piece by piece.
The code was the easy part.
I treated it like a product problem. Before writing any code, I got clear on the purpose and who would read it. The plan came first; the code followed.
Then I worked like an editor, not a coder. I'd give Claude Code the goal, it would draft a few versions, and I'd choose: keep this, cut that, say it sharper. It could build anything I described. The strategy was knowing what was worth keeping, and that judgment is the part that doesn't automate.
The process, step by step.
-
Study before building.
I spent the first session looking at a handful of sites I admired: a minimal academic page, a content-deep personal bio, a productized advisory page, a warm low-friction CTA. For each one I worked out what I liked, what I didn't, and what would be my own. That set the direction and saved weeks of wandering toward a generic portfolio.
-
Build one simple system.
Six pages on a single look: plain HTML and CSS, dark background, one color family (no bright accent, so it wouldn't clash with the AI brands I work around), one serif and one sans. Instead of reaching for a framework, I built my own lightweight system: shared styles, a few reusable patterns, no build step to slow it down. It keeps the site easy to change, and the restraint is a quiet statement of taste in itself. I experimented with colors and fonts before landing on what felt uniquely me, and I'll put the code on GitHub once the site is exactly where I want it.
-
Set up a memory file.
Once I had decisions worth keeping, I put them in a memory file the model read first: the locked choices, the rules, the options I'd rejected. It turned every new session from starting over into picking up where I left off.
-
Cut, and find the loop.
This step was the real evaluation. Every round, I judged every page and every paragraph against the same questions: does this earn its place, does it sound like me, does it carry the message I want, and can someone else learn from it? Across twenty-plus passes, most decisions removed something. A timeline block, a "My approach" section, a separate "My Story" page, a keyword chip cloud, a bright accent color. All cut. The site got smaller and sharper, not bigger. Partway through, the real lesson clicked: it wasn't any single cut. I kept running the same cycle every time, and learning to see that and reuse it is loop engineering.
-
Build an eval framework.
To know when it was actually done, I stopped going on instinct and built an eval framework. An eval, borrowed from AI, is a test of whether an output is good. I treated it like test-driven development, where the test comes before the code: I wrote down what "good" looked like first, then graded every change against it. The same checks every pass: does the positioning land in five seconds, is it written in my voice, do the claims hold up, and does it hold together across browsers and surfaces, from phone to laptop. I ran those checks from three angles: a recruiter skimming, a builder judging the craft, and a skeptic asking whether a person wrote it or a template.
What I chose, what else was on the table, and why.
The steps above are the pattern. These are the specific calls behind the site and the demo, with the option I passed on and what each one cost.
The voice on the walkthrough: Gemini, after ElevenLabs ran out.
Apple’s built-in voice is free and one command, and it sounded like a machine reading. ElevenLabs read the script well enough to ship, so the first cut used it, and then its free tier ran out halfway through a rebuild. Gemini’s voice API finished the job for a few cents on prepaid credit, and I moved both videos onto it so they match. Changing provider was one flag, because the narration, the frames and the assembly are a script rather than a file somebody exported. The build caches each scene’s audio by number, which is the trap: edit the words of a scene and you have to delete its clip, or the old voice line is silently reused.
Hosting the site: Netlify, by dragging a folder.
Plain HTML and CSS with no build step, so the deploy is a folder drop, the same flow I already used for another project. GitHub Pages and Vercel would have done the same job. The security headers are a text file in the folder. Free; the discipline is remembering to drag after every change.
Hosting the demo: Render, one container.
The Node server, the built client, and the Python search run in one Docker image. Two services or a serverless split would have been the tidier diagram. One container because the demo has to wake as a unit, and a free tier keeps one thing warm. The cost is the wake-up: the first visit after a quiet spell can take up to a minute, and the page says so.
The code: a separate public repository with nothing else in it.
The workspace where this was built holds other work and keys next to the demo. The public repository is a clean copy, synced by two commands: demo code only, no keys, and the Drive sync manifest replaced by a pseudonymized one. One extra step after every change, and it is the copy technical readers open, so it carries a page per use case too.
The model behind the agents: Claude, with an offline planner beside it.
The tool-use loop runs on Claude. The same tools and the same gates also run on a fixed-order planner with no network. That is what lets the eval suite run deterministic and free on every change, lets the public demo run without a key, and turns a failed model call into a fallback instead of a failed turn. About 13 cents per vacation-planning turn on the model; nothing on the planner.
Identity: a real Google Drive folder over MCP, instead of a mock.
A mock folder with invented grants would have been a day faster. Instead the ten policies live in a real Drive folder shared with real accounts, read through a connector, with a check that no account retrieves what Drive did not grant. The cost is a manifest of real addresses that must never reach the public copy, so the deploy replaces it with pseudonyms and the site shows labels.
The builder: Claude Code, with a memory file.
Covered in the steps above. The memory file holds the locked choices, the rules, and the options I rejected, so every session starts where the last one stopped instead of from zero.
It sounds harder than it is.
Read enough about AI and the jargon makes it sound hard. Applied to one real problem, the ideas are plain. The problem you're solving stays the same. What changes is how you solve it, and that's a whole new way of working.
Three things made it repeatable:
-
A prompt runs once. A memory file compounds.
Prompts don't repeat and they don't learn. The fix is a memory file: a .md doc where I log every decision and rejected option, read first each session. Over time the model stops re-suggesting what I've already cut. It learns, and the work becomes reusable instead of restarting.
-
One prompt is a one-off. The loop is the process you repeat.
One perfect prompt won't get you there. What works is spotting the steps you do every time (study, draft, cut, check) and turning them into a loop you run on purpose. It's an old programming idea, the for-loop: write the steps once, then run them from one to n. The output comes from running the loop, not from nailing a single prompt. I ran this one by hand. Wire the same cycle to run itself and it becomes an autonomous loop, the human stepped out. That's the next layer up, and where I'm headed.
-
An eval framework keeps repeatable from meaning mediocre.
A written bar for what "good" means, graded every pass, is how I knew when to stop instead of trusting instinct. Without it, you just repeat the same misses faster.
Doing it sharpened the read I started with. Flat orgs don't need more people who can describe a build or hand it off. They need people who can run the loop and own the judgment calls. That's a different job than most senior titles were written for, and I'd rather show I can do it than say I understand it.
How to build this yourself.
Enough to run it yourself, in five steps. Each one wires up a part of the loop. The prompts teach it; your references and your taste make the site your own.
-
Study references before you build.
Pick four to six things you admire. Work out what you like, what you don't, and what would be uniquely yours. It sets the direction and saves weeks of drift.
PromptHere are five sites I admire: [URLs]. For each, tell me the one structural or voice decision worth learning from, and the one thing that wouldn't fit my context as a [your role].
-
Build the simplest version.
Tell the model the goal, let it draft a few versions, and you choose. Plain and minimal beats clever. The bottleneck is taste, not code.
PromptBuild the simplest working version of a personal site that showcases me and my work. Plain and minimal, no framework. Give me two or three options for the layout, with the tradeoffs, and I'll choose.
-
Set up a memory file.
Once you've made a few calls worth keeping, put them in one doc the model reads first: your locked decisions, rules, and rejected options. It's what makes sessions compound instead of restart.
PromptKeep a file called memory.md. Each time we lock a decision or reject an option, append it with the reasoning. Read it at the start of every session before you suggest anything.
-
Cut, and find the loop.
Treat "remove it" as the strong move. Make the model justify anything it wants to add. After a few rounds, you'll notice you're running the same cycle. That's your loop.
PromptReview this page and tell me what to cut. For each, explain why it doesn't earn its place. Don't suggest anything to add.
-
Build an eval framework.
Stop shipping on instinct. Write down what "good" means, then grade every version against it: does it sound like you, do the claims hold, does it work on every browser and screen. You stop when it passes the bar, not when you run out of energy.
PromptHelp me turn this into an eval. List the checks that decide whether the page is good (voice, clarity, truthful claims, responsive across browsers and screens), grade the current version against each, and tell me what fails.
The building blocks.
If the terms are new, here they are in plain language. Wired together, they make the loop:
Worth your time.
-
Boris Cherny: "I have loops prompting Claude."
Claude Code's creator on the shift from prompting to building loops. (CNBC.)
-
Building Effective Agents
Anthropic. The loop, defined: a model that uses tools on feedback, over and over.
-
Demystifying evals for AI agents
Anthropic. How to know whether an output is actually good.
Chapter 05. The four use cases it hosts start with Ask: policy search →