newsroom.sgit.ai / admin / versions

Release history

Every push to dev is a release: CI validates the site, verifies the version bump, tags the commit v{release}.{major}.{minor}, and deploys to GitHub Pages. How it works.

VersionDateWhat shipped
v0.5.5 29 Sep 2026 The gate inside the published vault was broken again, by the release that added the app.

The vault’s README tells a reader to run python3 build/gates.py to re-derive every published count. v0.5.4 broke it twice over: the new published-or-private checks load data/vault-audit.json, which is a record about the vault and is deliberately not inside it; and the app was excluded from the page checks by its path, vault-app/index.html, which is where it lives in the repository and not where it lives in the vault. In the bundle it sits at the root, so the gate checked the app as if it were a page of this website and reported three failures about a file that has no business carrying site chrome.

Both fixed the same way as the v0.5.1 correction: the audit checks are skippable and say so by name, and the app is now excluded by identity rather than by path — it is whatever app.json names as its entry, which is true in both layouts. Verified by cloning the published vault with the published read key and running the gate inside it: clean, with the two skips named.

Third time this instruction has been caught failing, and the reason is always the same: the repository is not what was published, and only opening the published thing finds it. That check is now part of the release routine rather than something done when it occurs to us.

v0.5.4 29 Sep 2026 One vault, not two — and it opens as an app. Plus the release news on the front page, and the “design, not built” badge retired.

The outreach vault should never have been published. It holds who we are contacting, through which route, and what we plan to say — ours until it is sent, and about other people before it is about us. Deleting the line from a page would not have been a remedy: revocation is not retroactive, and anyone who fetched the objects keeps them. So the vault was rekeyed with sgit vault move: every object re-encrypted under a new key, pushed under a new identity, and the old vault hard-deleted from the server. The published key now recovers zero files, which we checked by cloning with it. The correction in full.

And the very next run of the publishing script re-published a key for it. Pushing a vault and publishing one are different acts and the script did not know the difference; it does now, from a table that says which vaults may carry a published key. Two new gates: a vault is PUBLISHED or PRIVATE with opposite obligations — a published one must carry a public read key the audit actually used, a private one must carry no key — and every revoked key is hunted across the whole repository, because llms-full.txt still carried this one after llms.txt had been fixed by hand.

The corpus vault is now a vault app. app.json with present: true, so the SG/Send host launches index.html from inside the vault instead of showing a file tree: the finding, the twenty-one pieces, every sentence typed and anchored, and the vocabulary — read from the vault’s own encrypted files in the reader’s browser over the sg.vfs bridge, with no server, no account and no database. It follows the authoring contract to the letter (all CSS and JS inlined, nothing declarative against a vault path, an inlined fallback so it renders saved to disk, and sg-app-ready posted when it has drawn), and the build checks all of that before it ships. The vault page now carries screenshots of it, in the shape sgit.ai uses.

Two site-wide changes. The design, not built badge is gone from the nav: it was written when everything here was a design, and it now undersells four sections that run, a published vault and a corrected record. The honest sentence on the front page and /shipped/ still draw that line properly, where there is room to draw it accurately. And the front page now opens with what changed lately — the newest six releases, generated from the release record so the page cannot claim an update that did not ship.

v0.5.3 29 Sep 2026 The outreach brief: what the collaborating agent is asked to do, to whom, in what order, and with what words.

world-news-day/outreach/agent-brief.md, in the outreach vault beside the protocol it depends on. It carries the established findings with every figure filled from the data files rather than typed; the links to send, leading with the recipient’s own piece’s page rather than with our argument; three tiers in order, the commissioner first because a licence is theirs to name and not an author’s; the nine organisations with a role address, the nine reachable only by contact page or LinkedIn, and the nine with no route at all; three message templates; what to record after every action; and the pacing, including one follow-up per target and never a second.

Two rules in it are worth naming here. A declined is final — recorded, and no other channel and no later attempt. And do not go looking for a personal address: where no route was established under the published rules, none is to be found by other means; a published organisational route can be proposed as a noted action and added at the next build.

The brief is generated, so it can be rebuilt after any recapture and its numbers cannot drift from the section’s. Both vaults were re-pushed and re-audited: 14 hits in the corpus vault and 22 in the outreach vault, all cleared, none unexplained.

v0.5.2 29 Sep 2026 The two vaults listed and described the way sgit.ai lists its thirty-seven — and the live page was pointing at a vault that did not exist.

The bug first. build/vault.py rewrote data/vault.json on every build and replaced the real vault id and read key with the BUNDLE's name and a null. The deployed page told readers to open wnd-2026-09-29 with an empty key. Nothing caught it because every check tested the repository rather than what the page claimed; a new gate now cross-checks the id and key on the page against the vault the audit actually opened, and fails if the page publishes the bundle id.

The method is not ours. sgit.ai writes down how it publishes a vault in seven steps for another agent to follow, serving two absolute rules: read keys yes and vault keys never, and audit BEFORE the key rather than after, because revocation is not retroactive. build/vault_audit.py reimplements those checks rather than importing them, so the code that classifies a credential and the code that scans a clone can be read beside the result.

What it does, all of it with the published read key and no token. Classifies both credentials; clones each vault; derives files, size, commit depth, HEAD and top-level layout from the clone rather than from the repository; scans every text file against eight patterns; and runs the negative control — an all-zeros read key, which must fail, and does, because the index address is derived from the key. 14 hits in the corpus vault and 11 in the outreach vault, every one cleared and none unexplained: they are the organisations' role addresses the contacts map publishes on purpose. Ruling a hit out is the work, so each carries the rule that cleared it, and an unexplained finding now fails the build.

And the vaults now open as pages. Each carries a _page.json at its root, so opening one shows what it is and what the rules are instead of whichever file sorts first — which for the corpus vault was MANIFEST.json, a list of hashes, an accurate and useless first impression of a piece of journalism.

Two more of the same family of bug. data/vault-audit.json was inside the bundle, so each audit found the previous audit's findings and the count grew from 14 to 39 in one cycle; it is now excluded, with the manifest that listed itself and the vault record that carried its own hash. The rule those three produced: a record about an artefact does not live inside it. And our own key tripwire fired on sgit clone sgit_public_read_… — the exact line a published vault page must carry. That is sgit.ai's own recorded mistake, and their rule applies: make it precise, not stricter.

v0.5.1 29 Sep 2026 Cloning our own published vault with our own published key found two defects that every internal check had missed.

The vault’s README tells a reader to run python3 build/gates.py to re-derive every published count. That instruction did not work. The gate resolved its paths from the repository layout, so inside the bundle it looked for world-news-day/data/ beside the bundle and died. A published instruction that fails is worse than no instruction: it invites somebody to check us and then tells them the fault is theirs. The gate now detects which layout it is in — by the presence of the whole-site build tooling, not by data/, which exists in both — and inside the bundle it names the four checks it skips and why, because they are about this website’s pages rather than about the data.

And the pushed corpus vault was two releases stale. publish_vaults.py only filled a working copy that had no vault in it yet, so every re-run pushed the same bytes: the vault was created before the fractal layer existed and silently stayed that way while its own page advertised files it did not contain. It now refreshes the contents on every run without touching .sg_vault.

Both were found the same way — by cloning the published vault with the published read key and running the check the vault tells you to run. Verified end to end: a clone with the public key now re-derives all 1,070 claim classifications, re-hashes all 43 frozen files, and re-runs every licence count, from a read-only vault a stranger can open.

