@bongos/core 1.20.76 → 1.20.78

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.
Files changed (62) hide show
  1. package/.bongos-core.json +93 -63
  2. package/clients/bongos-client/README.md +1 -1
  3. package/clients/bongos-client/bongos-client.global.js +2 -0
  4. package/clients/bongos-client/index.cjs +2 -0
  5. package/clients/bongos-client/index.d.ts +3 -0
  6. package/clients/bongos-client/index.mjs +2 -0
  7. package/docs/adr/0136-update-channel-subscription-policy.md +1 -1
  8. package/docs/adr/0360-bongos-follows-every-candidate-every-other-project-follows-releases.md +66 -0
  9. package/docs/adr/README.md +1 -0
  10. package/docs/api/openapi.json +70 -3
  11. package/docs/api-reference.md +3 -2
  12. package/docs/copy-inventory.md +531 -458
  13. package/docs/copy-registry.json +1269 -589
  14. package/docs/module-api-changelog.md +4 -0
  15. package/docs/page-inventory.json +11 -1
  16. package/docs/page-readings.json +1208 -1082
  17. package/docs/recipes/upgrading-the-core.md +11 -2
  18. package/modules/copy-desk/artist-stats.js +15 -1
  19. package/modules/copy-desk/module.json +1 -1
  20. package/modules/copy-desk/page-status.js +41 -0
  21. package/modules/copy-desk/routes/copy-desk-artist.js +44 -0
  22. package/modules/copy-desk/tests/copy_no_cms.mjs +11 -2
  23. package/modules/hall-ui/public/deploy.states.json +1 -1
  24. package/modules/hall-ui/public/profile-crafts.js +231 -0
  25. package/modules/hall-ui/public/profile.css +60 -0
  26. package/modules/hall-ui/public/profile.html +31 -12
  27. package/modules/hall-ui/public/profile.js +180 -75
  28. package/modules/hall-ui/public/profile.states.json +34 -0
  29. package/modules/hall-ui/public/sky-draw.js +66 -39
  30. package/modules/hall-ui/public/sky-interaction.js +1 -1
  31. package/modules/hall-ui/public/sky-panel.js +1 -1
  32. package/modules/hall-ui/public/thinking.css +52 -24
  33. package/modules/hall-ui/records/profile-roles.md +18 -0
  34. package/modules/npm-release/public/work.js +72 -0
  35. package/modules/npm-release/work.js +67 -1
  36. package/modules/provisioning/planet-physics.js +8 -0
  37. package/modules/provisioning/soft-limits.js +9 -0
  38. package/modules/public-landing/public/projects.html +579 -37
  39. package/modules/public-landing/public/projects.probes.json +6 -3
  40. package/modules/public-landing/public/projects.states.json +20 -14
  41. package/modules/ui-design/kit/serve.js +26 -3
  42. package/package-lock.json +2 -2
  43. package/package.json +1 -1
  44. package/release-notes.json +24 -0
  45. package/scripts/gds/update-channel.js +68 -1
  46. package/scripts/gds/update-sweep.js +100 -4
  47. package/scripts/migrate.sh +6 -2
  48. package/src/module-api.js +1 -1
  49. package/tests/hall_sky.mjs +77 -0
  50. package/tests/helpers.mjs +32 -7
  51. package/tests/migrate_applied_check.mjs +94 -0
  52. package/tests/npm_release_page.mjs +67 -0
  53. package/tests/npm_release_work.mjs +82 -0
  54. package/tests/profile_activity.mjs +23 -15
  55. package/tests/profile_role_headline.mjs +4 -4
  56. package/tests/profile_role_tabs.mjs +163 -0
  57. package/tests/projects_hub_app_step.mjs +4 -1
  58. package/tests/provisioning_planet_physics.mjs +24 -2
  59. package/tests/update_channel.mjs +80 -1
  60. package/tests/update_subscription_engine.mjs +99 -0
  61. package/tests/wizard_physics.mjs +11 -4
  62. package/tests/wizard_physics_more.mjs +470 -0
