{"v": 1, "release": "v0.2.5", "version": "v0.2.14", "chunks": [[0, "", "What this is. The code a reader runs on newsroom.sgit.ai, the reading meter, the reader's personas and lists, subscribe and the encrypted share, the vault layer, search, the wire reader, the passkey lab, released from one repository and served from this host at versioned paths that are never edited after they are published. \"API\" means client-side: components, formats and contracts the browser runs, with no server and nothing to deploy but files. On this network \"API\" can also mean the SG/Send server; this is not that."], [0, "", "Who. It is made by the SGit Newsroom's agents under the editorial and engineering responsibility of Dinis Cruz, as every page on newsroom.sgit.ai discloses. The reviews are done by agents and are open to people, which is what the public issues are for. The brief that governs the work is Go slow to go fast, refreshed in briefs/."], [0, "", "Licence. Apache 2.0, for the code, the tests and this site. The articles on newsroom.sgit.ai are the newsroom's and carry their own terms."], [0, "", "Contact. agent@riskmandate.ai, which an agent reads first and a person answers, for pilots and partnerships; issues in the repository for anything about the code, which is where the work happens in any case."], [0, "", "This site. Generated by site/build.py in the repository from markdown pages, the map of what a reader runs, the release manifests and the proof of the move; nothing on it is typed twice. Every page has a .md twin, an agent block, and a place in llms.txt and llms-full.txt. The source of a page is a file a person or an agent can edit; a pull request changes the site."], [0, "", "Names. SGit is the family of tools this comes from: the sgit command line, the SG/Send encrypted vaults, the sites under sgit.ai. The newsroom is one of them."], [0, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [0, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [0, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [0, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [1, "", "Nothing here needs permission. The code is Apache 2.0, the releases are directories of files with a manifest of hashes, and the live site that runs it is the reference, not the product. The aim is other newsrooms running the same reader, so that the formats, the article number, the list link, the share, the envelope, mean the same thing everywhere."], [1, "three-ways-in", "1. Put the meter on your pages. A static site, a JSON config, a custom element, a pinned import from this host. Readers get a credit and a balance, pay by depth and after reading, and rate. Your site publishes two small data files. Ten lines, explained. This is the route for a section of an existing site."], [1, "three-ways-in", "2. Run a newsroom like this one. The newsroom's repository is public: the pages, the build, the sync, the gate, the engineering board. Fork it, point it at this host, change the words. The newsroom's own replicate page says what is packaged and what is not yet (the article generator; payments beyond a Payment Link)."], [1, "three-ways-in", "3. Pilot it with us. For a publisher who wants to try the whole thing, meter, personas, lists, the vault, on a part of their site with their own payment link and lane, and to learn with us from what readers do. Write to agent@riskmandate.ai (an agent reads first; a person answers) or open an issue."], [1, "what-you-need", "A static host for your pages (any; the newsroom uses GitHub Pages)."], [1, "what-you-need", "The article feed (articles/graphs.json) and the numbers file (articles/ids.json), written by your build. The contracts."], [1, "what-you-need", "A Stripe Payment Link for the top-up, returning to your account page. Until it is set the site says so and nothing is charged."], [1, "what-you-need", "Optionally a vault on an SG/Send host for the lane: shares, subscriptions and notes arrive there, encrypted to your key. Setting up the lane."], [1, "what-you-need", "One line that pins the release you load, and a copy of its manifest. Taking a release."], [1, "what-you-keep-what-you-give", "You keep your readers' trust in a concrete form: their data never reaches you unless they send it, and when they do it arrives encrypted to a key only you hold. You keep the money, through your own payment link. You keep the site you have."], [1, "what-you-keep-what-you-give", "You give nothing to us. There is no account, no key, no telemetry, no call home: the only requests to this host are for the code, and a release never changes. If you prefer, copy a release to your own host; the manifest tells you whether you have the same bytes."], [1, "why-the-formats-matter-more-than-the-site", "An article number that never changes. A reading list that is a link. A persona that is a name, a theme and a list of what was kept. A share that is an encrypted envelope to a published key. These are the parts that are worth agreeing on across newsrooms, because then a reader's habits are theirs and not a site's. The contracts are small on purpose, and changing one is a release with a note, never an edit in place."], [1, "contributing", "Issues are the work: every finding of the review is one, and every change starts as one."], [1, "contributing", "A pull request is reviewed by a person and an agent before it merges; the agent's review is a required check."], [1, "contributing", "The served files are frozen until phase 4 of the brief is finished: a change is a new release with a test that fails without it and a reason in the pull request."], [1, "contributing", "The tests run in three engines on every commit, against the newsroom's real pages; a change that breaks a page there is caught before it ships."], [1, "contributing", "The brief that governs the work, and what changed when the move was done: briefs/ in the repository. The way the agents that keep this work are briefed is the agents page, which is written for people too."], [1, "contributing", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [1, "contributing", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [1, "contributing", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [1, "contributing", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [2, "", "You are reading the brief for the agents that keep this repository, and for the ones that keep newsroom.sgit.ai and consume it. It is public because the work is. A person changing the code should read it too."], [2, "what-this-is-in-three-lines", "The code a reader runs on newsroom.sgit.ai, released from this repository and served from https://api.newsroom.sgit.ai/<release>/<path>, never edited after it is published. \"API\" means client-side: components, formats and contracts the browser runs; no server. The newsroom (and, next, sgit.ai) pins one release."], [2, "read-these-first", "llms.txt: every page of this site with one line each; llms-full.txt is the whole site in one fetch."], [2, "read-these-first", "The current manifest: every served path, bytes, SHA-256, and which files differ from the newsroom's bytes and why."], [2, "read-these-first", "briefs/: the plan, refreshed at newsroom v0.12.10, with the addendum written when the move was done. The original is Go slow to go fast."], [2, "read-these-first", "map/before/: the map of everything a reader runs, as it was before the move; the review is read from it."], [2, "read-these-first", "tests/: what is proved, and how the harness works."], [2, "the-rules", "The served files are frozen until phase 4 of the brief is finished. A change is a new release with a test that fails without it and a reason in the pull request. A fix to a review finding is a deliberate change to the test that pinned it."], [2, "the-rules", "A release is a directory that is never changed. releases/<v>/ and its manifest.json, cut by tools/release.py cut; check recomputes every hash and fails when the tree is not the release tools/version.json names. Nothing is loaded unversioned."], [2, "the-rules", "Identical paths, for now. A served path is the path the file had in the newsroom; reshaping is phase 4."], [2, "the-rules", "Three files locate the site root from the page (data-root), not from their own URL: vault-pane.js, search.js, ask.js. Any new file that links to pages or fetches site data does the same."], [2, "the-rules", "Tests in three engines on every commit, against the newsroom at the commit in tests/newsroom.json; a SKIP fails CI. Clipboard reads and CDP (the virtual authenticator, the faked built-in model) are Chromium's."], [2, "the-rules", "A pull request needs a person and an agent reviewer. The agent's review is a required check."], [2, "the-rules", "Bugs and vulnerabilities are tests that pass, recording the behaviour as it is, with an issue; a vulnerability test and its issue stay in a private vault until the fix lands."], [2, "the-rules", "No third-party script on a reader page. One vendored library, pinned at a version, never edited here."], [2, "where-things-are", "assets/, for/, wire/, passkey/ at the root; tools/served.json is the list"], [2, "where-things-are", "releases/<v>/, tools/version.json, tools/release.py (cut, check, site), tools/live_check.py"], [2, "where-things-are", "tools/prove_move.py, map/proof/<v>.json"], [2, "where-things-are", "tests/harness.mjs (two trees: API and SITE; routes the host to the tree), tests/test_*.mjs, tests/vault-mock.mjs, tests/newsroom.json"], [2, "where-things-are", "site/build.py → www/; pages in site/pages/ (markdown or HTML fragments with front matter); data in site/data/; release notes in site/releases/; --check in CI"], [2, "where-things-are", "map/before/<newsroom release>/map.json and hashes.json; tools/api_map.py (moved from the newsroom; to be re-pointed at this tree and a newsroom checkout, nightly)"], [2, "where-things-are", "issues 1 to 18, labelled by phase, area and severity"], [2, "where-things-are", ".github/workflows/ci.yml, deploy-pages.yml (main: check, tag, Pages, live check)"], [2, "how-the-newsroom-consumes-a-release", "admin/build/api.json pins the release; admin/build/api-manifest.json is its manifest, copied; admin/build/api.py writes every reference (--repoint), recomputes the import gate's hashes (--rerecord) and checks every page; validate.js check 14 refuses a relative, unpinned or unlisted reader-file reference, check 13 holds the frozen meter copies to the manifest; the sync's items 11 and 14 point imported pages at the host and stop importing the reader code. The normaliser's one added rule (a reader-file reference, relative or on the host, reads as API/<path>) is in api.py, mirrored in validate.js; keep the two in step. The newsroom's release note v0.13.0 and card 036 describe the move from its side."], [2, "changing-this-site", "Edit or add a page under site/pages/ (markdown, or an .html fragment when the layout needs cards, doors or a diagram), with front matter: title, description, section, eyebrow, crumbs, agent (the one-paragraph brief for agents), wide. Then python3 site/build.py and commit www/ with the source; CI fails if www/ is not what the build writes. The data pages (contracts, state, review, map, proof, releases, articles) are built from the records, not written: change the record. Refresh the article feed from a newsroom checkout with --refresh-articles."], [2, "what-never-to-do", "Edit anything under releases/. Move a tag. Load a reader file unversioned or by a relative path. Change a served file without a new release and a failing test. Add a third-party script to a reader page. Put a key, a read key or an access key in a file. Merge without a person's review."], [2, "what-never-to-do", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [2, "what-never-to-do", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [2, "what-never-to-do", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [2, "what-never-to-do", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [3, "", "74 files in the current release, 1,154,711 bytes, listed path by path in the manifest. What follows is the same set by group: what each is for and where it came from."], [3, "sg-meter-assets-components-sg-meter-v1", "v1.4/v1.4.1/ (sg-meter.js, sg-meter-core.js, sg-meter.css, sg-meter.tpl)"], [3, "sg-meter-assets-components-sg-meter-v1", "the line that continues: the newsroom's build of v1.3.1 without \"Pause the meter\" and \"Start again\", with the landing view for persona links, and the v1.4.1 changes the newsroom made in October"], [3, "sg-meter-assets-components-sg-meter-v1", "v1.4/v1.4.0/, v1.3/v1.3.1/, v1.3/v1.3.0/, v1.2/v1.2.0/, v1.1/v1.1.0/, v1.0/v1.0.0/"], [3, "sg-meter-assets-components-sg-meter-v1", "frozen: published artefacts, served byte for byte, never edited; a page that pinned one keeps loading the same files"], [3, "sg-meter-assets-components-sg-meter-v1", "sg-meter.js is the element (twelve views, the reader card, the share form, the persona graph); sg-meter-core.js is the meter (prices, the charge, ratings, declining, credit, personas, picks, the share text); the .tpl and .css are fetched beside it."], [3, "the-component-base-assets-components-base-v1-v1-0-v1-0-0-sg-", "The contract a component follows: static jsUrl = import.meta.url, get resourceName(), onReady(), a .tpl and a .css beside the .js, published at an immutable versioned path. It fetches and caches the siblings and reports a failure as <name>:error."], [3, "reading-lists-for", "reading-list.js parses and builds the link (LIMITS, parse(), build()), shows a list and opens it as a visitor persona through the meter's public calls; make.js is the page that makes and previews one; for.css styles both. The grammar."], [3, "subscribe-and-the-share-assets-subscribe-js", "The subscribe form: reads the contact file, checks the key's fingerprint, encrypts an .eml to the published key (the sgit hybrid envelope v2) and appends it to the lane. The meter's share view uses the same envelope."], [3, "the-vault-layer-assets-newsroom-vault-js-assets-door-js-asse", "door.js derives the door from a passkey's PRF bytes or a recovery code; newsroom-vault.js is the newsroom's one module over the vault library: the door, the master, the reader vault, the lane. vault-pane/ is the pane on every page that carries the meter: vault-pane.js the UI, notes.js the notes as records, reading.js what was read, wire-state.js the wire's lens and stories seen, pending.js what only this browser holds, sync.js the sync as pure functions, inbox.js and send.js (with send.css) the reader's inbox: sending this browser's records to a vault from any browser, with a QR code from the vendored qrcode-generator."], [3, "search-and-ask-assets-search", "search.js ranks the site's pages in the browser (BM25 over fields and paragraphs) from search/docs.json and search/text.json that the site publishes; ask.js gives the top passages to Chrome's built-in model or to openrouter.ai with the reader's own key; search-nav.css is the Search link in every nav, search.css and ask.css the page."], [3, "the-wire-reader-wire", "vault-reader.js opens a public-read vault in the browser with its published read key (vendored from sgit.ai's vault); wire.js draws the edition, the sources and the documents as text, never as markup, for every wire (the Industry Wire, the OWASP Wire, the AWS Wire, the Portugal Wire); graphs.js draws the edition as graphs; subscribe.js is a wire's subscribe form; wire.css."], [3, "the-vendored-libraries-assets-vendor", "qrcode-generator/2.0.4/qrcode.mjs: the QR code the inbox shows, with its README."], [3, "assets-vendor-sg-vault", "v0.2.3/: twelve files of the library that runs the SG/Send host, from SGraph-AI__App__Send v0.2.3, never edited here; VENDOR.md records the upstream commit and every hash, and the vault test checks them. local/sg-vault--create-with-id.js: one extension pending upstream (create a vault at a chosen id)."], [3, "the-passkey-lab-passkey-lab-js-lab-css-vectors-json", "The proofs of concept for the passkey opens the vault: a passkey with PRF, the door derivation written out, sgit's keys, a recovery code, test vectors against sgit's Python (tools/passkey_vectors.py writes them), and the door created on a vault server. A lab, not a feature; it moved because it is reader-run code with a test."], [3, "what-is-not-here-on-purpose", "The pages (the newsroom's), the content data (articles/graphs.json, articles/ids.json, persona/links.json, search/*.json, wire/snapshot.json), the contact file at /.well-known/, and the site's chrome (site.js, shots.js, nav.js). They belong to the site that serves the page; this host serves what the browser runs."], [3, "what-is-not-here-on-purpose", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [3, "what-is-not-here-on-purpose", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [3, "what-is-not-here-on-purpose", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [3, "what-is-not-here-on-purpose", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [4, "", "Home / Docs / The hosting model"], [4, "", "The code lives on one host, in one directory per release, and a release is never changed after it is published. The pages that run it live wherever the newsroom lives. Everything about a reader stays with the page."], [4, "the-address-of-a-file", "<path> is the path the file had in the newsroom's repository, so the move was a prefix rewrite and nothing else; reshaping the paths is a later phase. The meter's own component versions nest inside the release unchanged. manifest.json lists every path with its bytes and SHA-256, and which files differ from the newsroom's bytes and why. releases.json lists the releases."], [4, "what-a-cross-origin-host-needs", "GitHub Pages serves every file with access-control-allow-origin: *. That is what an ES module import from another origin needs, and what the component base needs when it fetches a component's .tpl and .css beside its .js through import.meta.url. Classic <script src> tags (the vendored vault library) need nothing. The live check after every deploy fails if the header is missing."], [4, "what-stays-on-the-page-s-origin", "The reader's state. localStorage and sessionStorage belong to the page's origin, not the script's. sgit.meter.v1 stays on the newsroom whichever host serves the meter. This is the property the move depended on, and a test records it."], [4, "what-stays-on-the-page-s-origin", "The site's data. The meter fetches the article feed and the contact file from cfg.root on the page; the reading list fetches articles/ids.json from where the page says. Nothing is fetched from this host but code."], [4, "what-stays-on-the-page-s-origin", "The addresses. The Stripe return page, /for/#…, /persona/<id>/, /.well-known/sgit-subscribe.json are the newsroom's; pages do not move to this host, and could not, because another origin has another origin's storage."], [4, "data-root", "Three files locate the site's root to link to pages and fetch data: the vault pane, search and ask. In the newsroom they did it from their own URL; on another host that would be this host. They now read <html data-root=\"…\">, the path from the page to the site root, which every newsroom page carries (\"\" at the root, \"../\" one level down). A page that imports them needs the attribute. The code they load (the vault library) they still find from their own URL."], [4, "pinning-the-manifest-rollback", "A consuming site writes the release into one file and generates every URL from it. The newsroom's is admin/build/api.json; its admin/build/api.py --repoint rewrites every page, its gate (check 14) refuses a relative, unpinned or unlisted reader-file reference, and check 13 holds the frozen meter copies it still serves to the manifest's bytes. A rollback is the previous release in that file and one run. Taking a release."], [4, "content-security-policy", "No page sets one yet (finding R10). When one is added, script-src and connect-src include https://api.newsroom.sgit.ai; frame-ancestors cannot be set in a meta tag, so framing protection needs a host that sets headers, which GitHub Pages is not. The order of work in the brief is: load scripts as modules instead of fetched text through eval, then the meta policy, then decide on a layer in front."], [4, "what-a-different-host-changed", "Three files could not move unchanged, because they located the site root from their own URL: assets/vault-pane/vault-pane.js, assets/search/search.js, assets/search/ask.js. Each now takes the site root from the page (data-root) and keeps a second root, its own, for the code it loads. The manifest records each with its before-hash and the reason, and tools/release.py refuses any other difference from the newsroom's bytes. The proof."], [4, "what-a-different-host-changed", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [4, "what-a-different-host-changed", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [4, "what-a-different-host-changed", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [4, "what-a-different-host-changed", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [5, "", "Everything here is read from a record: the map of what a reader runs (map/before/<release>/map.json), the release manifests, tools/served.json. A number on these pages is not typed; a contract changes only with a release."], [5, "pages", "The contracts: the 14 formats other sites, pages and agents program against: the meter config, a charged page, persona links, the reading-list link, article numbers, the return page, the export, the share, the envelope, the contact file, the wire's vault, events, a component, the import's rules."], [5, "pages", "State, inputs and outputs: what localStorage holds under sgit.meter.v1, everything that comes in and who controls it, and every channel by which anything leaves the browser."], [5, "pages", "The components: the served files by group, what each is for, how they are versioned, and which are frozen."], [5, "pages", "The hosting model: https://api.newsroom.sgit.ai/<release>/<path>, never edited in place; CORS; the page's origin and data-root; pinning, the manifest and rollback; what a Content-Security-Policy must name."], [5, "pages", "The reading-list link: the grammar of /for/#…, field by field, with the limits the parser enforces."], [5, "the-element-in-brief", "<sg-meter view=\"…\"> is one custom element with twelve views; the page's charge is view=\"page\" with a kind (article_new is derived from date and newDays, the rest are article, issue, note, collection, page, free), date, topics, title, and quiet for a page that charges nothing. The config is a JSON block with id sg-meter-config; every key has a default. The views, the attributes and a full config are on the developer quick start."], [5, "events", "The meter emits DOM events on document that a page or another component can listen to: sg:meter.changed, sg:meter.charged, sg:meter.rated, sg:meter.declined, sg:meter.toppedup, sg:meter.reset, sg:meter.restored, sg:meter.persona, sg:meter.shared; and sg-meter:error when the element fails, with why."], [5, "versions", "The meter's own line is v1.4.0, served at assets/components/sg-meter/v1/v1.4/v1.4.0/; v1.0.0 to v1.3.1 are frozen and still served, so a page that pinned one keeps working. The API's releases (v0.2.5 today) wrap all of it under a versioned prefix. Releases."], [5, "versions", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [5, "versions", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [5, "versions", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [5, "versions", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [6, "", "Home / Docs / The reading-list link"], [6, "", "A reading list is a link. Everything the recipient sees is in the part after the #, which never reaches a server; nothing is stored anywhere but the link itself."], [6, "", "up to 40 characters of letters, spaces, hyphens and apostrophes; anything else is dropped and listed under Left out"], [6, "", "articles to read, by number, in the order given"], [6, "", "numbers that exist in articles/ids.json"], [6, "", "the same; r and s together hold 1 to 50"], [6, "", "personas or collections to start from"], [6, "", "persona ids, or c:<collection>, up to 10"], [6, "", "up to 240 characters, shown as text"], [6, "", "the sender's address, for a Reply button"], [6, "", "an address; the page sends nothing itself"], [6, "what-opens", "The page reads the fragment, looks each number up in articles/ids.json, and shows the list with titles, dates and teasers from the feed. Opening it adds a visitor persona named for the list (\"Steve's list, from Dinis\") through the meter's public calls, so the reader can keep it as a persona of their own or remove it; nothing is charged for opening a list. A list's persona is keyed by a hash of the names and numbers (finding R17 notes the hash is 32 bits)."], [6, "the-make-page", "/for/make.html builds a link from a form: search the articles, add up to 50, move them up and down, name the sender and the reader, write the note, copy the link. It reads its own link back through the recipient's parser, so what the preview shows is what the link opens. An existing link loads into the form for editing."], [6, "what-is-deliberately-not-in-it", "A signature. The names are whatever the link says; a signed list is a later step on the newsroom's keys, and the page says so."], [6, "what-is-deliberately-not-in-it", "A server. No list is stored anywhere; a link is the whole list."], [6, "what-is-deliberately-not-in-it", "Paying for someone else's reading. Designed, not built."], [6, "for-a-site-that-adopts-it", "Publish articles/ids.json with a stable n for every article (the newsroom's admin/build/ids.py assigns numbers once, in publication order, and its gate refuses a change) and import for/reading-list.js and for/make.js from this host on two pages; the newsroom's for/index.html and for/make.html are the worked examples. The parser's limits are in LIMITS at the top of reading-list.js; the tests that hold them are tests/test_lists.mjs."], [6, "for-a-site-that-adopts-it", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [6, "for-a-site-that-adopts-it", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [6, "for-a-site-that-adopts-it", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [6, "for-a-site-that-adopts-it", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [7, "", "A client-side API: components, formats and contracts the browser runs, with no server and nothing to deploy but files. Every file is served from this host at a versioned path that is never edited after it is published, and every release has a manifest of hashes. You pin a release; a rollback is one line."], [7, "1-put-the-meter-on-a-page", "Three pieces in the page: the element where the charge happens, the config, and the import. The element's kind is the price class; the config is the same on every page of a site, so write it once in your build."], [7, "1-put-the-meter-on-a-page", "Prices are in pence (or the smallest unit of symbol). start is the opening credit. The paths in links, picks and share.contact are from your site's root, and the meter resolves them against the page, never against this host. Every key has a default, so a config can be short; the full shape is the meter config contract."], [7, "1-put-the-meter-on-a-page", "Only sg-meter.js is imported; it brings its core, its template and its stylesheet from the same versioned directory on this host. A published path is never changed: a fix is a new version path, so a page that works today keeps loading the same bytes."], [7, "2-the-element-s-views", "One element, twelve views, each a page or a part of one. view=\"page\" charges and shows the reader card; the rest are the account."], [7, "2-the-element-s-views", "the balance chip; marks a negative balance; opens the account"], [7, "2-the-element-s-views", "charges by depth for the page's kind; the reader card: rating, decline, keep for a persona. quiet for a free page"], [7, "2-the-element-s-views", "balance, spent, history, top up, export and restore"], [7, "2-the-element-s-views", "the top-up page; the page the payment returns to"], [7, "2-the-element-s-views", "the packs and the payment link; crediting the return once per reference"], [7, "2-the-element-s-views", "picks for the active persona from your feed; the persona graph"], [7, "2-the-element-s-views", "the presets, the reader's own, rename, activate, keep and reject"], [7, "2-the-element-s-views", "a persona page (/persona/<id>/)"], [7, "2-the-element-s-views", "a link opens the site as a persona, added as a visitor the reader can keep or remove"], [7, "2-the-element-s-views", "a summary and the data as JSON, encrypted to your key and sent to your lane, after consent"], [7, "2-the-element-s-views", "The newsroom's own account pages are the reference implementation: account, newsroom, personas, share, top-up. Copy their bodies; the element does the work."], [7, "3-the-data-your-site-publishes", "picks, the persona graph, the reading list's titles"], [7, "3-the-data-your-site-publishes", "{\"articles\": [{\"slug\", \"title\", \"date\", \"url\", \"teaser\", \"topics\": [], \"tags\": []}, …]}; the newsroom's is here"], [7, "3-the-data-your-site-publishes", "{\"next\": N, \"articles\": [{\"n\", \"slug\", \"title\", \"date\", \"url\", …}]}: n and slug are the contract, assigned once, never changed or reused"], [7, "3-the-data-your-site-publishes", ".well-known/sgit-subscribe.json"], [7, "3-the-data-your-site-publishes", "sgit-subscribe/v1: your public key and its fingerprint, the lane's vault, endpoint and append token. Setting one up"], [7, "3-the-data-your-site-publishes", "whoever writes the persona links"], [7, "3-the-data-your-site-publishes", "one entry per preset, with its page; generated from the config"], [7, "4-the-reader-s-own-newsroom-lists-personas-the-vault-search", "These are pages of your own that import the code from this host. Each needs <html data-root=\"../\"> (the path from the page to your site's root), which is how the pane and search find your pages and data from another origin."], [7, "4-the-reader-s-own-newsroom-lists-personas-the-vault-search", "The make page (for/make.js), the persona pages, the search page (assets/search/search.js, ask.js) and the wire (wire/wire.js) follow the same pattern; the newsroom's pages are the worked examples, and the how-to guides walk through each."], [7, "5-the-hosting-model-and-what-a-different-host-changes", "GitHub Pages serves every file here with access-control-allow-origin: *, which is what a cross-origin module import and the component's sibling fetches need. Storage belongs to the page's origin, so a reader's state stays on your site whichever host serves the script. The meter fetches your feed and your contact file from the page's origin; nothing is fetched from this host but code. If you add a Content-Security-Policy, script-src and connect-src name https://api.newsroom.sgit.ai. The hosting model."], [7, "6-pin-a-release-verify-it-roll-it-back", "Write the release into one place in your build and generate every URL from it; the newsroom does this with admin/build/api.json and checks every page against the manifest in its gate. Taking a release and rolling back."], [7, "7-run-the-tests-against-your-pages", "The tests that cover the meter, the lists, the pane, search and the wire are in the repository, and they run against any site that imports this code: they serve your pages locally and route this host to the working tree, in Chromium, WebKit or Firefox."], [7, "7-run-the-tests-against-your-pages", "Running the tests, including what each file covers and which need Chromium."], [7, "where-everything-is", "Reference: contracts, state, inputs and outputs, components, hosting."], [7, "where-everything-is", "Releases and the current manifest."], [7, "where-everything-is", "Source, issues, and the brief for agents, which is also the brief for a person changing the code."], [7, "where-everything-is", "SG Meter, documented on the newsroom, with its security model."], [7, "where-everything-is", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [7, "where-everything-is", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [7, "where-everything-is", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [7, "where-everything-is", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [8, "", "Security, architecture, procurement"], [8, "", "This page is for the person who has to say yes or no. It is written so that nothing on it needs to be taken on trust: every number is read from a record in the repository, every finding is a public issue, every file has a hash on the live host, and the move that put the code here was proved byte for byte."], [8, "the-architecture-in-four-sentences", "There is no server of ours: the reader code is static files on a host that cannot run code, and the pages that use it are static too. The reader's state (balance, history, personas, lists, notes) lives in the browser's storage on the newsroom's origin, and optionally in an encrypted vault whose keys derive from the reader's passkey and which the newsroom cannot open. Money moves through a Stripe Payment Link the newsroom owns; a return page credits the balance once per payment reference. Anything a reader sends (a share, a subscription, a note) is encrypted in the browser to a published key and appended to a write-only lane in a vault."], [8, "trust-boundaries", "everything: the state is theirs, readable, exportable, editable"], [8, "trust-boundaries", "be stopped from editing their own balance (accepted; see the security model)"], [8, "trust-boundaries", "page requests, as any host does"], [8, "trust-boundaries", "see a balance, a persona, a list or a note; verify a payment"], [8, "trust-boundaries", "run code, set headers, see any reader data"], [8, "trust-boundaries", "card, email, name, postcode, at payment"], [8, "trust-boundaries", "read a share, a note or an account; the keys are the reader's and the newsroom's"], [8, "trust-boundaries", "The newsroom's agent, with the lane's read key"], [8, "trust-boundaries", "shares, subscriptions and notes, decrypted"], [8, "trust-boundaries", "write to the lane or to a reader's vault"], [8, "what-leaves-the-browser", "Nine channels, each listed with what, when and who sees it, on state, inputs and outputs, read from the map. In short: the page's own origin for files; POST of an encrypted envelope to the lane when the reader presses Send; navigation to Stripe when they press Top up; GET of ciphertext from the wire's vault; a postMessage ready signal if a page is framed; the clipboard and a download at the reader's command. The tests record the hosts a page contacted and fail on any other."], [8, "the-accepted-gaps-written-down", "The security model on the newsroom (meter/security.html) accepts four things a server would prevent, because there is no server by design: the return page credits any session id; the reader can edit their own balance; the names in a reading list are whatever the link says; a page is charged by the deepest point reached. The review's job was to prove those are the only gaps."], [8, "the-review-findings-findings-each-a-public-issue", "Before the code moved here it was mapped and reviewed line by line, the way a fractal semantic graph is read: every file, every control a reader can click, type or pay, every input and output, every contract, then every function the findings name. The findings are issues 1 to 18 in the repository, labelled by phase, area and severity. Where a finding can be pinned, a test records the behaviour as it is today, so that the fix is a visible change to a test. The three a security evaluator will want first:"], [8, "the-review-findings-findings-each-a-public-issue", "No Content-Security-Policy on any page (R10, high). The pages' loader runs fetched scripts through eval, and GitHub Pages sets no headers, so frame-ancestors cannot be set. The fix is a phase-5 change: load scripts as modules, then a meta CSP; framing protection needs a host that sets headers."], [8, "the-review-findings-findings-each-a-public-issue", "Payment references unbounded and unchecked (R14, low) and restore() trusts a file's fields (R2, low): the exposure is a file someone sent the reader to restore."], [8, "the-review-findings-findings-each-a-public-issue", "Production reader data goes to hosts named dev (R5): a naming decision for the operator, listed so that nobody is surprised."], [8, "the-review-findings-findings-each-a-public-issue", "The full table, with the test that pins each and the proposed change."], [8, "supply-chain", "Third-party scripts on the reader pages: none. The build fails if one appears (the brief's rule)."], [8, "supply-chain", "One vendored library, the vault library that runs the SG/Send host, pinned at a version and never edited here; its twelve files are hashed in VENDOR.md and the test checks them."], [8, "supply-chain", "Every release is a manifest of paths, bytes and SHA-256; the live host is checked against it after every deploy (tools/live_check.py), because green does not mean live."], [8, "supply-chain", "Nothing is edited in place. A release directory, once published, is frozen; CI recomputes every hash in every manifest on every commit."], [8, "the-proof-of-the-move", "This code lived in the newsroom's repository until 13 October 2026. Moving it to a host of its own was done as a pure refactoring, and proved: of 74 files, 60 hash exactly as they did before, and the three that differ do so by the lines that located the site root from the script's own address, each recorded in the manifest with its before-hash and the reason; of 597 pages on the newsroom, 593 normalise to what they were. The proof, with the report it was written from."], [8, "the-pipeline", "Every commit: syntax, the manifest, a build that is the same bytes twice, and the tests in Chromium, WebKit and Firefox against the newsroom's real pages, in about four minutes. Every push to main: a tag, the Pages deploy, and the live check. A pull request needs a person and an agent reviewer. The runs."], [8, "verify-it-yourself", "The newsroom's gate does the equivalent on its side: every page must load the reader code from the pinned release, by a URL that is in the manifest, and never by a relative path. Its source is public too."], [8, "licence-and-provenance", "Apache 2.0. The code was written by the newsroom's agents under Dinis Cruz's editorial and engineering responsibility, as every page on newsroom.sgit.ai discloses; the review was done by agents and is open to people, which is what the issues are for. About, licence, contact."], [8, "licence-and-provenance", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [8, "licence-and-provenance", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [8, "licence-and-provenance", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [8, "licence-and-provenance", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [9, "", "Home / For publishers, editors and executives"], [9, "", "You know the problem. A paywall turns a reader away at the door; a free site pays nothing back; a subscription asks for a commitment before the first paragraph. This is a third thing, running on a live site since October 2026: a reader walks in with a small credit, a meter charges by how far they read, they pay after, and what they pay is set by what they thought of it. Around it, a newsroom that is theirs: personas, picks, lists they can send in a link, an account that travels with them, and none of it on a server of ours."], [9, "", "Everything on this page is running at newsroom.sgit.ai. Open any article and watch the balance in the top bar; the reading account shows what you spent and why. It is a working instance, not a demo."], [9, "a-meter-not-a-wall", "£5 of credit to begin. An article costs 5p, a new one 10p, charged by the deepest point reached. Rate it at the foot and the price moves: excellent is double, not useful is free. Declining refunds the page."], [9, "read-as-who-you-are-today", "A founder, a journalist, a security lead, a builder, a board member. Each has a starting reading list and picks that follow what they keep and reject. A link can open the site as one."], [9, "send-five-articles-not-five-links", "Every article has a number that never changes. A reading list is a link with the numbers in it, from you to a named reader, with a note. Nothing is stored anywhere but the link."], [9, "an-account-that-travels-with-no-sign-in", "A passkey opens an encrypted vault that carries the reading account between a phone and a laptop. The newsroom never holds a key and cannot read it."], [9, "write-back-one-tap", "A reader marks a page done, wrong, more like this, or writes to the newsroom; the notes travel in their vault and arrive encrypted in a lane the newsroom reads."], [9, "industry-news-as-an-inbox", "Stories agents gather into a vault, read live in the browser, filtered by the reader's lens, with what is new since their last visit."], [9, "keeps", "The money. A reader tops up through a Stripe Payment Link you own; the return page credits their balance. No card data touches your site."], [9, "keeps", "The formats. Article numbers, persona links, the reading-list grammar, the share envelope: published contracts your readers and their agents can rely on, and that other newsrooms can share."], [9, "keeps", "The relationship. Shares and subscriptions arrive encrypted to a key only you hold, in a write-only lane; notes from the pane arrive the same way, with the page and the reader's words."], [9, "keeps", "The site you have. Static pages, any host. The reader code is a handful of files pinned from this host."], [9, "never-holds", "Reader data. The balance, the history, the personas, the lists and the notes live in the reader's browser, and in their own vault if they choose one. There is no reader database because there is no server."], [9, "never-holds", "Keys. The vault's keys are derived from the reader's passkey; the newsroom reads a lane with a read key the reader hands over, and nothing else."], [9, "never-holds", "A dependency on us. The code is Apache 2.0, every release is a directory of files with a manifest of hashes, and a rollback is one line."], [9, "a-static-site", "Your pages, wherever they are hosted. The meter is a custom element and a JSON config on each page; the balance chip sits in your navigation. Ten lines."], [9, "two-small-data-files", "An article feed (titles, dates, topics, teasers) for the picks, and a numbers file that gives every article a stable number. The newsroom's build writes both; yours can too. The contracts."], [9, "a-payment-link", "A Stripe Payment Link for the top-up, returning to your account page. Until it is set, the site says so and no money moves."], [9, "a-vault-for-the-lane-optional", "Shares, subscriptions and notes arrive in an encrypted vault on an SG/Send host, drained by a person or an agent with your key. Without it, the meter still runs; the reader just cannot write back."], [9, "a-pinned-release", "One line names the release you load from this host; a manifest lists every file's hash; a rollback is the previous line. How."], [9, "what-is-honestly-not-there-yet", "The site that runs this says so on its own what runs, what is designed page, and the review here lists it as findings. In short: the balance lives in the reader's browser, so a reader can edit their own credit, and the return page credits a payment reference without verifying it; both are accepted and written down in the security model. No page sets a Content-Security-Policy yet. The vault hosts the live site uses are named dev. Shares from the newsroom are still labelled with the site the code came from. Each is an open issue with a proposed change, and each will be a visible change to a test when it is fixed."], [9, "the-thinking-behind-it", "None of this was built first and explained after. Each piece is an article on newsroom.sgit.ai, written before it shipped and again when it went live. For an editor or an executive, start with these four:"], [9, "the-future-of-news-is-a-story-vault-not-a-paywall", "Why the unit of news should be a story a reader can hold, not a wall they must cross."], [9, "sell-the-graph", "The newsroom's founding idea: the value is in the connections between what is published, and that is what a reader pays for."], [9, "paying-the-fact-creator", "What a meter makes possible that a subscription does not: money that follows the reading, down to the person who found the fact."], [9, "going-live-with-the-reading-meter", "The day real money started moving, what was switched on, and the line between what runs and what is designed."], [9, "going-live-with-the-reading-meter", "More: the articles behind it, in reading order. The design pages on corrections that propagate, provenance as the product, and content rights are the newsroom's own."], [9, "starting-a-pilot", "If you run a newsroom and want to try this on a section of your site, with your own payment link and your own lane, the people behind newsroom.sgit.ai will help you set it up and will learn from what your readers do. Write to agent@riskmandate.ai, which an agent reads first and a person answers, or open an issue in the repository, which is where the work happens in any case. Share this page with your team: the developer quick start is what they will ask for next, and the evaluator's page is what your security team will."], [9, "starting-a-pilot", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [9, "starting-a-pilot", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [9, "starting-a-pilot", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [9, "starting-a-pilot", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [10, "", "Home / How-to / Add the meter to a page"], [10, "", "Ten lines on each page, one config written by your build, and five account pages you copy. Nothing to deploy but files."], [10, "1-the-element-where-the-charge-happens", "At the foot of the content, after the last paragraph a reader would reach:"], [10, "1-the-element-where-the-charge-happens", "kind is the price class (article, issue, note, collection, page, free); an article newer than newDays is charged as article_new. date and topics feed the personas' picks; title is what the history shows. A page that should charge nothing is kind=\"free\" quiet, which keeps the balance on screen without a card (a synthetic reader once took a vanished chip for lost credit)."], [10, "2-the-chip-in-the-navigation", "On every page, so a reader never loses sight of their balance. It marks a negative balance and opens the account."], [10, "3-the-config-once", "A JSON block with id sg-meter-config, the same on every page; write it in your build so it cannot drift. Prices in pence; every key has a default. The full shape and a live example are on the developer quick start. The parts you will change:"], [10, "3-the-config-once", "Leave topup.link empty until your Stripe Payment Link exists: the top-up page then says that no money moves. The newsroom's gate refuses a test-mode link on a live page."], [10, "4-the-import", "Pinned to a release and a component version; neither is ever edited in place. Generate the URL from one place in your build (taking a release)."], [10, "5-the-account-pages", "Five pages your site serves, each a shell around one view: account/index.html (view=\"account\"), account/top-up.html (topup), account/topped-up.html (topped-up; set it as the Stripe link's return URL with ?session_id={CHECKOUT_SESSION_ID}), account/newsroom.html (newsroom), account/personas.html (personas), and account/share.html (share). Copy the newsroom's: account/. The paths go in links and links2 of the config."], [10, "6-the-feed", "articles/graphs.json with one entry per article (slug, title, date, url, teaser, topics, tags) is what the picks and the persona graph read. The newsroom's build writes it from the articles; yours can write it from whatever you have. Without it the meter still charges; the newsroom view says the list could not be loaded."], [10, "7-check-it", "Open a page: the chip shows £5.00; scroll to the foot and watch the balance fall; rate the page at the card and see the price move; reload in the same tab and see nothing charged twice. Then run tests/test_meter.mjs against your site (running the tests)."], [10, "what-to-read-before-going-live", "Going live with the reading meter for what was switched on and in what order, Who will game the reading meter for the threat model, and the security model for the gaps the design accepts."], [10, "what-to-read-before-going-live", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [10, "what-to-read-before-going-live", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [10, "what-to-read-before-going-live", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [10, "what-to-read-before-going-live", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [11, "", "One task each, in the order a site adopts the API. The newsroom's pages are the worked examples throughout; its repository is public."], [11, "", "Add the meter to a page: the element, the config, the import, the balance chip, the account pages, and the two data files your site publishes."], [11, "", "Make a reading-list link: by hand from the grammar, or with the make page; what the recipient sees."], [11, "", "Open the newsroom as a persona: persona pages and links, persona/links.json, what a visitor persona is."], [11, "", "Set up the subscribe lane: a key pair, a vault on an SG/Send host, the contact file at /.well-known/, and reading the lane with the key alone."], [11, "", "Take a release, roll one back: for a site that consumes the API; the newsroom's procedure as the example."], [11, "", "Run the tests: in Chromium, WebKit and Firefox, against the newsroom's pages or your own."], [11, "", "Make a release: for maintainers: version, cut, check, pull request, deploy, the live check."], [11, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [11, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [11, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [11, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [12, "", "A release is a directory that is never changed after it is on dev, the default branch. The tree is always exactly the release the version file names, or the check fails."], [12, "the-rules-while-the-files-are-frozen", "Until phase 4 of the brief is finished (the refactoring with every test passing, and the adversarial exercise), the served files change only as a new release, each change with a test that fails without it and a reason in the pull request. A fix to a finding is a deliberate change to the test that pinned it. A new reader feature is built here, as a new versioned file, never in the newsroom's tree."], [12, "1-change-and-test", "Edit under the served paths (assets/, for/, wire/, passkey/); if the file is one of the meter's, it is a new component version at a new path, never an edit of v1.4.0. Run the tests in the three engines against the newsroom checkout (running the tests)."], [12, "2-version-and-cut", "tools/version.json holds two numbers and a date, all from the file, never the clock:"], [12, "2-version-and-cut", "version, the repository's version. Every change that lands on dev is a new one, in small increments: a patch for a small change (v0.2.1, v0.2.2, ...), a minor for a new capability. The deploy tags it, and refuses a version that is already a tag or not above the latest. CI on a branch fails when the version is not above dev's."], [12, "2-version-and-cut", "release, the latest cut of the reader code: releases/<release>/, what the consuming sites pin. It changes only when a served file changes; then it is set to the new version and cut."], [12, "2-version-and-cut", "Add the version's line to site/data/versions.json (newest first); the build refuses a version without one, and /versions/ shows them all. A new page needs its link-preview card: python3 site/og.py draws one into site/og/ for every page that has none (commit it; the gate fails a page without one)."], [12, "2-version-and-cut", "cut refuses to write over an existing release directory, refuses a release that is not the repository's version, and refuses a file that differs from the newsroom's bytes unless CHANGED_FROM_NEWSROOM records why. Write a release's note at site/releases/v0.2.3.md."], [12, "3-the-pull-request", "CI runs the syntax check, the manifest check, the build twice, the site check and the tests in three engines. A pull request needs one person and one agent reviewer; the agent's review is a required check. The description says what changed, which test fails without it, and why now."], [12, "4-merge-deploy-tag-check", "A push to dev (the default branch, and the release branch) runs deploy-pages.yml: the checks again, a tag of the version, the Pages deploy of www/ and releases/, and then tools/live_check.py, which asks the live host for every file of the release and compares the hashes, retrying while Pages propagates. The release is live when that job is green, not before."], [12, "5-the-consumers", "Tell the newsroom (and sgit.ai, once it pins): taking a release. The newsroom's release note names the API release it moved to."], [12, "what-never-happens", "A file under releases/ is never edited. A tag is never moved. A release is never cut from a tree that differs from it. A served file is never loaded unversioned."], [12, "what-never-happens", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [12, "what-never-happens", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [12, "what-never-happens", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [12, "what-never-happens", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [13, "", "Home / How-to / Open the newsroom as a persona"], [13, "", "A link that says who you are reading as. The reader can keep the persona or send it away; nothing is charged for arriving."], [13, "the-links", "Five starting personas: founder (Morgan), journalist (Rowan), security (Sam), builder (Kai), board (Jordan). persona/links.json lists them with their pages, for whoever writes the email. The picker at /persona/ shows all five; an unknown id is said so, and nothing is added."], [13, "what-happens", "The page's meter is in its landing view. It adds the persona as a visitor: active, with its starting reading list and picks, but marked as arrived by a link. The page says who you are reading as and offers Keep (it becomes one of the reader's own) and Remove (it goes, and the others stay). Opening the link twice adds nothing twice. The article A link to a persona is the design, with the vault as the step after it."], [13, "defining-the-presets", "Each preset is an entry in the meter config's personas.presets: id, label, name, theme (a hex colour), blurb, topics (weights by topic) and articles (the starting list, by slug). A persona added to the config gets its page and its row in links.json on the next build. The newsroom's admin/build/personas.py writes persona/index.html, one page per preset, and links.json; its pages carry the meter block with view=\"landing\" and the id in the address."], [13, "what-a-persona-does-afterwards", "It curates: Keep and Not for this persona on any reader card move an article onto or off its lists, and the picks on the newsroom page follow what it kept. A page read is credited to the active persona. A reading list opened from a link is a persona of this kind too, named for the list."], [13, "what-a-persona-does-afterwards", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [13, "what-a-persona-does-afterwards", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [13, "what-a-persona-does-afterwards", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [13, "what-a-persona-does-afterwards", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [14, "", "Home / How-to / Make a reading-list link"], [14, "", "A list is a link. Make it with the page, or type it."], [14, "with-the-make-page", "Open newsroom.sgit.ai/for/make.html. Search the articles, add up to fifty, move them up and down, mark some as worth a look rather than to read, name yourself and the reader, write a note, and copy the link. The preview shows the list exactly as the recipient will see it, because the page reads its own link back through the recipient's parser. Every article page also has a start a reading list with it link at its foot, which opens the make page with that article in it."], [14, "by-hand", "r is the articles to read, in order, by number; s is worth a look; from and to are names; n is a note. The numbers are in articles/ids.json, and each article prints its own (Article No. 78). The rules, field by field: the reading-list link."], [14, "what-the-recipient-sees", "The list, with each article's title, date and teaser, in the order you gave; your note; a Reply button if you gave an address. Opening it adds a visitor persona named for the list, which they can keep or remove; nothing is charged for opening it. Anything malformed in the link is dropped and listed under Left out, so a mangled link still opens."], [14, "for-a-site", "Two pages that import from this host, and a numbers file:"], [14, "for-a-site", "Publish articles/ids.json with a stable n per article (never changed or reused)."], [14, "for-a-site", "for/index.html: import { openList } from 'https://api.newsroom.sgit.ai/v0.2.5/for/reading-list.js' and call openList({ core, ids: '../articles/ids.json', root: '../', mount }) with core the meter core's URL on this host. Load for/for.css from this host too."], [14, "for-a-site", "for/make.html: the same with makeList from for/make.js and site: 'https://your-site/for/', the address the links will carry."], [14, "for-a-site", "The newsroom's admin/build/lists.py writes both pages; copy it or the pages it writes."], [14, "for-a-site", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [14, "for-a-site", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [14, "for-a-site", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [14, "for-a-site", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [15, "", "No mocks of the code: real browsers, the real pages, a real vault library against a mock of the vault API, and the sgit command line. The harness swaps one thing only: requests to this host are answered from the working tree."], [15, "set-up", "tests/newsroom.json names the commit CI checks the newsroom out at. NEWSROOM=<path> points the tests at any checkout, including your own site once it imports the code."], [15, "run", "A test prints ok or FAIL per check and exits 1 on any failure. It prints SKIP and exits 0 when it cannot run (no browser, no newsroom checkout, no sgit); CI treats a SKIP as a failure, so a missing install cannot pass quietly."], [15, "what-each-file-covers", "the served stylesheets write no colour outside a theme token (the newsroom's rule, held here since the files moved)"], [15, "what-each-file-covers", "this website: the five themes' tokens, no literal colour in its stylesheet, the picker and its memory, 4.5:1 in every theme, the bar at ten widths"], [15, "what-each-file-covers", "the meter in a browser: depth, rating, decline, reload, below zero, the return page, personas, picks, export and restore, the share form, the persona links, phone width"], [15, "what-each-file-covers", "the reading-list parser in Node and the two pages in a browser: malformed input, limits, the make page, copy, phone width"], [15, "what-each-file-covers", "the review's findings, pinned as the behaviour is today (R1 to R11, R14, R15, R17)"], [15, "what-each-file-covers", "all three; R2 is held in Chromium"], [15, "what-each-file-covers", "the wire pages reading the real vault: edition, lenses, sources, documents, what left the browser"], [15, "what-each-file-covers", "all three (needs the vault host)"], [15, "what-each-file-covers", "the wire's graphs: the lenses' edges and the picture drawn from the real vault"], [15, "what-each-file-covers", "all three (needs the vault host)"], [15, "what-each-file-covers", "the activity vault's logic as pure functions, two devices' states"], [15, "what-each-file-covers", "the index and the ranking in Node, the page in a browser"], [15, "what-each-file-covers", "the vendored library against the mock, the newsroom's layer, the sgit CLI round trip"], [15, "what-each-file-covers", "the passkey lab with a virtual authenticator that has PRF"], [15, "what-each-file-covers", "the pane: the account carried between three devices through the mock"], [15, "what-each-file-covers", "the feedback loop end to end: notes, the lane, the CLI reading it, a second device"], [15, "what-each-file-covers", "the pane's inbox and send: a link held, a QR code decoded, a second device"], [15, "what-each-file-covers", "ask: passages and messages in Node; the reader's key and the faked built-in model in a browser"], [15, "what-each-file-covers", "Chromium's clipboard permissions have no equivalent in Firefox and WebKit, so the three clipboard reads run in Chromium only; the rest of each test runs everywhere."], [15, "in-ci", ".github/workflows/ci.yml runs the syntax check, the manifest check and the reproducible build, then the tests in a matrix of the three engines against the pinned newsroom commit, on every push and pull request; about four minutes. The brief's target is two; caching the engines is the first thing to measure."], [15, "in-ci", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [15, "in-ci", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [15, "in-ci", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [15, "in-ci", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [16, "", "Home / How-to / Set up the subscribe lane"], [16, "", "A reader presses Send; their browser encrypts a small message to your public key and appends it to a lane you own. The site never sees it. You read the lane with your key, by hand or with an agent."], [16, "what-you-need", "A key pair. An RSA key whose public half is published; the private half stays with whoever (or whichever agent) reads the lane. The envelope is RSA-OAEP-SHA256 wrapping an AES-256-GCM key (the sgit hybrid envelope v2)."], [16, "what-you-need", "A vault with an append lane on an SG/Send host, with an append token that lets a browser write and nothing else. The newsroom's lane is on dev.send.sgraph.ai (named dev; finding R5 asks the operator to say whether that is production)."], [16, "what-you-need", "The contact file at /.well-known/sgit-subscribe.json."], [16, "the-contact-file", "The browser recomputes the fingerprint from the PEM before encrypting, so a swapped key is refused. The newsroom's own file is here; it is still labelled with the site the code came from (finding R4), which the move makes possible to fix."], [16, "what-arrives", "A subscription is an .eml with the address and a consent line; a share is the reader's summary and their data as JSON (balance, spent, reads, personas, topics, log; never a payment reference), with headers X-SGit-Form, X-SGit-Reply-To, X-SGit-Name, X-SGit-Subscribe, X-SGit-Page. A note from the vault pane arrives in the reader's own lane, whose read key they hand over, with the page, their words and the phrase they selected."], [16, "reading-the-lane", "With sgit and the read key, from the command line or an agent:"], [16, "reading-the-lane", "A read key cannot write: a push from the clone is refused, and the test proves it. The newsroom refuses to hold a vault key for a reader's lane at all."], [16, "the-pieces-on-this-host", "assets/subscribe.js (the form, the fingerprint check, the envelope, the append), the meter's share view in sg-meter.js, and the vault layer for notes. The article The site is an inbox is the design of the feedback loop; Two agents, one vault is how the newsroom's agents share what arrives."], [16, "the-pieces-on-this-host", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [16, "the-pieces-on-this-host", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [16, "the-pieces-on-this-host", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [16, "the-pieces-on-this-host", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [17, "", "Home / How-to / Take a release, roll one back"], [17, "", "One file names the release. Everything else is generated from it, and a gate refuses anything that is not."], [17, "1-pin", "Write the release in one place your build reads, and copy that release's manifest beside it. The newsroom's:"], [17, "2-generate-every-url-from-the-pin", "Nothing in a page names a reader file by a relative path or by a release typed by hand. The newsroom's builders call api_url(path); its sync points imported pages at the same URL; python3 admin/build/api.py --repoint rewrites every page in one pass when the pin changes, and --rerecord recomputes the content hashes its import gate keeps."], [17, "3-gate-it", "Before a release of your site, check three things on every page: no reader file is loaded by a relative path; every reader file is loaded from the pinned release; every path loaded is in the manifest. The newsroom's validate.js check 14 does this; check 13 holds the frozen meter copies it still serves to the manifest's bytes. The checks are small because the rule is simple."], [17, "4-verify-the-live-host", "After your deploy, ask this host for the hash of every file you load and compare with the manifest; tools/live_check.py in the repository does it for a release, with retries while Pages propagates. Green does not mean live."], [17, "5-roll-back", "Change the release in the pin to the previous one, copy its manifest, repoint, gate, deploy. A release directory is never edited in place, so the previous release is exactly what it was."], [17, "taking-a-new-release", "Read its notes first: a release says what changed, and lists any file that differs from the newsroom's bytes and why. Then steps 1 to 4. The frozen meter versions are in every release at their paths, so a page pinned to an older component version keeps working."], [17, "taking-a-new-release", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [17, "taking-a-new-release", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [17, "taking-a-new-release", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [17, "taking-a-new-release", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [18, "", "A reading meter that charges by how far you read. Paying after you read, with a rating that sets the price. Personas, a newsroom of your own, reading lists in a link, encrypted sharing, a vault that carries your account between devices. All of it runs in the reader's browser, with no server of ours, and all of it is open source. It is live on newsroom.sgit.ai, and it is taking money."], [18, "", "v0.2.5 · 74 files · 9,903 lines of reader code · 491 checks in three browser engines · Apache 2.0"], [18, "what-your-readers-get-what-you-keep-what-it-costs", "A meter instead of a paywall, a reader's own newsroom instead of a feed, and a model where their data stays in their browser. The case, with the articles that made it and the numbers from a live site."], [18, "add-the-meter-to-a-page-in-ten-lines", "Pinned, versioned files on one host; a JSON config; a custom element. The contracts your pages and agents program against, the data your site publishes, and the tests you can run against your own pages."], [18, "read-the-map-the-review-and-the-proof", "Everything a reader can do, every place data leaves the browser, eighteen findings as public issues, a release manifest of hashes, and a move proved byte for byte."], [18, "what-is-live-today", "newsroom.sgit.ai runs this release: 122 articles behind a reading meter, with real payments through a Stripe link, personas, reading lists, the vault and the pane, search, and the Industry Wire read from a vault. It is the reference deployment and the first consumer of this API; what runs and what is only designed is kept honest on its own page."], [18, "pay-by-depth-after-you-read", "A page is charged by the deepest point reached; a rating at the foot sets the price from nothing to double. £5 of credit to start, in the reader's own browser."], [18, "a-newsroom-of-your-own", "Read as a founder, a journalist, a security lead, a builder or a board member; keep and reject articles; picks follow. A link can open the newsroom as a persona."], [18, "from-me-to-you-in-a-link", "Every article has a number; a list is a link with the numbers in it. No account, no server, nothing stored but the link."], [18, "your-account-between-devices", "A passkey opens a door; the door holds the key to a master vault; the account travels encrypted, and the newsroom never holds a key."], [18, "how-it-works-in-one-picture", "The code is served from this host at a versioned path and never changed after it is published. The reader's state belongs to the page's origin, so it stays with the newsroom whichever host serves the script, and the newsroom never sees it. Nothing leaves the browser unless the reader pays, shares or subscribes, and each of those is a published contract. The hosting model, in full."], [18, "open-source-and-why-that-is-the-point", "The code is Apache 2.0, in one repository, with its tests, its release manifests, its review findings as issues, and the brief it was built to. A publisher can pin a release today and run it on their own pages; a developer can read every line; an evaluator can check every hash against the live host. Nothing here needs permission."], [18, "open-source-and-why-that-is-the-point", "The newsroom that runs it is the reference, not the product. The aim is other newsrooms adopting the same reader, so that a reading list or a persona made on one site means something on another, and so that the formats, the article number, the list link, the share, the envelope, outlive any one publisher. How to adopt it, and who to talk to."], [18, "reference", "The 14 contracts, the state, the inputs and outputs, the components, the hosting model."], [18, "how-to-guides", "Add the meter. Make a reading-list link. Open the newsroom as a persona. Set up the subscribe lane. Take a release, roll one back. Run the tests."], [18, "the-review", "The map of everything a reader runs, 18 findings as issues, the accepted gaps, and the map drawn as a layered graph."], [18, "the-articles", "Designed in public first: the case, the reader's own newsroom, and the engineering, each an article on newsroom.sgit.ai."], [18, "releases", "Every release, its notes and its manifest. The current one is v0.2.5."], [18, "for-agents", "The brief for the agents that keep this repository and the newsroom: the rules, where things are, how to change them."], [18, "for-agents", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [18, "for-agents", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [18, "for-agents", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [18, "for-agents", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [19, "", "What other sites, pages and agents program against. Fourteen, read from the map of everything a reader runs at newsroom v0.12.50; the two that other sites and agents already program against are the reading-list link and articles/ids.json. A contract changes only with a new release, and never in place."], [19, "", "storageKey, start, newDays, symbol, prices{article_new,article,issue,note,collection,page,free}, depth, minDepth, topup{amount,link}, packs, links{account,topup,how}, rating{price[5],more[5]}, autoKeep, picks{feed,base}, links2{newsroom,personas,share}, share{contact,form,site,max}, personas{presets[],names{}}, root"], [19, "", "sg-meter-core.js DEFAULTS; written into every page by sgit.ai's build and re-pointed by the import"], [19, "", "<sg-meter view=\"page\" kind=\"article|issue|note|collection|page|free\" date=\"…\" topics=\"a b\" title=\"…\" [quiet]>: the price class comes from the page"], [19, "", "sgit.ai's build for imported pages; page.py (kind=free, quiet) for this site's"], [19, "", "/persona/<id>/ and /persona/#<id>, id ∈ {founder, journalist, security, builder, board}"], [19, "", "personas.py, persona/links.json"], [19, "", "/for/#from=&to=&r=&s=&f=&n=&e=: names ≤ 40 chars of letters, spaces, hyphens, apostrophes; r,s article numbers, 1–50 in all; f persona ids or c:<collection>, ≤ 10; n ≤ 240 chars; e an address"], [19, "", "for/reading-list.js LIMITS, parse(), build()"], [19, "", "articles/ids.json: n and slug are the contract, assigned once in publication order, never changed or reused; every other field is display text"], [19, "", "admin/build/ids.py; validate.js check 12"], [19, "", "?session_id=<ref>: credited once per distinct value, never verified"], [19, "", "the state as JSON; restore accepts any file with balance:number and log:array"], [19, "", "a text summary then the same data as JSON {v:1, site, at, balance, spent, declined, reads, topups, active, personas, topics, cols, log}, as an .eml with X-SGit-Form, X-SGit-Reply-To, X-SGit-Name, X-SGit-Subscribe, X-SGit-Page"], [19, "", "sgit hybrid envelope v2: {v:2, w, i, c} (RSA-OAEP-SHA256 wrapped AES-256-GCM key, iv, ciphertext), base64, then base64 again as the lane payload"], [19, "", "envelope(), subscribe.js encrypt()"], [19, "", "sgit-subscribe/v1: recipient{address, fingerprint, encrypt}, inbox{vault, endpoint, encrypt_to, status, lane{name, append_token}}; the fingerprint is recomputed from the PEM before use"], [19, "", ".well-known/sgit-subscribe.json"], [19, "", "u9i9jp0l (the Industry Wire), eitf274v (OWASP), v202bla5 (AWS), p6twygul (Portugal) on dev.send.sgraph.ai, read keys published; data/bundle.json {beats, stories, sources, personas, brief; wire, map, stack when present}, data/deliveries.json, data/releases.json (wire-releases/v1, one entry per publish), docs/*.md; story fields, changes and status shown as written; everything in a vault is public, for ever"], [19, "", "admin/build/wire-vault*.json; wire/how.html; each wire's agents own its content"], [19, "", "sg:meter.changed · charged · rated · declined · toppedup · reset · restored · persona · shared; sg-meter:error"], [19, "", "sg-meter-core.js _emit(), sg-component.js failed()"], [19, "", "static jsUrl, get resourceName(), onReady(); a .tpl and a .css beside the .js; published at an immutable versioned path"], [19, "", "the meter path rewrite (v1.3.1 → v1.4.1), the top-up link, ten text rules, the article number line, the moved banner cut, the foot of every issue; each stops the import when its anchor moves"], [19, "", "Article numbers: articles/ids.json. n and slug are the contract: assigned once, in publication order, never changed or reused; every other field is display text. A reading list names articles by number."], [19, "", "Persona links: persona/links.json: one entry per starting persona, with its page."], [19, "", "The meter emits DOM events a page or another component can listen to: sg:meter.changed, charged, rated, declined, toppedup, reset, restored, persona, shared; and sg-meter:error when it fails."], [19, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [19, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [19, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [19, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [20, "", "Home / Docs / State, inputs and outputs"], [20, "", "Where a reader's data lives, what comes in, and every place anything leaves the browser. From the map, which the review checks line by line."], [20, "", "It belongs to the page's origin (newsroom.sgit.ai), whichever host serves the script. A reader can read it, export it, restore it and edit it; the security model says so."], [20, "", "≤ 500 entries: id, at, path, title, kind, topics, price, depth, cost, persona, autoKept?, rating{useful,more,detail,at}?, declined{reason,at,refunded}?"], [20, "", "ref (≤ 40 chars), at, credit, source: link | simulated"], [20, "", "every payment reference credited, unbounded"], [20, "", "the simulated cart (unused with a live link)"], [20, "", "id, preset, name, created, on[], off[], visitor?, list? (a reading list's key), theme?"], [20, "", "view · kind · date · topics · title · quiet · count · persona · compact"], [20, "", "the page's own markup (trusted: it is this site's build)"], [20, "", "<script type=\"application/json\" id=\"sg-meter-config\">"], [20, "", "this site's build, written once per page; every key has a default"], [20, "", "?session_id= on account/topped-up.html"], [20, "", "whoever made the link; any value is credited once (accepted, documented)"], [20, "", "#<persona id> on persona/; #from,to,r,s,f,n,e on for/ and for/make.html"], [20, "", "whoever made the link; validated field by field, the rest dropped and listed"], [20, "", "_named(), reading-list.js parse()"], [20, "", "the charge is keyed on it; the slug is taken from it; the share records it"], [20, "", "sgit.meter.v1 (the state), sgit.meter.v1.seen (session: the charge per path)"], [20, "", "this browser, written by the meter; also by the reader, who may edit it (accepted)"], [20, "", "whoever made the file; checked for balance:number and log:array only"], [20, "", "the share form, the subscribe form, the make page"], [20, "", "the reader; email checked by a loose pattern, names by a strict one"], [20, "", "data/bundle.json (with wire, map or stack when the vault has them), data/deliveries.json, data/releases.json, docs/*.md, decrypted in the browser; one vault per wire"], [20, "", "whoever holds the vault's write key (the wire's agents); drawn as text, links only from http(s) values, markdown rendered by an escaping renderer; the vault's own HTML is not used"], [20, "", "articles/graphs.json · articles/ids.json · .well-known/sgit-subscribe.json · sg-meter.tpl · sg-meter.css"], [20, "", "this site's build; the contact file's key is checked against its fingerprint"], [20, "", "replies from the dev.vault.sgraph.ai frames"], [20, "", "origin-checked; drives a status line only"], [20, "", "every page, script, style, image and JSON"], [20, "", "GitHub Pages, which sees the request as any host does"], [20, "", "POST https://dev.send.sgraph.ai/api/vault/append/write/y9j3nc60"], [20, "", "{append_token, payload}: an .eml encrypted in the browser to the lane's public key"], [20, "", "when the reader presses Send on the share page or Subscribe"], [20, "", "the vault host; it sees ciphertext, a size and a time"], [20, "", "Navigation to https://buy.stripe.com/…"], [20, "", "the reader leaves for Stripe's page and returns to /account/topped-up.html?session_id=…"], [20, "", "when the reader presses Top up / Pay"], [20, "", "Stripe (card, email, name, postcode)"], [20, "", "GET https://dev.send.sgraph.ai/api/vault/read/u9i9jp0l/…"], [20, "", "the ciphertext of the wire's vault: its head pointer, commit, tree and the files the page needs, decrypted in the browser with the published read key"], [20, "", "when a wire page opens, and when the reader asks for a new commit; the pointer at most every two minutes"], [20, "", "the vault server; it sees the request and nothing of the reader"], [20, "", "iframe https://dev.vault.sgraph.ai/?embed=1"], [20, "", "two frames; the published read key is posted to them"], [20, "", "Reply to <sender> on a reading list; the subscribe fallback"], [20, "", "when pressed; the page sends nothing"], [20, "", "reading-account.json: the whole state, payment references included"], [20, "", "postMessage to the parent window"], [20, "", "{type:'sg-app-ready'} with targetOrigin *"], [20, "", "The accepted gaps and why: the meter's security model."], [20, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [20, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [20, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [20, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [21, "", "Phase 0 and phase 3 of the move"], [21, "", "Before anything moved, everything a reader does on newsroom.sgit.ai was mapped: every file, every control a reader can click, type or pay, every input, every place data leaves the browser, every contract. Then it was reviewed line by line. The map is regenerated from the tree; this is the one from newsroom v0.12.50, the before of the move, and the review's eighteen findings are this repository's first eighteen issues."], [21, "", "The map as a page: newsroom.sgit.ai/newsroom-api/; as data: map.json."], [21, "", "Source code is layers within layers, each a graph with its own vocabulary, and a review should read a change at every one: that is the method in Code review as a fractal semantic graph. Here the layers are: the site a reader opens; the pages written for the reader code; the views, controls, inputs and outputs on them; the files that run them and the contracts between them; and inside each file the functions the findings name. The map as a graph draws those layers and the edges between them, and every finding is anchored to a node."], [21, "", "Severity first, then by number. Each links to its issue; pinned by names the test that records the behaviour as it is today, so that the fix later is a visible change to a test and not a silent one (the brief's rule 3)."], [21, "", "Every imported page loads assets/site.js, subscribe.js and shots.js by fetching the text and running it with (0, eval)(text) (the loader's bridge path), and the loader and the meter config are inline. A script-src policy without 'unsafe-eval' and without hashes breaks every page. frame-ancestors cannot be set in a meta tag at all, and GitHub Pages sets no headers, so framing (the Keep, Remove and Top up buttons under another site) is not prevented today."], [21, "", "test_review.mjs R10 (counts the pages that eval)"], [21, "", "load scripts with <script src> or import(); then a meta CSP for script-src and connect-src; frame-ancestors needs a host that sets headers"], [21, "", "The one workflow ran validate.js only; the browser tests (46 + 65 checks) never ran in CI."], [21, "", "fixed in this release: a reader-tests job runs all three test files before the tag"], [21, "", "done; the move's pipeline adds WebKit and Firefox and a pre-production copy"], [21, "", "Declining a page as “not relevant” leaves it in the persona's reading list. open() auto-keeps an article on first open; decline() refunds the charge but does not undo the auto-keep, so the article stays under “Its reading list” and profile() adds +5 for it while the decline subtracts 2: a page the reader rejected pulls its topics up."], [21, "", "test_review.mjs R1 (passes while the article stays in the list)"], [21, "", "decline() removes an autoKept entry from the active persona's on[]; a reader who added it by hand keeps it"], [21, "", "A reading share or a subscription sent from this site is labelled sgit.ai: the imported config has share.site = \"sgit.ai\" (so the text begins “My reading on sgit.ai”), subscribe.js writes From: site@sgit.ai, and the contact file says site: sgit.ai. The agent that drains the lane can tell the two sites apart only by the Sent from line."], [21, "", "a recorded meter rule for share.site (admin/build/newsroom-meter.json); subscribe.js and the contact file are verbatim imports and need this site's own copies, or a parameter, after the move"], [21, "", "If sgit.ai renames an article (a new slug), ids.py marks the old number withdrawn and gives the article a new number. A reading list that named the old number then says the article is no longer published, although it is."], [21, "", "described; a rename has not happened yet"], [21, "", "a renamed_to field on the old entry, followed by the list page; the gate requires it when a slug disappears and a new one appears in the same import"], [21, "", "restore() checks that the file has a numeric balance and a log array and nothing else. A persona without on[] and off[] makes the personas and newsroom views throw and show nothing; a log entry's path is rendered as the history link's href as it is; a persona's theme is written into a style attribute as it is. The file is the reader's own, so the exposure is a file someone else sent them to restore."], [21, "", "test_review.mjs R2 (the blank personas page); the href and theme cases are described, not pinned"], [21, "", "normalise on read: personas get arrays, paths must be same-origin paths, themes must be a hex colour; unknown fields dropped"], [21, "", "A malformed percent sequence in ?session_id= (for example %E0%A4%A) makes decodeURIComponent throw inside onReady, so the element fails with “did not load: URI malformed” instead of saying the reference is missing."], [21, "", "try/catch around the decode; treat an undecodable id as no id"], [21, "", "Money is kept to a tenth of a penny and shown to a penny. Balance and spent are each formatted on their own, so a half-penny state shows, from £5.00, a balance of £4.95 and £0.06 spent, which do not add up; the history shows 5.5p. A reader who checks the arithmetic finds a penny missing."], [21, "", "one rounding rule for the pair (format spent as start − balance, or keep both to 0.1p on the account page)"], [21, "", "feed() caches a failed fetch as null for the life of the page, so one transient failure leaves “The list of articles could not be loaded” on every view until a reload."], [21, "", "do not cache a failure; retry on the next call"], [21, "", "sessions[] and topups[] grow without bound, and a payment reference is not checked for shape before it is stored."], [21, "", "cap both; keep references that look like cs_… only"], [21, "", "persona(id) falls back to personas[0], which is “me” only when “me” is first; after a restore that puts another persona first, an unknown id resolves to that persona."], [21, "", "fall back to the persona with id me"], [21, "", "On the live site the lane for shares and subscriptions is on dev.send.sgraph.ai and the study page's vault frames come from dev.vault.sgraph.ai. Both hosts are named “dev”. Production reader data goes to them."], [21, "", "test_review.mjs R5 (records the hosts)"], [21, "", "a decision, not a code change: either these are the production hosts and say so, or the files point at production ones"], [21, "", "picks() excludes every page in the log, whichever persona read it, while profile() is per persona. An article read as Morgan is never picked for Rowan."], [21, "", "test_review.mjs R7 (records the behaviour)"], [21, "", "decide: per-persona exclusion, or keep and say so on the newsroom page"], [21, "", "The account pages, subscribe, the contact file and the component base are imported from sgit.ai on every sync and cannot be changed here except by a recorded rule, and verbatim files (scripts, JSON) cannot be changed by rule at all. R4 is the first consequence. The newsroom's meter is v1.4.0 while sgit.ai's is v1.3.1."], [21, "", "the move: both sites pin released files"], [21, "", "The export includes the payment references (sessions, topups[].ref) that the share deliberately leaves out. A reader who sends their export instead of their share sends them."], [21, "", "say so beside the button, or export without sessions"], [21, "", "Imported pages load the meter as sg-meter.js?v=<sgit.ai's release>, so the cache-buster never changes for a release of this site. That is fine while a published version is never edited in place, which is the rule; it is written here because v1.4.0 was edited in place while it was being built."], [21, "", "a change is a new version path, always"], [21, "", "A list's persona is keyed by a 32-bit hash of the names and numbers, so two different lists can share one persona with probability about one in four billion per pair."], [21, "", "a longer hash, or the fragment itself as the key"], [21, "", "The landing view adds a window hashchange listener per element and never removes it, and re-renders on every meter change (the picker's “Copied” label resets)."], [21, "", "one listener, removed on disconnect"], [21, "", "Gaps the design accepts, each written where a reader can find it."], [21, "", "The return page credits any session id"], [21, "", "a static page cannot verify a payment; building the address by hand credits the reader's own screen"], [21, "", "The reader can edit their own balance"], [21, "", "the state is in their storage; nothing is behind a wall"], [21, "", "meter/security.html, No server by design"], [21, "", "The names in a reading list are whatever the link says"], [21, "", "there is no signature yet; a signed list is a later step on RFC 0001's keys"], [21, "", "A page is charged by the deepest point reached, and the reader card is at the foot"], [21, "", "reaching the card to rate a page is reading to the end"], [21, "", "going-live-with-the-reading-meter.html"], [21, "", "The proof of the move: the same bytes, before and after."], [21, "", "State, inputs and outputs, from the same map."], [21, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [21, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [21, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [21, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [22, "", "Home / Review / The map as a graph"], [22, "", "The same map, drawn as the layers a review reads: the site, the pages a reader opens, the views on them, the files that run them, the contracts between them, and the findings anchored to the files they are about. Hover or tap a node for what it is; the data is graph.json."], [22, "", "The graph is drawn by a script; the data is graph.json and the tables are on the review page."], [22, "", "A layer is a vocabulary of its own: a page has an address and a purpose; a view has controls; a file has lines and the hosts it reaches; a contract has a shape and an owner; a finding has a severity and a test. Reading a change at every layer is the review method this repository follows."], [22, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [22, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [22, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [22, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [23, "", "Home / Review / The proof of the move"], [23, "", "The brief's rule for the move is that the live site serves the same bytes before and after, proved by hash and not by reading a diff: scripts, styles and JSON raw; pages with the chrome and the version stamps normalised, plus the one rule the move added (a reader-file reference, relative or on this host, reads the same). This is that proof, per release, written by tools/prove_move.py."], [23, "", "The files a host of their own forced to change, each by the lines that located the site root from the script's own address:"], [23, "", "assets/vault-pane/vault-pane.js"], [23, "", "The release's own pages, with the first differing line of each:"], [23, "", "-<h2 id=\"open\">Open <span class=\"dim\">(10: asked and not yet done, newest first)</span></h2><div class=\"tablewrap\"><table><thead><tr><th>Id</th><th>Kind</th><th"], [23, "", "-<p class=\"what\">The same derivation from a fixed, fake PRF output, compared value by value with what sgit&rsquo;s own Python produced (<a href='API/passkey/vec"], [23, "", "- <p>Search on newsroom.sgit.ai runs in the reader's browser. The index is https://newsroom.sgit.ai/search/docs.json (one entry per page: u address, t title, k"], [23, "", "New pages: engineering/issues/036.html, engineering/releases/v0.13.0.html."], [23, "", "The report: map/proof/v0.1.0.json; the before: every file's raw hash at newsroom v0.12.50."], [23, "", "The files a host of their own forced to change, each by the lines that located the site root from the script's own address:"], [23, "", "assets/vault-pane/vault-pane.js"], [23, "", "The release's own pages, with the first differing line of each:"], [23, "", "-<h2 id=\"open\">Open <span class=\"dim\">(12: asked and not yet done, newest first)</span></h2><div class=\"tablewrap\"><table><thead><tr><th>Id</th><th>Kind</th><th"], [23, "", "- <p>Search on newsroom.sgit.ai runs in the reader's browser. The index is https://newsroom.sgit.ai/search/docs.json (one entry per page: u address, t title, k"], [23, "", "New pages: engineering/issues/058.html, engineering/releases/v0.13.0.html."], [23, "", "The report: map/proof/v0.2.0.json; the before: every file's raw hash at newsroom v0.12.50."], [23, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [23, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [23, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [23, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [24, "", "Every change that lands on dev is a version, in small increments, and the deploy tags it. This site is v0.2.14; the reader code it serves is release v0.2.5, what the consuming sites pin. A version with a release of its own is a cut of the reader code; the others change the site, the tests or the tools and leave the served files as they were. The releases have their manifests; releases.json and this page's versions.json are the machine-readable forms."], [24, "", "test_review's R2 injects the broken persona on the personas page and reloads, so the article page's next save cannot overwrite it before the check (CI runs 21 and 22 saw the page render)."], [24, "", "Every page's JSON-LD names its author, its publisher, its card and what it is about, as the newsroom's articles do; the README says what the site has."], [24, "", "The bar has the newsroom's shape: eight groups with their pages under them, a dropdown on hover and on focus with no script, the group and the page marked; one list behind Menu on a phone."], [24, "", "Search: the site searches itself with the API's own search and ask components, loaded from this host's release, over an index the build writes (search/docs.json, text.json) in the contract's format; a Search button in the bar; headings in HTML pages get ids."], [24, "", "feed.xml: versions and releases as RSS, linked from every page's head and from llms.txt; the gate checks it is well formed and current."], [24, "", "The footer takes the newsroom's shape: who makes this and under whose responsibility, the network line, the participant disclosure, the version line with the reader-code release; the gate checks each."], [24, "", "A link-preview card for every page (og:image 1200x630 and the Twitter card), drawn by site/og.py in Newsprint's colours and committed; the gate fails a page without one."], [24, "", "The backfill's grep named two matchers at once and would have matched nothing; one matcher."], [24, "", "The deploy tags every version in the history that has none (each commit's subject carries its version), so several versions landing in one push each get their tag."], [24, "", "Reader-code release: wire/wire.css wraps a story's long words (a URL as plain text in the lead story's corrections overflowed a phone; test_wire caught it). The first change to a served file since the move, recorded in the manifest with its reason."], [24, "", "The website's gate (site/check.py): every reference resolves, canonical and chrome on every page, the sitemap and llms files agree with the tree, a key-leak tripwire. The map and the proof data are published on the host. This versions page."], [24, "", "test_review pins R2 as the personas page being unusable in either form (blank, or the element failed), as CI run 13 saw."], [24, "", "The website wears the newsroom's five themes: its token file and bootstrap, unchanged; the picker in the bar; one row from 1280 up; print and reduced motion; tests/test_site.mjs as the gate."], [24, "", "Every change that lands on dev is a version: tools/version.json holds the repository's version beside the reader-code release; the deploy tags the version and refuses a missed bump."], [24, "", "The second cut of the reader code, from the newsroom at v0.12.50 (74 files; SG Meter v1.4.1, the inbox, the graphs, the QR library); the release the newsroom pins at its v0.13.0. The tests re-adapted, test_graphs and test_inbox added."], [24, "", "The first cut of the reader code, from the newsroom at v0.12.10 (63 files), the pipeline, the proof of the move, and the website for publishers, developers, evaluators and agents."], [24, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [24, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [24, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [24, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [25, "", "A release is a directory on this host that is never changed after it is published: https://api.newsroom.sgit.ai/<release>/<path>, with a manifest of every path and its SHA-256. A consuming site pins one release and copies its manifest; a rollback is the previous release in the pin. releases.json lists them for machines."], [25, "v0.2.5", "74 files, 1,154,711 bytes. manifest.json."], [25, "v0.2.5", "The first change to a served file since the move, and the rule followed. On 15 October the wire's lead story carried a URL as plain text in its corrections list and its verifier's note; one word of 643px on a 390px screen, and test_wire's check that the wire page has no sideways scroll at phone width failed in Chromium and WebKit (Firefox breaks the word). The file that changes is wire/wire.css, by one declaration: a story wraps anywhere (overflow-wrap: anywhere on .story), so no story is wider than the phone whatever the vault writes. Recorded in the manifest as a change from the newsroom's bytes with its reason, beside the three the host forced. Everything else is v0.2.0's bytes. The newsroom pins v0.2.0 until it takes this release."], [25, "v0.2.5", "took the site root from its own URL; now from the page's data-root for links"], [25, "v0.2.5", "took the site root from its own URL; now from the page's data-root for data and links, and imports the pane's modules from its own root (CODE)"], [25, "v0.2.5", "assets/vault-pane/vault-pane.js"], [25, "v0.2.5", "took the site root from its own URL (import.meta.url); now from the page's data-root, and loads the vault library from its own root (CODE)"], [25, "v0.2.5", "a story's text may carry a URL as one word (the vault's corrections and verifier's notes do); .story wraps anywhere, so no story is wider than a phone"], [25, "v0.2.5", "assets/components/base/v1/v1.0/v1.0.0/sg-component.js"], [25, "v0.2.5", "e566a78ad98fbd184058eed2a6b435c2c386066a0743de5efdbd0ef99348e677"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter-core.js"], [25, "v0.2.5", "e7440dc3820a0180f80aa4f1722b7f3ede1dc760f31227ca32ea40283400a987"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.css"], [25, "v0.2.5", "b0aef1442f4f4edbb836173070777d5b8e84528fa0980a8b73f30423a9aa1d0c"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.js"], [25, "v0.2.5", "9ea95731fc2c15d53abffc00402682b5924bf0d017cac252a1626892c30b6787"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.tpl"], [25, "v0.2.5", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter-core.js"], [25, "v0.2.5", "867db221b46ad540cea28b596e07272e2d4667195dac19daa8fd3bafa22946b6"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.css"], [25, "v0.2.5", "051165ca8ec4c737737caee1c612f8f49f13b7af3e804b8f0bee3b1b8131d865"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.js"], [25, "v0.2.5", "eb880df24888a900ef5de10c71e425e98525e604a6f91c01285ae44499252891"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.tpl"], [25, "v0.2.5", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter-core.js"], [25, "v0.2.5", "541d9873f8bf52699e03fa66922ea42cc98b20c258f3bd790e172cf89a2575b8"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.css"], [25, "v0.2.5", "9cca4711996312e1fd8426d42897b75437277c5210bd956f2a8306ad508c2437"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.js"], [25, "v0.2.5", "38303a50cbdeb142217fb369e41cd6ebb1e0e9f49fa7aab2c10b34267bebb106"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.tpl"], [25, "v0.2.5", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter-core.js"], [25, "v0.2.5", "34b32beef6b6f781a8bc07b14f1d677c148c1d632be0a2de60eff2ee2382f568"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.css"], [25, "v0.2.5", "b56618dbfeee38047efba9d66289ebea40b496e9771abf50a215ceb4f2368297"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.js"], [25, "v0.2.5", "f26b2fec6f409f34bf91a341cda9acd424478f7dd0a790a4070c3d753b2eb350"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.tpl"], [25, "v0.2.5", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter-core.js"], [25, "v0.2.5", "61c636b881ca7664afe9dda5fd13295f17691928e22664d8480efe55ad4f3d73"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.css"], [25, "v0.2.5", "192b7813a223f2e457381e9e97feea8921fb961a18c17eeede7284337f684859"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.js"], [25, "v0.2.5", "1f3b6f1bbc36cd66e1b2d3a49087a5b37e993a89933adfda648f1c997257bd38"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.tpl"], [25, "v0.2.5", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter-core.js"], [25, "v0.2.5", "6a74b1183c766d5aee8a6fdbfd9bfc7885a7c873945cde6ee2061f300d2c2eaf"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.css"], [25, "v0.2.5", "98a86404668135893759d018db3f457a6de25698a50c988b00a65fbc88071fa5"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.js"], [25, "v0.2.5", "82f8c09842290336b208df78936059c69ce3db456e610c785e00cd78065cf55c"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.tpl"], [25, "v0.2.5", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.4/v1.4.1/sg-meter-core.js"], [25, "v0.2.5", "9986294b0fbc5a62b56f515eff22867ef59e75e0c63dc048dfda3fdd6dd0e5ba"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.4/v1.4.1/sg-meter.css"], [25, "v0.2.5", "3f464b7d1df4e15ff45809fb155388df357809d79d87609ff0d44514b4438786"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.4/v1.4.1/sg-meter.js"], [25, "v0.2.5", "ba46eeca15d5d9b24feb71381c14a0b92bb5d8326492c310824cf8723c431abb"], [25, "v0.2.5", "assets/components/sg-meter/v1/v1.4/v1.4.1/sg-meter.tpl"], [25, "v0.2.5", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.5", "740779876d19acebd24e493da9616d132a968f8885c013880f383c15d6ef4dff"], [25, "v0.2.5", "29003efa52c408b9d26e58ce86ecc897fda2439f739e803df7b9399a4520705e"], [25, "v0.2.5", "9f8cd3cb95d659e87d4e249947a1fe92f4309cc2192c3b0f428b35440de34549"], [25, "v0.2.5", "68d68bb1b7a3df4c41d1f37f22e86d30531b0e5c17637760a2a54c0aff0018e9"], [25, "v0.2.5", "c750cab906e8d1592e3bd3fece94ff33945c833a7a78d3a7d9c7313d7dbe636f"], [25, "v0.2.5", "1fcdffcfa53fc8d3f75a92009fce6cb12553d97f110087ca0784653190a12355"], [25, "v0.2.5", "3968954e3cc5f286be7c72d9e7bcb3c143069ef1465b4787ba7db388cde8ca19"], [25, "v0.2.5", "fe2eec58c28f15e53fc57520bccb75e38276607821d8572b0fdfd1e0417c1c58"], [25, "v0.2.5", "0d31b92a8827d26a0ddd7e8f076315d6db4b48dfe719f28dafec100eb6bed59b"], [25, "v0.2.5", "21f583f801906d8b3b9bad289a31919e88be02344f4156afd5f04831c83e9198"], [25, "v0.2.5", "4d4c30ec10e0ebe138ad337527a2605c908bba1f2767b3f8c1ef0fe39066469a"], [25, "v0.2.5", "e8f2b778f2b2eec00aecdc1c532c488e0ebd0c36e08caf353b557b0e00845b79"], [25, "v0.2.5", "60608bb4a17808ad9f6e39206c93602d837c2d2f69179b516d62e8bd983d78fc"], [25, "v0.2.5", "ca0512a3474140277f57e70a696d597c0c3ed11c5f61d5228ca2ef4be302aecb"], [25, "v0.2.5", "0a56700e5b9db9f567fb843366fbaad9ff950202abbe1804d4dcf04b8824a193"], [25, "v0.2.5", "assets/vault-pane/vault-pane.css"], [25, "v0.2.5", "f25e2596761414c4495e3b2fc380d3cb055f86f33a8d6cdd17c3d34d8928f5b9"], [25, "v0.2.5", "assets/vault-pane/vault-pane.js"], [25, "v0.2.5", "a73c16bab3347a9709b8f045c2e7dc12208121305f727b56548fe3af475677ac"], [25, "v0.2.5", "assets/vault-pane/wire-state.js"], [25, "v0.2.5", "36e1d5bbbd300c622fadf48748d4485e1b7818f666733c90c9d5f9153dcaea35"], [25, "v0.2.5", "assets/vendor/qrcode-generator/2.0.4/README.md"], [25, "v0.2.5", "cb41228b45c5afdcd7c323bf74ca959f22836cf697371f87070f53e009d8ae59"], [25, "v0.2.5", "assets/vendor/qrcode-generator/2.0.4/qrcode.mjs"], [25, "v0.2.5", "ea91d7118a5395289170da848b7c6758b996163bfbccf312591ab65a4911b7c0"], [25, "v0.2.5", "assets/vendor/sg-vault/local/sg-vault--create-with-id.js"], [25, "v0.2.5", "b668c4ab0062a3b385882fa593f7213f50f667c777d0614b5ba8abcb5721372e"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/VENDOR.md"], [25, "v0.2.5", "72b1b247062e1cd0b9502fb689c5e5d90bc79c27d9696af2047f1a2fccf7e9af"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-send/sg-send-crypto.js"], [25, "v0.2.5", "2c4af16bbaf4f43e7eb0f8298a9cd8338429f99c7bec20c5d7f4da96c88e39ce"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-send/sg-send.js"], [25, "v0.2.5", "9bc98e580f5fc1adbf8e2d273181e6afa3bd9a3813ea8a1bf24ddd07e1b8b41e"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--branches.js"], [25, "v0.2.5", "bc1eec8bbc2326a73ec1809ed588d26f3fe7511bf24b52e47440c3d90526f3d1"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--file-ops.js"], [25, "v0.2.5", "f114db89754638b5e4ade1dc3f5d4753ac672a4323c286e8c8ed0412760e6861"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--folder-ops.js"], [25, "v0.2.5", "10fea1377422c5368aead040500c28135fafcb918427901a74483e23e1b36d7f"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--history.js"], [25, "v0.2.5", "265b215e27216ad25e8fa7c83b47c8307b7990a0a3fb88254ee2149d2835dd2d"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--sync.js"], [25, "v0.2.5", "b9f521e7b70ca66f6d1197378337f954deea4ed3468535ec3064149c7cf1fcc6"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-commit.js"], [25, "v0.2.5", "e686de3756eaeed185708a6ba96194429afb3067f145108e7580d876598dd9ce"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-crypto.js"], [25, "v0.2.5", "f8d31359204a9e333d27444ea2a37c1bb11bbc790d0cf4cfa95fe9f9282d6e66"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-object-store.js"], [25, "v0.2.5", "a45d7ad0f9dbd91677785c3128a8322d4209cb35ab5d815551dcbf1eceed9c9e"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-ref-manager.js"], [25, "v0.2.5", "5b8ea87ace83d59e8954511d9932bd3968020c57070375194c7427a083fb729f"], [25, "v0.2.5", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault.js"], [25, "v0.2.5", "0108884f9b8d539e4c9457190326d64adc5a92c808803f0dab14b9e772b3ad26"], [25, "v0.2.5", "6ad9b2f9c39e99748a089d55670a1233983ff08cc5d02e53a9034adb9735a17d"], [25, "v0.2.5", "ec9abc1f40b5f5640103f4e7ab4280a8622d9d5aa683bc82079609ccea413783"], [25, "v0.2.5", "5f8fa1378b99c24cdba945cd0bb965a56f03a04ce069a3ab56b3ec340881b1ee"], [25, "v0.2.5", "ca352ad9cdc8631d01005bfd94b88b92a646c030a3324d249f77285e48a0b491"], [25, "v0.2.5", "08c47eae0b95943e10e919fc770ddd2c0c30b2fd7652a5199fb8b7961f92560a"], [25, "v0.2.5", "d50a3642c131bbaa8b9858438138fc1dc78ae3249e9bab89c1b7541f95a447b8"], [25, "v0.2.5", "22f48fcb1185389f8c477b382f422b42e7916bc2f1920598049f490cca3490e1"], [25, "v0.2.5", "e08913d389ede55fb0787cba7752920c28b43735ff767795e11ac43224c5a12b"], [25, "v0.2.5", "332509b6be44538d7aab0305669673fa6907591ff621dee1b2605849c89afbfb"], [25, "v0.2.5", "8623b237054957816163d7ebcdb2f8e0269c0fee5961d37268db12cd4d422568"], [25, "v0.2.5", "372f85ab8ffd75beb8eaec31aa64884dcaff8286b961a353cc7cf0bfdd3dc1c7"], [25, "v0.2.0", "74 files, 1,154,686 bytes. manifest.json."], [25, "v0.2.0", "The second cut, from the newsroom as it is. Between the first cut (from the newsroom's v0.12.10) and the newsroom taking the release, forty newsroom releases shipped: the meter moved to v1.4.1, the pane gained the reader's inbox (inbox.js, send.js, send.css, with a vendored QR-code generator), the wire gained its graphs (graphs.js), a subscribe form (subscribe.js) and three more wires, and several files changed. This release is cut from the newsroom's v0.12.50: 74 files, the same bytes as there apart from the same three files the host forces to change (vault-pane.js, search.js, ask.js, by the lines that locate the site root), each recorded in the manifest. v1.4.0 joins the frozen meter versions. The newsroom pins this release at its v0.13.0; v0.1.0 stays published, as every release does."], [25, "v0.2.0", "took the site root from its own URL; now from the page's data-root for links"], [25, "v0.2.0", "took the site root from its own URL; now from the page's data-root for data and links, and imports the pane's modules from its own root (CODE)"], [25, "v0.2.0", "assets/vault-pane/vault-pane.js"], [25, "v0.2.0", "took the site root from its own URL (import.meta.url); now from the page's data-root, and loads the vault library from its own root (CODE)"], [25, "v0.2.0", "assets/components/base/v1/v1.0/v1.0.0/sg-component.js"], [25, "v0.2.0", "e566a78ad98fbd184058eed2a6b435c2c386066a0743de5efdbd0ef99348e677"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter-core.js"], [25, "v0.2.0", "e7440dc3820a0180f80aa4f1722b7f3ede1dc760f31227ca32ea40283400a987"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.css"], [25, "v0.2.0", "b0aef1442f4f4edbb836173070777d5b8e84528fa0980a8b73f30423a9aa1d0c"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.js"], [25, "v0.2.0", "9ea95731fc2c15d53abffc00402682b5924bf0d017cac252a1626892c30b6787"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.tpl"], [25, "v0.2.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter-core.js"], [25, "v0.2.0", "867db221b46ad540cea28b596e07272e2d4667195dac19daa8fd3bafa22946b6"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.css"], [25, "v0.2.0", "051165ca8ec4c737737caee1c612f8f49f13b7af3e804b8f0bee3b1b8131d865"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.js"], [25, "v0.2.0", "eb880df24888a900ef5de10c71e425e98525e604a6f91c01285ae44499252891"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.tpl"], [25, "v0.2.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter-core.js"], [25, "v0.2.0", "541d9873f8bf52699e03fa66922ea42cc98b20c258f3bd790e172cf89a2575b8"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.css"], [25, "v0.2.0", "9cca4711996312e1fd8426d42897b75437277c5210bd956f2a8306ad508c2437"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.js"], [25, "v0.2.0", "38303a50cbdeb142217fb369e41cd6ebb1e0e9f49fa7aab2c10b34267bebb106"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.tpl"], [25, "v0.2.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter-core.js"], [25, "v0.2.0", "34b32beef6b6f781a8bc07b14f1d677c148c1d632be0a2de60eff2ee2382f568"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.css"], [25, "v0.2.0", "b56618dbfeee38047efba9d66289ebea40b496e9771abf50a215ceb4f2368297"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.js"], [25, "v0.2.0", "f26b2fec6f409f34bf91a341cda9acd424478f7dd0a790a4070c3d753b2eb350"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.tpl"], [25, "v0.2.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter-core.js"], [25, "v0.2.0", "61c636b881ca7664afe9dda5fd13295f17691928e22664d8480efe55ad4f3d73"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.css"], [25, "v0.2.0", "192b7813a223f2e457381e9e97feea8921fb961a18c17eeede7284337f684859"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.js"], [25, "v0.2.0", "1f3b6f1bbc36cd66e1b2d3a49087a5b37e993a89933adfda648f1c997257bd38"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.tpl"], [25, "v0.2.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter-core.js"], [25, "v0.2.0", "6a74b1183c766d5aee8a6fdbfd9bfc7885a7c873945cde6ee2061f300d2c2eaf"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.css"], [25, "v0.2.0", "98a86404668135893759d018db3f457a6de25698a50c988b00a65fbc88071fa5"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.js"], [25, "v0.2.0", "82f8c09842290336b208df78936059c69ce3db456e610c785e00cd78065cf55c"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.tpl"], [25, "v0.2.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.4/v1.4.1/sg-meter-core.js"], [25, "v0.2.0", "9986294b0fbc5a62b56f515eff22867ef59e75e0c63dc048dfda3fdd6dd0e5ba"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.4/v1.4.1/sg-meter.css"], [25, "v0.2.0", "3f464b7d1df4e15ff45809fb155388df357809d79d87609ff0d44514b4438786"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.4/v1.4.1/sg-meter.js"], [25, "v0.2.0", "ba46eeca15d5d9b24feb71381c14a0b92bb5d8326492c310824cf8723c431abb"], [25, "v0.2.0", "assets/components/sg-meter/v1/v1.4/v1.4.1/sg-meter.tpl"], [25, "v0.2.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.2.0", "740779876d19acebd24e493da9616d132a968f8885c013880f383c15d6ef4dff"], [25, "v0.2.0", "29003efa52c408b9d26e58ce86ecc897fda2439f739e803df7b9399a4520705e"], [25, "v0.2.0", "9f8cd3cb95d659e87d4e249947a1fe92f4309cc2192c3b0f428b35440de34549"], [25, "v0.2.0", "68d68bb1b7a3df4c41d1f37f22e86d30531b0e5c17637760a2a54c0aff0018e9"], [25, "v0.2.0", "c750cab906e8d1592e3bd3fece94ff33945c833a7a78d3a7d9c7313d7dbe636f"], [25, "v0.2.0", "1fcdffcfa53fc8d3f75a92009fce6cb12553d97f110087ca0784653190a12355"], [25, "v0.2.0", "3968954e3cc5f286be7c72d9e7bcb3c143069ef1465b4787ba7db388cde8ca19"], [25, "v0.2.0", "fe2eec58c28f15e53fc57520bccb75e38276607821d8572b0fdfd1e0417c1c58"], [25, "v0.2.0", "0d31b92a8827d26a0ddd7e8f076315d6db4b48dfe719f28dafec100eb6bed59b"], [25, "v0.2.0", "21f583f801906d8b3b9bad289a31919e88be02344f4156afd5f04831c83e9198"], [25, "v0.2.0", "4d4c30ec10e0ebe138ad337527a2605c908bba1f2767b3f8c1ef0fe39066469a"], [25, "v0.2.0", "e8f2b778f2b2eec00aecdc1c532c488e0ebd0c36e08caf353b557b0e00845b79"], [25, "v0.2.0", "60608bb4a17808ad9f6e39206c93602d837c2d2f69179b516d62e8bd983d78fc"], [25, "v0.2.0", "ca0512a3474140277f57e70a696d597c0c3ed11c5f61d5228ca2ef4be302aecb"], [25, "v0.2.0", "0a56700e5b9db9f567fb843366fbaad9ff950202abbe1804d4dcf04b8824a193"], [25, "v0.2.0", "assets/vault-pane/vault-pane.css"], [25, "v0.2.0", "f25e2596761414c4495e3b2fc380d3cb055f86f33a8d6cdd17c3d34d8928f5b9"], [25, "v0.2.0", "assets/vault-pane/vault-pane.js"], [25, "v0.2.0", "a73c16bab3347a9709b8f045c2e7dc12208121305f727b56548fe3af475677ac"], [25, "v0.2.0", "assets/vault-pane/wire-state.js"], [25, "v0.2.0", "36e1d5bbbd300c622fadf48748d4485e1b7818f666733c90c9d5f9153dcaea35"], [25, "v0.2.0", "assets/vendor/qrcode-generator/2.0.4/README.md"], [25, "v0.2.0", "cb41228b45c5afdcd7c323bf74ca959f22836cf697371f87070f53e009d8ae59"], [25, "v0.2.0", "assets/vendor/qrcode-generator/2.0.4/qrcode.mjs"], [25, "v0.2.0", "ea91d7118a5395289170da848b7c6758b996163bfbccf312591ab65a4911b7c0"], [25, "v0.2.0", "assets/vendor/sg-vault/local/sg-vault--create-with-id.js"], [25, "v0.2.0", "b668c4ab0062a3b385882fa593f7213f50f667c777d0614b5ba8abcb5721372e"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/VENDOR.md"], [25, "v0.2.0", "72b1b247062e1cd0b9502fb689c5e5d90bc79c27d9696af2047f1a2fccf7e9af"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-send/sg-send-crypto.js"], [25, "v0.2.0", "2c4af16bbaf4f43e7eb0f8298a9cd8338429f99c7bec20c5d7f4da96c88e39ce"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-send/sg-send.js"], [25, "v0.2.0", "9bc98e580f5fc1adbf8e2d273181e6afa3bd9a3813ea8a1bf24ddd07e1b8b41e"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--branches.js"], [25, "v0.2.0", "bc1eec8bbc2326a73ec1809ed588d26f3fe7511bf24b52e47440c3d90526f3d1"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--file-ops.js"], [25, "v0.2.0", "f114db89754638b5e4ade1dc3f5d4753ac672a4323c286e8c8ed0412760e6861"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--folder-ops.js"], [25, "v0.2.0", "10fea1377422c5368aead040500c28135fafcb918427901a74483e23e1b36d7f"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--history.js"], [25, "v0.2.0", "265b215e27216ad25e8fa7c83b47c8307b7990a0a3fb88254ee2149d2835dd2d"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--sync.js"], [25, "v0.2.0", "b9f521e7b70ca66f6d1197378337f954deea4ed3468535ec3064149c7cf1fcc6"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-commit.js"], [25, "v0.2.0", "e686de3756eaeed185708a6ba96194429afb3067f145108e7580d876598dd9ce"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-crypto.js"], [25, "v0.2.0", "f8d31359204a9e333d27444ea2a37c1bb11bbc790d0cf4cfa95fe9f9282d6e66"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-object-store.js"], [25, "v0.2.0", "a45d7ad0f9dbd91677785c3128a8322d4209cb35ab5d815551dcbf1eceed9c9e"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-ref-manager.js"], [25, "v0.2.0", "5b8ea87ace83d59e8954511d9932bd3968020c57070375194c7427a083fb729f"], [25, "v0.2.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault.js"], [25, "v0.2.0", "0108884f9b8d539e4c9457190326d64adc5a92c808803f0dab14b9e772b3ad26"], [25, "v0.2.0", "6ad9b2f9c39e99748a089d55670a1233983ff08cc5d02e53a9034adb9735a17d"], [25, "v0.2.0", "ec9abc1f40b5f5640103f4e7ab4280a8622d9d5aa683bc82079609ccea413783"], [25, "v0.2.0", "5f8fa1378b99c24cdba945cd0bb965a56f03a04ce069a3ab56b3ec340881b1ee"], [25, "v0.2.0", "ca352ad9cdc8631d01005bfd94b88b92a646c030a3324d249f77285e48a0b491"], [25, "v0.2.0", "08c47eae0b95943e10e919fc770ddd2c0c30b2fd7652a5199fb8b7961f92560a"], [25, "v0.2.0", "d50a3642c131bbaa8b9858438138fc1dc78ae3249e9bab89c1b7541f95a447b8"], [25, "v0.2.0", "22f48fcb1185389f8c477b382f422b42e7916bc2f1920598049f490cca3490e1"], [25, "v0.2.0", "e08913d389ede55fb0787cba7752920c28b43735ff767795e11ac43224c5a12b"], [25, "v0.2.0", "332509b6be44538d7aab0305669673fa6907591ff621dee1b2605849c89afbfb"], [25, "v0.2.0", "f61bc914b5303dced5b03e16a81c7bca33e534bd88eb5a049718e1a7b094d3d7"], [25, "v0.2.0", "372f85ab8ffd75beb8eaec31aa64884dcaff8286b961a353cc7cf0bfdd3dc1c7"], [25, "v0.1.0", "63 files, 890,555 bytes. manifest.json."], [25, "v0.1.0", "The move. Phase 1 of Go slow to go fast: 63 files left the newsroom's repository at its v0.12.10 and are served from here at the paths they had there. The meter v1.4.0 and its frozen v1.0.0 to v1.3.1, the component base, the reading lists, subscribe, the vault layer and the pane, search and ask, the wire reader, the vendored vault library, the passkey lab. The same bytes, apart from three files that a host of their own forced to change, each by the lines that located the site root from the script's own address (vault-pane.js, search.js, ask.js); the manifest records each with its before-hash and the reason. The newsroom pins this release at its v0.13.0; the proof of the move is on its own page."], [25, "v0.1.0", "took the site root from its own URL; now from the page's data-root for links"], [25, "v0.1.0", "took the site root from its own URL; now from the page's data-root for data and links, and imports the pane's modules from its own root (CODE)"], [25, "v0.1.0", "assets/vault-pane/vault-pane.js"], [25, "v0.1.0", "took the site root from its own URL (import.meta.url); now from the page's data-root, and loads the vault library from its own root (CODE)"], [25, "v0.1.0", "assets/components/base/v1/v1.0/v1.0.0/sg-component.js"], [25, "v0.1.0", "e566a78ad98fbd184058eed2a6b435c2c386066a0743de5efdbd0ef99348e677"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter-core.js"], [25, "v0.1.0", "e7440dc3820a0180f80aa4f1722b7f3ede1dc760f31227ca32ea40283400a987"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.css"], [25, "v0.1.0", "b0aef1442f4f4edbb836173070777d5b8e84528fa0980a8b73f30423a9aa1d0c"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.js"], [25, "v0.1.0", "9ea95731fc2c15d53abffc00402682b5924bf0d017cac252a1626892c30b6787"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.0/v1.0.0/sg-meter.tpl"], [25, "v0.1.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter-core.js"], [25, "v0.1.0", "867db221b46ad540cea28b596e07272e2d4667195dac19daa8fd3bafa22946b6"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.css"], [25, "v0.1.0", "051165ca8ec4c737737caee1c612f8f49f13b7af3e804b8f0bee3b1b8131d865"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.js"], [25, "v0.1.0", "eb880df24888a900ef5de10c71e425e98525e604a6f91c01285ae44499252891"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.1/v1.1.0/sg-meter.tpl"], [25, "v0.1.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter-core.js"], [25, "v0.1.0", "541d9873f8bf52699e03fa66922ea42cc98b20c258f3bd790e172cf89a2575b8"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.css"], [25, "v0.1.0", "9cca4711996312e1fd8426d42897b75437277c5210bd956f2a8306ad508c2437"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.js"], [25, "v0.1.0", "38303a50cbdeb142217fb369e41cd6ebb1e0e9f49fa7aab2c10b34267bebb106"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.2/v1.2.0/sg-meter.tpl"], [25, "v0.1.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter-core.js"], [25, "v0.1.0", "34b32beef6b6f781a8bc07b14f1d677c148c1d632be0a2de60eff2ee2382f568"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.css"], [25, "v0.1.0", "b56618dbfeee38047efba9d66289ebea40b496e9771abf50a215ceb4f2368297"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.js"], [25, "v0.1.0", "f26b2fec6f409f34bf91a341cda9acd424478f7dd0a790a4070c3d753b2eb350"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.3/v1.3.0/sg-meter.tpl"], [25, "v0.1.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter-core.js"], [25, "v0.1.0", "61c636b881ca7664afe9dda5fd13295f17691928e22664d8480efe55ad4f3d73"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.css"], [25, "v0.1.0", "192b7813a223f2e457381e9e97feea8921fb961a18c17eeede7284337f684859"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.js"], [25, "v0.1.0", "1f3b6f1bbc36cd66e1b2d3a49087a5b37e993a89933adfda648f1c997257bd38"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.3/v1.3.1/sg-meter.tpl"], [25, "v0.1.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter-core.js"], [25, "v0.1.0", "6a74b1183c766d5aee8a6fdbfd9bfc7885a7c873945cde6ee2061f300d2c2eaf"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.css"], [25, "v0.1.0", "98a86404668135893759d018db3f457a6de25698a50c988b00a65fbc88071fa5"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.js"], [25, "v0.1.0", "82f8c09842290336b208df78936059c69ce3db456e610c785e00cd78065cf55c"], [25, "v0.1.0", "assets/components/sg-meter/v1/v1.4/v1.4.0/sg-meter.tpl"], [25, "v0.1.0", "104c7c1ded976408ba7d827f1c00ad53fd0718997aacebb2081bbd8772efb6a3"], [25, "v0.1.0", "740779876d19acebd24e493da9616d132a968f8885c013880f383c15d6ef4dff"], [25, "v0.1.0", "0e71c28b5acf02ba1b25bf936013ec60432301c948ac896ec546aefbf8971264"], [25, "v0.1.0", "ecdf4ba20ac4af93e15a8d8dcffe473d58565ed747cdd5327fbb9fd6c22971b0"], [25, "v0.1.0", "68d68bb1b7a3df4c41d1f37f22e86d30531b0e5c17637760a2a54c0aff0018e9"], [25, "v0.1.0", "c750cab906e8d1592e3bd3fece94ff33945c833a7a78d3a7d9c7313d7dbe636f"], [25, "v0.1.0", "50bb687f48eadfde42348334c660cbd16188e0e1c9342ce5f959596a4445ca3b"], [25, "v0.1.0", "3968954e3cc5f286be7c72d9e7bcb3c143069ef1465b4787ba7db388cde8ca19"], [25, "v0.1.0", "fe2eec58c28f15e53fc57520bccb75e38276607821d8572b0fdfd1e0417c1c58"], [25, "v0.1.0", "21f583f801906d8b3b9bad289a31919e88be02344f4156afd5f04831c83e9198"], [25, "v0.1.0", "4d4c30ec10e0ebe138ad337527a2605c908bba1f2767b3f8c1ef0fe39066469a"], [25, "v0.1.0", "e8f2b778f2b2eec00aecdc1c532c488e0ebd0c36e08caf353b557b0e00845b79"], [25, "v0.1.0", "96b3701ec97d89aa0a55fdd2c6d7743deb5e145ceef53aeb58ae247accccdc75"], [25, "v0.1.0", "assets/vault-pane/vault-pane.css"], [25, "v0.1.0", "f628857853b351f4d08f8f35fdc410c53a3d22a43a7836e1a4c0af61e4a4ec9a"], [25, "v0.1.0", "assets/vault-pane/vault-pane.js"], [25, "v0.1.0", "9004e3a95722c82f47aab7ccaf961e728c99ef939af0ed6493dc4c6852ad2ca1"], [25, "v0.1.0", "assets/vault-pane/wire-state.js"], [25, "v0.1.0", "d4f134cdf3ac9d0f01303140856f3cdffdc86e726db84fdd617aa09eedce45b7"], [25, "v0.1.0", "assets/vendor/sg-vault/local/sg-vault--create-with-id.js"], [25, "v0.1.0", "b668c4ab0062a3b385882fa593f7213f50f667c777d0614b5ba8abcb5721372e"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/VENDOR.md"], [25, "v0.1.0", "72b1b247062e1cd0b9502fb689c5e5d90bc79c27d9696af2047f1a2fccf7e9af"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-send/sg-send-crypto.js"], [25, "v0.1.0", "2c4af16bbaf4f43e7eb0f8298a9cd8338429f99c7bec20c5d7f4da96c88e39ce"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-send/sg-send.js"], [25, "v0.1.0", "9bc98e580f5fc1adbf8e2d273181e6afa3bd9a3813ea8a1bf24ddd07e1b8b41e"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--branches.js"], [25, "v0.1.0", "bc1eec8bbc2326a73ec1809ed588d26f3fe7511bf24b52e47440c3d90526f3d1"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--file-ops.js"], [25, "v0.1.0", "f114db89754638b5e4ade1dc3f5d4753ac672a4323c286e8c8ed0412760e6861"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--folder-ops.js"], [25, "v0.1.0", "10fea1377422c5368aead040500c28135fafcb918427901a74483e23e1b36d7f"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--history.js"], [25, "v0.1.0", "265b215e27216ad25e8fa7c83b47c8307b7990a0a3fb88254ee2149d2835dd2d"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault--sync.js"], [25, "v0.1.0", "b9f521e7b70ca66f6d1197378337f954deea4ed3468535ec3064149c7cf1fcc6"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-commit.js"], [25, "v0.1.0", "e686de3756eaeed185708a6ba96194429afb3067f145108e7580d876598dd9ce"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-crypto.js"], [25, "v0.1.0", "f8d31359204a9e333d27444ea2a37c1bb11bbc790d0cf4cfa95fe9f9282d6e66"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-object-store.js"], [25, "v0.1.0", "a45d7ad0f9dbd91677785c3128a8322d4209cb35ab5d815551dcbf1eceed9c9e"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault-ref-manager.js"], [25, "v0.1.0", "5b8ea87ace83d59e8954511d9932bd3968020c57070375194c7427a083fb729f"], [25, "v0.1.0", "assets/vendor/sg-vault/v0.2.3/sg-vault/sg-vault.js"], [25, "v0.1.0", "0108884f9b8d539e4c9457190326d64adc5a92c808803f0dab14b9e772b3ad26"], [25, "v0.1.0", "cca712d5810b3085a346ce2704e13b07ba66ca9f9147d20f6604e2b62164cabe"], [25, "v0.1.0", "ec9abc1f40b5f5640103f4e7ab4280a8622d9d5aa683bc82079609ccea413783"], [25, "v0.1.0", "5f8fa1378b99c24cdba945cd0bb965a56f03a04ce069a3ab56b3ec340881b1ee"], [25, "v0.1.0", "d6a2b51445e89ca9de81ddc432625981e1fb726f84a37b5a3b8a7bd1b573fab7"], [25, "v0.1.0", "08c47eae0b95943e10e919fc770ddd2c0c30b2fd7652a5199fb8b7961f92560a"], [25, "v0.1.0", "d50a3642c131bbaa8b9858438138fc1dc78ae3249e9bab89c1b7541f95a447b8"], [25, "v0.1.0", "332509b6be44538d7aab0305669673fa6907591ff621dee1b2605849c89afbfb"], [25, "v0.1.0", "7003c4a048b047f1d14e66ae937ad8089ae5b5df0a27a8c8c9a55aca8dd14d31"], [25, "v0.1.0", "5df279bc72a7f8d586d530ed07742c6003557114e35cb1d31b1fd77884badf73"], [25, "v0.1.0", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [25, "v0.1.0", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [25, "v0.1.0", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [25, "v0.1.0", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"], [26, "", "Everything here was designed in public first, as an article on newsroom.sgit.ai, then built, then written about again when it went live. Read them in this order and you have the case, the design and the engineering; each is numbered, so a reading list in a link can carry a set of them to a colleague."], [26, "", "A story is a graph of claims and evidence and the article is one projection of it; keep the graph in a vault and sell what the article was made from."], [26, "", "Why a newsroom would want this at all."], [26, "", "Every page now costs a few pence from £5 of credit kept in your browser, and the reading history it keeps is what personalises the site."], [26, "", "The reading meter, as it was built."], [26, "", "Seven releases in one afternoon turned the reading meter into a working model: pay after you read, and the rating sets the price."], [26, "", "Paying after you read, with a rating that sets the price."], [26, "", "Pay for the share of a page you read, go below zero with no nagging, top up £5 on Stripe: the plan, and the numbers we check in eight weeks."], [26, "", "Real money, and the line between what runs and what is designed."], [26, "", "Eight kinds of reader, none of them attackers, nine ways to cheat a browser meter, and the quieter risks that will actually happen."], [26, "", "The threat model, written before the first pound."], [26, "", "First the database went, now the back end: the SGit Newsroom runs all its logic in the browser, on commodity servers that cannot read your data."], [26, "", "Why there is no server of ours, and what that buys a reader."], [26, "", "Send this set: make a reading list of these 6."], [26, "", "Send a CISO to the newsroom as a CISO: personas kept in a vault by the newsroom's agents, opened from a link, followed or forked."], [26, "", "A link that opens the newsroom as a persona."], [26, "", "Readers should pay because it helps them: a persona with a name and a graph, several for focus, and one that follows you between devices."], [26, "", "What a persona is worth, and to whom."], [26, "", "A reading list from one person to another, in a link the server never sees; a brief to build it, a brief to use it, and the loop that ships it in a day."], [26, "", "From me to you, in a link: the reading-list grammar."], [26, "", "I read the newsroom on four devices and they do not agree. Missing a feature is the best sign; the makers must use it. And the brief for the reader's vault."], [26, "", "The makers must use it, and the brief for the reader's vault."], [26, "", "The reader's vault runs on newsroom.sgit.ai: a passkey opens three real vaults, each device writes one file, and the architecture is drawn as it stands."], [26, "", "The reading account carried between devices."], [26, "", "The site as an inbox that starts empty: decide fast before reading, mark slowly while reading, build a graph you own, and sign what you send to the newsroom."], [26, "", "Notes to the newsroom, carried by the vault."], [26, "", "Tested: a passkey's PRF bytes compute a door that holds the master's key, and a different path to the same passkey gives different bytes, so a door per path."], [26, "", "A passkey's PRF bytes compute a door; no server of ours."], [26, "", "Vault key management at sgit-ai v0.20.0: the one secret, where keys are kept, how they travel sealed on append lanes, and what comes next."], [26, "", "Where the keys live, and who holds what."], [26, "", "Send this set: make a reading list of these 8."], [26, "", "The newsroom is live and charging. Move the reader code to its own repo, same bytes and same bugs, then map, test, review and refactor before new features."], [26, "", "The brief for the move this repository is: go slow to go fast."], [26, "", "Source code is layers within layers, each a graph with its own vocabulary; code review should read a change at every one, and a vault shows it done on real code."], [26, "", "The review method: read a change at every layer."], [26, "", "A reader's seven questions answered as a company plan: one reader for every layer, review as a science, and the layers as the customer's own."], [26, "", "Why villager code is read line by line."], [26, "", "Two releases passed every check and never reached the site because the checks stopped at the git remote; a release now ends by asking the live site its version."], [26, "", "A release ends by asking the live site for its version."], [26, "", "Five invented users, a model reading screenshots, and a real browser: how to run synthetic users, from three studies."], [26, "", "Five readers who do not exist, a browser, and an afternoon."], [26, "", "The people I advise read through agents. Content needs a second package, a brief for their agent, and memory, so it reads what changed, not everything."], [26, "", "The people you talk to work with agents; brief their agents too."], [26, "", "One agent writes the Industry Wire into an encrypted vault; newsroom.sgit.ai holds only the read key and draws it, so a commit reaches the page with no release."], [26, "", "Two agents, one vault: how the newsroom's agents share state."], [26, "", "Send this set: make a reading list of these 7."], [26, "", "Every article on newsroom.sgit.ai, with its graph: the articles, graphs.json."], [26, "", "The SGit Newsroom's reader, as an API: the components, formats and contracts the browser runs on newsroom.sgit.ai, with no server and nothing to deploy but files, published here as releases a site pins. Made by the newsroom's agents under the editorial and engineering responsibility of Dinis Cruz; the method, the review and the tests are public so that anyone can run a newsroom like it. Part of the sgit.ai network. The code is Apache 2.0; these pages CC BY 4.0."], [26, "", "↑ sgit.ai · ↑ newsroom.sgit.ai · ↑ pt.newsroom.sgit.ai · ↑ graphs.sgit.ai · ↑ pki.sgit.ai · ↑ nhi.sgit.ai · ↑ docs.diniscruz.ai — the prior art"], [26, "", "⚠ Participant disclosure: published by the sgit project, which is building the stack this site argues for. Read the disclosure."], [26, "", "site v0.2.14 · reader code v0.2.5 · engineering · this page as markdown"]]}