Also: validate.js now fails on a page whose nav or footer block is empty. Pages are generated with empty chrome that chrome.py fills; skip that step and every page ships with no navigation and no version badge — and every other check still passed, because they all test what a page says rather than whether it has any furniture at all. That happened in v0.5.0 and was caught by reading a diff, which is not a control.

v0.5.0 29 Sep 2026 The fractal layer: all 1,070 sentences of the twenty-one op-eds, typed, anchored and connected — plus a page for each piece, and LinkedIn routes.

Until now the section treated each op-ed as one node. This builds the level below and the level above at once. Each piece becomes its own graph of claims; the pieces connect to each other through a shared vocabulary; a term is a graph of everywhere it is used. Same shape at every zoom, which is what makes it fractal rather than merely big.

1,070 sentences, each typed by a published formula in data/claim-rules.json: 828 flat assertions, 79 hypotheses, 51 quantified observations, 41 evaluations, 31 questions, 24 attributed statements — and 16 proposals. Twenty-one of the most senior voices in news, asked what journalism is for, and sixteen sentences in twenty thousand words that propose doing anything. The rule order was deliberately set so that attributed statement is tested early, ahead of proposal and hypothesis: it is the only class that points outside the piece, and ordering it late would have undercounted attributions and flattered our own argument about evidence.

How this avoids republishing anything. A claim node carries a type, an offset into the frozen prose, a length, and an anchor of at most 8 verbatim words — enough to find the sentence, far short of reproducing it. The sentence itself is stored nowhere. The gate checks every anchor is in the bytes and under the limit, and re-derives all 1,070 classifications from the frozen prose with the published rules.

And the finding about meaning. 38 vocabulary terms are used, 33 by more than one piece — and there are 4 places in 1,070 sentences where anybody says what one of those words means. The vocabulary is shared; the definitions are assumed. A looser rule found 29, but read “the decline of local news is a global phenomenon” as that piece defining local news — so it was tightened to require the term to be the subject of its own sentence, both counts are published, and the 25 given up are stated as a cost. The only term stated twice is stated by the same author both times, and the gate checks that label against the bylines rather than trusting it, because calling a repetition a disagreement would manufacture a finding.

Twenty-one piece pages under /world-news-day/pieces/: every sentence typed and anchored, the claim profile beside the corpus average, who wrote it with the published route to them, what it cites, the vocabulary it shares with pieces that never cite it, and a mapping to this site’s own argument by a published rule over the terms used — which claims only that the piece uses those words and that we have written about them.

LinkedIn, only as an organisation offers it. 8 company pages taken from frozen bytes we already held. Personal profiles are published only where the slug is an author of this corpus, letter for letter: 12 were found and dropped and 0 passed — including a near miss, because three of the four profiles on one page belong to people with nothing to do with that newsroom, and “probably the same person” is not a standard for publishing somebody’s profile as theirs.

One rule was loosened and bounded rather than quietly relaxed: each author’s role line, exactly as affiliations.json records it, joins the permission statement as an exempt quotation — because the affiliation claim is a reading of that line. The exemption is enumerated, not pattern-matched, and the gate fails if it ever grows past 400 words of the corpus’s 20,060.

v0.4.4 29 Sep 2026 Two encrypted vaults, pushed and readable — the corpus, and a second one that the agent at riskmandate.ai works in.

The corpus vault (wnd-2026-09-29) holds the twenty-one op-eds as frozen bytes, every derived dataset, the build code and the gate: 107 files. It is finished on the day it was made. The outreach vault (clsc1dg4) is the opposite kind of thing — append-only, and it will move every time a message is sent or answered. It carries 27 target files, a protocol.md, a brief, an action log with a JSON schema and a closed list of verbs, and 0 actions: nothing has been sent. Its contents are generated into world-news-day/outreach/ so anyone can rebuild them and diff.

Why two and not one. The first is a record of what somebody else published, safe to hand to anyone including the people it describes. The second is a record of what we do about it, and holds who we are contacting and what we plan to say. Different claims, different failure modes, different audiences — sharing a history and a hash chain between them would be a mistake in both directions.

