cat ~/autoblog/how-it-works.md
how it works
Every article on this site was written by a machine, and every one of them says so.
The thesis
A pipeline that generates prose is unremarkable now. One that publishes its own receipts — which models ran, how many revisions it took, what it cost — is rarer.
The seven stages
- ideate
- plan
- research
- draft
- critique
- revise
- polish-prose
Each stage is a separate process, so nothing carries hidden state between them. The article accumulates on disk in a scratch file that every later stage reads and rewrites in place. Drafting is the one stage that loops. The outline's H2 headings are extracted and one drafting pass runs per heading, appending as it goes. That's why a single article can log more drafting rows than the pipeline has stages. Which model runs which stage is configuration, not code. The seven stages map onto five named entries in a JSON config, and each asks for a tier ("cheap" or "strong") rather than a model id. Changing models is an edit to one file.
The gate
Two checks, and both have to pass. Every citation the research stage collected is fetched — HEAD first, then GET for the servers that dislike HEAD. One unreachable link fails the whole article. Then a separate judge process grades the draft against a rubric and returns a verdict. An unparseable verdict counts as a failure. A failed gate means nothing is copied into the site at all.
The budget circuit breaker
A running total, a ceiling from the same config file (two dollars, in the config that ships), and a check every time a stage records what it cost. Exceeding it throws. The staging directory is deleted and the run exits non-zero, so an expensive article dies before it can reach the repository. One more check runs immediately before publishing, between "the last stage was affordable" and "we are about to commit".
What publishing means
Publishing is the least clever part of this. The article is assembled in a temporary directory outside the repository, and only a passing gate moves it in — exactly two files, the MDX and its provenance sidecar. Then a real production build runs against them. If it fails, both files are deleted and the tree is back where it started. What survives is committed by explicit path, never by a wildcard add, with a one-line message naming the slug, pushed if a remote exists, and deployed.
What is captured, and what isn't
The sidecar holds nine fields per stage: the stage name, the model, four token counts, the cost, the revision number, and a timestamp. It's built by naming those nine explicitly — a whitelist, so a field added upstream is absent by default. Two things aren't there: the session id, and any per-request billing identifier. That omission has a test of its own. The test seeds a fake session id and fails both if that value appears and if the key set is anything other than those nine.
Live aggregates
| Articles published | 1 |
|---|---|
| Total tokens | 12,480 |
| Total cost | $0.42 |
| Models used | fixture-model-a, fixture-model-b |
| Pipeline versions seen | v0.0.0-fixture |
Pipeline version and source
Every sidecar is stamped with the pipeline version that produced it, which is why the table above can list more than one. An article is a record of the code that existed when it ran, not of the code running now. The source isn't public. Publishing the repository is a decision I haven't made yet.