DEV Community

Cover image for Building a One-Person Software Shop with Claude Code
Chauncey Wang
Chauncey Wang

Posted on

Building a One-Person Software Shop with Claude Code

I build a clinical-trial matching product alone — no cofounder, no team. Just one person, an AI coding agent, and a set of conventions that keep "vibes-based solo dev" from falling apart across weeks of parallel work.

The first version was a command-line tool, open-sourced. Turning it into a real web app — something a patient could open in a browser and trust with their situation — is the jump where a lot of solo projects quietly stall. I made it: today it's a live web app with ~30 drug pages, dozens of disease-specific trial landscapes, and a matcher real cancer patients use to find trials.

I'm also a cancer patient; I built this partly because I needed it to exist. So I care less about it being impressive than correct — a wrong trial match wastes a sick person's time. That constraint is the whole point: the interesting part isn't that an AI writes my code — it's the scaffolding that makes its work trustworthy when I'm not watching every keystroke.

A note on the tool first, then the transferable patterns — most of them scar tissue from something that broke once. Everything's sanitized — fake IPs, generic paths, invented tasks; the real secrets stay home. And the fake IPs aren't only for the article: the real task files never held a raw IP or email, and the server logs that hold IP addresses are purged within 14 days — matching the privacy policy.


Why Claude Code, specifically

People ask why Claude Code and not one of the other coding agents. Two reasons — one soft, one hard.

The soft one: it infers intent from less. I can hand it a terse, half-specified ask — "the ranking's off for first-line patients, dig into it" — and it usually fills the gaps the way I meant, not the way I literally typed. That matters when I'm running several sessions and can't write a full spec for each. Subjective, not a benchmark — but it's what keeps me reaching for it.

The hard one: my review workflow feeds real patient-submission data to the agent — I pull a patient's result set to check whether the matcher did right by them. ClinTrialFinder's privacy policy names Anthropic's Claude as a tool for exactly that — "quality-checking match results, diagnosing issues." Using Claude Code for the review keeps the implementation matched to what patients were told. Other disclosed vendors handle other steps; the point isn't that Claude is the only option — it's that the words I show patients and the tools I run stay in lockstep.


The core bet: your task tracker is a git repo

Most people reach for Jira, Linear, Notion. I keep every task as a plain file in a git repo of its own:

project-manager/            # a git repo
  tasks/
    412-fix-ranking-edge-case.html
    413-wizard-validation.html
    414-review-user-submission.html
Enter fullscreen mode Exit fullscreen mode

One task file, rendered — fixed shape, plain HTML in git. (Sanitized example.)

One file per task, fixed shape — priority, status, the problem, the fix, verification plan, links to related tasks. No API, no board, no login. Just files in git — 500+ of them now, and the flat directory has never needed anything fancier.

Why this beats a tracker for an AI-assisted solo shop specifically:

  • Version-controlled. The backlog is plain files in git — every status flip and edit is a diff you can read, branch, or revert, exactly like source. It's a history you own and grep, not rows in someone else's database.
  • Queryable with the tools the agent already has. "Next free task number?" is ls | sort. "Which tasks touch the ranking bug?" is grep -rl. No integration — just grep.
  • Linkable and self-documenting. Tasks cross-link; six weeks later the why is one click away, written at the time, not reconstructed from memory.

The insight: when your teammate is an AI agent, your project management should be a git repo of plain files it can grep — not a SaaS it has to poke through an API. (I use HTML for the files — renders and links nicely — but the format is the least interesting part; Markdown would do.)

One file sits on top of that flat directory: a single overview — a hand-maintained index that splits the backlog into the full list and the sprint (what to actually work on now). The task files are the atomic units; the overview is the priority view.

And two kinds of judgment get their own role. Worker sessions append tasks freely as they surface — a bug found mid-fix, a spinoff from a review — but none of them promotes itself into the sprint. That call belongs to a dedicated "CEO" session: a Claude Code session that reads the backlog, decides what's worth doing now (via its own update-active-sprint skill), and proposes the forward-looking work the workers won't file on their own — new features, UI refinements, the product's next move. Reactive filing is mechanical and belongs to whoever hit the problem; setting direction — both prioritizing and proposing — is judgment, so I concentrate it in one named role instead of smearing it across four sessions that each think their task is the important one.

The overview — the CEO-promoted Active Sprint on top, the full backlog below. (Sanitized example.)


Parallelism — four sessions, each a standing role

