Series: genesis

Start Here: Building the Tool While Using It

By John Hardy

This project exists to test a new model of software development and content production in public. The repository is both the lab and the record, and the system I am building will publish the discoveries that come out of building it. If you want the map of how the system is built, treat this series as a lab notebook with working notes and decisions in view. I want readers to see the system forming alongside the result.

The first content is the documentation process itself, so I write while I build and treat the conversation and decisions as raw material with constraints and contradictions kept visible. The Q/A process I am working out here is the real work, and it becomes the content. Each entry shows a decision while it is still forming, before it hardens into tooling.

Over time, this back-and-forth will harden into scripts as the workflow stabilises and the content aligns with the system it describes. The point of doing it in the open is that I can test the system by publishing its formation. The diary becomes the tool because each change leaves a record I can test and reuse.

I minimise imports and treat third-party tools as a last resort. When a problem fits in a small script, I write it and keep it in the repo so the implementation stays visible. When the problem is larger than that, I import a library and document the specific gap it fills.

On the publishing side, I am aiming for the most boring convention that still works: a home page index with the newest post at the top. Each post also gets a dedicated article page with a stable permalink. That is the shape of the site I want to live inside. It lets me read the archive as a plain list without extra machinery. It also keeps the build simple enough to inspect.

To follow the build as it forms, read the genesis series in order, starting here. After this post, read Guarding Against the Machine Voice. Next, read Why I'm Building This in Public and continue forward through the series.

Related posts: Guarding Against the Machine Voice, Why I'm Building This in Public.

Guarding Against the Machine Voice

By John Hardy

I built a linting script to flag formulaic phrasing and hedge words that creep into prose during fast writing when assisted by automation. The script runs against drafts by default and stops the build if too many issues accumulate in a single file. Speed matters to this project, yet unexamined speed produces exactly the variety of writing I want to avoid. I need a mirror that catches when prose drifts into explanation mode or starts sounding like a corporate blog post. The linter serves as that mirror by reflecting my own habits back to me during the draft process. Each rule carries a numeric weight where high-severity rules target the common formulaic failures that almost never appear in careful writing. The script flags these immediately to keep the voice sharp and direct.

Medium-weight rules catch passive voice and weak paragraph openers. Lower-weight rules flag hedge words that dilute precision. The script also enforces standard British spelling and watches for first-person plural pronouns. This blog is a personal diary written in first person singular, so the tool flags specific collective pronouns to keep the voice anchored and avoid a detached tone.

One of the heavier checks targets contrast framing by flagging ideas defined by negation followed by correction. AI-generated text produces these constructions constantly, which means they simulate structure without requiring deeper thought. The script scores each contrast construction and caps the penalty per paragraph so repetition doesn't blow out the score. When it catches these constructions, it samples the matches and shows where the framing appeared.

It also checks sentence-length variance and paragraph uniformity. Low variance produces rhythmic monotony that makes prose feel generated, while high use of markers like "however" and "moreover" signals over-structured thinking. Paragraphs that stay uniformly short or uniformly long create a flattened reading experience, so the script flags both extremes. It also counts list blocks because bullet points can replace explanation when overused.

The script supports three severity levels including high and medium along with low priority issues. Each problem receives a severity assignment based on weight and files undergo evaluation against per-file thresholds. The default thresholds allow one high-severity issue along with three medium and six low errors before a file fails the gate. The build fails if any file exceeds its thresholds. During local development, the script prints warnings without blocking so I can keep moving forward while still seeing where the prose needs attention. Strict mode rejects any file with issues, which helps during final review passes. Gate mode balances friction with velocity by allowing some imperfection while still catching the worst constructions before they ship.

Why I'm Building This in Public

By John Hardy

I'm building this in public because writing details down changes how I think. When ideas stay private they remain vague and provisional. Writing for an imagined reader sharpens the ideas and shows the gaps as decisions harden on the page.

