James CarlsonDraft · unlisted

comment with a stable id. - Do not rename ids; a later page build maps id -> component. - marks a blank only James can fill. - marks a claim that must be checked before sending. - marks a section awaiting the prototype build. ============================================================ -->

Deciding What to Build

A decision log for the MangoVoice product challenge — James Carlson, August 2026

Written while the work was still happening. The outcome is open, some of these decisions are probably wrong, and the parts I don't know yet are marked as unknown rather than smoothed over.1



1. The assignment

I came into this process sideways — as a reference for someone else's application, not as a candidate.2

Alicia's prompt, verbatim:

Identify a problem that interests you in any domain and use AI to take it from idea to a working prototype. Assume someone other than you will use it. Please send me what you built and describe your process by EOD Thursday.

I also carried three things she said in our conversation, and treated them as constraints on the answer rather than as pleasantries:

  1. Product is about solving the right problem, not just the solution.
  2. Involving developers early matters.
  3. Not building anything is sometimes better than building something.

The third one is the hardest to honor in a challenge whose deliverable is a thing you built. I've tried to honor it anyway, and section 4 is where that gets uncomfortable.


2. Deciding what to build

The constraint that shaped everything: I started a two-week work trial at another company on Monday morning. It's capped at fifteen hours a week, I'm in the final round there, and I wasn't willing to shortchange it. So the real question wasn't "what's the best possible thing to build." It was "what's the best thing I can build in the hours that are actually left."

That pushed hard against one obvious option: build something new and disposable purely to demonstrate the process. Throwaway builds are legitimate — you build to learn, then you throw it away, and the learning was the point. But that's the right move when the thing you need is knowledge. What I needed was a working prototype someone else could use, and I already had a list of ideas that had never gotten past the idea stage because I could never find the time.

So I inverted it. Rather than invent a problem for the challenge, I screened the problems I already had against Alicia's prompt: does it interest me, is it real, can AI take it from idea to working prototype, and can somebody other than me actually use the result.

IdeaProblem is real to meUsable by someone else in daysBlocked on anythingVerdict
LatestfileYes — felt it directlyYes — spec and schema already existNoSelected
Diamonds in the RoughYes — my own layoffNo — too earlyEntangled with a live co-founder conversationRejected
Lendio AI-usage pilotYesYesI no longer work thereRejected

The one that had gone furthest was Latestfile.

I bought the domain latest.dev back in . I have wanted to make it into something ever since and never had the runway to do it. What changed is that AI collapsed the cost of the work — a spec, a schema, reference implementations, and a site are no longer a season of evenings. That's not incidental to this challenge; it's the same shift the challenge is asking me to demonstrate.


3. Why Latestfile

Everyone is talking about AI, and almost everyone is talking past each other.

Ask ten engineers at the same company how they use AI and you get ten different answers, none of them written down anywhere you can find. One lives in Cursor with autocomplete on and privacy mode off. One drives Claude Code through a wall of custom instructions. One pastes into a chat window and copies back. One routes through a personal API key nobody in security has heard of. Multiply that across teams and you get the question every leader is now asking and nobody can answer: how do we actually use AI here?

It matters more than it sounds, because the performance swings are enormous and they hinge on small things. Which model. Which harness. Whether someone wrote good instructions. Two engineers with the same license and the same task can be an order of magnitude apart, and the difference lives in configuration nobody has written down.

Latestfile is the proposal that this be declarable — with the specificity of code. A small, readable, version-controlled file that states how a person, team, or organization uses AI: tools, models, workflows, instructions. It composes: a personal file rolls up into a team's, a team's into the org's. package.json for AI usage. Descriptive, not prescriptive — it captures what's in use, not what's allowed.

We've made this move before, repeatedly. Untracked dependencies became package.json. Hand-clicked infrastructure became Terraform. Crawler guesswork became robots.txt. Doc ingestion became llms.txt. None of them are clever. They're all the same move: take a practice living in people's heads and give it a small portable file that travels, diffs, and composes.

Honest scorecard on the idea when I picked it back up:

I chose not to spend this week's hours on demand interviews. That's a real trade and I want to be explicit about it rather than let it pass — section 5.

The tooling: Claude Code, plus gstack and gbrain — an open-source suite of Claude Code skills written by Garry Tan, President and CEO of Y Combinator. Among other things, it runs a YC-style office-hours critique against your own idea. That is what pushed the spec harder than I would have pushed it alone, and it is where the initial launch plan came from.

