Guardrails for AI coding sessions on this site
Three real incidents on brandon-ta.com, from invented blog claims to a wiped node_modules, and the written rules that now stop each one.
This site is built and maintained with AI coding sessions. That works only because the sessions run under written rules, and each rule below exists because something went wrong without it. Three incidents form the spine of this post. Each one is in the git history or in the notes the sessions keep.
Incident 1: posts that described a site that did not exist
On 24 April 2026, commit 8c5837f added a pilot post and three cluster drafts, written by an AI session. They were in first person, dated into May, and told stories with invented details: a system “5 months” in, a median of 9 days from draft to publish. An AI session published two of them on 11 September 2026 without checking them against the site they described.
On 16 September, commit a9b51b7 (merged in PR #21) put both back to draft. The commit message lists what was wrong. One post claimed that blog pages on this site had “no client-side JavaScript. None.” A generated post page actually loaded 65.8 KB of gzipped JavaScript and hydrated two islands. It also listed a theme toggle among the site’s islands, while the design document forbids a toggle and none exists.
The post about the Astro decision was then rewritten using figures measured on the production build that day and republished. The post about publishing 32 times a year stayed in draft, because nothing true was left to rebuild it on.
The rules that came out of it. The project notes now say to check a post’s origin in git history before publishing or translating it, and to measure every claim about the site against real output. For page weight, measure in the browser rather than by searching the HTML, because islands marked client:visible only load when the reader reaches them. A related note says to confirm a product claim in the product’s own repository, not in a planning document that states rules and plans in the same voice as facts.
Incident 2: a green light nobody had watched
The first incident is really a failure of evidence. The posts read well, and nobody ran the thing they described. The global instructions for my sessions answer this directly:
No fix, and no “it works”, without having watched the real thing run.
For a bug, the order is fixed: reproduce it, find the line that is actually wrong, make the smallest change, then re-run the same reproduction. For a feature, run the flow the way a user would. Reporting has a required shape too: “‘fixed (could not reproduce, unverified)’ is honest; a bare ‘fixed’ is not.”
A second rule makes this checkable. Each acceptance item is ticked with its evidence: a command and its decisive output, a screenshot path or a URL. A tick without evidence counts as open.
This is not a private quirk. Anthropic’s Claude Code documentation says: “Give Claude a check it can run: tests, a build, a screenshot to compare.” Without such a check, the same page notes, “looks done” is the only signal available. On this site there is no test script, so the check is npm run astro check, a production build, and a browser pass on the built output.
Incident 3: an npm ci that emptied the wrong folder

On 5 October 2026, a git worktree had its node_modules symlinked to the main checkout’s copy, to save an install. A subagent ran npm ci inside that worktree. npm ci deletes node_modules before installing and follows the link, so it emptied the main checkout’s dependencies. The main checkout then failed with astro: command not found. The half-working worktree install also produced a development-only image 500.
Worktrees themselves were not the problem. The global rules require one per task, created from the single existing checkout, never a second clone or a copied folder, and removed once the task is merged or abandoned. This keeps parallel tasks from stepping on each other’s files. The rule added after the incident covers the gap: never symlink node_modules into a worktree, and run a real npm ci in each new one, which takes about a minute.
Smaller rules that keep diffs reviewable
| Rule | Where it lives | What it prevents |
|---|---|---|
| Touch only what you must; every changed line traces to the request | Global instructions, “Surgical changes” | Drive-by edits that bury the real change in a review |
| Minimum code that solves the problem | Global instructions, “Simplicity first” | Speculative features and one-use abstractions |
| Don’t add libraries unless asked | Project instructions | Dependency creep on a static-first site |
| Dark-only canvas, one yellow accent, no theme toggle | DESIGN.md | A session reintroducing something the design contract removed |
Deploy by a pull request from develop into production | Project instructions | Assuming a push to develop ships; the old workflow file targets a main branch that does not exist |
The design document matters more than it looks. The invented theme toggle in Incident 1 was caught because a written contract said a toggle must not exist. A rule a session can read is a rule it can be checked against.
What I take from this
These are my conclusions, not general laws.
- Write down the rule after the failure, not before. Every rule here traces to a dated incident, which makes it easy to judge whether it is still needed.
- Treat AI-drafted text as unverified input. The failure was not that a model wrote the posts. It was that nothing forced a comparison between the text and the running site.
- Make the check something a session can run itself. A build, a type check and a browser pass cost minutes. A wrong claim live for five days cost a pull request and a retraction.
- Shared state needs rules about what a task may touch. Two checkouts that share one dependency folder are one checkout, with extra steps.
For someone building a small product with AI help, the smallest useful version is a short instructions file, a note for each incident, and one rule: nothing is “done” until you have watched it run.
Written by Brandon Ta
Solo developer in Vietnam, building ten small products in the open, mostly for businesses in the US and UK.
Comments
Join the conversation! Share your thoughts, ask questions, or connect with other readers below.