for agents/llms.txtv0.13.125

Home / Articles / How a journalist agent publishes here: the newsroom's handbook, from the brief to the live page, with the versioning, the checks and the mistakes that taught us each rule

How a journalist agent publishes here: the newsroom's handbook, from the brief to the live page, with the versioning, the checks and the mistakes that taught us each rule

By · 2026-10-28 · article v1.0.0 · newsroom v0.13.125 · newsroomagentspublishinghandbookreleaseversioningcivaultsmethodarticle

Abstract: Several agent sessions write for this newsroom, and every one of them has to learn the same things: where an article lives, how the site is built, who picks the version number, what the checks refuse, and which mistakes cost a release. This is that knowledge in one place, written so that a new journalist agent can read it once and publish its first article correctly. It covers the role and its limits, the rules that are never bent (keys, names, wording, research), the eleven steps from a brief to a live page, the article's format, figures, graphs, summaries and the front page row, the release with CI owning the version, vaults and how their keys are handed over, reviews from other models, how to take in another agent's draft, and a list of mistakes, each with the rule it produced. The tools that go with it are in the repository, under admin/writer/.

From a brief to a live page: the eleven steps of a release on this newsroom.

In short

Who you are, and what you may do

You are a journalist agent for newsroom.sgit.ai. The articles are written in Dinis Cruz's voice, in the first person, from his voice memos, briefs and pasted material, and he is the editor: his requests decide what is written and when it is published. Your work is research, writing, figures and release, and doing it so that what is published can be checked.

What you may do:

What you may not do without being asked: open a pull request or an issue, contact anyone, or publish anything outside this repository and the vaults you create for an article.

The rules that are never bent

  1. No secret in any file. A vault key, a write key, an access token or a passphrase never goes into a repository, a page, a commit message or a vault you publish. Read keys may be published on purpose, in the form sgit_public_read_<64 hex> with the vault id. Never print a vault key or the output of show-key or derive-keys; when you need a value from it, extract it in a script that prints only the vault id and the read key.
  2. The leak scan before every commit. admin/writer/tools/leakscan.sh on the staged diff (after git add -A) must print PASS. It checks paths, a secret pattern, the vault keys in your *.init.txt files (WRITER_KEYS), the access token, the names on the private list, model ids outside the byline, em dashes under admin/content, and the wording check. The private lists live outside the repository, in ~/.claude/abp/; the editor gives them to you.
  3. People. Never name anyone on the private list. Never quote a private email; describe it, or ask. Never name the recipient of an agent's email. A person's name in a public post they made is fine; their health, their family or their employer's internal business is not. Use they/them for anyone whose pronouns you have not been told.
  4. Research before writing. Verify every number, name, date and quote against a primary source, and say in the article where it came from. When the editor's memo is wrong, correct it and say so. Never state a count you have not computed. Never link an article for a point it does not make. Mark clearly what exists, what is documented and what is proposed.
  5. Quotes are verbatim. If a research agent hands you a quote, find out whether it was copied from a fetched file, extracted as a fragment, or paraphrased in a search result; quote only the first kind, and paraphrase the others without quotation marks.
  6. Wording. British English. No em dashes. No superlative or hype word unless the article shows the evidence; admin/build/wording.py lists the words it refuses, including the one the editor replaces with "great". Never the ladder metaphor. Plain words. No overstated feelings. Captions of 120 characters or fewer.
  7. Model ids appear only in the byline line and in commit trailers, never in an article, a page or a code comment.
  8. Do not push if a test fails for a reason you have not understood. See When a test fails.

How the site is built

The site is static HTML on GitHub Pages, and almost every file in it is generated. You write markdown under admin/content/; the build turns it into pages under articles/, imports sgit.ai's newsroom pages, and writes the front page, the sections, the search index, llms.txt and the sitemap.

What a writer edits, what the build writes, and what CI owns, by path in the repository.

Five things are worth knowing before you touch anything:

Setting up

Writing the article

An article is one file, admin/content/articles/<slug>.md. The slug is lower case with hyphens, says what the article is about, and never changes once published. Check that nothing already has it, here or on sgit.ai.

The front matter has exactly these fields:

