Inside the loop I use to build with AI
A walkthrough of my actual implementation prompt, from choosing a documented task to checking the build and leaving the next agent a useful handoff.
A walkthrough of my actual implementation prompt, from choosing a documented task to checking the build and leaving the next agent a useful handoff.
To build complex apps and projects, I use a ledger system in order to get the actual implementation to loop until the project is complete. This is an exploration of a real world loop prompt I used when building a browser multiplayer game, including the mistakes I made along the way to work out the bugs.
Today, frontier models can produce some really impressive projects in a one-shot. Ask for a Minecraft style game and you can get a working world with a surprising amount of the expected features right out of the box. With models like Astra and Fable 5.1, I'm often more interested in what I can add to the result than whether the first build will be any good.
The specific things I want are where the work gets complicated. A multiplayer game can look great while two children are seeing different villages. A new feature can touch a part of the project I haven't looked at yet. Another round of "also add this" may work, but I need a way to keep track of the product as those requests accumulate.
I usually get there by talking through the idea, moving the product requirements into files, and using documentation review loops to make individual tasks buildable. A central ledger points to those task documents. Then an implementation worker can run for a long time without needing the original planning conversation.
The example here is from "websling," a working title for a browser multiplayer voxel game for a six year old and his friends. You can read the original loop prompt. It's a project handoff with real paths and unfinished investigations, so treat it as an example to study before adapting it.
The prompt opens with this:
Each tick:
git fetch, then build exactly whatdocs/items/<ID>.mdsays, run that spec's acceptance check (it must genuinely pass), runnpm run checkin a worktree gate at HEAD (git worktree add /tmp/wt<ID> HEAD, hard-linked node_modules viacp -al, apply your staged patch), flip the ledger token and the item doc'sstatus:, commit as<ID>: <title>, push, repeat.
Most of the rest of the prompt explains what those words need to mean in this particular repo.
I use "tick" for an activation of the worker. It can complete several items during that activation, but each item still goes through its own build, check, and commit sequence. A scheduling or agent tool has to provide the next activation. Writing "repeat" in a prompt doesn't create a scheduler by itself, and the prompt doesn't specify a universal interval or CLI command.

