@bongos/core 1.19.1041 → 1.19.1043

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 (87) hide show
  1. package/.bongos-core.json +127 -87
  2. package/clients/bongos-client/README.md +1 -1
  3. package/clients/bongos-client/bongos-client.global.js +6 -0
  4. package/clients/bongos-client/index.cjs +6 -0
  5. package/clients/bongos-client/index.d.ts +8 -1
  6. package/clients/bongos-client/index.mjs +6 -0
  7. package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +14 -0
  8. package/docs/adr/0339-a-projects-owner-upgrades-it-and-a-hosted-project-hands-off-to-the-hub-door.md +1 -0
  9. package/docs/adr/0340-every-hall-takes-its-update-from-settings-and-deploy-is-the-platform-halls-page.md +64 -0
  10. package/docs/adr/README.md +1 -0
  11. package/docs/api/openapi.json +109 -7
  12. package/docs/api-reference.md +9 -2
  13. package/docs/copy-inventory.md +79 -59
  14. package/docs/copy-registry.json +248 -68
  15. package/docs/file-map.md +1 -1
  16. package/docs/module-api-changelog.md +12 -0
  17. package/docs/modules-contract.md +4 -1
  18. package/modules/hall-ui/public/atlas.html +1 -1
  19. package/modules/hall-ui/public/blockers.html +1 -1
  20. package/modules/hall-ui/public/board-room.html +1 -1
  21. package/modules/hall-ui/public/collab.html +1 -1
  22. package/modules/hall-ui/public/copy-desk.html +1 -1
  23. package/modules/hall-ui/public/deploy.html +1 -1
  24. package/modules/hall-ui/public/diagrams.html +1 -1
  25. package/modules/hall-ui/public/drachmae.html +1 -1
  26. package/modules/hall-ui/public/fleet.html +1 -1
  27. package/modules/hall-ui/public/gate.html +1 -1
  28. package/modules/hall-ui/public/goals.html +1 -1
  29. package/modules/hall-ui/public/government.html +1 -1
  30. package/modules/hall-ui/public/idea.html +1 -1
  31. package/modules/hall-ui/public/ideas.html +1 -1
  32. package/modules/hall-ui/public/index.html +1 -1
  33. package/modules/hall-ui/public/modules.html +1 -1
  34. package/modules/hall-ui/public/palette.js +1 -0
  35. package/modules/hall-ui/public/people.html +1 -1
  36. package/modules/hall-ui/public/primer.html +1 -1
  37. package/modules/hall-ui/public/profile.html +1 -1
  38. package/modules/hall-ui/public/project-settings.html +1 -1
  39. package/modules/hall-ui/public/ranks.html +1 -1
  40. package/modules/hall-ui/public/roadmap.html +1 -1
  41. package/modules/hall-ui/public/roster.html +1 -1
  42. package/modules/hall-ui/public/sessions.html +1 -1
  43. package/modules/hall-ui/public/settings-software-update.js +194 -0
  44. package/modules/hall-ui/public/settings.css +39 -0
  45. package/modules/hall-ui/public/settings.html +24 -2
  46. package/modules/hall-ui/public/settings.js +5 -0
  47. package/modules/hall-ui/public/settings.states.json +2 -1
  48. package/modules/hall-ui/public/shell.js +25 -39
  49. package/modules/hall-ui/public/studio.html +1 -1
  50. package/modules/hall-ui/public/style.css +4 -0
  51. package/modules/hall-ui/public/task.css +6 -0
  52. package/modules/hall-ui/public/task.html +2 -2
  53. package/modules/hall-ui/public/task.js +17 -0
  54. package/modules/hall-ui/public/watch.html +1 -1
  55. package/modules/hall-ui/public/work.html +1 -1
  56. package/modules/hall-ui/records/panel-family.md +9 -0
  57. package/modules/hall-ui/records/record-family.md +2 -0
  58. package/modules/npm-release/module.json +8 -2
  59. package/modules/npm-release/public/task-widget.js +79 -0
  60. package/modules/npm-release/public/work.js +8 -3
  61. package/modules/npm-release/routes/task-where.js +48 -0
  62. package/modules/npm-release/work.js +78 -11
  63. package/package-lock.json +2 -2
  64. package/package.json +1 -1
  65. package/release-notes.json +16 -0
  66. package/scripts/gds/exec-path-guard.js +1 -1
  67. package/scripts/gds/fitness.js +7 -0
  68. package/scripts/gds/main-audit.js +204 -7
  69. package/scripts/gds/seam-wiring-guard.js +4 -2
  70. package/scripts/hall-preview/server.js +14 -1
  71. package/{modules/npm-release/registry.js → src/bongos/package-registry.js} +14 -7
  72. package/src/bongos/routes/core-update.js +65 -3
  73. package/src/bongos/serve-internal.js +35 -4
  74. package/src/bongos/software-update.js +127 -0
  75. package/src/module-api.js +10 -1
  76. package/src/module-loader/loader.js +13 -3
  77. package/tests/core_upgrade_owner_door.mjs +27 -18
  78. package/tests/hall_record_world.mjs +23 -1
  79. package/tests/helpers.mjs +92 -0
  80. package/tests/main_audit_attestation.mjs +238 -0
  81. package/tests/module_api.mjs +1 -0
  82. package/tests/module_loader.mjs +27 -0
  83. package/tests/nav_permission_atoms.mjs +1 -1
  84. package/tests/npm_release_page.mjs +11 -1
  85. package/tests/npm_release_where.mjs +323 -0
  86. package/tests/npm_release_work.mjs +9 -94
  87. package/tests/software_update.mjs +449 -0