Here's where it gets honest. I often run four Claude Code sessions at once, against a shared backlog and shared repos — but they're not four workers chewing through the same queue. Each holds a standing role: a CEO that prioritizes and proposes new work, an SEO/content session that also watches the traffic and files a review task whenever a patient submits, and two full-stack engineers working different tasks in parallel. And full-stack undersells it — one engineer session will write HTML and CSS, write the Python behind it, review a real patient submission and file the fix tasks its defects reveal, and rewrite a matching prompt, all in one afternoon; a single context spans what used to be four specialties.

That engineer session also writes as it works — logging its findings and progress back onto the task file, so the task becomes a running record of what was tried and learned, not a write-once spec. That record earns its keep: when a mid-work diagnostic disproves the task's own premise — the "bug" was correct behavior, the evidence was confounded — the CEO reads the update and demotes the task back to the backlog instead of shipping it. The sprint self-corrects.

And these sessions don't close when a task is done — each stays open and picks up the next thing in its lane, so it accumulates context instead of starting cold each time. A big multiplier for one person — the nearest thing to a team I've got.

They all run from the same home directory — one shared filesystem, not four sandboxes. That's mostly the point: the SEO session opens the analytics export I just downloaded to ~/Downloads, any session can reach any repo in the tree, and nobody has to shuttle files between isolated boxes.

The one place that sharing bites is the two engineers — point both at the same working tree and they'll clobber each other, one's half-finished edit sitting there when the other runs its tests. So each works in its own git worktree: a separate checkout on its own branch, sharing the repo's history but not its uncommitted state. Shared filesystem, isolated working copies — both build, commit, and test at once without ever seeing each other's in-progress files, and each branch merges to main only after I've reviewed it.

Those roles don't act in a vacuum — here's the full lifecycle they move a task through, for both kinds of task the shop runs.

The life of a task — two task types sharing one backlog, color-coded by which role acts. Dev lane (top): Filed → Backlog → Active Sprint → In progress → Review gate → Shipped, with a Diagnostics box off In progress (premise holds → keep building; premise disproved → the CEO demotes the same task back to the Backlog) and a Review-gate send-back to In progress for rework. Review lane (bottom): a patient submission triggers a review task (filed by the SEO session, audited by an engineer across the three result pools, funnel, and retrieval); a clean audit closes, but a defect found in review spawns a new fix task up into the Backlog. (Sanitized example.)

Of those 500-plus task files, about 90 were spawned by reviewing real patient submissions — the rest are features and fixes the CEO session or I dreamed up. That ratio is the part I care about: every genuine submission gets audited, and the ones that expose a gap become fix tasks. Roughly 230 of the whole are done or shipped; the rest are a living backlog. The traffic isn't huge — a few hundred submissions over the tool's life, at least 100 real enough to enter an email to get their results back.


Every change gets its own URL before it's real

The counterpart to building in parallel: every change to the product needs somewhere to run that isn't production and isn't the other tasks in flight. So every task that touches the product gets its own isolated instance — a fresh clone of the repo, its own service on its own port, reachable at its own private review URL behind a reverse proxy.

Under the hood it's one small nginx config: a location block per instance, each routing a private sub-path to that instance's local port (/task-<name>/ → a service on 127.0.0.1:<port>). Spinning one up is a clone, a service on a fresh port, and a few lines of proxy. The honest ceiling is memory — each instance is a full running copy of the app, so the dev box has to hold several at once; that, more than anything, caps how many tasks I can keep live for review at the same time.

At any moment I might have several live, independently-viewable copies of the product up — one per task — each showing exactly that task's changes and nothing else. I open the URL, click through the actual rendered thing, and see the change in situ before it's anywhere near a user.

That's the deploy gate: nothing reaches production until I've looked at it running on its own instance. Build on an isolated branch → spin up an instance → review the real rendered page at its URL → approve → merge → deploy. The agent never pushes to prod on its own — the "approve" is mine, and it's a look at a running thing, not a diff.

The transferable pattern: give every unit of parallel work its own running, reviewable instance. "Does it actually work, rendered, in isolation?" is a question you can only answer if the work has somewhere to live that isn't production and isn't your other tasks. The isolation is what makes parallel and careful compatible.


Skills that encode judgment, not macros

Claude Code lets you define skills — named routines the agent runs on command. The naive use is automation: "deploy the site," "run the tests." Useful, but shallow.

The valuable skills encode how a domain expert thinks — the judgment, not just the steps.