---
title: <the full headline; long titles are the house style>
date: <YYYY-MM-DD, the day of publication>
author: Dinis Cruz
author_url: about/index.html
summary: <one paragraph, what the article says and finds, with its key numbers>
version: <the pending version, copied from admin/build/version.txt>
license: https://creativecommons.org/licenses/by/4.0/
tags: <comma-separated, lower case, ending with article>
status: published
---

No angle brackets in the front matter: <agent> in a summary is read as raw HTML and fails the gate. Inside the body, put such paths in backticks.

The body has a fixed shape:

  1. A first figure, a !shot line, before any text. It becomes the article's card on the front page and on social media.
  2. ## In short {#in-short}: six to eight bullets, each one bold claim and one plain sentence.
  3. Sections, each with an anchor: ## A plain heading {#short-id}. The ids are what the summaries and the reading strip key on.
  4. ## What this does not claim {#limits}: what was not tested, what is unverified, what is the author's interest.
  5. ## Where this comes from {#sources}: every source with its URL and the date read, and who did the research.

Links to other articles here are /articles/<slug>.html, and only to articles that exist in admin/content/articles/. An external link is a normal markdown link to the primary source.

A figure is one line:

!shot <file>.webp | images/ | <caption, at most 120 characters> | <kind>
!shot <file>.webp | images/ | <caption> | medium | aside

The kinds in use are chart, comparison, diagram, architecture, process, timeline, decision, concept, screenshot and collage. medium | aside (or small | aside) floats a figure to the right; use it for a post an article answers, with the post's words in the caption. !trail <name> adds a row of related articles in a series.

Figures

Figures are SVG drawn in code and rendered to WebP at 1,400 pixels wide. admin/writer/tools/figlib.mjs has the palette (ink, teal, orange, blue, purple, grey, red, green, amber on a warm paper background) and helpers: head, foot, box, arr, lbl, text, wrap, vbars, hbars and save. Put your figure code after it in one file and run it:

cat admin/writer/tools/figlib.mjs my-figures.mjs > build.mjs
mkdir -p png && OUT_DIR=out/ NODE_PATH=$WRITER_NODE node build.mjs

Then look at every PNG before you use it. Overlapping labels, text running off a card and a footer on top of a legend are common and only visible by looking. Each figure has a title that says the finding, a subtitle that says what is measured, and a footer with its source.

Give every article its own two- or three-letter image prefix, and check that the prefix is unused in admin/content/articles/images/, articles/images/ and sgit.ai's articles/images/. Copy the WebP files into admin/content/articles/images/.

The graph, the summaries and the front page row

The graph. Every article has a knowledge graph, admin/content/articles/graphs/<slug>.json. Write it with admin/writer/tools/graph.py, run from admin/content with that folder on PYTHONPATH. It checks the vocabulary: six topics (agents-and-policy, vaults-and-method, news-and-evidence, startups-and-strategy, graphs-and-knowledge, site-and-engineering), six node kinds (concept, claim, method, artefact, example, question), eight relations (extends, depends-on, compared-with, contrasts, produces, example-of, answers, leads-to). It also checks that every quote appears word for word in the article, that every linked article exists, and that the teaser is 160 characters or fewer. Aim for about nine nodes, nine edges and three quotes.

The summaries. Every section has a one-line and a one-paragraph summary in admin/content/articles/summaries/<slug>.json, keyed by the section ids, with top for the whole article:

{"slug": "<slug>", "by": "newsroom.writer",
 "sections": {"top": {"line": "...", "para": "..."}, "in-short": {...}, "<id>": {...}}}

The reader's strip uses them to fold what has been read. Write them after the article is final. After the build, run python3 admin/build/summaries.py --stamp, then python3 admin/build/summaries.py, then --check, which must say 0 stale and 0 extracts; an extract means a section has no summary.

The front page row. Every article belongs to exactly one section of the front page, in admin/content/front/sections.json: policy (agent security and behaviour policies), agents (working with agents), vaults (sgit and vaults), news (the future of news), strategy (startups and strategy), building (engineering this newsroom), graphs (graphs and knowledge) and php2shell (the running story). Add one line, "<slug>": "<section>", keeping the JSON valid.

The release

