@bongos/core 1.21.157 → 1.21.159

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3151,5 +3151,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
3151
3151
  landed since 1.21.155 with no explicit bump. run 39808834444. (task 1002620)
3152
3152
  1.21.157 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3153
3153
  landed since 1.21.156 with no explicit bump. run 39861648960. (task 1002620)
3154
+ 1.21.158 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3155
+ landed since 1.21.157 with no explicit bump. run 39863960705. (task 1002620)
3156
+ 1.21.159 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3157
+ landed since 1.21.158 with no explicit bump. run 39950957911. (task 1002620)
3154
3158
  ---------------------------------------------------------------------------
3155
3159
  ```
@@ -388,6 +388,7 @@ Run `bongos upgrade` to confirm coreVersion compatibility, then `node scripts/gd
388
388
 
389
389
  - The version is `module.json`'s `version`. Each version is published **once** and must be newer than the last — bump it to publish a fix.
390
390
  - Your first publish of a key makes you its author; only the author can publish later versions, and a delisted key takes none.
391
+ - **Every new version goes to testers first** (task 1003803, [ADR 0344](adr/0344-a-tester-is-a-project-that-opts-in-once.md) D2). A published version, first release or update, is recorded on the `tester` channel (`store_module_version_channels`, reason `new_version`), and the publish response says so as `channel`. A publish cannot name a channel, so there is no flag that sends an untested version to every project. Moving it to `general` is a separate, later step: the promotion gate (task 1003804).
391
392
  - The publish denylist applies (ADR 0098), plus a refusal of credential-named files (`.env*`, `*.pem`, `*.key`, `id_rsa`, …) anywhere in the module. The store re-checks every hash and the denylist itself.
392
393
  - Gate: Metic+ (`module.submit`) for now. This is not `bongos module submit`, which proposes a module *into* core.
393
394
  - **A how-to is required** ([ADR 0347](adr/0347-every-store-module-ships-a-how-to.md)). `modules/<key>/HOWTO.md` is what a buyer reads — the store shows it as the module's page — so it is written for the person who installs the module, not for an AI working inside it (that is `CLAUDE.md`). It is plain Markdown: any AI or person can write it. Publish refuses the version unless it has these five level-2 headings, in any order and any case, each with some text under it: `## What it does`, `## Install and enable`, `## How to use it` (with one worked example), `## Configuration` ("None." is fine) and `## Limits and known issues` ("None known." is fine). HTML comments don't count as text, so the scaffold's prompts must be replaced. The refusal names each failing section. The check is one function, `checkHowto` in `scripts/gds/module-artifact.js`; the CLI runs it before uploading and the store runs it again on upload, so a hand-built upload can't skip it. `bongos module check` reports it as advice only — an upstream submit is not gated by it. Install and update don't re-check it, so a version published before the gate still installs. The file travels in the tarball, so its hash pins it to the version. An optional `howto.artifactUrl` in `module.json` (an `https://` link on `claude.ai`) is shown as an extra, never graded.