My highest-value one reviews a user submission. It doesn't just dump data. It:

  1. Pulls the result across three pools (shown to the user / computed-but-hidden / rejected).
  2. Reconstructs what the user actually did from the logs — did they wait, did they click through, did they leave.
  3. Checks whether a genuinely-good result got silently dropped before the scoring stage even saw it (a whole class of bug that's invisible if you only look at what was shown).
  4. Cross-references anything it finds against a catalog of known past defects.

That's not a macro. That's a reviewer's worldview — what to suspect, what to verify, what caveat to attach to a claim — written down once and rerun consistently. When I invoke it, I'm not saving keystrokes; I'm borrowing a disciplined second brain that never gets lazy on step 3.

The transferable pattern: your best skills should capture the reasoning of your most careful self, especially the checks you'd skip when you're tired. Automation saves time. Encoded judgment saves you from your own shortcuts.


The operating manual: where corrections become rules

There's a file Claude Code reads at the start of every session — CLAUDE.md. Mine has grown into an operating manual: the project's standing rules, accumulated one mistake at a time.

  • Deployment discipline. Never deploy to production without explicit sign-off. Never edit files directly on the server — always local, commit, push, pull.
  • Expected behaviors. How to format a task, when to sync which repo, what "done" means.

Every one of those started as a bug. The first time the agent restarted prod and interrupted a live request, the fix wasn't "don't do that this time" — it was a line in the manual so it never happens again.

That's the load-bearing pattern: a correction that lives only in a chat window evaporates; a correction written to a file that loads next session is a permanent behavior change. The manual is the accumulated scar tissue of the project — the difference between an agent that repeats your mistakes and one that compounds your lessons. The test of a good rule is simple: can the mistake it came from happen again?


What actually transfers

Strip away my specifics and here's what I'd hand another solo builder working with an AI agent:

  1. Make your project management out of primitives your agent is fluent in. Files, grep, git — not a SaaS behind an API. The backlog should be as greppable as the code. Let worker sessions append to it freely, but concentrate direction-setting — both prioritizing and proposing new work — into one role, a dedicated "CEO" session, instead of every session promoting its own.
  2. Run parallel sessions as standing roles, not a shared queue. Give each a lane and let them share one filesystem so they see the same world — then isolate what would collide (a git worktree per engineer) so "more hands" never becomes clobbered work.
  3. Give every change somewhere to run before production. Isolated per-task instances behind a reverse proxy let you review the real rendered product — so "approve" is a look at a running thing, not a diff, and prod stays a deliberate step.
  4. Write skills that encode judgment, not just steps. Capture the careful reasoning you'd skip when tired. That's the compounding asset; automation is just the floor.
  5. Keep an operating manual, and treat every correction as a candidate rule — written to a file that loads next session, not left in a chat window that evaporates. The manual is your project's scar tissue; the test of a rule is whether the mistake it came from can happen again.

None of this is about the AI being the smartest. It's about building the scaffolding that makes an AI agent's work trustworthy — which, when the output affects a sick person looking for a trial, is the only thing that matters.


I build ClinTrialFinder solo, with Claude Code, as a patient myself. If any of these patterns are useful in your own shop, I'd genuinely like to hear how they hold up — the failure modes especially.

Top comments (2)

Collapse
 
skillselion profile image
Skillselion

The detail I would steal first is the policy-tooling lockstep: the privacy policy names the vendor that actually runs the review workflow, so the words patients read and the pipeline that touches their data cannot drift apart without someone noticing. That is a governance pattern, and it is rarer than the task-tracker pattern that will get most of the attention here.

On the tracker itself, the one drift risk I would watch is the hand-maintained overview. The task files are self-verifying in the ways you list, greppable, diffable, linkable, but the index sitting above them is prose that references them by number, and nothing you describe fails when the sprint cites a task that was renamed, superseded, or closed by a worker session mid-week. Since the CEO session already reads the whole backlog on each run, it seems cheap to make it emit a consistency check first: every sprint entry resolves to an existing file, every file above priority N appears either in the sprint or with an explicit deferral. How often does the CEO session actually run, and has it ever reversed its own prioritization from two runs earlier?

Collapse
 
chncwang profile image
Chauncey Wang

Thanks — great catch on both.

The policy/tooling lockstep as a "governance pattern" is the better frame; agreed.

On the overview: you're right — the task files self-verify, the index above them doesn't, and the skills that maintain it reconcile by comparison, not verification. So I added your check: the overview/CEO skills now run a consistency pass first (every link resolves, duplicate numbering flagged, missing high-priority tasks surfaced). First run it turned up a couple dozen high-priority tasks referenced nowhere in the index — the silent-drop class you named. Cheap, as you said.

Your two questions: the CEO runs event-driven, not scheduled — every couple of days. And it rarely reverses itself; it leans to stability, keeping in-flight sprint items and refilling the drained slots.

Appreciate it — the most useful kind of comment.