The next instruction is unusually specific:
START WITH 565 — docs/items/565.md, status doc, measured and specced last tick.
That's a shortened excerpt. doc is this project's ready-for-implementation state. The worker has a task ID and a spec path, so it doesn't need to choose its own priority before doing useful work.
The handoff then describes the village mismatch. Over a ten-minute two-client run, the host's villager population grew from 12 to 24 while the joining child's stayed at 12. Babies changed on both clients, so some state was being synchronized. It names src/components/net/VillagerSync.tsx and src/net/villagerSync.ts, and asks whether the host publishes villagers created after a join and whether the joiner can apply an addition instead of only updating an existing villager.
It also names previous wrong guesses. I want the next attempt to use the evidence already collected, including evidence against the earlier explanation. I don't want to preserve an entire failed chat just to carry those few facts forward.
The prompt says to start with 565; it doesn't claim 565 is fixed. That's still work to do.
After that item, the prompt says the ledger is empty and gives the worker permission to choose the next task, with one condition. Write the item document first.
It also says to check the item directory and recent commits before choosing an ID. Another agent owns the 900-series and can claim numbers while this one is working. "Next free number is 566" is a hint from the last handoff, not a guarantee about the current tree.
For this ongoing game, I had authorized continuing beyond the current list. For a bounded feature, I'd stop at the end of the ledger. I wouldn't copy the open-ended version into a project where I only wanted the listed work completed.
The prompt includes another issue under "STILL UNSPECCED." A long run produced a maximum update depth error through the cart synchronization path. The notes trace incoming events into a store update which allocates a new cart object and map, with UI components subscribed to the map's identity.
An update can leave the values unchanged while still creating new object identities. That makes the unconditional updates worth investigating, but the notes explicitly say the cycle hadn't been reproduced. The instruction is "REPRODUCE FIRST, then fix the cycle you can name."
This is a useful handoff even without a fix. It gives the next worker a concrete path to inspect and preserves the distinction between a suspected cause and a demonstrated one.
The worktree gate tests the candidate change against a clean checkout of HEAD, the current commit. The staged patch is applied there before running npm run check.
The purpose is to catch a change which only passes because some other uncommitted file happens to exist in the main working directory. Git worktrees provide separate working directories and indexes while sharing repository data. The prompt tells the agent to commit from the main repo, then remove its temporary worktrees as part of cleanup.
There are details here I wouldn't copy blindly. cp -al is the example's environment-specific shortcut for hard-linking dependencies. It isn't a portable installation command, and hard-linked files are shared, so tools which modify those dependencies can affect the original copy. A normal install from the lockfile is easier to reason about when setting up this process elsewhere.
Also, git fetch retrieves remote changes; it doesn't integrate them into the current branch. The worker still needs to handle branch movement before claiming it checked the version it commits. If the base changes during a gate, I want the final candidate checked on the new base.
The original prompt checks the code, then updates the ledger and document status. Those record changes belong in the final diff review as well. Neither HEAD nor a passing check is a promise about changes made afterward.
The task's acceptance check comes before the repo-wide gate. A build can pass while the feature is wrong, and a narrow feature test can pass while the wider project breaks. I want both.
This prompt requires deliberately breaking every new test's behavior to verify the test fails. It also asks for a test which catches an over-correction. If a fix synchronizes additions but inserts duplicates on repeated messages, checking only whether a villager arrived would miss the new bug.
When an automated test can't detect the intended defect, the prompt allows honest measurement evidence instead of a decorative test. Item 562 is cited as using profiles and screenshots. The handoff also says to correct tests based on a wrong runtime model without weakening the underlying acceptance requirement.
I've put the longer discussion, including the recorded village counts, in how I check AI work before calling it done. The command is strict because "tests pass" doesn't tell me whether the tests exercise the behavior I asked for.
The soak instructions specify separate browsers, the same room, small probes, and a steady-state CPU profile. They also explain why different room names change the workload and why a block read can confuse unloaded chunks with air.
I want those details available when the worker rebuilds the measurement setup. They came from investigating the actual game, and omitting one can invalidate the next comparison.
The prompt prohibits running Vitest while the gate is running and calls out test browsers left open during timing checks. It also names existing dev servers and ports the worker must leave alone. Cleanup is limited to its own processes. A broad "kill all Next.js processes" would interrupt my other work.
Some notes are even smaller. Wait until both clients are standing on loaded ground before editing. The inventory shortcut may be intercepted while the player is in a bed or near a villager. If a browser automation script fails to open the inventory, these are things to establish before declaring an inventory bug.
Another agent was editing and committing in the same tree. The prompt therefore forbids staging paths the worker didn't edit and requires inspecting the staged diff before every commit.
For overlapping files, it mentions blob staging with git hash-object and git update-index. The intention is to construct a staged version from HEAD plus only the worker's own change. I consider that an advanced response to a shared-tree setup, not something everyone needs in a starter prompt.
Separate worker worktrees with controlled integration are easier to manage. Even in the shared tree, checking filenames and line counts isn't enough to prove ownership or compatibility. The worker has to inspect the actual hunks and avoid committing while another worker changes the shared index.
The instruction to read the other agent's comments matters, too. The handoff describes an earlier finding where one circuit path already used the right index while other scans didn't. Existing code and the other worker's measurements can save another round of implementing the same idea in the wrong place.
The original command has four hard limits:
npm run check gate and has no CI.skip with the limitation recorded.That third limit is about new project costs. It doesn't imply running the coding model is free.
There are smaller standing rules as well. Numbers specified by the product live in src/config/, with an audit checking the convention. A config key no code reads or a flag which changes nothing is a defect. Judgment calls go into an append-only decisions document. A measurement finding no leak over ten minutes is still worth recording, with its time window intact.
These constraints apply on every iteration, including when the worker chooses a new task. Permission to continue doesn't remove them.
Once the docs are in good shape, much of the implementation is scoped enough for a less expensive capable model. I usually give it enough reasoning effort to finish the task properly, and use the frontier models for difficult investigations or specific visual work when they're useful.
Higher effort isn't a substitute for a missing capability. If the worker keeps failing the same item, I can change the model or improve the spec. Because the requirements and results live in files, I can do that without moving the whole product out of one chat.
I judge the cost by completed work. A lower-priced model which needs repeated corrections can cost more to finish an item, which is the issue I explored in the turn-count tax. I don't have a universal model-and-effort setting for every ledger.
Most projects won't need the villager counts, the cart-store investigation, or my reserved ports. The reusable part can be much shorter. This is an adaptation, not the original command, and the repo needs to define the paths and checks it refers to:
Work from the project's central ledger and linked task documents.
Take the next ready item assigned to you. Read its spec, source
requirements, dependencies, and existing implementation before editing.
Build the scoped behavior. Do not invent missing product decisions.
Run the item's acceptance checks and the repository's required checks
against the candidate you intend to commit. For browser behavior, use
the browser and record what you could and could not verify. Confirm a
new regression test fails when the relevant defect is reintroduced,
then restore the correct code before the final check.
When checks pass, record the tested revision or patch, evidence, and
limitations. Update the ledger and task document consistently. Inspect
the actual staged diff, commit only your changes, and publish the commit
only within the repository's authorized workflow. Recheck if the base
or candidate changes.
If blocked, preserve the requirement and record the blocker. Never
relax a check to manufacture success. Continue only with independent,
assigned work; don't retry an unchanged blocker indefinitely.
Preserve user data, license constraints, spending limits, and unrelated
work. Clean up only resources you started. Leave the next item and any
unresolved findings in files before the session ends.
Repeat within the agreed budget and scope. Stop when the assigned
ledger is complete, the budget is reached, or user input is required.
The surrounding agent tool must provide any later activation.
I'd run the first item while watching the result. Open the product, check the feature, and read the evidence the worker left. If I can't tell what it verified, I'd fix the task document or the checking instructions before leaving it to work through the rest of the list.