@@ -405,7 +406,7 @@ Run `bongos upgrade` to confirm coreVersion compatibility, then `node scripts/gd
405
406
  - Install never enables. Switch the module on from the hall's Modules tab.
406
407
  - **Every version's how-to is a page** (task 1004366). `GET /store/modules/:key/versions/:version/howto` reads the `HOWTO.md` from that version's own stored tarball, after the same hash check install runs, and returns it as text; the hall shows it at `/builders/modules?howto=<key>&version=<X.Y.Z>`, rendered through the hall's escaping markdown reader (`md-reader.js`) because the file is author-written. Any signed-in builder can read it without holding the module; a delisted module's how-to reads only for people who hold it. "Save as PDF" is the browser's own print, with a print sheet that keeps only the document. The optional `howto.artifactUrl` shows as "Also available as a Claude page". Install prints the link, and a Modules-tab row links it when the module on disk is a published store version. A version published before the gate has none and answers 404 `howto_missing`.
407
408
  - A module already on disk, in the instance's `modules/` or bundled with the core, is refused; moving one to a newer version is `update`. A module this core cannot mount is refused before download.
408
- - A delisted module cannot be acquired or downloaded. Channels are not checked yet: every version is general until the channel tasks land.
409
+ - A delisted module cannot be acquired or downloaded. Channels are not checked yet: install and update hand out a version whatever its channel until task 1003805 lands.
409
410
 
410
411
  `bongos module update <key> [--version X.Y.Z]` moves an installed store module forward through the same three calls, so a paid module and a free one take one identical path, and a module you already hold is never charged again (`tests/module_update.mjs` fails if a price-conditional branch appears).
411
412
 
@@ -5,7 +5,7 @@
5
5
  "adr": "0341 D3",
6
6
  "reread": "node scripts/gds/page-reader.js --stale",
7
7
  "how": ["Generated by node scripts/gds/page-reader.js (BV2.TW04, task 1004315; ADR 0341 D3). Do not hand-edit.","One entry per page of docs/page-inventory.json. Lines are in page order: the default state first, and a line only another state shows sits where that state shows it, with its state named.","placement: placed = a docs/copy-registry.json row renders it (file, line, string_id); shared = shell text every page of the surface carries (top bar, sidebar, footer), with its row when the registry has one; unplaced = the registry cannot place it (a rewrite becomes an engineer task, ADR 0341 D4).","text keeps {…} where the registry row has a hole, or where a value the page read from its API was filled in. A string that is only such data is counted under omitted.data, not listed.","reading_hash is over the non-shared lines (key, section, text); files_hash is over the page's inventory files. --check compares files_hash only and never opens a browser.","Rendered through the hall-preview harness (hall) and the ui-design kit stub (landing, status), at 1280x800 with the clock pinned, so a reading is the fixture world's page."],
8
- "counts": {"pages":46,"lines":5568,"placed":1711,"shared":398,"unplaced":3459,"omitted_data":3606},
8
+ "counts": {"pages":46,"lines":5569,"placed":1711,"shared":398,"unplaced":3460,"omitted_data":3606},
9
9
  "pages": [
10
10
  {
11
11
  "id": "builders:atlas",
@@ -4938,9 +4938,9 @@
4938
4938
  "surface": "landing",
4939
4939
  "title": "{{productName}}: {{tagline}}",
4940
4940
  "states_read": ["out","in","out-projects","in-profile","cli-out"],
4941
- "files_hash": "6727dfd3ff131333",
4942
- "reading_hash": "54cc700073c7757e",
4943
- "counts": {"lines":85,"placed":53,"shared":14,"unplaced":18},
4941
+ "files_hash": "14cd102ca1448dde",
4942
+ "reading_hash": "c8858c338bf942ab",
4943
+ "counts": {"lines":86,"placed":53,"shared":14,"unplaced":19},
4944
4944
  "omitted": {"data":6},
4945
4945
  "notes": [],
4946
4946
  "lines": [
@@ -4954,81 +4954,82 @@
4954
4954
  {"key":"L0008","section":"page top","text":"Sign out","placement":"placed","file":"modules/public-landing/public/index.html","line":723,"string_id":"f9af2d90ce5b","state":"in-profile"},
4955
4955
  {"key":"L0009","section":"top bar","text":"Sign in","placement":"shared","file":"modules/public-landing/public/index.html","line":690,"string_id":"ad80586f802a"},
4956
4956
  {"key":"L0010","section":"page top","text":"Sky","placement":"unplaced","state":"out-projects"},
4957
- {"key":"L0011","section":"page top","text":"the sky of every project","placement":"placed","file":"modules/public-landing/public/index.html","line":703,"string_id":"8fa12f730019","state":"out-projects"},
4957
+ {"key":"L0011","section":"page top","text":"a universe of Projects","placement":"placed","file":"modules/public-landing/public/index.html","line":703,"string_id":"ed075e6e5f3a","state":"out-projects"},
4958
4958
  {"key":"L0012","section":"page top","text":"Table","placement":"unplaced","state":"out-projects"},
4959
- {"key":"L0013","section":"page top","text":"the same projects as rows","placement":"placed","file":"modules/public-landing/public/index.html","line":704,"string_id":"21453b3ba5c3","state":"out-projects"},
4960
- {"key":"L0014","section":"page top","text":"New project","placement":"placed","file":"modules/public-landing/public/index.html","line":706,"string_id":"0a81a82d10c4","state":"out-projects"},
4961
- {"key":"L0015","section":"page top","text":"five questions and a home","placement":"placed","file":"modules/public-landing/public/index.html","line":706,"string_id":"94a3462373d2","state":"out-projects"},
4959
+ {"key":"L0013","section":"page top","text":"sky project directory","placement":"placed","file":"modules/public-landing/public/index.html","line":704,"string_id":"dd8f15e45e84","state":"out-projects"},
4960
+ {"key":"L0014","section":"page top","text":"+ Create New Project","placement":"placed","file":"modules/public-landing/public/index.html","line":706,"string_id":"205f6e9eab89","state":"out-projects"},
4961
+ {"key":"L0015","section":"page top","text":"fresh start/fresh idea","placement":"placed","file":"modules/public-landing/public/index.html","line":706,"string_id":"46c35bc7dcdf","state":"out-projects"},
4962
4962
  {"key":"L0016","section":"Building Digitally,as simple as Bongos.","text":"Building Digitally,","placement":"placed","file":"modules/public-landing/public/index.html","line":737,"string_id":"16bc370da814"},
4963
4963
  {"key":"L0017","section":"Building Digitally,as simple as Bongos.","text":"as simple as Bongos.","placement":"placed","file":"modules/public-landing/public/index.html","line":737,"string_id":"acbabdef6f40"},
4964
- {"key":"L0018","section":"Building Digitally,as simple as Bongos.","text":"AI agents claim tasks and ship the code. You set the direction and the gates.","placement":"placed","file":"modules/public-landing/public/index.html","line":739,"string_id":"632b49062d74"},
4964
+ {"key":"L0018","section":"Building Digitally,as simple as Bongos.","text":"Bringing AI to the builder, ideator, and artist in everyone.","placement":"placed","file":"modules/public-landing/public/index.html","line":739,"string_id":"750136e8637c"},
4965
4965
  {"key":"L0019","section":"Building Digitally,as simple as Bongos.","text":"Find a project to join","placement":"placed","file":"modules/public-landing/public/index.html","line":743,"string_id":"483a7eff25f2"},
4966
4966
  {"key":"L0020","section":"Building Digitally,as simple as Bongos.","text":"Start a project","placement":"placed","file":"modules/public-landing/public/index.html","line":744,"string_id":"2ae36be1c531"},
4967
- {"key":"L0021","section":"Built on Cloud Bongos","text":"Built on Cloud Bongos","placement":"placed","file":"modules/public-landing/public/index.html","line":753,"string_id":"78fd8d18ba64"},
4968
- {"key":"L0022","section":"Built on Cloud Bongos","text":"At present, Bongos projects are all held by Verro Labs or its pilot clients.","placement":"placed","file":"modules/public-landing/public/index.html","line":754,"string_id":"b99ea6917ce9"},
4969
- {"key":"L0023","section":"Built on Cloud Bongos","text":"Example World","placement":"placed","file":"modules/public-landing/public/index.html","line":758,"string_id":"1b5a6cfc494c"},
4970
- {"key":"L0024","section":"Built on Cloud Bongos","text":"a game, 11 builders","placement":"placed","file":"modules/public-landing/public/index.html","line":759,"string_id":"b7cee0f10353"},
4971
- {"key":"L0025","section":"Built on Cloud Bongos","text":"0 builders","placement":"unplaced"},
4972
- {"key":"L0026","section":"Built on Cloud Bongos","text":"Emersonian Circles","placement":"placed","file":"modules/public-landing/public/index.html","line":768,"string_id":"9a4a940d2a56"},
4973
- {"key":"L0027","section":"Built on Cloud Bongos","text":"1 builder","placement":"placed","file":"modules/public-landing/public/index.html","line":764,"string_id":"22825067f4c5"},
4974
- {"key":"L0028","section":"Built on Cloud Bongos","text":"Open the map","placement":"placed","file":"modules/public-landing/public/index.html","line":772,"string_id":"74cdcd87d1fa"},
4967
+ {"key":"L0021","section":"Built on Bongos.","text":"Built on Bongos.","placement":"placed","file":"modules/public-landing/public/index.html","line":753,"string_id":"20b4fa9a0424"},
4968
+ {"key":"L0022","section":"Built on Bongos.","text":"At present, all Bongos projects are held by Verro Labs or its pilot clients.","placement":"placed","file":"modules/public-landing/public/index.html","line":754,"string_id":"b2da3498f53d"},
4969
+ {"key":"L0023","section":"Built on Bongos.","text":"Example World","placement":"placed","file":"modules/public-landing/public/index.html","line":758,"string_id":"1b5a6cfc494c"},
4970
+ {"key":"L0024","section":"Built on Bongos.","text":"a game, 11 builders","placement":"placed","file":"modules/public-landing/public/index.html","line":759,"string_id":"b7cee0f10353"},
4971
+ {"key":"L0025","section":"Built on Bongos.","text":"0 builders","placement":"unplaced"},
4972
+ {"key":"L0026","section":"Built on Bongos.","text":"Emersonian Circles","placement":"placed","file":"modules/public-landing/public/index.html","line":768,"string_id":"9a4a940d2a56"},
4973
+ {"key":"L0027","section":"Built on Bongos.","text":"1 builder","placement":"placed","file":"modules/public-landing/public/index.html","line":764,"string_id":"22825067f4c5"},
4974
+ {"key":"L0028","section":"Built on Bongos.","text":"View Projects","placement":"placed","file":"modules/public-landing/public/index.html","line":772,"string_id":"b97287183335"},
4975
4975
  {"key":"L0029","section":"A project as a codebase, regardless of function.","text":"A project as a codebase, regardless of function.","placement":"placed","file":"modules/public-landing/public/index.html","line":779,"string_id":"407982c3d4ff"},
4976
4976
  {"key":"L0030","section":"A project as a codebase, regardless of function.","text":"A laddered beat progresses all tasks.","placement":"placed","file":"modules/public-landing/public/index.html","line":780,"string_id":"545c82e99696"},
4977
4977
  {"key":"L0031","section":"A project as a codebase, regardless of function.","text":"claim","placement":"unplaced"},
4978
- {"key":"L0032","section":"A project as a codebase, regardless of function.","text":"Locked to one agent","placement":"placed","file":"modules/public-landing/public/index.html","line":785,"string_id":"07a4c3686414"},
4978
+ {"key":"L0032","section":"A project as a codebase, regardless of function.","text":"Take on a task","placement":"placed","file":"modules/public-landing/public/index.html","line":785,"string_id":"c160ff80c611"},
4979
4979
  {"key":"L0033","section":"A project as a codebase, regardless of function.","text":"build","placement":"unplaced"},
4980
- {"key":"L0034","section":"A project as a codebase, regardless of function.","text":"built in its own worktree","placement":"placed","file":"modules/public-landing/public/index.html","line":790,"string_id":"c16cf5f7fe01"},
4980
+ {"key":"L0034","section":"A project as a codebase, regardless of function.","text":"run your preferred model","placement":"placed","file":"modules/public-landing/public/index.html","line":790,"string_id":"efbb62ff5488"},
4981
4981
  {"key":"L0035","section":"A project as a codebase, regardless of function.","text":"grade","placement":"unplaced"},
4982
- {"key":"L0036","section":"A project as a codebase, regardless of function.","text":"read by a panel","placement":"placed","file":"modules/public-landing/public/index.html","line":795,"string_id":"646b1e72622d"},
4982
+ {"key":"L0036","section":"A project as a codebase, regardless of function.","text":"evaluated by agentic agents","placement":"placed","file":"modules/public-landing/public/index.html","line":795,"string_id":"f8d9d6f2490f"},
4983
4983
  {"key":"L0037","section":"A project as a codebase, regardless of function.","text":"ship","placement":"unplaced"},
4984
- {"key":"L0038","section":"A project as a codebase, regardless of function.","text":"merged and verified live","placement":"placed","file":"modules/public-landing/public/index.html","line":800,"string_id":"239ac33aa0b0"},
4984
+ {"key":"L0038","section":"A project as a codebase, regardless of function.","text":"agentically merged and made live","placement":"placed","file":"modules/public-landing/public/index.html","line":800,"string_id":"eedec34758da"},
4985
4985
  {"key":"L0039","section":"A project as a codebase, regardless of function.","text":"credit","placement":"unplaced"},
4986
- {"key":"L0040","section":"A project as a codebase, regardless of function.","text":"paid only once it lands","placement":"placed","file":"modules/public-landing/public/index.html","line":805,"string_id":"af9fcc3a4124"},
4986
+ {"key":"L0040","section":"A project as a codebase, regardless of function.","text":"equity or cash payouts","placement":"placed","file":"modules/public-landing/public/index.html","line":805,"string_id":"a7767cf28a36"},
4987
4987
  {"key":"L0041","section":"A project as a codebase, regardless of function.","text":"1,111 of 1,561 shipped on V1","placement":"placed","file":"modules/public-landing/public/index.html","line":813,"string_id":"14277fea260d"},
4988
- {"key":"L0042","section":"A project as a codebase, regardless of function.","text":"The six most recent, straight from the ledger.","placement":"placed","file":"modules/public-landing/public/index.html","line":815,"string_id":"62377d81c52c"},
4988
+ {"key":"L0042","section":"A project as a codebase, regardless of function.","text":"The six most recent shipped tasks.","placement":"placed","file":"modules/public-landing/public/index.html","line":815,"string_id":"40ed6300ba27"},
4989
4989
  {"key":"L0043","section":"A project as a codebase, regardless of function.","text":"Landing composition round: three versions of the approved world","placement":"placed","file":"modules/public-landing/public/index.html","line":819,"string_id":"376b549bf7c8"},
4990
4990
  {"key":"L0044","section":"A project as a codebase, regardless of function.","text":"Percy Jackson","placement":"placed","file":"modules/public-landing/public/index.html","line":820,"string_id":"3eb67b892dea","occurrences":4},
4991
- {"key":"L0045","section":"A project as a codebase, regardless of function.","text":"27 Aug","placement":"unplaced","occurrences":6},
4991
+ {"key":"L0045","section":"A project as a codebase, regardless of function.","text":"27 Aug","placement":"unplaced","occurrences":4},
4992
4992
  {"key":"L0046","section":"A project as a codebase, regardless of function.","text":"See what you did, by role, including every idea you filed and what became of it","placement":"placed","file":"modules/public-landing/public/index.html","line":825,"string_id":"67b61947244d"},
4993
4993
  {"key":"L0047","section":"A project as a codebase, regardless of function.","text":"ship.js still writes no session record when the session is rooted in another project dir","placement":"placed","file":"modules/public-landing/public/index.html","line":831,"string_id":"156d37716e14"},
4994
4994
  {"key":"L0048","section":"A project as a codebase, regardless of function.","text":"World round: PRODUCT.md and four style candidates across landing, hall and status","placement":"placed","file":"modules/public-landing/public/index.html","line":837,"string_id":"8a4892d03781"},
4995
4995
  {"key":"L0049","section":"A project as a codebase, regardless of function.","text":"Footer doors before launch: privacy, terms and contact pages linked from the landing page and the hub","placement":"placed","file":"modules/public-landing/public/index.html","line":843,"string_id":"0a0667aea2db"},
4996
- {"key":"L0050","section":"A project as a codebase, regardless of function.","text":"Task titles are write-once, no route can edit one, so a wrong title is permanent","placement":"placed","file":"modules/public-landing/public/index.html","line":849,"string_id":"052e2da986c2"},
4997
- {"key":"L0051","section":"A project as a codebase, regardless of function.","text":"VERRO LABS","placement":"placed","file":"modules/public-landing/public/index.html","line":863,"string_id":"6e1001190059"},
4998
- {"key":"L0052","section":"A project as a codebase, regardless of function.","text":"Built by Verro Labs, Cloud Bongos is our way of making AI co-building usable by entire project groups, whether that's a 5,000-person company, a 3,000-person department inside one, a college research project, or a solo dev.","placement":"placed","file":"modules/public-landing/public/index.html","line":864,"string_id":"1e3de399e779"},
4999
- {"key":"L0053","section":"A project as a codebase, regardless of function.","text":"For founders","placement":"placed","file":"modules/public-landing/public/index.html","line":876,"string_id":"dbced351ca0d"},
5000
- {"key":"L0054","section":"Types of projects","text":"Types of projects","placement":"placed","file":"modules/public-landing/public/index.html","line":877,"string_id":"a165999f36a9"},
5001
- {"key":"L0055","section":"Types of projects","text":"Open source.","placement":"placed","file":"modules/public-landing/public/index.html","line":879,"string_id":"275ca0d5ce65"},
5002
- {"key":"L0056","section":"Types of projects","text":"Download our core code and protocols, and build instantly with your team.","placement":"placed","file":"modules/public-landing/public/index.html","line":879,"string_id":"d919980d2ca5"},
5003
- {"key":"L0057","section":"Types of projects","text":"Bongos Managed.","placement":"placed","file":"modules/public-landing/public/index.html","line":881,"string_id":"4782de01c86b"},
5004
- {"key":"L0058","section":"Types of projects","text":"Buy microtransaction packages of code modules on our marketplace.","placement":"placed","file":"modules/public-landing/public/index.html","line":883,"string_id":"101339c676b4"},
5005
- {"key":"L0059","section":"Types of projects","text":"Have us handle your hosting.","placement":"placed","file":"modules/public-landing/public/index.html","line":884,"string_id":"41778f67b4c9"},
5006
- {"key":"L0060","section":"Types of projects","text":"Get access to our advanced project presets and module packages.","placement":"placed","file":"modules/public-landing/public/index.html","line":885,"string_id":"8bb1f00b1558"},
5007
- {"key":"L0061","section":"Types of projects","text":"Equity issuance, business filing, and builder compensation.","placement":"placed","file":"modules/public-landing/public/index.html","line":886,"string_id":"af5ca714d375"},
5008
- {"key":"L0062","section":"Types of projects","text":"For builders","placement":"placed","file":"modules/public-landing/public/index.html","line":892,"string_id":"f510ba460300"},
5009
- {"key":"L0063","section":"Ways to get paid","text":"Ways to get paid","placement":"placed","file":"modules/public-landing/public/index.html","line":893,"string_id":"5370dd2d0e62"},
5010
- {"key":"L0064","section":"Ways to get paid","text":"Build equity in multiple projects.","placement":"placed","file":"modules/public-landing/public/index.html","line":895,"string_id":"0f1ec6cf9dfa"},
5011
- {"key":"L0065","section":"Ways to get paid","text":"Work as a contractor for companies big, medium and small, and get paid instantly.","placement":"placed","file":"modules/public-landing/public/index.html","line":896,"string_id":"80a63cbd4280"},
5012
- {"key":"L0066","section":"Ways to get paid","text":"Build as a game or a learning experience.","placement":"placed","file":"modules/public-landing/public/index.html","line":897,"string_id":"998fbc46a927"},
5013
- {"key":"L0067","section":"Ways to get paid","text":"Start a project","placement":"placed","file":"modules/public-landing/public/index.html","line":744,"string_id":"2ae36be1c531"},
5014
- {"key":"L0068","section":"Ways to get paid","text":"Find a project","placement":"placed","file":"modules/public-landing/public/index.html","line":909,"string_id":"0208e4bbba9c"},
5015
- {"key":"L0069","section":"Ways to get paid","text":"Download the CLI","placement":"placed","file":"modules/public-landing/public/index.html","line":912,"string_id":"41c49e22002d","state":"cli-out"},
5016
- {"key":"L0070","section":"Ways to get paid","text":"Linux, x64 · v0.4.2","placement":"unplaced","state":"cli-out"},
5017
- {"key":"L0071","section":"Ways to get paid","text":"Also for","placement":"unplaced","state":"cli-out"},
5018
- {"key":"L0072","section":"Ways to get paid","text":"macOS, Apple silicon","placement":"unplaced","state":"cli-out"},
5019
- {"key":"L0073","section":"Ways to get paid","text":"macOS, Intel","placement":"unplaced","state":"cli-out"},
5020
- {"key":"L0074","section":"Ways to get paid","text":"Linux, ARM64","placement":"unplaced","state":"cli-out"},
5021
- {"key":"L0075","section":"Ways to get paid","text":"Windows","placement":"unplaced","state":"cli-out"},
5022
- {"key":"L0076","section":"footer","text":"A non-profit, capture-resistant commons.","placement":"shared","file":"modules/public-landing/public/index.html","line":922,"string_id":"afe83bbbd0d4"},
5023
- {"key":"L0077","section":"footer","text":"Built by agents, on Cloud Bongos.","placement":"shared","file":"modules/public-landing/public/index.html","line":922,"string_id":"bd315dd71ea7"},
5024
- {"key":"L0078","section":"footer","text":"Open source","placement":"shared","file":"modules/public-landing/public/index.html","line":922,"string_id":"d6314ddcc1d0"},
5025
- {"key":"L0079","section":"footer","text":"AGPL-3.0","placement":"shared"},
5026
- {"key":"L0080","section":"footer","text":"About","placement":"shared"},
5027
- {"key":"L0081","section":"footer","text":"Docs","placement":"shared"},
5028
- {"key":"L0082","section":"footer","text":"Privacy","placement":"shared"},
5029
- {"key":"L0083","section":"footer","text":"Terms","placement":"shared"},
5030
- {"key":"L0084","section":"footer","text":"Contact","placement":"shared"},
5031
- {"key":"L0085","section":"footer","text":"Builders' hall","placement":"shared","file":"modules/public-landing/public/index.html","line":928,"string_id":"90a128c97eae"}
4996
+ {"key":"L0050","section":"A project as a codebase, regardless of function.","text":"26 Aug","placement":"unplaced","occurrences":2},
4997
+ {"key":"L0051","section":"A project as a codebase, regardless of function.","text":"Task titles are write-once, no route can edit one, so a wrong title is permanent","placement":"placed","file":"modules/public-landing/public/index.html","line":849,"string_id":"052e2da986c2"},
4998
+ {"key":"L0052","section":"A project as a codebase, regardless of function.","text":"VERRO LABS","placement":"placed","file":"modules/public-landing/public/index.html","line":863,"string_id":"6e1001190059"},
4999
+ {"key":"L0053","section":"A project as a codebase, regardless of function.","text":"Built by Verro Labs, Cloud Bongos is our way of making AI co-building usable by entire project groups, whether that's a 5,000-person company, a 100-person department, a college research project, or a solo dev.","placement":"placed","file":"modules/public-landing/public/index.html","line":864,"string_id":"215b5356f401"},
5000
+ {"key":"L0054","section":"A project as a codebase, regardless of function.","text":"For founders","placement":"placed","file":"modules/public-landing/public/index.html","line":874,"string_id":"dbced351ca0d"},
5001
+ {"key":"L0055","section":"Types of projects","text":"Types of projects","placement":"placed","file":"modules/public-landing/public/index.html","line":875,"string_id":"a165999f36a9"},
5002
+ {"key":"L0056","section":"Types of projects","text":"Open source.","placement":"placed","file":"modules/public-landing/public/index.html","line":877,"string_id":"275ca0d5ce65"},
5003
+ {"key":"L0057","section":"Types of projects","text":"Download our core code and protocols, and build instantly with your team.","placement":"placed","file":"modules/public-landing/public/index.html","line":877,"string_id":"d919980d2ca5"},
5004
+ {"key":"L0058","section":"Types of projects","text":"Bongos Managed.","placement":"placed","file":"modules/public-landing/public/index.html","line":879,"string_id":"4782de01c86b"},
5005
+ {"key":"L0059","section":"Types of projects","text":"Buy microtransaction packages of code modules on our marketplace.","placement":"placed","file":"modules/public-landing/public/index.html","line":881,"string_id":"101339c676b4"},
5006
+ {"key":"L0060","section":"Types of projects","text":"Have us handle your hosting.","placement":"placed","file":"modules/public-landing/public/index.html","line":882,"string_id":"41778f67b4c9"},
5007
+ {"key":"L0061","section":"Types of projects","text":"Get access to our advanced project presets and module packages.","placement":"placed","file":"modules/public-landing/public/index.html","line":883,"string_id":"8bb1f00b1558"},
5008
+ {"key":"L0062","section":"Types of projects","text":"Equity issuance, business filing, and builder compensation.","placement":"placed","file":"modules/public-landing/public/index.html","line":884,"string_id":"af5ca714d375"},
5009
+ {"key":"L0063","section":"Types of projects","text":"For builders","placement":"placed","file":"modules/public-landing/public/index.html","line":890,"string_id":"f510ba460300"},
5010
+ {"key":"L0064","section":"Ways to get paid/rewarded","text":"Ways to get paid/rewarded","placement":"placed","file":"modules/public-landing/public/index.html","line":891,"string_id":"3597d73ce7f9"},
5011
+ {"key":"L0065","section":"Ways to get paid/rewarded","text":"Build equity in multiple projects.","placement":"placed","file":"modules/public-landing/public/index.html","line":893,"string_id":"0f1ec6cf9dfa"},
5012
+ {"key":"L0066","section":"Ways to get paid/rewarded","text":"Work as a paid contractor for companies big, medium and small.","placement":"placed","file":"modules/public-landing/public/index.html","line":894,"string_id":"a581f96fb2c8"},
5013
+ {"key":"L0067","section":"Ways to get paid/rewarded","text":"Play as a: game or learning experience.","placement":"placed","file":"modules/public-landing/public/index.html","line":895,"string_id":"384c5b38f500"},
5014
+ {"key":"L0068","section":"Ways to get paid/rewarded","text":"Start a project","placement":"placed","file":"modules/public-landing/public/index.html","line":744,"string_id":"2ae36be1c531"},
5015
+ {"key":"L0069","section":"Ways to get paid/rewarded","text":"Find a project","placement":"placed","file":"modules/public-landing/public/index.html","line":907,"string_id":"0208e4bbba9c"},
5016
+ {"key":"L0070","section":"Ways to get paid/rewarded","text":"Download the CLI","placement":"placed","file":"modules/public-landing/public/index.html","line":910,"string_id":"41c49e22002d","state":"cli-out"},
5017
+ {"key":"L0071","section":"Ways to get paid/rewarded","text":"Windows · v0.4.2","placement":"unplaced","state":"cli-out"},
5018
+ {"key":"L0072","section":"Ways to get paid/rewarded","text":"Also for","placement":"unplaced","state":"cli-out"},
5019
+ {"key":"L0073","section":"Ways to get paid/rewarded","text":"macOS, Apple silicon","placement":"unplaced","state":"cli-out"},
5020
+ {"key":"L0074","section":"Ways to get paid/rewarded","text":"macOS, Intel","placement":"unplaced","state":"cli-out"},
5021
+ {"key":"L0075","section":"Ways to get paid/rewarded","text":"Linux, x64","placement":"unplaced","state":"cli-out"},
5022
+ {"key":"L0076","section":"Ways to get paid/rewarded","text":"Linux, ARM64","placement":"unplaced","state":"cli-out"},
5023
+ {"key":"L0077","section":"footer","text":"A non-profit, capture-resistant commons.","placement":"shared","file":"modules/public-landing/public/index.html","line":920,"string_id":"afe83bbbd0d4"},
5024
+ {"key":"L0078","section":"footer","text":"Built by agents, on Cloud Bongos.","placement":"shared","file":"modules/public-landing/public/index.html","line":920,"string_id":"bd315dd71ea7"},
5025
+ {"key":"L0079","section":"footer","text":"Open source","placement":"shared","file":"modules/public-landing/public/index.html","line":920,"string_id":"d6314ddcc1d0"},
5026
+ {"key":"L0080","section":"footer","text":"AGPL-3.0","placement":"shared"},
5027
+ {"key":"L0081","section":"footer","text":"About","placement":"shared"},
5028
+ {"key":"L0082","section":"footer","text":"Docs","placement":"shared"},
5029
+ {"key":"L0083","section":"footer","text":"Privacy","placement":"shared"},
5030
+ {"key":"L0084","section":"footer","text":"Terms","placement":"shared"},
5031
+ {"key":"L0085","section":"footer","text":"Contact","placement":"shared"},
5032
+ {"key":"L0086","section":"footer","text":"Builders' hall","placement":"shared","file":"modules/public-landing/public/index.html","line":926,"string_id":"90a128c97eae"}
5032
5033
  ]
5033
5034
  },
5034
5035
  {
@@ -700,10 +700,10 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
700
700
  <div class="menuBand" id="menuProjects" data-menu="projects" hidden>
701
701
  <div class="bandIn">
702
702
  <ul class="bandRow">
703
- <li class="bandCell"><a class="bandT" href="/projects?view=map">Sky</a><span class="bandC">the sky of every project</span></li>
704
- <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">the same projects as rows</span></li>
703
+ <li class="bandCell"><a class="bandT" href="/projects?view=map">Sky</a><span class="bandC">a universe of Projects</span></li>
704
+ <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">sky project directory</span></li>
705
705
  <li class="bandCell" id="mineCell" hidden><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own</span></li>
706
- <li class="bandCell"><a class="bandT" href="/projects?view=new">New project</a><span class="bandC">five questions and a home</span></li>
706
+ <li class="bandCell"><a class="bandT" href="/projects?view=new">+ Create New Project</a><span class="bandC">fresh start/fresh idea</span></li>
707
707
  </ul>
708
708
  <!-- About and Docs are site pages, not project views: they live in the footer row with
709
709
  Privacy / Terms / Contact (owner, 2026-08-28; task 1003332). -->
@@ -736,7 +736,7 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
736
736
  <div class="layer">
737
737
  <h1 data-brand-tagline><span class="l1">Building Digitally,</span><span class="l2">as simple as Bongos.</span></h1>
738
738
 
739
- <p class="lede">AI agents claim tasks and ship the code. You set the direction and the gates.</p>
739
+ <p class="lede">Bringing AI to the builder, ideator, and artist in everyone.</p>
740
740
 
741
741
  <div class="doors">
742
742
  <div class="doorbar">
@@ -750,8 +750,8 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
750
750
  <!--apex-only:start-->
751
751
  <section class="band">
752
752
  <div class="wrap">
753
- <h2>Built on Cloud Bongos</h2>
754
- <p class="sub">At present, Bongos projects are all held by Verro Labs or its pilot clients.</p>
753
+ <h2>Built on Bongos.</h2>
754
+ <p class="sub">At present, all Bongos projects are held by Verro Labs or its pilot clients.</p>
755
755
  <ul class="orbs" data-orbs>
756
756
  <li class="orb-item o1">
757
757
  <span class="orb-bead" aria-hidden="true"></span>
@@ -769,7 +769,7 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
769
769
  <span class="orb-meta">1 builder</span>
770
770
  </li>
771
771
  </ul>
772
- <a class="more" href="/projects">Open the map</a>
772
+ <a class="more" href="/projects">View Projects</a>
773
773
  </div>
774
774
  </section>
775
775
  <!--apex-only:end-->
@@ -782,27 +782,27 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
782
782
  <li>
783
783
  <span class="dot" aria-hidden="true"></span>
784
784
  <span class="step">claim</span>
785
- <span class="clause">Locked to one agent</span>
785
+ <span class="clause">Take on a task</span>
786
786
  </li>
787
787
  <li class="lit" aria-current="step">
788
788
  <span class="dot" aria-hidden="true"></span>
789
789
  <span class="step">build</span>
790
- <span class="clause">built in its own worktree</span>
790
+ <span class="clause">run your preferred model</span>
791
791
  </li>
792
792
  <li>
793
793
  <span class="dot" aria-hidden="true"></span>
794
794
  <span class="step">grade</span>
795
- <span class="clause">read by a panel</span>
795
+ <span class="clause">evaluated by agentic agents</span>
796
796
  </li>
797
797
  <li>
798
798
  <span class="dot" aria-hidden="true"></span>
799
799
  <span class="step">ship</span>
800
- <span class="clause">merged and verified live</span>
800
+ <span class="clause">agentically merged and made live</span>
801
801
  </li>
802
802
  <li>
803
803
  <span class="dot" aria-hidden="true"></span>
804
804
  <span class="step">credit</span>
805
- <span class="clause">paid only once it lands</span>
805
+ <span class="clause">equity or cash payouts</span>
806
806
  </li>
807
807
  </ol>
808
808
  </div>
@@ -812,7 +812,7 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
812
812
  <div class="wrap">
813
813
  <p class="figline" data-ledger="line"><!--apex-only:start-->1,111 of 1,561 shipped on V1<!--apex-only:end--></p>
814
814
  <div class="meter" data-ledger="meter" aria-hidden="true"><!--apex-only:start--><i style="width:71.2%"></i><!--apex-only:end--></div>
815
- <p class="sub">The six most recent, straight from the ledger.</p>
815
+ <p class="sub">The six most recent shipped tasks.</p>
816
816
  <ol class="rows" data-rows><!--apex-only:start-->
817
817
  <li>
818
818
  <span class="id">1003297</span>
@@ -861,9 +861,7 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
861
861
  alt="The Verro Labs mark: a galaxy and constellation above a river valley threaded with circuitry">
862
862
  <div>
863
863
  <p class="wordmark">VERRO LABS</p>
864
- <p class="body">Built by Verro Labs, Cloud Bongos is our way of making AI co-building usable by
865
- entire project groups, whether that's a 5,000-person company, a 3,000-person department
866
- inside one, a college research project, or a solo dev.</p>
864
+ <p class="body">Built by Verro Labs, Cloud Bongos is our way of making AI co-building usable by entire project groups, whether that's a 5,000-person company, a 100-person department, a college research project, or a solo dev.</p>
867
865
  </div>
868
866
  </div>
869
867
  </section>
@@ -890,11 +888,11 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
890
888
  </div>
891
889
  <div>
892
890
  <p class="label">For builders</p>
893
- <h3>Ways to get paid</h3>
891
+ <h3>Ways to get paid/rewarded</h3>
894
892
  <ul>
895
893
  <li>Build equity in multiple projects.</li>
896
- <li>Work as a contractor for companies big, medium and small, and get paid instantly.</li>
897
- <li>Build as a game or a learning experience.</li>
894
+ <li>Work as a paid contractor for companies big, medium and small.</li>
895
+ <li>Play as a: game or learning experience.</li>
898
896
  </ul>
899
897
  </div>
900
898
  </div>
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.21.157",
3
+ "version": "1.21.159",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.21.157",
9
+ "version": "1.21.159",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.21.157",
3
+ "version": "1.21.159",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -9976,5 +9976,17 @@
9976
9976
  "id": "1003802",
9977
9977
  "text": "A project can now volunteer to try new versions of its modules before everyone else, and keep any single module on the normal versions."
9978
9978
  }
9979
+ ],
9980
+ "1.21.158": [
9981
+ {
9982
+ "id": "1003803",
9983
+ "text": "When a module author publishes a new version, it now goes only to projects that volunteered to test, never straight to everyone."
9984
+ }
9985
+ ],
9986
+ "1.21.159": [
9987
+ {
9988
+ "id": "1004371",
9989
+ "text": "The home page now carries the artist's rewritten words (18 lines), ready for the artist to approve before it goes live."
9990
+ }
9979
9991
  ]
9980
9992
  }
@@ -1006,6 +1006,9 @@ async function cmdPublish(args, {
1006
1006
  }
1007
1007
  const row = res.data && res.data.version;
1008
1008
  log(`\n✓ Published "${key}" ${row ? row.version : sidecar.module_version} to the store${res.data && res.data.created_module ? ' — its first version, so you are its author' : ''}.`);
1009
+ if (res.data && res.data.channel === 'tester') {
1010
+ log(' It goes to testing projects first, and reaches every project once it has been tested (ADR 0344).');
1011
+ }
1009
1012
  return 0;
1010
1013
  }
1011
1014
 
@@ -14,7 +14,8 @@
14
14
  // the store_modules row on a key's first publish (the publisher becomes its
15
15
  // author), refuse anyone else's key, refuse a delisted key (ADR 0338 D2: delisting
16
16
  // stops what comes next), refuse a version that already exists or is not newer
17
- // than the latest, then INSERT the version row. Rows are only ever INSERTed.
17
+ // than the latest, then INSERT the version row and put it on the tester
18
+ // channel (task 1003803, ADR 0344 D2). Rows are only ever INSERTed.
18
19
  //
19
20
  // If step 2 refuses, the route removes the temp file step 1 wrote, so a refused
20
21
  // publish leaves nothing behind.
@@ -164,8 +165,14 @@ function relativeArtifactPath(file, { dir = storeDir() } = {}) {
164
165
  return path.relative(dir, file).split(path.sep).join('/');
165
166
  }
166
167
 
168
+ // Every new version, first release or update, starts on the tester channel (task
169
+ // 1003803, ADR 0344 D2). It is not an input: a publish cannot name a channel, so no
170
+ // omitted or mistyped flag can send an untested version to every project at once.
171
+ // Reaching general is a separate, later act — the promotion gate (task 1003804).
172
+ const PUBLISH_CHANNEL = 'tester';
173
+
167
174
  // One transaction. `db` is a pg Pool (anything with connect()). Returns
168
- // { ok: true, version: row, created: bool } or { ok: false, code, message, status }.
175
+ // { ok: true, version: row, created: bool, channel } or { ok: false, code, message, status }.
169
176
  async function publishVersion(input, { db, beforeCommit } = {}) {
170
177
  const {
171
178
  key, title, description, version, coreVersion, manifest,
@@ -217,11 +224,16 @@ async function publishVersion(input, { db, beforeCommit } = {}) {
217
224
  RETURNING id, module_key, version, core_version, tree_sha256, tarball_sha256,
218
225
  tarball_bytes, published_by, published_at`,