Read keys are published; vault keys are not. Both pages now carry a sgit_public_read_… key, derived one-way and granting read and only read. The vault keys were never printed, copied or written to any file by the publishing script: it derives the read key in memory and leaves the credential where sgit put it. A new gate fails the build if any private key shape reaches data/*.json.

And the tripwire that would not have fired. The whole-site key-leak check had been written against a UUID-shaped vault id. When real vaults were created, sgit issued keys of the form sgit_private_vault_<…>:<id> — which that pattern does not match at all. It now matches the real prefixes by name, and the archive is no longer exempt, because a key committed into an archived copy is exactly as leaked. A tripwire satisfied by the absence of a shape nobody uses is not a tripwire.

A third gate now runs over the outreach vault before it is pushed: no address in it may be anything but an organisation's role address, by the same published two-part rule the contacts map uses.

v0.4.3 29 Sep 2026 The argument, as one piece written to be sent: Free to republish is not a licence.

Seventeen hundred words for the twenty-one people who wrote the corpus, and for anyone else who publishes open material without saying so in a form a machine can read. It opens by saying what is good about the act — twenty thousand words given away by people whose day job is deciding what stays behind a paywall — and then asks the question a machine asks. All twenty-one grant permission; none names a licence; the terms are stated three different ways; twenty-one of twenty-one already ship schema.org JSON-LD and none populates its license field.

It carries the aggregate too: nineteen of twenty-one pieces are about truth and facts, eleven raise AI, three mention copyright or licensing at all; eleven of twenty-one offer the reader no outbound link whatsoever; and of the twenty-three domains cited between them, no two pieces point at the same one. It says plainly that the diagnosis in the corpus is shared and correct, that what is missing is a mechanism, and that we are not a neutral party — naming which parts of our own stack are designs rather than things that run.

Every figure in the prose is a token filled from the data files at build time, not typed, so the article and data/*.json cannot disagree, and the build fails on an unfilled token. The markdown source ships beside it under CC BY 4.0 at world-news-day/content/ — the piece asks publishers to license their work in a form a machine can read, so it does.

The last section is the one that took the longest to write: an account of this section publishing a claim about WAN-IFRA's infrastructure more strongly than the evidence supported, withdrawing it, and the gate that now fails the build if the withdrawn claim reappears without the correction beside it.

v0.4.2 29 Sep 2026 A correction about the publisher of the corpus, made in public — and a contacts map built under rules published before the looking started.

What we got wrong. v0.4.0 said the World News Day announcement was “the one page in the beat a machine cannot read”, on the evidence of two refused attempts. wan-ifra.org is served through a JavaScript-challenge firewall that refuses some automated requests: going back to the same host for an unrelated reason, it answered 200, and a third attempt returned the full 59 KB page. A refusal observed twice is a fact about two attempts, not a property of a page. The announcement is now a registered, hashed source; every attempt is counted and recorded with the size and hash of what came back; and the terms it states — “All of the op-eds are free to republish with appropriate credit” — are read from the frozen bytes instead of quoted by hand. The hand-quoted sentence turned out to be verbatim, and the two-statement finding stands, now anchored on both sides. The correction in full, with the rule it produced, and a gate that fails the build if the withdrawn claim appears anywhere without the correction beside it.

How to reach them. Not one of the twenty-one pages offers a way to reach its author or its publisher: no contact address, no author URL in the structured record, no press line. So the map was built by going to the organisations’ own sites, one hop each, under rules fixed in data/contact-rules.json before the fetching started: organisations and never people; a published list of role local parts; four published tests before a site counts as established; and every address re-derived from frozen bytes by the gate. Result: 20 of 27 organisations established, 14 with a contact page, 11 role addresses publishable out of 43 seen, and 15 of 23 authors with any published route — all of it via an organisation.

Three pages were fetched and deliberately not kept. A page carrying ten or more addresses of named people is a staff directory; the Globe and Mail’s publishes the direct address of seventy-nine journalists. Those pages are public, so this is not secrecy — it is that freezing a staff directory into a repository and shipping it in a downloadable bundle makes it materially easier to scrape than the publisher made it. The URL, the hash and the counts are recorded so the count can be re-checked; the cost of that choice is stated rather than hidden. Organisation pages that are kept are stored gzipped with the SHA-256 of the original bytes, which the gate decompresses and re-verifies: eleven megabytes of script bundle became two, with the anchoring unchanged.

The vault bundle now carries all of it: 104 files, 2.68 MB, SHA-256 02816a3dabac7085a01010d7….

v0.4.1 29 Sep 2026 The World News Day corpus as one downloadable bundle — and the section declaring its own licence in the field it says the corpus leaves empty.

The vault: vault.zip, 64 files, 0.83 MB, SHA-256 72920f612e069f096f6a8e70…. Every frozen op-ed and REST record, every derived dataset, the build code and the gate that checks it, in one file. Built deterministically — the same frozen bytes produce the same zip, hash for hash — so the digest is a fact about the contents rather than a record of when the build ran. Two circular dependencies were caught getting there: the bundle contained the record of its own hash, and the section manifest listed itself.

Two sets of terms, on the bundle’s own face. Our description, counts, graph, transcription and code are CC BY 4.0 — named, versioned, with a URL, and declared in licence.json. The twenty-one op-eds under sources/frozen/ are not ours and are not relicensed; the README quotes the publisher’s own sentence and says plainly that it grants the reader nothing over somebody else’s work. The bundle carries the frozen third-party pages, which departs from this publication’s standing rule that a delivered vault holds no copies of somebody else’s pages, and the reason is written into the bundle rather than left implicit.

No sgit vault has been pushed, and the page says so. Creating one needs an SG/Send access token; this build environment has none, and a section about licensing does not invent a credential or publish a key. PACKAGE.sh inside the bundle carries the exact commands, and data/vault.json records "pushed": false and "read_key": null. When a vault is pushed the read key goes there — never the vault key.

And the part of the argument that can only be made by doing it. Every page in the section now carries schema.org JSON-LD with license, copyrightHolder, copyrightNotice, usageInfo and isAccessibleForFree, plus a rel="license" link — the five fields the section counts as unused on all twenty-one — and a new gate fails the build if a page loses any of them, or if the notice stops saying that the licence covers our description and not the op-eds.

v0.4.0 29 Sep 2026 A new section, and the first time this publication has turned its method on somebody else’s open corpus: World News Day 2026 — twenty-one op-eds, free to republish, under no named licence.

For World News Day on 28 September, WAN-IFRA and the Canadian Journalism Foundation commissioned twenty-one opinion pieces from editors, publishers and directors from Manila to Managua and made them free to republish. All twenty-one were fetched, frozen to a dated snapshot, hashed and described here — and none of the prose is republished. Forty-two frozen files: the page as served and the record from the publisher’s own undocumented WordPress REST API, for each piece.

The finding, derived from the bytes by two separate implementations. All 21 carry a permission to republish. 0 carry a licence with a name — no Creative Commons, no rel="license", no copyright notice, nothing with a version and a URL. The permission exists only as a sentence at the foot of the prose, in two wordings, and the announcement states the terms a third way: the articles require republication “in full” and never mention credit; the announcement requires “appropriate credit” and never says in full. And while 21 of 21 already ship schema.org JSON-LD, generated automatically by the site’s own SEO plugin, 0 of 21 use its license field. The gap between “we want this to spread” and a statement a machine can act on is one line of JSON long.

The aggregate, over twenty-one of the most senior voices in news. 19 of 21 pieces are about truth and facts; 11 raise artificial intelligence; 3 mention copyright or licensing at all. 11 of the 21 offer the reader no outbound link whatsoever — 38 links across the whole corpus, and of the 23 domains cited between them, no two pieces point at the same one. That is the measurement this publication has argued for since its first page, taken on the people making the case for trusting journalism, in the week they made it. The aggregate maps the shared diagnosis onto what we have published, and says plainly what nobody in the corpus proposes: a mechanism.

And one refusal, recorded rather than tidied away. wan-ifra.org answered an automated reader with HTTP 307 and no body, from two user-agents, while rendering normally in a browser. The announcement that grants the permission is the one page in the beat a machine cannot read, and the register says so rather than quietly dropping it.

The section ships with the estate’s grammar: 153 nodes and 420 edges over 8 types and 8 verbs, every verb with a distinct named inverse and a Portuguese form, 1,449 N-Triples, a published twenty-pattern lexicon as the only classification, and thirteen gates — among them one that fails the build if twelve consecutive words of any op-ed appear on any page we generate, and one that re-derives every licence count from the frozen HTML with a second implementation. agrees_with is a banned verb: shared vocabulary is not agreement, and this section does not put words in a named editor’s mouth.

v0.3.13 20 Sep 2026 The Startup Summit beat, consolidated into one archive: 160 files, each with its live URL, its repository URL and its hash.

Brief 15 and the bundle (210 files, 1.5 MB, also unpacked under briefs/summit-archive/) hold everything this publication did on the beat in one place: twenty pages and seven role pages as served, twenty-two data files, twelve build scripts and viewers, three stories as prose, seven documents, and the eighty-nine frozen sources that everything else stands on. Every file was fetched from the live site and checked before the bundle was cut — all 160 returned 200 and were byte-identical to the repository, and the manifest carries the SHA-256 so a reader can repeat the check rather than take our word.

Four documents carry what a file list cannot. The chronology: six days, two captures, and the release-by-release order in which the section was built. Every published number beside the file it derives from, including the four this publication refused to print — attendance, the speaker total as a fact about the event, countries, and anything about what happened in the room. The method and its eighteen gates, with the argument for why each rule is a gate rather than a habit. And three things that went wrong: the notice that should have shipped with v0.3.0, a rendered count that had become false, and the posture on biographies that changed under pressure and was nearly changed silently.

The boundary is on the first page, not inferred from the last. The register stops on 13 September, four days before the doors opened; there is no capture from during or after the event, and the archive says what a successor should do first — capture again, write the fourth piece, and never backfill a dated capture.

v0.3.12 14 Sep 2026 A sibling transfer: two frozen captures go to pt.newsroom.sgit.ai, and a rule for evidence that changes hands.

Memo 14, written after reading the sibling repository at its v0.3.1 and its live site. It opens with what that site built and this one does not have — a read-only JSON API with an OpenAPI document, the delivery quarantine as a build gate, and the accent and Portuguese-path gates the pack could only ask for — because the comparison is not one-way.

What goes the other way is one thing that matters and several that help. Its lead story says there is only one capture of the speaker list, 70 names, nothing to report, and that it exists to say so and wait for a second. This site froze the same pages on 8 September (60 names) and 13 September (64, +5 −1). With theirs, that is three captures in six days — 60 → 64 → 70 — and the one speaker who left on the 13th has not come back. Also in the bundle: three press pages they lack, the fourth that returned 404 and is excluded with its reason, and the Guinness pitch-marathon story that two publishers report and the event’s own agenda does not list — every byte for it already frozen in their tree, and no story written.

The rule the transfer forces, which neither site had written down: evidence transferred between sibling publications stays evidence only if the provenance travels with it and is published. The bundle’s manifest carries, per file, the URL, who fetched it, when, under which version, and the SHA-256 the origin register recorded — all fourteen re-verified before packaging, and meant to be verified again on arrival, because the hash is the only thing in it that requires trusting nobody. The memo proposes a register field and a gate that make the provenance impossible to lose in a refactor, and names the limits that belong on the page beside it.

v0.3.11 14 Sep 2026 Research deliveries travel as sgit vaults.

Both research briefs gain a section on packaging and distributing what they find as an sgit vault — a versioned, end-to-end encrypted folder the server cannot read, pushed with one command, handed over with a read key or a share token and never with the vault key — with the vault layout the newsroom expects, the exact commands for an assistant that can run a shell, and the fallback for one that cannot (produce the layout; the operator packages it). The delivery schema gains delivery.vault (vault id, commit, read key or share token); the ingestion guide says how the newsroom clones a delivery, checks the manifest and keeps the vault id and commit as provenance. Links to the sgit docs that matter: the agent surface, the guidance page, the publishing method and its two rules.

v0.3.10 14 Sep 2026 Two research briefs for outside assistants, and the contract their deliveries must meet.

For ChatGPT and for Perplexity: paste-ready briefs that say what pt.newsroom.sgit.ai needs (the eight sections in priority order, the three first articles’ open questions, the Summit this week, and what is already held), how to search Portuguese sources first, the rules on people and characterisation that do not bend, and how to hand results back — as leads with provenance, never facts, in a published JSON Schema (briefs/pt-newsroom-pack/08__research-briefs/research-schema.json, draft 2020-12, with a worked example that validates and a person with a forbidden field that does not). Every claim names one exact page and carries a verbatim excerpt the newsroom will search the frozen bytes for; a person is reduced to the three fields a primary page lists; edges are Portuguese verbs with a distinct inverse. The pack gains the folder and a page on how a delivery is ingested: saved unchanged, validated, every URL fetched and frozen, every excerpt re-found or the claim dropped, and what survives becomes issues on the desk for the research department to re-derive from the frozen page.

v0.3.9 14 Sep 2026 The briefing pack for the session that will build and run pt.newsroom.sgit.ai.

One zip, browsable unpacked under briefs/pt-newsroom-pack/, for a Claude Code session with commit access to the repository that deploys to pt.newsroom.sgit.ai. In it: the commissioning brief; the chosen front-page design with its sources, renders and the seven vendored typefaces; the code to inherit from the Portugal section, the databases section and the site chrome, with a file-by-file note on what to copy and what to rewrite; the operating model of the newsroom — three departments that each own a folder, files as the communication layer (issues, mail, run records), the run loop, and the human editor as the only one who can publish; a CLAUDE.md and .claude/settings.json for the new repository; the prompts and repository skills for the bootstrap, the scheduled run, the editor’s review and a correction; the three documented ways to run the session on a schedule (a Routine, a cron workflow with the official action, or the headless CLI), checked against the Claude Code docs, with the workflow ready to copy; the acceptance test for v0.1.0; and a handover of what exists here and the decisions already taken. Section 17 of the brief points at it. The pack carries no personal data: the new site fetches and freezes its own sources under its own notice.

v0.3.8 13 Sep 2026 All four pt.newsroom home-page directions are archived on the site, at full size, with the reason each was drawn and the reason three were not chosen.

/pt-newsroom/directions.html renders the five artboards of 13 September — the chosen broadsheet at 1440px and 390px, then the dense capture-ordered ledger, the dark graph-first cover and the magazine with the claims underlined in the text — each from its own source under pt-newsroom/design/, each with the motivation and trade-off that were written beside it on the design canvas (kept as canvas.json, so the page reads the notes rather than restating them), and each labelled chosen or not chosen. The page says it is an archive, not a menu.

Five more typefaces are vendored for the three archived directions — Archivo, JetBrains Mono, Space Grotesk, Bodoni Moda and Karla, latin subsets as variable woff2 files, all under the SIL Open Font License and attributed in LICENSES.md — so no design on the site fetches anything from a third party at render time. The chosen-design page links to the archive; the archive is in the Portugal menu, the sitemap, llms.txt and section 16 of the commissioning brief.

v0.3.7 13 Sep 2026 The pt.newsroom home page is a page, not a picture.

/pt-newsroom/ renders the chosen design at full size — the 1440px broadsheet in a frame that scrolls sideways on a narrow screen, and the 390px phone version beside it — from the design sources kept verbatim in the repository (pt-newsroom/design/Main.dc and MainPhone.dc). The builder scopes the design’s stylesheet so it cannot restyle the site chrome around it and edits nothing else; a change to the design is a change to the source file. The page says on its face that the site does not exist yet, that the copy is the Portugal section’s data of 13 September and is not maintained, and that the links inside the mock-up go nowhere.

Two typefaces are vendored: Newsreader and IBM Plex Mono, latin subsets as woff2 under assets/fonts/, both under the SIL Open Font License and attributed in LICENSES.md, loaded only by the pages that use them. The design had specified them and the site had been fetching them from Google Fonts at render time, which is the dependency the rest of the site refuses for its code; the renders in section 16 of the commissioning brief, which had shown fallback faces for the same reason, are redrawn with the real ones. The page is in the Portugal menu, the footer’s What runs column, the front page’s brief card, the sitemap and llms.txt.

v0.3.6 13 Sep 2026 The things that run get their own doors: three top-level menus, a front-page band, a footer column, and every page in llms.txt.

Until now the Governance Wire, Portugal Startups and the no-server databases were single links inside Rights & ops, one hop from anywhere and invisible from the front page. The nav is now eight groups: the three running instances sit between the argument and the record, each with its own submenu — the floor, the state map and the research runs under the Governance Wire; the wire, graph, files, connections, Summit, speakers, organisations, changes, sources, method, team, notice, limits and the pt.newsroom brief under Portugal Startups; the argument and the two consoles under Databases. The group label is always a link to the hub, so nothing is reachable only by opening a menu.

The front page gains a band, What runs on this site, with a card per instance and one for the pt.newsroom commissioning brief; the markdown twin carries the same section. The footer gains a What runs column. llms.txt now names the three running instances in its opening properties, lists every Portugal story and team page by path, and says which of the three are human-reviewed.

v0.3.5 13 Sep 2026 The pt.newsroom.sgit.ai home page has a chosen direction, and the commissioning brief now carries it.

Four home-page mockups were drafted for the Portuguese-language newsroom on 13 September — a classic broadsheet, a dense capture-ordered ledger, a dark graph-first cover, and a magazine with the claims underlined in the text — all drawn with the Portugal section’s real data of that day. The editor of record chose the broadsheet. Section 16 of the commissioning brief records the choice with two renders (1440px and 390px) and the system behind it — paper and ink values, the two faces, rules rather than boxes, the order of the page, what is deliberately not on it — so the agent that builds the site inherits a decision rather than a question. The three unchosen directions are kept on a second page of the design canvas and are not published.

v0.3.4 13 Sep 2026 The graph learns what the speakers’ pages say: topics, industries, technologies, ideas and offerings — and a connections page that answers who should talk to whom, at organisation level, as queries.

Sixty-four more frozen sources. Each speaker’s own page on the event site is now fetched, frozen and hashed like every other source (88 in the register, from 24). Two things are read from each page and nothing is reproduced: the event’s own Topics list for that speaker, verbatim (60 of 64 pages carry one; 23 distinct topics), and the words on the page that match a published lexicon of 57 patterns for industries, technologies, ideas, services and products. A derived tag carries the matched words on the edge and nothing else; it says the page contains those words, which is all it says.

The ontology grows by six types and five verbs, each with its Portuguese: Topic (speaks_on / fala_sobre), Industry (active_in / atua_em), Technology (uses / usa), Idea (advocates / defende), Service and Product (offers / oferece). Two new taxonomy classes say which is which: Themes for the event’s vocabulary, Derived by formula for ours. The graph is 329 nodes and 1,106 edges in ten packs; the two new packs are off by default. The triples grow to 4,001 and the tag nodes carry their pattern as a property, so the SPARQL console can show the formula beside the result.

Connections: who should be talking, who could be buying from whom, who could help whom. Three SQL queries at organisation level, run at build and stored with their SQL so the identical query runs in the browser console. The unit is the organisation a speaker is listed under, because the data-protection notice refuses any characterisation of a named person and “X should talk to Y” is one; the person-level join is a query away for a reader who wants it, and this page does not make it. The notice now lists the two new categories held, and the refusals are reworded rather than quietly relaxed.

Three more gates. 16: every Topic node is on the frozen page verbatim, and every topic on a frozen page is in the graph. 17: every derived edge re-derives — the lexicon pattern is run again on the frozen bytes, no match no edge, and every match must have an edge, so a tag can be neither typed in nor left out by hand. 18: the connections rows are what their SQL gives. The databases section gains three tables (person_topics, person_tags, lexicon), three SQL and two SPARQL worked queries, and a build-time cross-check that the connections SQL returns the same row counts against its tables as it did on the Portugal page.

v0.3.3 13 Sep 2026 Databases with no server: SQLite and a SPARQL store running in the reader’s browser over the Portugal section’s own files.

A new section, and the argument first. This site has no server. The Portugal section is JSON files in a git repository with a hash for each. Two real database engines now run over exactly those files in the visitor’s browser, compiled to WebAssembly — nothing uploaded, nothing queried remotely, the store discarded when the tab closes. The files are the database; the engines are readers. It is the pattern the estate already runs (sgit.ai’s RiskMandate vault, where “the browser becomes the database”; graphs.sgit.ai’s Regulation Graph, SQLite over WebAssembly, client-side and ephemeral) with the second language added, and graphs.sgit.ai’s not a graph database pitch is inherited on the page rather than quietly contradicted.

The SQL console: sql.js 1.14.2 (SQLite, MIT, vendored), twelve tables built on load from a loader spec that names the file and field behind every column, and thirteen worked queries — a count by role class, the programme as a table, who arrived between snapshots, every verb with its inverse in both languages, a path as a sentence the SQL way, and a recursive CTE that walks two hops from the event, which is the query that shows where SQL stops being the natural language for a graph.

The graph console: Oxigraph 0.5.11 (SPARQL 1.1, MIT or Apache-2.0, vendored, 3.9 MB and said so) over triples.nt, which the Portugal graph build now writes beside graph.json: 1,982 triples under one stated IRI scheme, the ontology inside the store, every inverse declared with owl:inverseOf and walked with ^, labels in English and Portuguese so a path reads aloud from the store alone. Eleven worked queries, each shown beside the same question in Cypher, which is displayed and not run: Kùzu would run it and is 73 MB unpacked, and the choice is recorded on the page.

The build is the test. Every SQL example is executed at build with Python’s sqlite3 against tables built from the same spec the browser uses; every SPARQL example with pyoxigraph over the same triples. A query that fails or comes back empty fails the build, and the count each returned at build is printed beside it on the page, so a reader’s run can agree or differ in the open. Both consoles publish window.__tools after tool:ready, read-only, the convention the estate’s graph readers set.

Also: the Portugal graph page and file explorer link to the consoles; the section README and llms.txt describe both; LICENSES.md carries the two new attributions.

v0.3.2 13 Sep 2026 Portugal Startups becomes a graph, a front page and a file explorer — and the press enters the register.

The graph: 192 nodes, 298 edges, 10 types, 14 verbs. The event, 64 speakers, 61 derived organisations, 16 sessions on 3 stages, 24 frozen sources across 2 snapshots, 7 pieces of coverage and our stories, as one graph. Every edge is a verb with a distinct named inverse in English and in Portuguese, so a path reads as a sentence walked either way in either language — the commissioning brief’s rule that in a Portuguese publication the edge verbs are Portuguese verbs, applied a release early so it is a switch and not a rewrite. Nodes arrive in packs the reader switches on block by block; the one classification the graph makes rather than reads (role_class on a person) is published as a formula over the listed title and says so on every node.

The instrument is graphs.sgit.ai’s, on purpose. Cytoscape.js 3.30.2 is vendored (MIT, attributed in LICENSES.md) and the control panel is that site’s altitude-graph vocabulary — radius exploration from any node, collapse and expand, path tracing read as sentences, a bounded path-query builder that says when it hits its cap, save and restore a view with every position. Packs replace levels; otherwise a reader who has used one should not have to learn the other. The page publishes window.__graph after a tool:ready event, read and view methods only, so the console, Playwright and an agent are equal consumers.

The files: the platform’s vault-browser idea rendered from a manifest for a section that is not in a vault yet — every file with its SHA-256 on the left, rendered / as a graph / raw on the right. Frozen third-party pages are listed and hashed and deliberately not rendered. The page says on its face that it goes when the vault browser takes over.

The front page is now a newspaper’s: a lead, the wire, the programme by day, what the press says, the room as a graph, who made it, and the brief for whoever builds the next one.

Seven third-party pages are in the register, each fetched, frozen and hashed before it could be cited, summarised in our words and never quoted; gate 15 fails the build on a long quotation. An eighth returned 404 and is recorded as excluded with the reason. Two of the seven — AICEP Portugal Global and Portugal Business News, both 29 July — report a 48-hour Guinness pitch marathon on 16–17 September that the event’s own agenda page, four days out, does not list. That is the third story, and it is the first to stand on sources with more than one publisher.

Three more gates. 13: the graph conforms to its ontology — every verb declared with a distinct inverse and Portuguese, every node a declared type naming a registered source, every edge within its verb’s domain and range, and nobody in the graph who is neither on the published list nor marked as no longer listed. 14: every session title in sessions.json appears verbatim in the frozen agenda, because a transcription is a claim. 15: coverage is frozen before it is cited and never reproduced.

Also fixed: the whole-site link scanner reads href=" inside inline JavaScript as a link; the explorer now emits single-quoted attributes from its templates rather than teaching the gate to be cleverer.

v0.3.1 13 Sep 2026 The notice that should have shipped with v0.3.0, and a commissioning brief for pt.newsroom.sgit.ai.

The correction first. v0.3.0 published the names, roles and organisations of 64 people this site did not get the data from, and it did so with no data-protection notice, no stated lawful basis and no route to object. That is the wrong order — the notice belongs before the first named person, not after — and the notice now live says so on its own face rather than quietly fixing it.

The journalistic derogation is not claimed, and that is the substantive finding. Article 24(3) of Portugal’s Lei 58/2019 conditions processing for journalistic purposes on the national legislation governing access to and exercise of the profession, which an unaccredited publication produced by agents does not satisfy. So the basis is legitimate interests, with a written three-limb balancing test, and the notice exists because Article 14(5)(b) makes the disproportionate-effort exemption conditional on making the information publicly available. Removal on request is unconditional — no reason required, none asked for. The page carries a Portuguese summary, because several of the people named are Portuguese. None of it is legal advice and no lawyer has reviewed it.

Two new gates, because a refusal without an enforcer is a sentence. Check 11 fails the build if an email address, telephone number or personal postal address appears anywhere in the section’s data — enforced where the data is parsed, not where it is rendered, so a contact detail cannot reach the data and then be hidden by a template. Verified by injecting one and confirming the build fails. Check 12 fails the build if any page that names individuals does not link to the notice, because a notice nobody can find from the page that named them is a file rather than a measure.

And the 12 May design page is updated rather than rewritten. That design is still unlaunched and still says so; what changed is that a much smaller first instance now runs, and that its open question 5 — who is the editor of record — is answered after four months, with the constraint the design did not anticipate: not as journalism.

The commissioning brief is the first document in the pack written to be executed rather than read. It cuts the fifteen-department design to three, replaces the seven-stories-in-seven-days test with one story whose whole process is visible, settles the subdomain by wildcard-certificate mechanics, sorts the agents into four tiers by what each can write, and rules that in a natively Portuguese publication the graph edge verbs are Portuguese verbs — because a path that does not read as a sentence in the reader’s language has the wrong edges, and an English ontology behind a Portuguese interface fails that test while looking finished.

v0.3.0 13 Sep 2026 A second publication: Portugal Startups — and the first section on this site whose sources are primary, frozen and hashed.

The door The Governance Wire cannot open. That section specifies a frozen state — a hashed byte copy of the source — and carries blocked: true against it, which is why every fact there is secondary and nothing is anchored. Here the path runs: fetch, freeze, hash, extract, diff. 17 frozen files across 2 dated snapshots, every SHA-256 published and re-verified by the gate on every build. A claim on this section points at bytes in this repository, not at a URL that may have moved.

The first beat is Startup Summit Lisbon 2026, which opens on 17 September. It was chosen on the criterion the 12 May 2026 brief argued for — small enough to map comprehensively, large enough to be interesting. An event that publishes its own speaker list has a closeable graph: 64 speakers and 61 organisations, derived from the cards rather than typed by hand, with the 2 placeholder values flagged rather than cleaned away.

Freezing twice produced the first story. The same page, captured on 8 and 13 September, went from 60 speakers to 64: 5 names added and 1 no longer listed. Both copies and both hashes are in the repository, which is the only reason anyone can now say that — the earlier version exists nowhere else a reader can reach. The removal is published with no reason attached, and gate check 4 fails the build if any page implies one: withdrawal, a clash, a duplicate and an editing error are indistinguishable from outside, and guessing would be the easiest way for a publication like this to harm a real person.

Open question 5 is answered. The original brief left the editor of record undecided, and this site called it the question it should be most uncomfortable about. Dinis Cruz is the named editor of record and reviews every page before it publishes — a deliberate departure from the fully-agentic sibling, because this beat is about named people in a small ecosystem rather than about regulations.

Frozen copies are .snapshot, not .html. They are unmodified bytes of another organisation’s pages held as evidence, and serving a browsable mirror of somebody’s whole site under this domain would contradict the one rule this publication has. The extension keeps them verifiable and un-servable at once. Speaker biographies are not extracted, stored or published for the same reason; gate check 10 fails the build if any node field grows long enough to be one.

Ten section checks on top of the whole-site gate, covering hash re-verification, derived-not-typed organisations, no-reason-for-removals, no-target-reported-as-result, and no claim of a Portuguese edition that does not exist.

v0.2.9 28 Aug 2026 The generator for /governance/ had never been committed. The site was green, deployed, and unrebuildable.

A bare build/ rule in a generic Python .gitignore matches at every depth. It was excluding governance/build/ — build.py, floor.py, gates.py, the whole section generator and its thirteen checks — from every commit since v0.2.6. Nothing broke, and that is the point: the generated HTML was committed and only the thing that generated it was missing, so the site deployed correctly three releases running while nobody could have rebuilt it from a clone.

It surfaced by accident. The debrief shipped in v0.2.8 links to floor.py on GitHub so the sibling sites can copy it. Checking those links found three 404s.

This is the second time the same rule has done this. It caught admin/build/ at v0.1.0, where CI failed loudly with MODULE_NOT_FOUND, and the fix was to re-include that one path by name — which is exactly why it recurred. The rule is now root-anchored (/build/), which is what the Python template meant, and no <section>/build/ can be swallowed again.

Fixing the instance twice would have guaranteed a third time, so it is now check 10 of the whole-site gate: nothing under a build/ directory, and no .py, .js or .mjs file anywhere, may be excluded by .gitignore. Verified by restoring the old rule and confirming the gate fails with three errors, then restoring the fix. A generated page whose generator is not in the repository cannot be rebuilt by anyone who clones it.

The debrief gains a paragraph on it under “where the code is”, because a document telling other sites to copy a generator owes them the reason its own links were broken.

v0.2.8 28 Aug 2026 A debrief for the sibling sites: how the agentic team became a room you click around, and how to build one.

The first document here that reports on shipped work rather than specifying work to do. Every site on this network publishes its agentic team the same way — a roster and an ordered list — and neither shows what any role is holding, why it is stuck, or what it will refuse. The floor makes the team a place instead. The debrief carries the parts that transfer: the one rule that separates the room from a mock-up (every word it speaks is derived at build time from the same files the pipeline runs on), the genre-versus-work line on the adventure-game reference, the SVG and responsive mechanics, a porting recipe with candidate mappings for five siblings, and the gate that fails the build if the drawn route stops matching the declared pipeline.

It states what has not been proven, which is the half a debrief usually omits: one implementation, one site, one day; no user testing; no screen-reader testing; Chromium only; untested past seven actors; and the dialogue is 28 fixed strings rather than a conversation.

Four screenshots — the first images ever published on this site. They live in the markdown, so an agent fetching the raw document gets them too.

A defect found and fixed on the way in. llms-full.txt says it carries “every markdown document in the brief pack”, and brief 09 had never been added to its ORDER list — so that claim had been false since v0.2.5. Both 09 and 10 are now in it; the file grew from 15,000 to 23,167 words.

Also fixed in the floor itself: with JavaScript off the verb bar rendered and did nothing. It now carries a <noscript> block saying so and pointing at the table that holds the same information — found by testing the degradation paths rather than assuming them, which is advice the debrief gives and therefore had to follow.

v0.2.7 28 Aug 2026 The Governance Wire gains a newsroom: a floor you can click around, a state map of how a story moves, a page per agent role, and the Researcher's first real run.

The floor is a point-and-click scene. Seven desks, a verb bar — look at, talk to, hand over, ask what they refuse — and a dialogue box. The genre is borrowed and everything in it is ours: our palette, our figures drawn as inline SVG, our verbs, our writing. What a desk says about its workload is read from desk.json at build time, so the room cannot report a queue the newsroom does not have. A token travels the pipeline route through the desks; the route and team.json's seven steps are compared by gate check 13, because a room that keeps drawing a workflow nobody runs is a lie that looks like decoration.

Nine states, and one shut door. The state map names, for each state, the one role that can advance it and the condition the next role will not take the work without. frozen — a hashed byte copy of the source — carries blocked: true, and nothing has ever passed it. That single closed door is why every fact in the graph reads secondary, why nothing is anchored, and why the two stories already on the wire went round it rather than through it.

A folder and a page per role, following graphs.sgit.ai's making-a-book team: the definition in full, the doors only that role can open, what is on its desk, and an honest inventory of the three directories the inherited shape has that ours does not yet fill.

The first research run is real, and its failures are published. The Researcher searched the beat for 28 August 2026, tried six URLs, read two European Commission pages in full, and found that the Article 6(5) classification guidelines due on 2 February are still marked draft — 207 days past the statutory deadline, last touched 23 July, with no date given for a final version. Four candidates were proposed with their weaknesses attached; one was recommended, and the pick is recorded separately, because proposing is the Researcher's job and choosing is not.

Two Council of the EU pages returned 403 to our fetch. They are excluded from the register and recorded as unreachable from here — our egress, not a claim about those pages. Gate check 11 now makes that structural: a URL that did not resolve cannot appear in the source register, and its note must distinguish our reach from the state of the page.

Seven new gate checks (7–13), 11 new pages, 3 new machine surfaces — workflow, desk, research. Section v0.2.0.

v0.2.6 26 Aug 2026 The commissioning brief stops being a document: /governance/ is a first, running MVP of the risk-and-governance publication.

Built to the conventions graphs.sgit.ai arrived at over v0.4–v0.6: JSON is the source of truth for structure, markdown for prose, and the HTML is a projection of both. Five machine surfaces — graph, ontology, sources, stories, team — and a generator that cannot render a claim the data does not carry. The section is self-contained: its own data, prose, generator and gate, depending on nothing but the shared stylesheet and chrome, so it can be lifted to its own domain whole.

The one convention deliberately not copied. The sibling renders markdown in the browser and fails CI if a page lags its source. This section renders at build time instead, because this site lists crawler-invisibility of client-assembled pages as an inherited existential risk and a story whose text is not in the HTML is a story an agent cannot read. Gate check 5 re-derives every story page from its markdown, so the no-drift guarantee is kept without paying that cost.

Fully agentic, and the pages lead with what that costs. Seven agent roles, each with a centre of gravity and a written list of what it refuses; no human reviews a page before publication. In that posture the Editor's refusals are the only thing standing where a duty editor would be, so they are rules rather than judgement calls — chief among them that no named organisation is assessed, there being no legal sign-off. A generated disclaimer block appears on every page and gate check 6 fails the build if it is missing from one.

The honesty the gate enforces. Every fact in the seed graph is secondary — taken from a sibling site's reading of a text, never from the text — and nothing is anchored. Check 4 fails the build if any page claims a verified anchor while no node carries one, and it caught exactly that during the build: an ontology definition described a Fact as “anchored to a byte range”, which overclaimed for this release. The definition was rewritten rather than the check loosened.

19 nodes, 22 edges, 5 sources all re-fetched and confirmed 200 on the day, 2 stories, 8 pages, 6 section gates on top of the whole-site gate.

v0.2.5 25 Aug 2026 The pack gains its first forward-looking document: a commissioning brief for a risk-and-governance publication, and with it the reciprocal statement the Risk Mandate inversion has owed since v0.2.0.

Everything in the pack until now was material this site was built from, frozen at 21 August 2026. This is a publication to build — assembled from newsroom, graphs, risks, pki, the vault layer and the personalisation pipeline, with riskmandate.ai as its named customer. It is labelled v1.1 addendum rather than dated into the v1.0 pack, and the generator was changed to make the pack line per-document so it could say so: misstating a document's own provenance is the one failure this site's gate exists to prevent.

The argument that makes it worth commissioning. The Portugal instance required a ≥200-entity graph before it could report competently, never built it, and never launched. A risk-and-governance beat inverts that constraint: 1,523 nodes and 1,944 edges of EU AI Act, three worked risk graphs and a 42-concept ontology are already public on the sibling sites. The publication starts where Portugal was still trying to get to.

The commercial claim is architectural, not promotional — a split of the grounding ladder. The publication owns Evidence and Fact for the public regulatory world; the customer owns Reality, Twin and Measure in their own vault; and a Vulnerability, by the published formula, exists only where the two meet. That is why the brief is written as a news operation whose first customer is a risk product rather than the reverse: the inversion is the whole point, and dropping it would have made this a compliance feature with a masthead.

Two things the brief refuses to smooth over. A publication that profits when risk looks severe has a structural incentive to inflate it, so the brief answers that with mechanism rather than promise — severity computed from edge count, facts-only, absence reports as the counterweight — plus a hard rule that no assessment of a named third party publishes without their right of reply as a node in the same vault. And it half-answers Portugal's open question 5: the editor of record is whoever's signature is on the current interval. The legal half stays open, and is raised to T9 as a precondition for launch rather than a detail.

Also: the eighth instance is now listed on /mvps/, and T2 is advanced rather than closed — the brief is the statement, the standalone comparison page it named is still unwritten.

v0.2.4 25 Aug 2026 New section: /mvps/ — the part of the source corpus that asks what would actually launch first.

The site was built almost entirely from the corpus's argumentative material: the thesis, corrections, provenance, the economics. A second cluster in the same repository was catalogued in the brief pack but never surfaced as pages — seven briefs, dated 10 April to 17 May 2026, in which the newsroom is specified not as one product but as a series of small, separately launchable publication instances. A bilingual country publication with a trip for a deadline; an eleven-role agentic newsroom to run it; an evidence-backed report tool small enough to ship in days; an eight-phase rebuild of a live property; seven Creative Commons business templates published so someone else could build them. Three pages: the index of the programme, the flagship instance in full, and the seed companies.

The reason it belongs on this site is the gap it measures. Fifteen public departments is what this site argues for; eight of fifteen is what the first MVP was scoped to actually run, recorded at the time as an open decision. Alongside it, two more open decisions from the same register — the launch domain and the reader-validation specification — and the newsroom brief's own six unanswered questions, republished unresolved. Open question 5 is the one this site should be least comfortable with: a daily agentic publication with no named editor of record and no answer on who carries legal responsibility for what it publishes. A site arguing that provenance must be walkable has an unclosed chain at precisely the point where it has to terminate in a person, and that is now stated on the page rather than left in a repository.

Also recorded: the two source briefs of 12 May contradict each other on whether the publication launches bilingual or in one language. Neither this section nor llms.txt resolves the disagreement; both flag it, on the same reasoning as everywhere else here — silently picking a side would be the site editing its own sources.

Boundaries applied rather than assumed. The publishing-substrate mechanics in the 17 May architecture brief belong to sgit.ai and are cited rather than re-explained, per the sibling boundary; only the third primitive — the management layer, where editorial state lives — is treated here, because that one is the decision graph given somewhere to be stored. The commercial detail attached to the live property in that same cluster is Tier 3 and is absent: the ideas are published, the pricing, clients and entity detail are not, and the omission is stated on the page rather than left to be noticed.

v0.2.3 24 Aug 2026 Front-page links were rendering flush against the viewport edge instead of aligned with the text they follow.

A section.band is full-bleed and had no horizontal padding at all. Every component inside one carries its own centred column — .blurb 660px, .note and .proof 1100px, .cards 1160px, .split 1000px — so anything without such a rule fell back to the full band width starting at x=0. Two bare <p> links on the front page started their text at 1px where the note directly above them starts at 109px, and the for-an-agent block spanned the whole viewport. Nothing overflowed and nothing warned; it simply read as a misalignment against the very components it sat between.

Fixed at the root rather than per element: the band now carries a gutter, so nothing inside one can reach the viewport edge whatever column rule it has, and the remaining block children — a bare paragraph, a list, the agent block — take the same 1100px column .note already used. Scoped to direct children, so the identical elements nested inside .note, .cards and every main.doc page are untouched. Verified across eleven widths from 1600px to 360px: the four text columns now agree to within 2px at every one, and the gutter also fixed a separate phone-width defect the measurement exposed — .blurb putting its text 2px from the edge at 390px, because a 660px max-width stops constraining anything once the viewport is narrower than 660.

This is the third defect in three releases that the gate could not see, after the wrapping nav bar and the raw-markdown documents page. All three were visual or conventional rather than structural, and all three were found by looking at the shipped site. The gate checks that a page is correct; it has no opinion about whether it looks right. That is a real limit and it is worth stating rather than discovering again — the shared stylesheet carries all of these latent on the sibling sites too.

v0.2.2 24 Aug 2026 The published brief pack was leaking the identifiers it exists to withhold. Fixed, disclosed, and the gate that let it through has been corrected.

What happened. The pack's redaction watch-list (06 §2) is a list of things not to publish, and it names each one in the course of forbidding it — a venture-capital firm, an AWS account number, an investor-facing hostname, a B2B price range. v0.2.0 published the pack verbatim, so the act of documenting the exclusion performed the disclosure: four identifiers the pack marks Tier 3 went live at /briefs/. The identifiers are now replaced with visible [redacted] markers in the published copies, and every one is recorded in the transparency note — nine redactions, in three files, with the surrounding reasoning, tiering and manifest rows fully intact. A silent redaction would have been the worse of the two options.

Why the gate did not catch it. The redaction check exempted briefs/, on the reasoning that the pack "documents the watch-list by naming these". That reasoning is inverted, and it is now recorded as a comment in validate.js so it is not reintroduced. Second defect in the same check: the pricing patterns had been written from memory of the brief's prose rather than against the strings actually in the files, so they matched nothing at all. Every entry in the list is now a literal verified to appear in the source before masking, and the published pack is checked like every other file — an unredacted identifier in briefs/ now fails the build.

Also shipped: /llms-full.txt, required by the pack's own house style (06 §3) and missing since v0.2.0 — llms.txt, the front page and all eleven pack documents in one fetch, because agent fetch tools frequently refuse URLs a search has not already returned. It was generating this file that surfaced the leak: the concatenation tripped the redaction check that the briefs/ exemption had been suppressing.

Two remaining gaps against the brief's build order are now tracked rather than silent: T5 (/provenance/the-citation-chain/) and T6 (/infographics/, the only build-order step not started).

v0.2.1 23 Aug 2026 Two defects found by looking at the shipped site rather than at the source.

The nav bar was silently breaking onto two lines below about 1400px. The row is flex-wrap:wrap, so once its contents outgrew the viewport the ★ GitHub link dropped to a second row and the header doubled in height — no overflow, no console warning, just a ragged two-row bar at the most common laptop widths. The shared stylesheet has the same latent dead zone on every sibling site, between the full-width bar and the 820px phone menu; this site hit it first because its nav row is the widest in the network. Fixed at both ends: the two longest items were trimmed (Rights & the newsroom → Rights & ops, and the stage pill to design, not built), and the stylesheet now tightens the row at 1400px and again at 1180px before collapsing to the phone menu at 1000px. Verified across an eighteen-width sweep from 1600px to 360px: one clean row at every width, and no horizontal overflow. The stylesheet half of this fix is worth carrying back to the siblings — graphs.sgit.ai wraps the same way at 1100px.

/documents/ was handing readers raw .md files. On a site whose central claim is that most articles do not provide evidence, they provide a link, and the link is never followed, that was the lazy version of exactly the failure the site exists to argue against. Adopted the reader-page convention the siblings already use: admin/build/gen_documents.py generates one page per pack document, each stating the single most important thing in it and why it is on this site, then rendering the raw markdown in-page from that same file through assets/mdreader.js — so a reader page cannot drift from the document it claims to render. Ten documents now have reader pages; the two machine-readable files (the 48-row manifest and the provenance JSON) stay raw, because wrapping data in a reader page would only get in the way. The raw file is still one click away from every page and is still the stated source of truth.

Neither defect was caught by the gate, and that is worth recording: the gate checks that a page is correct, not that it looks right, and not that a convention the rest of the network follows has actually been adopted here. Reader pages under documents/ are exempt from the agent-block rule as generated projections, matching the exemption issues-fs.sgit.ai makes; documents/index.html is hand-written and still owes one.

v0.2.0 23 Aug 2026 The real brief pack arrived, and this release replaces v0.1.0's content in full.

v0.1.0 shipped without a brief pack, under the working assumption that this site would report on the *.sgit.ai network's own activity. That assumption was wrong: the actual commissioned brief — newsroom.sgit.ai, The Future of News — describes a site about how news gets made, proven and paid for, built from ~110,000 words across three corpora, ~68,846 of them already public and dated since February 2025. Every page from v0.1.0 built on the wrong premise has been replaced, not patched; nothing about the wrong premise is preserved, since a corrections-first site keeping a superseded page live under the old thesis would be the exact failure it argues against elsewhere.

The build order from the brief, followed in full for the first five steps: the front page, /corrections/ (hub plus all five specified subpages — the 10,000-hours case, the 242-paper citation network, how a graph answers it, the self-critique on agenda, and the AI Act staleness case), /provenance/ (hub plus the £8.40 worked story, the decision graph, show-your-work and articles-as-vaults), /library/ (all ten core articles and three adjacent pieces, chronological, each carrying the provenance contract), and /economics/ (hub plus paying-the-fact-creator, trust-as-a-service, the payment rails, and the republished 2025 micropayments piece paired deliberately with the 2026 rail).

Three sections shipped as single comprehensive hub pages rather than the full multi-page trees the brief specifies: /rights/, /newsroom/ and /thesis/. That is a real, stated de-scoping — tracked as task T1 — made to get the whole architecture live and gated in one release rather than shipping half of it silently complete.

The provenance contract is now enforced by the gate, not just documented. A new validate.js check requires every block marked class="provenance" to state a first-published date and a working link to the original — this site's central argument, applied to itself. A second new check enforces the redaction watch-list: a fixed set of Tier 3 strings from the brief's own manifest (a named venture-capital firm, an infrastructure account number, live product pricing) may not appear anywhere in the published tree.

Two honest limits, stated rather than smoothed over. The brief's own N1 request — roughly 15,000 words of likely origin material sitting in an external repository not yet retrieved — means the library's chronology may still be incomplete at the start. And several republished docs.diniscruz.ai pieces are published here as this site's own synthesis, not verbatim reproductions — the brief pack recorded their metadata in full but not their complete text, and reproducing them as if verbatim would have been exactly the provenance failure this site exists to argue against.

v0.1.0 22 Aug 2026 The site, first release — pipeline first, shipped without a brief pack.

No brief pack had reached this site at the time of this release. Rather than block, v0.1.0 shipped the validate → tag → deploy pipeline, carried in from the sibling *.sgit.ai sites, plus a provisional front page, a role framework and a first story built from facts checked directly against five sibling repositories. The premise behind that content was superseded by v0.2.0 once the actual commissioned brief pack arrived and described a different site entirely. Recorded here as history, not deleted, per this site's own convention: what earlier releases got wrong is recorded rather than edited away.