Station builds itself

Station builds itself

● Current as at 3 September 2026, AEST

Station is the second brain I built to hold everything I’d otherwise forget. This page is about the strangest thing it grew into: Station now runs its own software development.

Not "I use AI to write my code" — I do, and that has its own page. This is the layer above it: Station holds the backlog, starts the coding session, waits for the tests, checks weeks later whether I ever actually used the thing that shipped — and, the part that still makes me laugh, deploys the tool that writes its code. None of it was designed up front. Every piece exists because something went wrong in a way I could feel.

The loop

Seven steps, and four of them are still mine on purpose.

  1. Idea — a want, or a bug I hit, lands in Station like any other thought. My call.
  2. Session — I start a coding session from Station, pointed at one project’s code. My call.
  3. Proposed change — the agent works on its own copy and offers the change up rather than making it. Developers call this a pull request. The agent’s work.
  4. Gate — the automated tests, and a written note of what changed, must both pass before that change can be folded into the real code. The server decides, and it cannot be talked round.
  5. Test copy — it reaches a test copy of Station first: same code, a scrubbed copy of my real data. My call.
  6. Promote — production moves forward only when I say so. My call.
  7. Follow-up — days later Station asks whether I used it, and can prove whether I did. Station’s move, not mine.

The front half lives on a screen called the Development board: one place per project, sorted by whose move it is next — waiting on me, waiting on the agent, blocked, in flight.

The Development board: work for each repository grouped by whose move it is next.
The Development board: work for each repository grouped by whose move it is next.

Why a second brain does this

The work was already here. Ideas, plans and the notes explaining why I wanted something all live in Station. A separate project tool would mean the same thoughts in two places, and I know how that ends.

I forget. Not a joke — it’s the founding condition of the whole system. I shipped a feature in June 2026 and could not remember how to use it a few weeks later.

Speed made it necessary. In a good week several changes land in an hour, and by then "I’ll remember to look at that" has stopped being a plan.

The engineering journal

Every coding session — whichever tool or model drove it — is archived to one private place when it finishes. A small model running on my own hardware then reads those transcripts and writes a plain-English diary entry for each day, for each project.

Not a log. A diary. It answers "what was I doing on the 18th of August, and why" without me re-reading a five-hour conversation. As at 3 September 2026: 317 diary days across 48 projects, from 637 archived sessions going back to 21 May 2026.

The engineering journal: a date index, and each project I touched that day summarised in plain English.
The engineering journal: a date index, and each project I touched that day summarised in plain English.
One day in the journal: each project I worked on, summarised in a paragraph or two.
One day in the journal: each project I worked on, summarised in a paragraph or two.
Two ways the journal was quietly wrong

It filed most of every day under yesterday. Dates were worked out in UTC rather than my own timezone, so anything I did between midnight and about 3pm AEST got the previous day’s date. From outside it looked fine — the entries were all there, just on the wrong page. Fixed 29 July 2026; about 90 entries were re-dated.

It only ever read the first thousand files. The archive had grown to 1,995 files, and the way it asked for the file list only ever handed back a thousand. Because files come back in alphabetical order that didn’t lose a random sample — it lost whole categories of session, silently, from around 21 July 2026. Also fixed 29 July.

Both are the same shape, and it’s the shape this whole page keeps circling: something that has stopped working looks identical to something with nothing to report. Most of what got built since exists to tell those two apart.

Monday morning: how the work went

The journal records what got built. It throws away the more useful half — how the building went. So every Monday, Station reads the past week’s sessions at the level of events rather than prose: every approval I was asked for, every command that failed, every time I stopped the agent and corrected it, what it cost, where it stalled.

One problem across five sessions becomes one finding that says seen 5×. And something is only ever proposed as self-fixable if it happened in at least two separate sessions — a one-off is never safely self-healable, however confident the write-up sounds.

The first honest run was humbling

Before it ever ran on a schedule I pointed it at 60 real coding sessions. It worked perfectly and produced a board nobody would have read twice (18 August 2026).

  • The loudest problem it found was the workflow itself — me approving the same planning step over and over. True, and useless. That detector was deleted rather than tuned.
  • One session that cost $208 was reported as having 208 occurrences of a problem. It was counting dollars as incidents, so an expensive session sailed straight past the "must have happened repeatedly" safety rule.
  • The same project spelled two different ways split one real finding neatly in half.

After the fixes, 271 raw signals became 156 and 88 groups became 62. The lesson I’d give anyone: for anything that judges rather than calculates, run it against real data before its first scheduled run, and treat that output as the actual test.