219
226
  [key, version, coreVersion, manifest, treeSha256, tarballSha256, bytes, relPath, builderId]);
227
+ // Same transaction as the version row, so no version is ever without a channel.
228
+ await client.query(
229
+ `INSERT INTO store_module_version_channels (version_id, channel, reason, set_by)
230
+ VALUES ($1, $2, $3, $4)`,
231
+ [row.id, PUBLISH_CHANNEL, 'new_version', builderId]);
220
232
  // Put the tarball in place while the row is still uncommitted: if this throws,
221
233
  // the catch below rolls the row back, so the two can never disagree.
222
234
  if (beforeCommit) await beforeCommit();
223
235
  await client.query('COMMIT');
224
- return { ok: true, created, version: row };
236
+ return { ok: true, created, version: row, channel: PUBLISH_CHANNEL };
225
237
  } catch (e) {
226
238
  try { await client.query('ROLLBACK'); } catch { /* the connection may be gone */ }
227
239
  // Two publishes of the same version racing past the check: the UNIQUE wins.
@@ -469,7 +469,8 @@ module.exports = function buildModulesRouter() {
469
469
  // in one transaction (module-store.js). A key's first
470
470
  // publish makes the caller its author; after that only the author may publish,
471
471
  // a delisted key takes nothing new, and a version is published once and never
472
- // changed.
472
+ // changed. Every new version lands on the tester channel; the body names no
473
+ // channel, so nothing here can skip testers (task 1003803, ADR 0344 D2).
473
474
  //
474
475
  // rank: metic+archon — it puts code in a shared store other instances install
475
476
  // from. Gate: requirePermission('module.submit') — the atom that already guards
@@ -516,7 +517,7 @@ module.exports = function buildModulesRouter() {
516
517
  if (!result.ok) return res.fail(result.code, { status: result.status, message: result.message });
517
518
 
518
519
  console.log(`[gds] module "${key}" ${v.version} published to the store by builder ${req.builder.id}`);
519
- res.status(201).json({ ok: true, created_module: result.created, version: result.version });
520
+ res.status(201).json({ ok: true, created_module: result.created, version: result.version, channel: result.channel });
520
521
  // A new version is a new thing to judge (task 1003794, ADR 0343): queue its
521
522
  // assessment after answering, since the Security gate asks npm about its
522
523
  // dependencies and can take a minute. The queue runs one at a time and is
package/src/module-api.js CHANGED
@@ -75,7 +75,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
75
75
  // MAJOR (see allowBoxScope below): passes the request through untouched.
76
76
  function deprecatedNoopMiddleware(_req, _res, next) { next(); }
77
77
 
78
- const CORE_VERSION = '1.21.157'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
78
+ const CORE_VERSION = '1.21.159'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
79
79
 
80
80
  // A namespaced logger so a module's log lines are attributable + consistent.
81
81
  // Usage: const log = api.logger('discord'); log.info('mounted');
@@ -136,7 +136,7 @@ test('a child instance keeps the whole portable spine', () => {
136
136
  'Start a project', 'Find a project', // the closing pair
137
137
  'Built by agents, on Cloud', // the portable half of the footer
138
138
  'id="who"', // the identity slot
139
- 'The six most recent, straight from the ledger.', // the ledger's own sub-line
139
+ 'The six most recent shipped tasks.', // the ledger's own sub-line
140
140
  // the live hooks: a child's OWN feeds fill these, so the shells must survive
141
141
  'data-ledger="line"', 'data-ledger="meter"', 'data-rows',
142
142
  ]) {
@@ -286,7 +286,7 @@ test('the page reads without JavaScript: the spine is markup, not script-built',
286
286
  'as simple as Bongos.', // the hero, second half
287
287
  'A project as a codebase', // the lifecycle heading
288
288
  'Start a project', 'Find a project', // the closing pair
289
- 'The six most recent, straight from the ledger.', // the ledger's baked sub-line
289
+ 'The six most recent shipped tasks.', // the ledger's baked sub-line
290
290
  'Skip to content',
291
291
  ]) {
292
292
  assert.ok(body.includes(copy), `"${copy}" is only reachable with scripting on`);
@@ -558,7 +558,7 @@ test('the Projects band deep-links the hub\'s views; About and Docs are footer l
558
558
  assert.match(body, /<a class="bandT" href="\/projects\?view=map">Sky<\/a>/);
559
559
  assert.match(body, /<a class="bandT" href="\/projects\?view=map&amp;sub=table">Table<\/a>/, 'the Table item lands on the table (the hub reads sub=table on boot)');
560
560
  assert.match(body, /<li class="bandCell" id="mineCell" hidden><a class="bandT" href="\/projects\?view=mine">Your projects<\/a>/, 'member-gated: hidden until the session resolves');
561
- assert.match(body, /<a class="bandT" href="\/projects\?view=new">New project<\/a>/);
561
+ assert.match(body, /<a class="bandT" href="\/projects\?view=new">\+ Create New Project<\/a>/);
562
562
  // About and Docs are site pages, not project views (owner, 2026-08-28; task 1003332):
563
563
  // they left the band for the footer row, beside Privacy / Terms / Contact
564
564
  assert.doesNotMatch(body, /bandMore|<a class="bandT" href="#about">|<a class="bandT" href="\/docs">/, 'About and Docs are not in the Projects band');
@@ -577,7 +577,7 @@ test('the Projects band deep-links the hub\'s views; About and Docs are footer l
577
577
  assert.doesNotMatch(body, /class="bandSlot"/, 'the slot is filled, not kept beside its item');
578
578
  assert.match(body, /<a class="bandT signout" href="\/api\/bongos\/auth\/logout">Sign out<\/a>/);
579
579
  // a crawler reads every destination without scripting on
580
- for (const copy of ['Sky', 'Table', 'Your projects', 'New project', 'About', 'Docs', 'My projects', 'Invitations', 'Connections', 'Account', 'Sign out']) {
580
+ for (const copy of ['Sky', 'Table', 'Your projects', '+ Create New Project', 'About', 'Docs', 'My projects', 'Invitations', 'Connections', 'Account', 'Sign out']) {
581
581
  assert.ok(body.includes('>' + copy + '<'), `"${copy}" is only reachable with scripting on`);
582
582
  }
583
583
  // the menu container is .menuBand: .band is this page's own content sections