This repository is where I'm working decisions out and where those workings live. The notes and specs sit beside the code they shape, with half-decisions and revisions kept close by. They stay inside the process, present while I shape the code.

The writing is one of the tools I'm using to build the system. It affects the choices I make and keeps the work accountable because it has to be readable to someone besides me. One concrete example: when I wrote down the rule that templates should remain pure HTML, it stopped me from adding conditional logic in a rush. That single paragraph forced me to move selection into named queries and keep the rendering mechanical, which is now a fixed constraint in the build.

Speed matters to this experiment because the work happens in real time and the record only helps if I keep it current. That pace has a cost: it pulls me toward familiar phrasing and tidy scaffolding that drains the writing of its edge. I feel the slide when I announce a topic and leave the decision unstated, or when sentences line up into the same rhythm.

The prose-lint script is my counterweight. It catches scene-setting lines that do no work and contrast framing that drifts into narration. It also flags tidy lists that flatten nuance. One example I keep fixing is the empty opener. Draft: This section is about speed and quality in writing. Revision: I write fast to capture decisions while they are fresh. I then slow down to keep the voice intact. After the rewrite, I run another pass and keep the decision in front.

A central concern in the experiment is how AI fits into this. I want AI as a constrained collaborator with clear boundaries about authority and intent, along with what I allow to change. Those constraints preserve the shape of the work while still letting me use speed and advantage when they help. The blog that will appear here comes from the project and follows the same rules, so templates and queries show up alongside build scripts and deployment because the writing needs them. Another example came from tagging, where writing down the normalisation rule forced me to rename a handful of tags and rebuild the indexes so the archive stayed coherent and kept near-duplicates in one place.

I still work out my position, and I take my time with it. This is an attempt to think carefully and design slowly while leaving a readable trail behind. The trail should stand on its own, even if I am the only person who ever reads it end to end.

A Blog That Is Also the Build System

By John Hardy

This blog only works if it lets me publish day to day technical work without friction, with AI drafting alongside me and me keeping control of the final voice. That constraint is the reason the rest of the system exists.

The web itself is the anchor for this project. I want documents that read cleanly in source and still make sense without scripts. Links should behave as stable addresses and stay clear of runtime actions. The site should resemble the early web, when a page was a page and a URL meant what it said.

That stance forces decisions about durability and access. Accessibility and internationalisation are core requirements because headings and landmarks have to make sense to assistive tools. Layout choices cannot collapse when language or fonts change, or when the reader never uses a mouse. Performance and cacheability sit in the same layer because pages have to load fast on slow networks and stay responsive on old devices.

Discoverability sits beside all of that and keeps the surface legible to crawlers. Clean URLs and clear titles should show intent without JavaScript. Indexable pages should do the same work. I use unobtrusive JavaScript where it helps navigation, but the baseline page remains intact with classic HTML as the foundation.

The tooling has to match the posture, so I keep the toolchain small and inspectable. I add theming and user settings only when they serve reading, and I leave the rest out.

The repository is the blog and the build system, with the record of how the build changes kept in the same place. A post is a folder with a Markdown file and nearby assets, plus a small amount of metadata that makes indexing possible. The folder tree is the public rhythm of the blog. Dates become paths and months become folders, so each post sits as a leaf in the tree. I can point at the layout and show how the site is built.

Automation has a narrower role here and stays focused on repetition. I rely on a handful of scripts that are obvious when I read them, because that keeps the system legible to me and to the AI that helps maintain it. The scripts handle repetition and the repo holds the permanent record. When the AI adds a script, it becomes an event in the diary and the change itself becomes content.

Templates are plain HTML and only stamp content into a page. Queries decide what exists, and those queries live beside the content they select. That is the heart of this approach. The data stays visible and the selection stays visible. The render stays visible once the build runs. When I say the blog is the build system, I mean the path from idea to page is traceable inside one repository.

Pick any entry and follow its folder path to trace the decision trail that produced it. If I drop these constraints, the archive loses its promise and the project fails its own test.

Years