Report: one repository into six, the first day in numbers
Status: a report, written by dev@php.newsroom at the editor's request on 25 October 2026 ("write a detailed article … as much details as you can, as much statistics as you can … and even some of the challenges"). It is the first of four: this one is the day and its numbers; Report: one source for every file is the design; Report: one repository into six, the challenges is what went wrong and what it taught; Report: one repository into six, how to work in it is the runbook. Measured at site v0.22.5 (v1 commit 30dd7ddd6052), press v1.0.5 and data v0.1.5, between 18:00 and 18:20 UTC.
The site that tracks the two PHP flaws of October 2026 was one repository until 15:31 UTC on 25 October. By 18:12 UTC it was seven: the original (v1, still where every page is built and every agent writes) and six new ones that serve it in parts, each with its own gate, release and address. Every page v1 builds has exactly one owner among the new sites. Every old address answers on every site. No site holds a copy of a file another one serves. None of the six is live yet, for one reason only: GitHub Pages has not been told to deploy them (board row 328, the editor's).
The proposal (why split, and how) and the plan (who does what, in which order) were written before the work: the proposal and the plan. This report is what happened.

The day, by the clock (UTC, 25 October 2026)
| Time | What | Where |
|---|---|---|
| 15:31 to 15:34 | The editor creates the six repositories (…__PHP__press, __data, __refs, __updates, __team, __site), dev as default | GitHub |
| 15:39 | The names, as the editor decided: press (not kit), data (not api), site | v1 v0.21.9 |
| 15:54 | The data API's first version: 49 catalogue entries, 466 files, a schema each | data v0.1.0 |
| 15:56 | The team's records, first import: the board split into one file per row | team |
| 16:02 | The split, in progress, recorded | v1 v0.21.10 |
| 16:21 | The design agent's refactor lands: the line is live on every page | v1 v0.22.0 |
| 17:00 to 17:02 | Pass one: the press cuts v1 at d9af616ffd0b into four sites, each with its own runtime | press v1.0.0, four sites |
| 17:03 | Data imported again at the same commit | data v0.1.1 |
| 17:10 | Pass one recorded | v1 v0.22.1 |
| after 17:10 | The editor: one source for every file, and the Content-Security-Policy maintained to allow it; every release after the first adds one to the last number | this session |
| 17:25 | One resolver for every URL a script builds (assets/route.js) | v1 v0.22.2 |
| 17:32 | The four files the scripts fetch join the data API | data v0.1.2 |
| 17:38 | Every data/ request on the split sites goes to the API | v1 v0.22.3 |
| 17:46 | The press publishes v1's assets; the partition stops copying | press v1.0.1 |
| 17:47 | Data at v0.22.3 | data v0.1.3 |
| 17:54 | The control room loads under a view address (a bug found by the browser test, broken on v1 too) | v1 v0.22.4 |
| 17:58 | Four more runtime files, assets at v0.22.4 | data v0.1.4, press v1.0.2 |
| 18:00 to 18:02 | Each site answers its own VERSION; the main site staged at the name its DNS record has | press v1.0.3, v1.0.4, four sites |
| 18:07 | The work recorded (the plan's Progress, REALITY, the board) | v1 v0.22.5 |
| 18:11 to 18:12 | The chain again from v0.22.5: assets, data, four cuts | press v1.0.5, data v0.1.5, four sites |
In under three hours: 6 repositories went from an empty README to a working system; 8 releases of v1 (7 for the split; v0.22.0 was the design agent's), 6 of the press, 6 of the data API, 4 released cuts of each site. Every release went through its repository's own release script and gate; nothing was pushed by hand, nothing force-pushed, nothing to main.
The seven repositories
| Repository | Serves | Commits | Files tracked | Bytes tracked | Version |
|---|---|---|---|---|---|
v1, …__PHP | php.oct.2026.newsroom.sgit.ai (live) | 348 | 3,502 | 102.7 MB | v0.22.5 |
…__PHP__press | press.php.oct.2026.newsroom.sgit.ai | 7 | 940 | 42.8 MB | v1.0.5 |
…__PHP__data | data.php.oct.2026.newsroom.sgit.ai | 7 | 4,216 | 108.2 MB | v0.1.5 |
…__PHP__team | team.php.oct.2026.newsroom.sgit.ai | 7 | 2,094 | 35.9 MB | cut from v0.22.5 |
…__PHP__site | site.php.oct.2026.newsroom.sgit.ai until the cutover | 5 | 1,354 | 16.0 MB | cut from v0.22.5 |
…__PHP__refs | refs.php.oct.2026.newsroom.sgit.ai | 5 | 1,674 | 28.5 MB | cut from v0.22.5 |
…__PHP__updates | updates.php.oct.2026.newsroom.sgit.ai | 5 | 1,176 | 7.8 MB | cut from v0.22.5 |
The press and the data API are big because they keep every published version whole (v/<version>/), which is the point: a version is an address that never changes. The data repository holds six versions of 474 files (12.8 MB each) plus its working copy; the press six versions of its 131 files (6.1 MB of assets each).
The four sites
Each site is v1's committed output at one commit, cut by first path segment (sites.json in the press says who owns which section). A page another site owns becomes a redirect page at its old address, so old links and search engines' indexes land.
| Site | Sections | Pages of its own | Other files of its own | Redirects | Page bytes | Redirect bytes |
|---|---|---|---|---|---|---|
| site | everything not named below: the homes, briefings, questions, stories, tools, the risk graph's pages | 230 | 245 | 865 | 11.4 MB | 0.64 MB |
| refs | sources, facts, actors, wikipedia, graph, fractal, review, code, pulse, vaults | 563 | 564 | 532 | 24.4 MB | 0.36 MB |
| updates | views, versions, updates, whatsnew, feeds | 60 | 66 | 1,035 | 4.9 MB | 0.75 MB |
| team | team, admin, sherpa, feedback, collaborators, status | 242 | 245 | 852 | 13.4 MB | 0.62 MB |
| all four | 21 sections | 1,095 | 1,120 | 3,284 | 54.1 MB | 2.37 MB |
v1 builds 1,096 pages (2,228 files in its outputs.txt): the 1,095 above, each owned once, and the 404 router, which every site keeps its own copy of because it is how GitHub Pages answers a view address (/agencies/as/security/). The "other files" are each page's markdown twin and a few feeds.
A redirect page is 600 to 750 bytes: a canonical link, a meta refresh, noindex, and one sentence with the link. The 3,284 of them cost 2.37 MB in all.

The links, rewritten
The partition reads every href and src of every page it writes. On the four sites, at v0.22.5:
| Link | site | refs | updates | team | All |
|---|---|---|---|---|---|
| relative, to the same site | 28,843 | 18,441 | 1,782 | 15,641 | 64,707 |
| absolute, to another of the four sites | 18,508 | 86,331 | 10,891 | 42,425 | 158,155 |
| to the press (an asset) | 3,741 | 10,142 | 1,081 | 4,215 | 19,179 |
| to the data API (a data file) | 27 | 31 | 7 | 4 | 69 |
| to v1's sources on GitHub | 2 | 13 | 1 | 135 | 151 |
| absolute, elsewhere (the outside world, a canonical address) | 3,607 | 7,617 | 685 | 2,672 | 14,581 |
refs carries the most cross-site links because every source and fact page links back to the stories and the claims that cite it, which the main site owns. team carries the most links to GitHub, because its pages (the appsec reviews, the agents' rounds) link to markdown sources that no site serves; those go to the file in v1's repository.
30 links do not resolve in v1 either; the partition leaves them as they were and lists them in each site's press.json: 27 on one prototype page (/admin/design/line/agencies/, one directory too shallow, board row 329, story-site's), two on graph/component/ (its page and its markdown twin link data/graph.json relative to the page) and one markdown ellipsis in an advisory (SA-2026-003). They are v1's to fix at the source.
The data API
| Catalogue entries | 57 (15 story, 9 evidence, 8 risk and compliance, 8 runtime, 6 ontology, 5 desk, 3 graphs, 2 code, 1 fact-check) |
| Files in a version | 474 (one folder, wikipedia/, holds 418 of them) |
| Bytes in a version | 12.8 MB |
| Schemas | 56, one per top-level file, inferred once and then kept |
| Versions | 0.1.0 to 0.1.5, six in all, each immutable, each with a manifest.json of sha256s |
| Its gate | 6.1 s: JSON, schemas, provenance (418 sources; every claim cites one that exists; 727 risk-graph nodes and 1,357 edges, each edge joining two nodes and saying how it is known), every version against its manifest, nothing published changed, the same bytes on a second publish, no credential shapes |
"Runtime" is the group the pages' scripts fetch: items, telemetry, contributors, collaborators, control, personas, stack, subscriptions. Two of them (telemetry and subscriptions) hold their lane's write-only append token, as v1 always has; a published version keeps the token it was published with (flagged to security).

The press
| What it is | sites.json (who owns which section), the partition, each site's gate and release, and v1's assets, published once |
| Assets in a version | 122 files, 6.05 MB: 53 scripts, 41 PNG, 13 stylesheets, 5 JSON, 3 JPEG, 2 modules, 2 templates, 2 markdown, 1 SVG |
| Versions | 1.0.0 to 1.0.5 |
| Its gate | 1.1 s |
| A cut | 0.8 s (site) to 1.2 s (refs) |

The team's records
The team repository holds two things: the team's pages at its root (cut by the press like the other sites) and, under records/, what the agents write, imported from v1 until the cutover. The board, one JSON object in v1, is one file per row here, so two agents adding rows never touch the same file.
| Records | Files |
|---|---|
| Board rows | 329 (the two rows that both took the id 013 are kept, and named) |
| Schedule cards | 13 |
| Run records | 40 |
| Messages | 26 |
| Members' folders (role, policy, status, debriefs) | 211 files |
| Vault registers | 11 |
| Briefs | 65 |
Its records' gate takes 0.11 s; its pages' gate 2.1 s.

The gates, timed
| Gate | Time | What it checks |
|---|---|---|
v1 (admin/build/validate.py) | about 75 s | the whole site, as before |
| data | 6.1 s | see above |
| press | 1.1 s | sites.json assigns every section once; every version matches its manifest |
| team records | 0.11 s | every board row has an id, a title, a status and an owner; every card and register parses |
| site pages | 0.31 s | every file is what the press wrote, every link resolves, every cross-host link names a file that host's pinned version serves, CNAME, no credential shapes |
| refs pages | 6.9 s | the same, over 1,667 files |
| updates pages | 0.57 s | the same |
| team pages | 2.1 s | the same |
The point of the split is in that table. A change to the references is checked in 7 seconds instead of 75, and a change to the team's records in a tenth of a second.
What one source for every file saved
The first cut (press v1.0.0) gave every site its own copy of the assets and the data, because the pages' policy allowed scripts and requests only from their own host. Each site carried 726 copied files, 25.95 MB: 2,904 files and 104 MB across the four, every one a second (or fifth) source for a file that already existed. The editor ruled it out the same afternoon ("we don't want to have engineering issues, and ironically security issues, by having multiple sources for the same files"), and the policy changed instead. At v1.0.3 the copies were gone: each site keeps only its pages, its redirects, VERSION, the 404 router and .well-known/. How, and what the policy says now, is Report: one source for every file.
The browser test
The six hosts were served from their repositories in Chromium (Playwright intercepting each host name), and these pages loaded: the four front pages; sources, the graph, the parties, the component page and the Wikipedia article on refs; the stack tool, the risk graph's explorer and its changes, the reader, your desk, an article and a view address on the main site; what's new and the feeds on updates; the status page, the control room and the collaborators on team; a moved address on the main site (it redirects to refs). On each: no missing file, no Content-Security-Policy violation, the Ask pane opens. A page makes 23 to 27 requests to the press, 2 to 3 to the data API and 1 to 3 to its own site.
Separately, every executable inline script on the four sites (198) was hashed and checked against its own page's policy: all 198 are allowed, as v1's 195 are on v1 (the three more are the 404 router's copies).

What is left
- Deploy. Each of the six repositories needs its Pages source set to "Deploy from a branch: dev, / (root)" (board row 328). The press and the data API first: every page of the other four loads its scripts from the press.
- Pass two. Each site's sources (its pages' content and the build code that writes them) move into its repository and the build library into the press, so v1 stops being where every page is built. Until then every v1 release is followed by the chain: the press takes the assets, the data is imported, the four sites are cut (Report: one repository into six, how to work in it).
- The cutover. The agents' cards and
WAKE.mdname their repositories; php.oct.2026.newsroom.sgit.ai moves to the site repository; v1 is renamed…__PHP__v1, archived and read-only. The editor's go.