@@ -5,7 +5,7 @@ A **generated**, zero-dependency typed client for the Bongos API — produced fr
5
5
  by hand; it regenerates when the spec changes, so it can never drift from the routes.
6
6
 
7
7
  - API version: **v1** (served at `/api/bongos/v1`)
8
- - 440 operations across 67 resource groups
8
+ - 442 operations across 68 resource groups
9
9
 
10
10
  ## Use it from your project
11
11
 
@@ -745,6 +745,8 @@ function createClient(opts = {}) {
745
745
  postMyProjectsJoin: (args) => request("POST", "/my-projects/join", { hasBody: true }, args),
746
746
  },
747
747
  "npmRelease": {
748
+ // GET /npm-release/task/{id} — rank: any-builder — GET /npm-release/task/:id
749
+ getNpmReleaseTaskId: (args) => request("GET", "/npm-release/task/{id}", { hasBody: false }, args),
748
750
  // GET /npm-release/work — rank: archon — GET /npm-release/work
749
751
  getNpmReleaseWork: (args) => request("GET", "/npm-release/work", { hasBody: false }, args),
750
752
  },
@@ -948,6 +950,10 @@ function createClient(opts = {}) {
948
950
  // GET /sky/mine — rank: any-builder — GET /sky/mine
949
951
  getSkyMine: (args) => request("GET", "/sky/mine", { hasBody: false }, args),
950
952
  },