Features have to earn their keep

Nothing counts as shipped until it’s registered with a short test plan written for me, not for a developer. Station then checks in at 2, 7, 14 and 30 days: did you use it, why not, anything broken, anything you’d change? That first question isn’t a test of memory — Station can see whether the screen was ever opened.

The follow-ups page: today's check-in with its test plan, and the catch-up backlog of ones I have skipped.
The follow-ups page: today’s check-in with its test plan, and the catch-up backlog of ones I have skipped.

Three rules make it survivable: one check-in a day at most; skipping is free — ignore it three times and it stops nudging but moves to a catch-up list rather than vanishing; and nothing is deleted. An actionable answer gets up to three clarifying questions and becomes a real item on the Development board. The feature then comes back just briefly — a couple of check-ins after the fix ships, to confirm it actually worked.

As at 3 September 2026: 161 features registered, 87 check-ins answered, 131 pieces of my own feedback captured.

Deploying the tool that builds it

On 1 September 2026 a new model was released and neither of my coding tools could reach it — and neither of them said so. The version of the command-line tool they had pinned decides for itself which model names are real, from a list baked inside it, so an out-of-date pin quietly hands you an older model with no error at all.

So Station now watches for releases of the tool that writes its code and tells me in words I can act on — "the new model is now reachable". One press proposes the change in each affected project, folds each one in when its tests pass, deploys both, and confirms from inside the running software itself that the new version is really there.

The release screen: a new version of the coding tool detected, with each step of the update shown and its status.
The release screen: a new version of the coding tool detected, with each step of the update shown and its status.

Two things make that defensible rather than reckless. The edit is deterministic — one line changed by a rule, no model writing it, and a file that doesn’t match the expected shape is refused rather than guessed at. And Station doesn’t get to restart the coding tool: it asks it to redeploy when nothing is running, and the tool fires on its own idle gate. Station can never destroy a live coding session — including the one belonging to whoever pressed the button.

Four ways this went wrong before it went right

Three in the first days of September 2026, and one a week earlier. None was caught by any test:

  • A change that changed nothing, reported as a success. It told me both proposed changes had gone in. Neither version had actually moved — and one of them had never gone in at all. The new file was being compared against a leftover copy rather than against the real thing, found the change already there, and wrote nothing. Now an empty proposal is refused outright and the file is re-read afterwards to prove the change landed. A "success" message tells you the thing was asked for, not that it happened.
  • It deleted 4KB of a changelog — the running written record of what changed and why. The helper that reads a file stops at 200,000 characters; that file was 204KB, so it was written back ending mid-sentence. New rule, permanently: anything written back is read whole.
  • A step waited without saying what for. Working perfectly, invisible, and indistinguishable from broken. That’s now a bug in its own right.
  • A restart that updated nothing (24 August 2026, on a different button). The setting meant to make a deploy fetch the new version is ignored entirely by the software underneath. It was removed rather than left in place — a control that does nothing reads as proof that it works.

What “the map” means

I wanted something like a dependency bot: tell me when something my code relies on releases a new version. Then, on 20 August 2026, I read eight of my projects properly, and that changed the design. In six of the eight, the version that actually matters is written down nowhere a machine would look — a web address typed straight into the code, a dated version number buried in a settings file, or a line of prose in a README saying "requires version 2026.6". A conventional dependency bot would have missed the six that mattered.

So the thing worth watching isn’t the packages, it’s the products — and the map of which project depends on which product exists in no file on earth. Station infers it; I own it and correct it. A new release is then judged against the map as it stands right now, and stays re-checkable for 90 days.

The repositories page: every repository, with the products each one actually depends on.
The repositories page: every repository, with the products each one actually depends on.
The map had a hole shaped like the tools I use most

On 30 August 2026 it covered only 39 of my 101 projects — by construction, because it had only ever looked at the ones published publicly. Everything private, including the coding tool and Station itself, was invisible to it. It now reads every project it can see — 104 of them on 3 September 2026 — and when it spots a product it isn’t watching, it asks on that project’s own card whether it should start.

The guardrails

Three things I’d want to know about before trusting any of the above.

The gate is enforced by the server, not by good intentions

Every agent working on Station is told to run the tests and update the documentation. Instructions raise the cost of a false claim; they don’t make one impossible. So since 27 August 2026 the real, live copy of the code — the one everything is built from — is protected. A change that breaks the tests, or touches the code without a written note of what changed, cannot be folded in — by any tool, whatever its summary claims — and writing straight into that live copy is closed off entirely.