Worth naming what that means about the process: the sharpest early pressure on this idea came from a tool, not a person. That is not a substitute for talking to users — see section 5, where it is precisely the thing I still haven't done — but it is a real change in what one person can subject their own thinking to before showing it to anyone.


4. The gap, and the layoff

Here is the part that doesn't flatter me.

May 15, 2026. I wrote the first Latestfile spec design document.

May 15–23. I finished v0.1: RFC 2119 normative language, four scopes, a JSON Schema, four reference Latestfiles covering personal, team, org and project, all schema-validated. I ran adversarial reviews against my own spec and revised twice.

May 23 – July 28. Nothing. Two months of silence.

July 28. Two things converged: my employer said publicly that it wanted to understand how AI was actually being used in order to set policy, and the broader "we're not getting the ROI from AI" complaint was everywhere. That was the moment. In one night I wrote the manifesto and built the landing site.

July 28 – August 19. Nothing again. Never deployed. Never shown to a single person.

August 12. The RIF.

So the honest accounting is: fourteen weeks, a finished specification, a JSON Schema, four reference implementations, a manifesto, and a landing page — and zero external validation. Not a soft launch that underperformed. Nobody had ever seen it.

Alicia's third insight was that not building anything is sometimes better than building something. I had spent fourteen weeks building on an assumption I never tested. I'm not going to pretend the challenge is what taught me that. What the challenge did was create the forcing function I hadn't created for myself, and that is its own uncomfortable finding: I needed an external deadline to do the thing I already knew I should do.


5. The riskiest assumption

Stated plainly: I don't know whether anyone but me wants this.

Everything else is comparatively safe. I know the format works — it's specified and schema-validated. I know I can build it — the site exists. I know the pain is real for at least one person, because I'm the one.

What I don't know is whether it's real for anyone else, and every hour I spend on polish before answering that is an hour spent on a possibly-worthless asset.

There were two ways to test it in the hours available:

Talk to people. More rigorous. Better information. Also slow, and in this window it would have consumed the entire budget and produced a report rather than a prototype — which is not what was asked for.

Ship it and watch. Faster, noisier, and it produces the artifact the prompt actually calls for. A working prototype is itself a demand instrument: it either draws signal or it doesn't, and either answer is more than I have now.

I chose to ship. What I'm giving up by choosing it: a null result is ambiguous. If nobody engages, I won't know whether the idea is wrong or the distribution was. I'm accepting that ambiguity because the alternative was to arrive at Thursday with a well-researched opinion and nothing anyone can use.

The standard name for this is a riskiest-assumption test. I want to be straight that the name came after the decision, not before it. I didn't consult a framework; I made a call under time pressure and the framework is a decent description of its shape.


6. What I built, and what I cut

For a reader who doesn't care about the internals: it's a website where you answer a few questions about how you use AI, and it hands you back a file describing it plus a public page at latest.dev/@yourname you can send to someone. No account, no login, about two minutes.

Three things exist:

Underneath: roughly 2,600 lines, of which the interesting part is an HCL lexer and parser written from scratch, a 700-line validator, and a small storage layer.

The cuts, and why

No login, no accounts. The single most important cut. The moment a prototype has signup, the thing you learn is how many people will create an account, which is a different and much worse question than whether anyone wants the format. Claiming a handle returns a one-time edit token instead. It's weaker security than a password and it is the right trade at this stage: the cost of being wrong about the format is that I wasted fourteen weeks, and the cost of being wrong about auth is that somebody has to re-claim a handle.

No database. Storage is a key-value store, because the data model is a dictionary: every read is "here's a handle, give me the record." No queries, no joins, no aggregation. Adding Postgres would have bought a SELECT ... WHERE slug = $1 that does what GET profile:acme already does, in exchange for provisioning, migrations, and a connection pool. The threshold where that flips is specific and I want it on the record: the moment I want to ask questions across profiles — which tools are most declared, how do teams differ — I need a query engine, and that's exactly the analysis layer the spec names as a downstream use. It's the second version, not this one.

Deferred: the composition demo. Latestfile's most interesting claim is that files compose — personal rolls up into team, team into org. It's specified, and it is not demonstrated in the prototype. That's the biggest honest gap in what I'm shipping. I cut it because the composition demo only means something once individual files exist, and nobody has written one yet.