953
+ "softwareUpdate": {
954
+ // GET /software-update — rank: any-builder — GET /software-update
955
+ getSoftwareUpdate: (args) => request("GET", "/software-update", { hasBody: false }, args),
956
+ },
951
957
  "specialities": {
952
958
  // GET /specialities — rank: any-builder — GET /specialities
953
959
  getSpecialities: (args) => request("GET", "/specialities", { hasBody: false }, args),
@@ -744,6 +744,8 @@ function createClient(opts = {}) {
744
744
  postMyProjectsJoin: (args) => request("POST", "/my-projects/join", { hasBody: true }, args),
745
745
  },
746
746
  "npmRelease": {
747
+ // GET /npm-release/task/{id} — rank: any-builder — GET /npm-release/task/:id
748
+ getNpmReleaseTaskId: (args) => request("GET", "/npm-release/task/{id}", { hasBody: false }, args),
747
749
  // GET /npm-release/work — rank: archon — GET /npm-release/work
748
750
  getNpmReleaseWork: (args) => request("GET", "/npm-release/work", { hasBody: false }, args),
749
751
  },
@@ -947,6 +949,10 @@ function createClient(opts = {}) {
947
949
  // GET /sky/mine — rank: any-builder — GET /sky/mine
948
950
  getSkyMine: (args) => request("GET", "/sky/mine", { hasBody: false }, args),
949
951
  },
952
+ "softwareUpdate": {
953
+ // GET /software-update — rank: any-builder — GET /software-update
954
+ getSoftwareUpdate: (args) => request("GET", "/software-update", { hasBody: false }, args),
955
+ },
950
956
  "specialities": {
951
957
  // GET /specialities — rank: any-builder — GET /specialities
952
958
  getSpecialities: (args) => request("GET", "/specialities", { hasBody: false }, args),
@@ -61,7 +61,7 @@ export interface GetConnectionsDegreeHandleResponse { handle: unknown; degree: u
61
61
  export interface GetConnectionsRequestsResponse { incoming: unknown; outgoing: unknown; incoming_count: unknown; outgoing_count: unknown }
62
62
  export interface GetConnectionsResponse { connections: unknown; count: unknown }
63
63
  export interface GetConnectionsSuggestionsResponse { suggestions: unknown; count: unknown }
64
- export interface GetCoreUpdateResponse { ok: boolean; update: unknown; deploy_url: unknown }
64
+ export interface GetCoreUpdateResponse { ok: boolean; update: unknown }
65
65
  export interface GetCoreUpgradesResponse { ok: boolean; running: unknown; limit: unknown; upgrades: unknown }
66
66
  export interface GetDiscordChannelsPlanResponse { ok: boolean; guild_id: unknown; op_count: unknown; ops: unknown; warnings: unknown }
67
67
  export interface GetDiscordChannelsSnapshotResponse { ok: boolean; guild_id: unknown; config: unknown; warnings: unknown }
@@ -157,6 +157,7 @@ export interface GetSecurityScansResponse { scans: unknown }
157
157
  export interface GetSessionsIdResponse { session: unknown }
158
158
  export interface GetSessionsMineResponse { sessions: unknown; count: unknown }
159
159
  export interface GetSessionsSearchResponse { sessions: unknown; count: unknown; total: unknown; totals: unknown; limit: unknown; offset: unknown; session_types: unknown }
160
+ export interface GetSoftwareUpdateResponse { ok: boolean; update: unknown; door: unknown; can_update: unknown }
160
161
  export interface GetSpecialitiesIdDocumentsResponse { documents: unknown }
161
162
  export interface GetSpecialitiesIdResponse { speciality: unknown }
162
163
  export interface GetSpecialitiesOfferedResponse { suggestions: unknown }
@@ -1159,6 +1160,8 @@ export interface BongosClient {
1159
1160
  postMyProjectsJoin(args: RequestArgs & { body: PostMyProjectsJoinRequest }): Promise<PostMyProjectsJoinResponse>;
1160
1161
  };
1161
1162
  "npmRelease": {
1163
+ /** GET /npm-release/task/{id} — rank: any-builder */
1164
+ getNpmReleaseTaskId(args?: RequestArgs): Promise<ApiResponse>;
1162
1165
  /** GET /npm-release/work — rank: archon */
1163
1166
  getNpmReleaseWork(args?: RequestArgs): Promise<ApiResponse>;
1164
1167
  };
@@ -1362,6 +1365,10 @@ export interface BongosClient {
1362
1365
  /** GET /sky/mine — rank: any-builder */
1363
1366
  getSkyMine(args?: RequestArgs): Promise<ApiResponse>;
1364
1367
  };
1368
+ "softwareUpdate": {
1369
+ /** GET /software-update — rank: any-builder */
1370
+ getSoftwareUpdate(args?: RequestArgs): Promise<GetSoftwareUpdateResponse>;
1371
+ };
1365
1372
  "specialities": {
1366
1373
  /** GET /specialities — rank: any-builder */
1367
1374
  getSpecialities(args?: RequestArgs): Promise<GetSpecialitiesResponse>;
@@ -741,6 +741,8 @@ export function createClient(opts = {}) {
741
741
  postMyProjectsJoin: (args) => request("POST", "/my-projects/join", { hasBody: true }, args),
742
742
  },
743
743
  "npmRelease": {
744
+ // GET /npm-release/task/{id} — rank: any-builder — GET /npm-release/task/:id
745
+ getNpmReleaseTaskId: (args) => request("GET", "/npm-release/task/{id}", { hasBody: false }, args),
744
746
  // GET /npm-release/work — rank: archon — GET /npm-release/work
745
747
  getNpmReleaseWork: (args) => request("GET", "/npm-release/work", { hasBody: false }, args),
746
748
  },
@@ -944,6 +946,10 @@ export function createClient(opts = {}) {
944
946
  // GET /sky/mine — rank: any-builder — GET /sky/mine
945
947
  getSkyMine: (args) => request("GET", "/sky/mine", { hasBody: false }, args),
946
948
  },
949
+ "softwareUpdate": {
950
+ // GET /software-update — rank: any-builder — GET /software-update
951
+ getSoftwareUpdate: (args) => request("GET", "/software-update", { hasBody: false }, args),
952
+ },
947
953
  "specialities": {
948
954
  // GET /specialities — rank: any-builder — GET /specialities
949
955
  getSpecialities: (args) => request("GET", "/specialities", { hasBody: false }, args),
@@ -131,6 +131,20 @@ live reference instance where the Builder 25 incident happened, so it carries it
131
131
  - The layer table above stands: Layer 1 is still not a trust boundary; the post-push main audit —
132
132
  since task 1002612 a CI job on every push to `main` — remains the authoritative layer.
133
133
 
134
+ ## The un-spoofable signal: attestation pass, flag-only (2026-09-26, task 1001433)
135
+
136
+ The residual in the #863-followup section, that the git author name can be typed, gets its
137
+ closure. The owner chose to build it on the mark the server already writes: the
138
+ `gate-author-trust` commit status, posted on a ship's pushed tip only after the server has
139
+ resolved the builder's CLI session to a Metic+ rank (ADR 0058). `main-audit.js` now traces
140
+ each permission-sensitive commit to the pull request that brought it onto main (the second
141
+ parent of its first-parent merge). It requires that head to carry a success of that context,
142
+ **posted by the server's own GitHub identity**; anyone with write access can post a status
143
+ of the same name, so the creator is the part checked. By the owner's ruling it is
144
+ **flag-only**: an unattested commit is a `review` finding and never fails the audit or the
145
+ deploy gate. Moving it to blocking is a later, separate decision. Measured against the last
146
+ 60 mainline merges: 32 protected commits, 0 flagged.
147
+
134
148
  ## Notes
135
149
 
136
150
  We did **not** take immediate action against Builder 25 — Lars was overseeing the session and the change itself was a legitimate bug fix. The point of this ADR is the *mechanism*, not the person: the system must make the bypass hard and visible regardless of intent.
@@ -5,6 +5,7 @@
5
5
  - **Task:** [task 1004174](https://cloudbongos.com/builders#/task/1004174) (goal 1000090 — BONGOS-V2)
6
6
  - **Deciders:** the owner, Lars. On 2026-09-22 he said "every project has the option to upgrade its version of bongos including bongos itself", and that the control belongs in that project's own hall. On 2026-09-26 he ruled that **only a project's owner upgrades it**, adding that for him "owners and archons are the same", because he owns the platform.
7
7
  - **Amends:** [ADR 0293](0293-the-owners-deploy-door-is-an-intent-the-control-plane-drains.md) D5 ("Archon-gated server-side"). The deploy door gains a second audience, as stated below. D1 (the web tier only asks, the control plane acts), D3, D4 and D6 are unchanged.
8
+ - **Amended by:** [ADR 0340](0340-every-hall-takes-its-update-from-settings-and-deploy-is-the-platform-halls-page.md) (task 1004296) — D3's hand-off moves from the banner and the rail to Settings → Software update's Update button, and `GET /core-update` no longer answers `deploy_url`.
8
9
  - **Related:** [ADR 0328](0328-a-hosted-projects-authority-is-its-membership-row-not-its-owner-column.md) (the owner-OR-operator gate shape this reuses), [ADR 0210](0210-scouting-graduates-on-an-instance-asserted-owner-claim.md) (the `alsoAdmits` page-gate door this reuses), [ADR 0246](0246-catalog-membership-is-a-projection-not-a-federation-side-effect.md) (a hosted project's hub client id is its slug), [ADR 0043](0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md) / 0111 §2 (the web tier gains no capability)
9
10
 
10
11
  ## Context
@@ -0,0 +1,64 @@
1
+ # ADR 0340 — Every hall takes its update from Settings, and /deploy is the platform hall's page
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-09-26
5
+ - **Task:** [task 1004296](https://cloudbongos.com/builders#/task/1004296) (goal 1000090 — BONGOS-V2), split out of [task 1002622](https://cloudbongos.com/builders#/task/1002622) §1.
6
+ - **Deciders:** the owner, Lars. On 2026-09-25 he asked that each builders hall's Settings carry "a version description where they can pull the latest release. Just like iOS does", and ruled that `/deploy` is "only for bongos builders hall itself not for all production ones".
7
+ - **Amends:** [ADR 0339](0339-a-projects-owner-upgrades-it-and-a-hosted-project-hands-off-to-the-hub-door.md) D3 (where a hosted hall uses the hub address) and the reach of [ADR 0293](0293-the-owners-deploy-door-is-an-intent-the-control-plane-drains.md)'s door page. Nothing about who may move a pin, or how the move runs, changes.
8
+
9
+ ## Context
10
+
11
+ Before this change a project learned about a newer core in one place, the banner (task 1004045), and only a holder of `core.pin.move` ever saw it. The banner named two version numbers and nothing that had landed between them. The only per-version record of work is the `release-notes.json` each package carries (task 1004218); the changelog's CI lines name none.
12
+
13
+ Every hall also served `/deploy`. The page's data and both of its acts are provisioning-module routes, so in a hall without that module (a hosted project, a self-hosted instance) it was a page with nothing behind it.
14
+
15
+ ## Decision
16
+
17
+ ### D1 — Settings → Software update, in the core, in every hall
18
+
19
+ A sixth Settings group. It shows the running core, then either "up to date" or the newest release the update channel lets this project take, then what each version in between brings, read from the newest package's own release notes.
20
+
21
+ - **Every signed-in builder reads it** (`GET /api/bongos/software-update`, `requireBuilder` only). It discloses nothing the public `GET /version` and npm do not already publish, so ADR 0043's vulnerability-window reason, which keeps the banner's reads on `core.pin.move`, does not apply here.
22
+ - **The channel rule is the runner's own** (`resolveChannelTarget`), with no channel passed, exactly as the banner. The panel never offers a version the runner would refuse.
23
+ - **"Up to date" is said only from an answer.** A failed registry read, a running version that cannot be named, and release notes that could not be read each render as what they are.
24
+
25
+ ### D2 — The Update button leads to the door; it is not the door
26
+
27
+ The server names where this project's door is:
28
+
29
+ - `local` — `/deploy`, where the hall runs the provisioning module.
30
+ - `hub` — ADR 0339 D3's `<hub>/deploy?project=<slug>`, on a federated hosted project.
31
+ - `cli` — neither, as on a self-hosted instance. The panel says `bongos upgrade` on the server takes the version, with the same health check and rollback.
32
+
33
+ The button is drawn only when the viewer holds `core.pin.move`. That check is cosmetic; the door re-checks every request.
34
+
35
+ ### D3 — `/deploy` exists only where the door does
36
+
37
+ In a hall that does not run the provisioning module, `GET /deploy` answers `302` to `/settings#software-update`. The redirect carries no gate, because it discloses nothing and Settings' own wall applies once it is followed. The platform's hall keeps `/deploy` behind its unchanged page gate. It remains the door for its own pin and, through `?project=`, for every hosted project's (ADR 0339).
38
+
39
+ ### D4 — The banner and the rail stop linking off-site
40
+
41
+ On every hall but the platform's, the banner's Upgrade link opens Settings → Software update. On that panel itself the banner points rather than linking to the page it is on, the rule task 1004145 set for `/deploy`. The rail's Deploy item is no longer re-pointed at the hub, and it stays hidden wherever the module is off. `GET /core-update` no longer answers `deploy_url`. The hub address now lives only in `GET /software-update`'s `door`, which is ADR 0339 D3's hand-off moved from two places to one.
42
+
43
+ ### D5 — The registry reader is the core's
44
+
45
+ `src/bongos/package-registry.js` holds the packument read, the in-process tarball stream and the small tar reader. It moved out of the npm-release module (task 1002622), because the one reader every hall needs cannot live inside a module that only one hall runs. Modules reach it through the doorway's `readPackageRegistry`, and both readers share one process-local cache.
46
+
47
+ ## Rejected
48
+
49
+ - **A copy of the two-step door inside Settings.** It would put the confirmation, the busy states and the rollback display in two places for one act. Those are the rules ADR 0293 D4 exists to keep exact.
50
+ - **Gating the panel on `core.pin.move`, as the banner is.** The owner asked for the version in every builder's Settings, and the panel offers no act of its own.
51
+ - **Keeping `/deploy` on other halls with a "moved" notice.** A page that exists only to say it does not belong there is the dead end this replaces.
52
+
53
+ ## Consequences
54
+
55
+ - **A hosted project gets the panel when it runs a core carrying this ADR**, like every in-hall change. Until then its banner still hands off as ADR 0339 D3 described.
56
+ - **The first open of the panel after a new release downloads that package once per server process** (about 24 MB for 1.19.1040, under a second from a droplet), then serves it from memory. It is read only when the group opens, never with the page.
57
+ - **What's new links each entry to its task only in the platform's hall**, whose ledger the ids belong to. Elsewhere the entries are plain text.
58
+ - **Proof:** `tests/software_update.mjs`:
59
+ - the reading, over a real gzipped tar and packument;
60
+ - the route, over real requests;
61
+ - the panel, executed in a DOM stub against a live reading;
62
+ - `/deploy`, answered by two real servers, one with the module and one without.
63
+
64
+ `tests/core_upgrade_owner_door.mjs` covers the banner's new link. Each guard was deleted in turn and a test went red.
@@ -431,3 +431,4 @@ This keeps the decision history honest and traceable.
431
431
  | 0337 | [**The hub account is the person, a hall account is their seat in one project, so anything that spans projects lives on the hub** ([task 1004255](https://cloudbongos.com/builders#/task/1004255), goal 1000110 — the owner's hub/hall re-scope, 2026-09-24/25). Extends [ADR 0141](<redacted>.md) from identity to placement: (1) a surface about the person across projects, or about more than one project, goes on the HUB (`public-landing`, `platform-identity`): people directory, community, guilds, connections, recruiting, platform-account settings; one about this project goes in the HALL (`hall-ui`); "Builders you may know" is on both; `status-ui` is the status dashboard, not the hall; (2) no authority moves, and hub actions still land as the project's own rows; (3) hall `/people` retires, ADR 0334's recruiting directory moves unchanged to the hub community page, `/roster` is the in-project directory; (4) owner calls: the hidden-builder recruiter panel is recruiter-only while public search is unchanged (amends community-tab spec D8); platform-account settings get a new hub page; **guild totals count hidden and private members by default, with a notice on the join card and a per-guild off switch (`counted_in_totals`), rounded to a 1–2–5 band, only once a guild has at least 3 of them, refreshed weekly; size stays the public roster length** (supersedes ADR 0336 D5; relaxes the privacy spec's "`hide_stats` beats everything" for guild totals only, for a member who was told), with the fake-account padding limit stated and accepted.](0337-the-hub-account-is-the-person-a-hall-account-is-their-seat-in-one-project.md) | platform identity / placement / privacy |
432
432
  | 0338 | [**Modules travel through a Bongos-hosted store, and an acquired module keeps working forever** ([task 1003782](https://cloudbongos.com/builders#/task/1003782), goal 1000091 — working area 5, owner Will). A module had no transport of its own: it reached an instance only inside the core (ADR 0107 §6) or in the instance's repo. Weighed npm packages, a Bongos-hosted store and git refs against the four things area 5's criteria require — entitlement before install, a per-version score, a tester channel, and a delist that stops distribution. npm and git refs fail entitlement and delist by construction. **D1:** Cloud Bongos hosts the store; a module version is a tarball + hash manifest in the same format `package-core.js` already emits (same `isPublishable()` gate), registry rows on the control-plane DB, artifacts in the already-paid DO Spaces bucket, served by the control plane only after an entitlement + channel check; free modules take the same path at price zero; install/update verify hashes on arrival; modules' own npm deps still travel via npm (ADR 0138). No new fixed cost. **D2 (owner):** delisting, author withdrawal or deletion removes a module from the catalog and stops new acquisitions and updates, but **an acquired module keeps working forever** — the store never disables or removes an installed copy and a delist never revokes an entitlement; the holder is told no more updates will come. Security issues are not a special case; a remote kill switch would need a superseding ADR. Rejected: npm, git refs, remote disable on delist.](0338-modules-travel-through-a-bongos-hosted-store.md) | modules / distribution / economy |
433
433
  | 0339 | [**A project's owner upgrades it, and a hosted project hands off to the hub's door** ([task 1004174](https://cloudbongos.com/builders#/task/1004174), goal 1000090 — the owner's ruling of 2026-09-26 that only a project's owner upgrades it). Amends ADR 0293 D5. **D1:** the deploy door's preview and move routes admit the OWNER of a tenant row (`co-tenant`/`cloud-host`) for that row, asked first; every other caller meets the unmodified `core.pin.move` gate, so a non-owner's refusal is unchanged whether or not the id exists and the widening can only admit. **D2:** the platform's own row stays atom-only. **D3:** `GET /core-update` names `<hub>/deploy?project=<slug>` on a federated project, and the hosted hall's banner and rail hand off there (the dead local Deploy item is gone); the hub's `/deploy` shell admits a project owner through `alsoAdmits: 'isProjectOwner'`. **D4:** the intent's actor records the door (`api:owner:<id>` / `api:archon:<id>`), both attributed on the `core_upgrades` ledger. Rejected: a tenant-side API that performs the upgrade, granting the system atom to owners, owners moving the platform row. ADR 0328 Phase 1 (task 1004159) should fold this gate into `requireProjectOwner`.](0339-a-projects-owner-upgrades-it-and-a-hosted-project-hands-off-to-the-hub-door.md) | provisioning / deploy door / permissions |
434
+ | 0340 | [**Every hall takes its update from Settings, and /deploy is the platform hall's page** ([task 1004296](https://cloudbongos.com/builders#/task/1004296), goal 1000090 — the owner's 2026-09-25 asks: a Settings version panel "just like iOS", and /deploy only in the Bongos hall). Amends ADR 0339 D3 and the reach of ADR 0293's page. **D1:** Settings → Software update in the core — the running core, the newest release the runner's own channel rule allows, and what each version in between carries from the newest package's release notes; every signed-in builder reads it, and "up to date" is said only from an answer. **D2:** its Update button leads to the door (local /deploy, the hub's /deploy?project=, or a `bongos upgrade` sentence), drawn only for holders of core.pin.move. **D3:** /deploy 302s to Settings on a hall without the provisioning module. **D4:** the banner links Settings everywhere but the platform; the rail is no longer re-pointed; /core-update drops deploy_url. **D5:** the registry reader moved into the core (module-api readPackageRegistry). Rejected: a second copy of the two-step door, gating the panel on the atom, a "moved" page.](0340-every-hall-takes-its-update-from-settings-and-deploy-is-the-platform-halls-page.md) | deploy door / settings / core update |
@@ -261,6 +261,10 @@
261
261
  "name": "sky",
262
262
  "description": "Endpoints under `/api/bongos/sky`."
263
263
  },
264
+ {
265
+ "name": "software-update",
266
+ "description": "Endpoints under `/api/bongos/software-update`."
267
+ },
264
268
  {
265
269
  "name": "specialities",
266
270
  "description": "Endpoints under `/api/bongos/specialities`."
@@ -13318,6 +13322,51 @@
13318
13322
  ]
13319
13323
  }
13320
13324
  },
13325
+ "/npm-release/task/{id}": {
13326
+ "get": {
13327
+ "operationId": "get_npm_release_task_id",
13328
+ "tags": [
13329
+ "npm-release"
13330
+ ],
13331
+ "summary": "GET /npm-release/task/:id",
13332
+ "description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
13333
+ "x-rank": "any-builder",
13334
+ "x-source": "modules/npm-release/routes/task-where.js",
13335
+ "parameters": [
13336
+ {
13337
+ "name": "id",
13338
+ "in": "path",
13339
+ "required": true,
13340
+ "schema": {
13341
+ "type": "string"
13342
+ },
13343
+ "description": "Path parameter `id`."
13344
+ }
13345
+ ],
13346
+ "responses": {
13347
+ "200": {
13348
+ "description": "Success."
13349
+ },
13350
+ "400": {
13351
+ "$ref": "#/components/responses/BadRequest"
13352
+ },
13353
+ "401": {
13354
+ "$ref": "#/components/responses/Unauthorized"
13355
+ },
13356
+ "403": {
13357
+ "$ref": "#/components/responses/Forbidden"
13358
+ },
13359
+ "404": {
13360
+ "$ref": "#/components/responses/NotFound"
13361
+ }
13362
+ },
13363
+ "security": [
13364
+ {
13365
+ "builderSession": []
13366
+ }
13367
+ ]
13368
+ }
13369
+ },
13321
13370
  "/npm-release/work": {
13322
13371
  "get": {
13323
13372
  "operationId": "get_npm_release_work",
@@ -17088,6 +17137,44 @@
17088
17137
  ]
17089
17138
  }
17090
17139
  },
17140
+ "/software-update": {
17141
+ "get": {
17142
+ "operationId": "get_software_update",
17143
+ "tags": [
17144
+ "software-update"
17145
+ ],
17146
+ "summary": "GET /software-update",
17147
+ "description": "GET /software-update — Settings → Software update (task 1004296): this project's core, the newest release its channel allows, what the versions between them carry, and where this project's Update button leads. Any signed-in builder (see the header).\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
17148
+ "x-rank": "any-builder",
17149
+ "x-source": "src/bongos/routes/core-update.js",
17150
+ "responses": {
17151
+ "200": {
17152
+ "description": "Success.",
17153
+ "content": {
17154
+ "application/json": {
17155
+ "schema": {
17156
+ "$ref": "#/components/schemas/GetSoftwareUpdateResponse"
17157
+ }
17158
+ }
17159
+ }
17160
+ },
17161
+ "400": {
17162
+ "$ref": "#/components/responses/BadRequest"
17163
+ },
17164
+ "401": {
17165
+ "$ref": "#/components/responses/Unauthorized"
17166
+ },
17167
+ "403": {
17168
+ "$ref": "#/components/responses/Forbidden"
17169
+ }
17170
+ },
17171
+ "security": [
17172
+ {
17173
+ "builderSession": []
17174
+ }
17175
+ ]
17176
+ }
17177
+ },
17091
17178
  "/specialities": {
17092
17179
  "get": {
17093
17180
  "operationId": "get_specialities",
@@ -21129,13 +21216,11 @@
21129
21216
  "ok": {
21130
21217
  "type": "boolean"
21131
21218
  },
21132
- "update": {},
21133
- "deploy_url": {}
21219
+ "update": {}
21134
21220
  },
21135
21221
  "required": [
21136
21222
  "ok",
21137
- "update",
21138
- "deploy_url"
21223
+ "update"
21139
21224
  ]
21140
21225
  },
21141
21226
  "GetCoreUpgradesResponse": {
@@ -22383,6 +22468,23 @@
22383
22468
  "session_types"
22384
22469
  ]
22385
22470
  },
22471
+ "GetSoftwareUpdateResponse": {
22472
+ "type": "object",
22473
+ "properties": {
22474
+ "ok": {
22475
+ "type": "boolean"
22476
+ },
22477
+ "update": {},
22478
+ "door": {},
22479
+ "can_update": {}
22480
+ },
22481
+ "required": [
22482
+ "ok",
22483
+ "update",
22484
+ "door",
22485
+ "can_update"
22486
+ ]
22487
+ },
22386
22488
  "GetSpecialitiesIdDocumentsResponse": {
22387
22489
  "type": "object",
22388
22490
  "properties": {
@@ -27938,9 +28040,9 @@
27938
28040
  "description": "A required dependency/feature is not configured or is temporarily down."
27939
28041
  }
27940
28042
  },
27941
- "x-endpoint-count": 440,
27942
- "x-schema-count": 481,
28043
+ "x-endpoint-count": 442,
28044
+ "x-schema-count": 482,
27943
28045
  "x-undocumented-bodies": 9,
27944
- "x-response-schemas": 329,
28046
+ "x-response-schemas": 330,
27945
28047
  "x-generated-by": "scripts/gds/gen-api-docs.js"
27946
28048
  }
@@ -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. 440 endpoints across 75 route files.
5
+ > **Generated from the live route files** — the route file is authoritative. 442 endpoints across 76 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`.
@@ -521,10 +521,11 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
521
521
  | POST | `/api/bongos/my-projects/invites/:clientId/decline` | `any-builder` | — | decline an invite (delete the pending row) for the caller's OWN account. |
522
522
  | POST | `/api/bongos/my-projects/join` | `any-builder` | `origin`, `note` | request to join a project. |
523
523
 
524
- ## `npm-release` (1)
524
+ ## `npm-release` (2)
525
525
 
526
526
  | Method | Path | Rank | Body | Description |
527
527
  |---|---|---|---|---|
528
+ | GET | `/api/bongos/npm-release/task/:id` | `any-builder` | — | |
528
529
  | GET | `/api/bongos/npm-release/work` | `archon` | — | Query: days (ledger window, default 14, max 60), before + limit (history paging). |
529
530
 
530
531
  ## `override-requests` (2)
@@ -679,6 +680,12 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
679
680
  | GET | `/api/bongos/sky` | `any-builder` | — | GET /sky, the whole project sky (task 1004230, ADR 0331). |
680
681
  | GET | `/api/bongos/sky/mine` | `any-builder` | — | GET /sky/mine, every thought the SIGNED-IN builder filed with its state, size and descent, capped at 1000 (task 1004230). |
681
682
 
683
+ ## `software-update` (1)
684
+
685
+ | Method | Path | Rank | Body | Description |
686
+ |---|---|---|---|---|
687
+ | GET | `/api/bongos/software-update` | `any-builder` | — | GET /software-update — Settings → Software update (task 1004296): this project's core, the newest release its channel allows, what the ve… |
688
+
682
689
  ## `specialities` (12)
683
690
 
684
691
  | Method | Path | Rank | Body | Description |