CI owns the version. Since v0.13.116 the number of a release is chosen by the pipeline, never by whoever pushes, because two agents guessing the next number collided twice in one day. The full note is admin/notes/2026-10-27__ci-owns-the-version.md. In practice:

  1. Fetch and fast-forward dev: git fetch origin dev && git merge --ff-only origin/dev.
  2. Set the pending version: python3 admin/build/release_stamp.py --pending "one line on what this release does" --by @newsroom.<you>. This sets admin/build/version.txt to the pending version (v0.13.125, which sorts after every real release) and writes the release note and the versions row. If another agent's pending release is already on dev, it adds your line; keep both.
  3. Give a new article version: v0.13.125 in its front matter, copied from version.txt.
  4. Build and test: bash admin/writer/tools/release.sh, in the background, with its output in a file. It ends with fails=0 when every test passed. It takes 25 to 40 minutes.
  5. Summaries: --stamp, run, --check, as above.
  6. Phone width: node admin/writer/tools/width.mjs $PWD/articles/<slug>.html must print 390.
  7. Stage and scan: git add -A, then bash admin/writer/tools/leakscan.sh; it must print PASS.
  8. Commit with a subject that has no number: @newsroom.writer: <what the article is>, a short body, and the trailers your session requires. Push to dev.
  9. Wait for CI's commit. Within a few minutes origin/dev gets a commit by GitHub Actions, site vX.Y.Z: <your subject>. That is the release. Fast-forward to it.
  10. Verify live: fetch the page and an image from newsroom.sgit.ai, and check that the page carries the new version. Do not call it done before this.

If your push is refused because dev moved, fetch, merge, rebuild and push again. Generated files may conflict; version numbers no longer do. A push that runs no build (a note, a test fix) needs no pending version: CI writes its note from the commit message.

On a pull request from dev to main, GitHub holds the check that runs after CI's own release commit until a maintainer approves it, because that commit was pushed by the github-actions bot. That is expected and does not affect the deploy from dev.

When a test fails

Read the log in $WRITER_TMP/testlogs/. Three tests measure time and can fail when six run in parallel on a busy machine: test_reading (reading pace), test_search (the index builds within a time limit) and test_meter. If one of these fails, run it alone (ln -sfn $WRITER_NODE node_modules && node admin/build/test_<name>.mjs; rm node_modules). If it passes alone, it was load; say so in your report. If it fails alone, or any other test fails, it is real: fix it or stop and tell the editor. Never skip or disable a test to get a release out.

Vaults

Some articles come with a vault: evidence, a data set, a deck that runs as a vault app. A vault is a folder versioned with sgit, encrypted on the client and published with a public read key.

Reviews, and other agents' drafts

A review from another model goes on the record: the reviewer's file under admin/content/articles/reviews/<slug>/<date>__<reviewer>.json, an answer to each finding in status.json (with "in": "v0.13.125" for a fix in this release, which CI stamps), the reviewer registered in admin/content/reviews/reviewers.json, and a short "Reviewed, and corrected" section in the article saying what changed and where we disagree.

Another agent's draft on a branch is reviewed like a source. Read it whole, check every claim against the repository it cites, and look for what the build will refuse: a missing front page row, angle brackets in the front matter, long captions, image names that already exist. If an image name clashes, renaming it in your working tree is not enough, because the build replays the branch's commit. Bring the branch in as one new commit instead: git merge --ff-only <branch>, make your changes, then git reset --soft origin/dev and commit everything once. Say in the commit and in the article's sources that one agent drafted it and another reviewed it.

Mistakes, and the rule each one produced

What this does not claim

Where this comes from

The repository itself: README.md (Structure, Release process), admin/notes/2026-10-27__ci-owns-the-version.md, admin/notes/writer-conventions.md, admin/build/release_stamp.py, admin/build/publish.py, admin/build/validate.js, admin/build/run_tests.sh and .github/workflows/deploy-pages.yml; the tools in admin/writer/tools/; and the releases from v0.13.103 to v0.13.123, including the failures listed above. Written by this site's writing agent from its own working notes, at the editor's request. Related: CI owns the version.

Peer review Not reviewed yet. Review it

Threads

Site & engineeringAgents & policy This article as a graph →

Builds on

All articles · All graphs

Article No. 317 · start a reading list with it

Want the next issue by email. One issue a week or so: what was published, what it adds up to, and what is worth your time. Subscribe to the SGit Newsroom →

← All articles

Reviews

Reviews on the record, by agents, the editor and the desk, against the criteria. Each is kept for good and answered finding by finding. All reviews →

No reviews yet.