@@ -0,0 +1,66 @@
1
+ # ADR 0360 — Bongos follows every candidate; every other project follows releases
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-09-26
5
+ - **Task:** [task 1004297](https://cloudbongos.com/builders#/task/1004297) (goal 1000090 — BONGOS-V2), split out of [task 1002622](https://cloudbongos.com/builders#/task/1002622) §4.
6
+ - **Deciders:** the owner, Lars. His decision, confirmed 2026-09-26: "Bongos takes every candidate automatically."
7
+ - **Amends:** [ADR 0136](0136-update-channel-subscription-policy.md) (the update-channel subscription policy). It adds a second axis and a retry hold. The channels, the opt-in roster, autonomy-gating and auto-rollback are unchanged.
8
+
9
+ ## Context
10
+
11
+ Other projects will soon receive only the versions the owner presses Release on (task 1004298). Bongos must not wait on that button: it is the project every change is built in, and running each version first is what gives Release its evidence.
12
+
13
+ Today the machinery exists but is slow. The update sweep upgraded cloudbongos.com from 1.19.1030 to 1.19.1033 at 00:22 UTC on 2026-09-26, and nothing else moved it that day. Its timer on the control plane still fires daily, although task 1003674 declared a 15-minute cadence; installing that is [task 1003969](https://cloudbongos.com/builders#/task/1003969), an operator step on the host.
14
+
15
+ The site served 1.19.1033 all afternoon while 1.19.1034–1.19.1039 were published. The deploy page listed that work as "published, not running here" and did not say that the sweep was the reason.
16
+
17
+ ## Decision
18
+
19
+ ### D1 — A per-instance FOLLOW beside the channel
20
+
21
+ `config/update-subscriptions.json` entries carry `follow`:
22
+
23
+ - **`released`**, the default for every project. It takes only versions at or below the registry's `latest` label, which is what the owner has released to other projects.
24
+ - **`candidates`**, for the platform's own hall only. It takes every version as soon as it is published.
25
+
26
+ The channel still bounds how far a jump may go (patch, minor, never a major). The follow bounds which versions exist to jump to. An unknown value reads as `released`, the follow that takes fewer versions, the same way an unknown channel reads as `patch`.
27
+
28
+ ### D2 — Released means the `latest` label, and an unreadable label moves nobody
29
+
30
+ `readReleaseTags` reads `npm view @bongos/core dist-tags`. It is a separate read, because `listAvailableVersions`' output shape is relied on by the deploy door and by `bongos upgrade`. An instance that follows releases and whose label cannot be read is **skipped** and logged. It is never upgraded on a guess.
31
+
32
+ Until task 1004298 publishes candidates under a label of their own, `latest` is the newest version and both follows pick the same target. The axis lands first so that the split changes nothing for Bongos.
33
+
34
+ ### D3 — Cadence is the lag
35
+
36
+ The sweep's timer period is the delay between a merge and Bongos serving it; CI publishes within about two minutes. The declared cadence is 15 minutes, with a floor of about 5 minutes (ADR 0136, task 1003674). Nothing in the core can install a host timer, so the declaration and the recipe are the core's half. Task 1003969 installs it on the control plane.
37
+
38
+ ### D4 — A version that failed here is held for a day
39
+
40
+ At a daily cadence a version that failed its health check was retried once a day. At 15 minutes the same version would be installed, fail, restart the service and roll back four times an hour until something newer was published. So when an upgrade fails and the version did not go in, the sweep records it for that instance in its own config home (`~/.config/<instance>/core-update-refused.json`, never inside an instance's tree, where it would wedge the lane).
41
+
42
+ For a day the sweep skips that version and says so. Any newer version is taken at once, because it is the fix. The hold expires, so a transient failure is retried rather than refused forever.
43
+
44
+ ### D5 — The deploy page says whether it is happening
45
+
46
+ The npm-release section of the platform hall's `/deploy` gains **Upgrades on this hall**, read from the `core_upgrades` ledger, newest first:
47
+
48
+ - **Who moved it.** An Upgrade pressed on `/deploy`, the automatic update, or "on the server" when the ledger cannot tell a sweep from a shell.
49
+ - **Rolled-back moves**, flagged with their reason. A rollback as the last move is a warning.
50
+ - **A published version waiting more than 30 minutes**, twice the declared cadence. The page calls it "the automatic update may have stopped", which is what the afternoon of 2026-09-26 was.
51
+
52
+ ## Rejected
53
+
54
+ - **A second, candidate-only runner.** One sweep over one roster, with the difference expressed as data on the entry, keeps one code path and one set of safety rules.
55
+ - **CI pushing the upgrade to the box.** It would move the act across the trust boundary ADR 0293 D1 keeps on the control plane.
56
+ - **Holding a failed version until a human clears it.** That trades an outage generator for a silently frozen lane. The day-long hold plus "a newer version is taken at once" covers the real case, where the fix is the next merge.
57
+
58
+ ## Consequences
59
+
60
+ - **Owner or operator step before task 1004298 ships:** set the platform's roster entry to `"follow": "candidates"`. Otherwise, the day candidates stop carrying `latest`, the platform stops taking them.
61
+ - **Operator step (task 1003969):** install the timer at `OnCalendar=*:0/15`. Until then the lane still runs once a day, and the deploy page will say so.
62
+ - **The platform restarts on each new version**, roughly one every merge, with the existing health check and auto-rollback as the net.
63
+ - **Proof:**
64
+ - `tests/update_channel.mjs`: follow normalisation, `versionsForFollow`, `readReleaseTags`, the roster field, and composition with the channel.
65
+ - `tests/update_subscription_engine.mjs`: `followTarget` over the real channel math, the fail-closed skip, the old-core fallback, and the hold (skip, expiry, a newer version still taken, the record kept outside the instance tree).
66
+ - `tests/npm_release_work.mjs` and `tests/npm_release_page.mjs`: the ledger reading, the rollback, the waiting alarm, and their rendering.
@@ -478,3 +478,4 @@ These 20 numbers are each shared by exactly two files. They are **accepted histo
478
478
  | 0357 | [**The update rule set on /deploy is the one the sweep follows** ([task 1004468](https://cloudbongos.com/builders#/task/1004468), goal 1000090 — BONGOS-V2, owner's ruling 2026-09-30). Amends [ADR 0136](0136-update-channel-subscription-policy.md)'s rejected DB-column alternative. **D1:** for a roster entry whose slug matches a `provisioning_instances` row, the unattended sweep uses that row's `update_channel` (set on /deploy, task 1004445). **D2:** the roster's `channel` is only the fallback — no matching row, or the database unreadable; enrollment and topology stay in the roster. **D3:** the sweep logs each entry's channel and its source, naming an overridden roster value. **D4:** read over psql from the sweep's own `DATABASE_URL`/`PGDATABASE`, never an entry's `env`. **D5:** nothing is copied; a row never changed is `patch`. Delivery to cloudbongos.com waits on the frozen sweep checkout (task 1004307). Rejected: roster stays in charge; stricter-of-the-two; copying roster values into rows.](0357-the-update-rule-set-on-deploy-is-the-one-the-sweep-follows.md) | distribution / updates |
479
479
  | 0358 | [**A hall wears a look, and its night takes a tint of it** ([task 1004421](https://cloudbongos.com/builders#/task/1004421), goal 1000121 — BV2.PS06; owner D2 + D8, 2026-09-30). Amends [ADR 0219](0219-a-look-is-a-branding-pack-the-style-library.md) (a look could not carry a dark ground) and DESIGN.md's pure-black rule, for halls only. **D1:** the night tint is a formula over the thirteen — the four dark grounds take 5–6% of the look's accent (src/night-tint.js), emitted after the sheet as both dark twins; no token added. **D2:** on by default, and only a chosen look turns it on — a hall with no look is unchanged. **D3:** the apex and hub stay pure black (ADR 0204). **D4:** a custom look is ONE accent for both modes, its lightness nudged until every pair the hall paints with it reads (lookAdjustAccent, client copy test-pinned). **D5:** look + night_tint join the provisioning settings vocabulary; the accent and logo address ride as companion env; the instance resolves the look from the style library. **D6:** a logo is PNG/JPEG/WebP ≤256 KB, magic-sniffed, never SVG, served content-addressed; it is the hall mark and the favicon. Rejected: per-look dark palettes, two custom accents, refusing an unreadable accent, sending the palette over env.](0358-a-hall-wears-a-look-and-its-night-takes-a-tint.md) | hall / branding / design world |
480
480
  | 0359 | [**Nobody sets a module's score by hand; a Metic+ person can ask for a re-check** ([task 1003796](https://cloudbongos.com/builders#/task/1003796) · goal 1000091, criterion `wa5-quality-assessed`). Amends [ADR 0343](0343-a-module-score-is-a-security-gate-then-an-average-of-visible-parts.md) D6 and [ADR 0347](0347-every-store-module-ships-a-how-to.md) D5 on the owner's ruling: there is no score override. A score only ever comes from its signals. Instead `POST /store/modules/:key/versions/:version/reassess { reason }`, gated by the new `module.assessment.rerun` atom (metic floor, granted to metic + archon by `government_021`), queues the same assessment a publish runs. A reason is required and nothing else is accepted. The delist (task 1003797) is unchanged.](0359-nobody-sets-a-module-score-by-hand-metic-can-ask-for-a-re-check.md) | module store / assessment / permissions |
481
+ | 0360 | [**Bongos follows every candidate; every other project follows releases** ([task 1004297](https://cloudbongos.com/builders#/task/1004297), goal 1000090 — the owner's 2026-09-26 decision that the Bongos hall takes every candidate automatically). Amends ADR 0136. **D1:** a per-instance `follow` beside the channel — `released` (default: at or below the registry's `latest` label) or `candidates` (every version, the platform hall only). **D2:** released is the `latest` dist-tag, read separately; an unreadable label skips the instance, never a guess. **D3:** the timer period is the lag — 15 min declared, installed by task 1003969. **D4:** a version that failed here is held for a day per instance (recorded in the sweep's config home), while any newer version is taken at once — no restart loop at a 15-minute cadence. **D5:** the deploy page's "Upgrades on this hall" — the core_upgrades ledger, rollbacks flagged, and a published version waiting past 30 min said to be the automation stopping. Rejected: a second runner, CI pushing to the box, a hold only a human clears.](0360-bongos-follows-every-candidate-every-other-project-follows-releases.md) | update channel / deploy / core update |
@@ -4018,6 +4018,58 @@
4018
4018
  ]
4019
4019
  }
4020
4020
  },
4021
+ "/copy-desk/artists/{id}/pages": {
4022
+ "get": {
4023
+ "operationId": "get_copy_desk_artists_id_pages",
4024
+ "tags": [
4025
+ "copy-desk"
4026
+ ],
4027
+ "summary": "GET /copy-desk/artists/:id/pages",
4028
+ "description": "any signed-in builder may read any artist's approved pages, as the profile's other Activity tabs are; a stranger gets the sign-in line.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
4029
+ "x-rank": "any-builder",
4030
+ "x-source": "modules/copy-desk/routes/copy-desk-artist.js",
4031
+ "parameters": [
4032
+ {
4033
+ "name": "id",
4034
+ "in": "path",
4035
+ "required": true,
4036
+ "schema": {
4037
+ "type": "string"
4038
+ },
4039
+ "description": "Path parameter `id`."
4040
+ }
4041
+ ],
4042
+ "responses": {
4043
+ "200": {
4044
+ "description": "Success.",
4045
+ "content": {
4046
+ "application/json": {
4047
+ "schema": {
4048
+ "$ref": "#/components/schemas/GetCopyDeskArtistsIdPagesResponse"
4049
+ }
4050
+ }
4051
+ }
4052
+ },
4053
+ "400": {
4054
+ "$ref": "#/components/responses/BadRequest"
4055
+ },
4056
+ "401": {
4057
+ "$ref": "#/components/responses/Unauthorized"
4058
+ },
4059
+ "403": {
4060
+ "$ref": "#/components/responses/Forbidden"
4061
+ },
4062
+ "404": {
4063
+ "$ref": "#/components/responses/NotFound"
4064
+ }
4065
+ },
4066
+ "security": [
4067
+ {
4068
+ "builderSession": []
4069
+ }
4070
+ ]
4071
+ }
4072
+ },
4021
4073
  "/copy-desk/flags": {
4022
4074
  "post": {
4023
4075
  "operationId": "post_copy_desk_flags",
@@ -23560,6 +23612,21 @@
23560
23612
  "count"
23561
23613
  ]
23562
23614
  },
23615
+ "GetCopyDeskArtistsIdPagesResponse": {
23616
+ "type": "object",
23617
+ "properties": {
23618
+ "rows": {},
23619
+ "total": {},
23620
+ "inventory_known": {},
23621
+ "page": {}
23622
+ },
23623
+ "required": [
23624
+ "rows",
23625
+ "total",
23626
+ "inventory_known",
23627
+ "page"
23628
+ ]
23629
+ },
23563
23630
  "GetCoreUpdateResponse": {
23564
23631
  "type": "object",
23565
23632
  "properties": {
@@ -31226,9 +31293,9 @@
31226
31293
  "description": "A required dependency/feature is not configured or is temporarily down."
31227
31294
  }
31228
31295
  },
31229
- "x-endpoint-count": 488,
31230
- "x-schema-count": 518,
31296
+ "x-endpoint-count": 489,
31297
+ "x-schema-count": 519,
31231
31298
  "x-undocumented-bodies": 12,
31232
- "x-response-schemas": 346,
31299
+ "x-response-schemas": 347,
31233
31300
  "x-generated-by": "scripts/gds/gen-api-docs.js"
31234
31301
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Bongos API reference
4
4
 
5
- > **Generated from the live route files** — the route file is authoritative. 488 endpoints across 89 route files.
5
+ > **Generated from the live route files** — the route file is authoritative. 489 endpoints across 90 route files.
6
6
  > Machine-readable spec: [`docs/api/openapi.json`](api/openapi.json) (OpenAPI 3.1). Rendered docs site: **`/docs`** (e.g. `cloudbongos.com/docs`).
7
7
 
8
8
  Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust-boundary-server-enforced-permissions.md)): `public` < `any-builder` < `metic+archon` < `archon`.
@@ -180,11 +180,12 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
180
180
  | GET | `/api/bongos/connections/requests` | `any-builder` | — | MY pending requests, both directions (own data). |
181
181
  | GET | `/api/bongos/connections/suggestions` | `any-builder` | — | "builders you may know" (R21, task 1002297; ADR 0202 D5). |
182
182
 
183
- ## `copy-desk` (19)
183
+ ## `copy-desk` (20)
184
184
 
185
185
  | Method | Path | Rank | Body | Description |
186
186
  |---|---|---|---|---|
187
187
  | GET | `/api/bongos/copy-desk/approvals` | `any-builder` | — | GET /copy-desk/approvals — every round waiting for its artist, oldest applied first, with its position ("1 of 2"), the lines it rewrote (… |
188
+ | GET | `/api/bongos/copy-desk/artists/:id/pages` | `any-builder` | — | any signed-in builder may read any artist's approved pages, as the profile's other Activity tabs are; a stranger gets the sign-in line. |
188
189
  | POST | `/api/bongos/copy-desk/flags` | `any-builder` | `scope`, `surface`, `string_id`, `reason`, `kind` | ------------------------------------------------------------------------- POST /copy-desk/flags — file a flag. |
189
190
  | POST | `/api/bongos/copy-desk/flags/:id/close` | `any-builder` | `status`, `resolution_note`, `resolved_task_id` | ------------------------------------------------------------------------- POST /copy-desk/flags/:id/close — resolve or dismiss. |
190
191
  | GET | `/api/bongos/copy-desk/next` | `any-builder` | — | ------------------------------------------------------------------------- GET /copy-desk/next — the Tweak/CopyWrite Flow's recommendation… |