Where the judgment was mine

The prompt is about using AI to get from idea to prototype, so it's worth being precise about where the model drove and where I did.

The model drove: the parser and lexer, the validator's structure, the route scaffolding, most of the CSS. I did not hand-write an HCL tokenizer, and I would not have finished this week if I had.

I drove these:

Validation runs in the browser, and nothing is uploaded. This is why the parser is hand-written rather than pulled from a package — the real HCL parsers are server-side or ship a wasm payload. The requirement came first and the implementation followed from it. A file describing your company's AI tooling is not a thing people should have to POST to a stranger's server to check.

Unknown blocks and unknown fields are warnings, not errors. The spec requires parsers to tolerate what they don't recognize, so that old tools don't break on new files. A validator that rejects anything unfamiliar would be more "correct" and would quietly sabotage the format's ability to evolve. That's a product decision expressed as an error severity.

You get every validation error at once. Parse errors stop at the first one, because after a syntax error the parser doesn't know what it's looking at. Validation errors are collected in full, so you fix everything in one pass instead of playing whack-a-mole with a form that reveals one problem at a time.

I rewrote the manifesto in my own voice. It was AI-drafted in July and I never finished making it mine. I spent a meaningful share of today's remaining hours on that rather than on features. The argument only works if it sounds like a person making it, and a manifesto in a model's voice asking people to adopt a standard is self-defeating.

I stopped myself from launch-planning too early. Partway through I started sketching the Hacker News and LinkedIn sequence, then asked whether that was premature and decided it was. Finish the thing, then sequence the launch.


7. How I worked

Two AI sessions running in parallel, deliberately separated.

One session built the product. A second session — this one — wrote the record. They were pointed at different repositories and never shared a context window.

The separation was the point. A single session writing both would have been marking its own homework: the same context that made a decision would be narrating why the decision was good, from memory, with every incentive to make the story tidy. Instead the record session reads the build session's git history and transcripts as primary sources. When I claim something happened, it's because there's a commit or a message showing it, not because I remembered it that way. Several details in this document came back at me from that reading in a form I would not have chosen — the fourteen-week gap in section 4 being the obvious one.

The handoff between sessions is written, not live. Trying to keep two AI contexts in sync in real time is a losing game; a checkpoint file that either session can read is not.

Where it broke. Partway through I lost track of which repository I was drafting the manifesto in, and spent a stretch reviewing a stale copy while the current one sat elsewhere. That's a real cost of splitting the work across sessions and I'd rather name it than present the method as frictionless. The fix was boring — check which repo you're in before you trust what you're reading — but the failure mode is worth knowing about if you're going to work this way.


8. What would make me kill it


9. Decision log

D0 — Write this as a decision log, not a case study

D1 — Use a domain I know cold, not a MangoVoice problem

D2 — Latestfile over Diamonds in the Rough

D3 — Kill the Lendio pilot angle entirely

D4 — Ship rather than interview

D5 — No login, no accounts

D6 — Validate in the browser; write the parser by hand

D7 — Key-value store, no database

D8 — Unknown blocks are warnings, not errors

D9 — Rewrite the manifesto in my own voice

D10 — Defer launch sequencing until the build was done


10. What someone else can do with it


Colophon

Built with Claude Code. This document was drafted in a separate session from the prototype, deliberately, so that the record of the process wasn't being written by the same context that was making the decisions.

Footnotes

  1. I considered writing this as a case study and decided against it. A case study is written after the fact with the outcome already known, which is why case studies never contain a decision the author got wrong. The product here isn't finished, so a case study would have to invent an ending or hide the absence of one. See D0.

  2. Danielle, a PM at Lendio, asked me to be a reference for a job she was pursuing at a company called MangoVoice. I said yes, and spent a call with Alicia Cawley talking about Danielle's work. Danielle got the offer and took it. Lendio counter-offered and kept her.

    That could have been the end of it. Instead I kept sending Alicia names — people I thought were good who might be a fit. My brain works that way; connecting people is something I do reflexively whether or not there's anything in it for me.

    On August 12th, Lendio ran a reduction in force and I was impacted. My first instinct was still to send Alicia more names, since a lot of good people had just become available at once. Somewhere in the middle of writing that message it occurred to me that I could throw my hat in the ring myself.

    Alicia offered to meet. I rewrote my resume as a product management resume rather than an engineering one — — and we talked on . She moved me to the next round.