I proved it by deliberately proposing a broken change. The tests passed, the documentation check failed exactly as designed, and both attempts to fold it in were refused by the server. Then I withdrew it.

Two decisions can no longer share a number

Every significant decision gets written down and numbered. On one day in early September, numbers collided three times.

The diagnosis is the interesting part: it’s structural, not careless. Parallel sessions each look up "the highest number used so far", get the same answer, and the gap between looking and merging is hours. Nothing noticed, because two files with the same number and different names merge together perfectly happily. The duplicate only surfaces the day someone cites a number and reads the wrong decision.

A test now refuses it. Three historical collisions already exist — one number was used three separate times — and they’re frozen rather than fixed, because renumbering would rewrite decisions that other decisions already cite, purely to tidy a folder.

The development copy cannot operate the real house

The test copy of Station is refreshed nightly from a real backup, and that’s exactly what makes it dangerous. The scrub takes out the obvious things, but it never covered everything: the copy still holds working credentials for the real world.

Left alone, a click there could have sent a real notification, changed something in my actual home, run a command on a real machine, started real coding work, or published to a real public page. Every one of those paths now checks, immediately before it writes anything, whether it’s allowed to reach the outside world — and if it isn’t, says "suppressed on this instance" in the same shape the screen already knew how to draw. Reading and inspecting still work. It just can’t touch the house.

Does any of it actually run?

Fair question, with an embarrassing answer. There’s a chart on my public profile counting how many coding sessions I run, and it claimed to refresh itself weekly. It hadn’t moved since the week of 20 July 2026 — six weeks — while the journal behind it quietly collected 631 sessions.

There was no broken job to find. The job never existed. An attempt at it had been written in July, drifted 486 changes out of date, and was abandoned in August. The absence looked precisely like a job that had simply never fired.

Which is why the screen listing every scheduled task matters more than it sounds. Each one says when it last ran and what it decided — including ○ skipped, with the reason, which is a different thing from ● ran and different again from ⚠ failed. And a weekly task now raises an alert on its first failure rather than its third, because three weekly failures is 21 days of silence.

The jobs screen: every scheduled task with when it last ran, how long it took and what it decided.
The jobs screen: every scheduled task with when it last ran, how long it took and what it decided.

It was republished on 3 September 2026 at 4pm AEST, 634 sessions — and then rebuilt again half an hour later, because GitHub won’t render that kind of chart any wider than it likes and sixteen weekly bars had nowhere to go. So it now counts by month instead: 1 session in May, 42 in June, 213 in July, 274 in August, and September still running. Same 634 sessions, drawn in five bars rather than sixteen.

The numbers

Counted on 3 September 2026, late afternoon AEST, from Station’s own database and its own history — not estimated.

Count Since
Archived coding sessions 637 21 May 2026
Diary days in the journal 317, across 48 projects 22 May 2026
Changes proposed for review 908 (898 folded in) 31 May 2026
Written-down decisions 271 22 April 2026
Changelog entries — the running record of what changed and why 840, of which 423 since 8 July 22 April 2026
Changes to how information is stored 174 22 April 2026
Features registered for follow-up 161 mid-June 2026
Check-ins answered · feedback captured 87 · 131 8 July 2026
Automated tests passing 5,443 as at 31 August 2026

Which model drove those 637 sessions: 559 Claude, 60 Azure’s GPT-5 family, 14 GitHub Copilot, 3 Station’s own chat, 1 a model on my own GPU — a cost and availability decision, not a loyalty one.

Two of those numbers deserve their footnote, because this page is about exactly this sort of thing. The chart said 634 sessions when it published at 4pm AEST — its five monthly bars still add up to exactly that — while the table says 637, counted a little over an hour later. Three sessions finished in between. And the decisions run up to number 267, yet there are 271 of them, which is the collision described above still sitting there on purpose.

What this isn’t

It isn’t autonomous. Unattended dispatch — Station starting coding work while I sleep — was built and deliberately shipped switched off, because overturning the attended-only rule is a decision for a human, not a feature flag.

I am still the only one who can say yes. Every change an agent proposes gets an independent automated review before it reaches me, and that review is always a comment, never a verdict.

It isn’t a product and it isn’t for sale. It runs on hardware in my house, for one user, and a good deal of what you’ve just read is a description of me being wrong in public and writing down what it cost.


Where all this came from, and what it grew out of: Origins and growth →. The coding tool at the other end of the loop: Rufus →.