Plan: one repository into six, the implementation
Status: the plan for the proposal the editor agreed on 25 October 2026 ("I think that's the way to do it"), written by dev@php.newsroom at his request. The proposal (why, what goes where, versions by URL, not submodules) is on the briefs page as "Proposal: one repository into six". This brief says who does what, in which order, and how to tell it worked. Measured on site v0.21.5.
What makes it possible now
A Claude session can now hold more than one repository. So one session can attach today's repository and the six new ones together, and cut the site in one pass, with every move checked against the original in the same working tree. Afterwards each agent's session attaches only the repositories its schedule card names. That is least privilege by construction: an agent cannot write a repository it does not hold, whatever its prompt says. It is also the basis of the behaviour policies the editor wants to write next: per-repository rules, required checks and owners, enforced by GitHub instead of by a check every agent has to run.
The names
Decided by the editor on 25 October 2026:
- The six repositories are
press,data,refs,updates,teamandsite. press, notkit. It typesets (the build), proofs (the gate) and publishes (the release) every site, and supplies the shared components.data, notapi. "API" is kept for the newsroom's main API, which the site already uses for billing.siteis the main UI's repository.
The new repositories get their final names from the start. Only today's repository is renamed, once, at the cutover. Every name starts with SGit-AI__Website__Newsroom__2026__Oct__PHP, written … below:
| Repository | Site | Live from |
|---|---|---|
…__PHP__press | press.php.oct.2026.newsroom.sgit.ai | day one (this story's own for now, like its name; the editor, 25 October) |
…__PHP__data | data.php.oct.2026.newsroom.sgit.ai | day one |
…__PHP__refs | refs.php.oct.2026.newsroom.sgit.ai | day one |
…__PHP__updates | updates.php.oct.2026.newsroom.sgit.ai | day one |
…__PHP__team | team.php.oct.2026.newsroom.sgit.ai | day one |
…__PHP__site | next.php.oct.2026.newsroom.sgit.ai until the cutover, then php.oct.2026.newsroom.sgit.ai | cutover |
today's …__PHP | stays as it is until the cutover; then renamed …__PHP__v1, archived, read-only |
Why not build in a "php-v2" repository and rename it to the main name later:
- The old name stops redirecting. GitHub redirects a renamed repository's old name only until another repository takes that name.
- Sessions would push to the wrong repository without warning. Today 17 lines in the schedule cards, the wake instructions and
CLAUDE.mdname the repository exactly. Any session not yet updated would push into the new repository. - Distinct names fail loudly. A missed update errors instead.
- Nothing else depends on the name. Renaming the old repository keeps its clones and pushes redirecting. A Pages custom domain belongs to a repository's settings, not its name.
Progress
- 25 October: the editor created the six repositories, with
devas their default branch, Pages and DNS, and attached all seven to dev's session. - data: v0.1.0 is on
dev: 49 catalogue entries (466 files) imported from v1, a schema for every top-level file, immutable/v/0.1.0/with a manifest of sha256s,/latest/,versions.jsonand a front page. Its gate takes under a second. - team: its first import is on
dev. The board is split into one file per row (323 rows; the two rows that both took 013 are kept and named). It also holds the 13 schedule cards, the runs and messages, 29 members' folders, the registers, the briefs, the Sherpa's material andWAKE.md. Its gate takes a tenth of a second. - Waiting on the design agent's UX refactor: press, refs, updates and site. They carry the layout it is reworking, so they move after it, and with less code.
Step 0: the editor's setup (before the session)
1. Create the six repositories in the SGit-AI organisation, each with a dev branch as default, empty but for a README.
2. For each, turn Pages on with "GitHub Actions" as the source, and add its custom domain. In DNS, the same record as today's site (a CNAME to sgit-ai.github.io., TTL 300):
press.php.oct.2026.newsroom.sgit.ai CNAME sgit-ai.github.io. data.php.oct.2026.newsroom.sgit.ai CNAME sgit-ai.github.io. refs.php.oct.2026.newsroom.sgit.ai CNAME sgit-ai.github.io. updates.php.oct.2026.newsroom.sgit.ai CNAME sgit-ai.github.io. team.php.oct.2026.newsroom.sgit.ai CNAME sgit-ai.github.io. next.php.oct.2026.newsroom.sgit.ai CNAME sgit-ai.github.io.
php.oct.2026.newsroom.sgit.ai needs no new record: at the cutover only its Pages setting moves. Verify sgit.ai in the organisation's Pages settings, so no other account can claim a subdomain before its repository serves it, and turn on HTTPS for each once its certificate is issued.
3. Give the Claude GitHub app access to the six, and the same rulesets as today's repository: no force-push, no deleting dev, main protected.
4. Start one session with all seven repositories attached, and give it the go for the steps below.
Step 1: the one big session
The session works in all seven at once. Agents keep releasing into today's repository while it works. Every move reads today's repository at a recorded commit, and step 1.8 replays what landed after it.
1. press. Lift the build library out of admin/build/build.py (7,847 lines) and design.py:
page(), the layout,E(),U()andJ(), the markdown and article renderers (figures, split, slider, diff),render_md_file();- the generic part of the gate (links, sitemap, determinism, credential shapes);
release.shmade per-repository (one config file: what to build, what to check);security_check.py;- the shared components (graph, dials, Ask, telemetry, the reader's vault, compare).
Publish v1.0.0 at press.php.oct.2026.newsroom.sgit.ai/v/1.0.0/ with a sha256 for every file. Each consumer keeps a vendored copy in press/, fetched by press sync 1.0.0 and checked against those sums, so a build never needs the network. Security reviews the press before v1.0.0 is published (it holds the gate and the release script).
2. data. Move data/*.json that are evidence or derived, and their exporters:
- the files:
export_vault.py,export_watch.py,export_loops.py,grc_history.py,release_pages.py; - a JSON schema for every file, written from today's files;
- publish v0.1.0 at
/v/0.1.0/withmanifest.json, plus/latest/; - its gate: schemas, provenance (every claim's sources exist, every graph edge's basis), determinism.
3. team.
- Move the board, splitting
data/admin.json's board intoboard/<id>.json: today's ids kept, new ones per writer (dev-0001). - Move the schedule cards, the run records, the messages and notes, every member's folder (
admin/content/agents/), the registers, the briefs,schedule.py,agents.py,WAKE.md, the control room, the status pages. - Every policy's
scope.writesgains a repository name (team:board/dev-*). - Its gate: schemas and the scope check, in seconds.
4. refs. The source pages (about 840 files), what each source says, the claims as evidence; built from data at a pinned version.
5. updates. The state of affairs and its versions, the desk, what is new, the line, the feeds; built from data at a pinned version.
6. site. What is left: the homes, briefings, questions, stories, tools, the risk graph's pages. Its routing follows story-site's two briefs of 25 October, "Refactoring the site to URL paths and a single page" and "The 404 router, and a site with two modes": the persona in the path, and the 404 router, which also answers the moved addresses of step 1.7. Built from data and the press at pinned versions, served on next.php.oct.2026.newsroom.sgit.ai.
7. Every old address still answers. Each of today's 1,058 pages, with its markdown twin, either exists in the new site or redirects to its new home. Two examples: /team/… goes to team.php…, /sources/… to refs.php…. Today's sitemap is the list. The site's gate checks every entry answers, so nothing a reader or a search engine kept breaks.
8. Parity, then the replay.
- Parity: a report compares every page's main text in today's site with the new one. It uses
release_pages.py's comparison: same words, version numbers masked. Every difference is listed and explained. - The replay: whatever landed in today's repository after the recorded commit is carried over, and the report is run again.
9. The session's debrief: the repositories, the commits, the parity report, what did not move, and what each agent must change in its card.
Step 2: each agent reviews its own repository
The editor wakes each agent's own session with its repositories attached. Each agent:
1. reads the parity report for its pages and its data;
2. fixes what is its own;
3. updates its card, naming the repositories it attaches and its new scope.writes;
4. confirms in a run record in team.
WAKE.md (the conductor's) changes once: step 1 says "attach the repositories your card names".
Step 3: the cutover (the editor's go)
1. The parity report is clean, and every agent has confirmed its card.
2. The custom domain php.oct.2026.newsroom.sgit.ai moves from today's repository to …__PHP__site (its CNAME file and Pages setting).
3. Today's repository gets one last release: a notice that it is archived, with a link to the new home. It is then renamed …__PHP__v1 and archived read-only.
4. The schedule's next wakes run against the new repositories. The conductor's first pass afterwards checks that every agent left a run record in team.
Going back is one step while the old repository is still there: move the custom domain back.
How to tell it worked
| Measure | Today (v0.21.5) | Target |
|---|---|---|
| Files a run record's release rewrites | about 1,936 | 1 in team, no reader's page |
| Gate for a release in team, data or updates | 74 s | under 20 s |
| Release messages naming a conflict, a collision or a renumbering | 28 in three days | none from the board; rare elsewhere |
| Agents able to write a repository outside their card | all of them | none |
| Old addresses answering | every one of today's 1,058 pages |
What does not move
- The vaults: the source watch
7r83qic5, the evidence vault3ytzxm3g, pulse, telemetry and the lanes, with every key where it is. - The telemetry lane and its tokens.
- The editor's root key and the pki.sgit.ai rules.
CLAUDE.md, copied into each repository, with each copy naming its repository's rules.
Decisions still the editor's
1. Whether data, updates and team build at deploy time (commit only sources) or commit their output as today. The proposal recommends deploy-time builds; it is a workflow change, so it goes through security review.
2. A day for the session, and whether the scheduled agents pause during the replay (step 1.8) or keep running.
3. Whether the persona-first proposal (parked on dev's branch) is built in the new site straight away, or after the cutover.