@bongos/core 1.19.1034 → 1.19.1036
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.
- package/.bongos-core.json +88 -68
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +6 -0
- package/clients/bongos-client/index.cjs +6 -0
- package/clients/bongos-client/index.d.ts +9 -1
- package/clients/bongos-client/index.mjs +6 -0
- package/docs/adr/0339-a-projects-owner-upgrades-it-and-a-hosted-project-hands-off-to-the-hub-door.md +84 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +126 -8
- package/docs/api-reference.md +9 -2
- package/docs/copy-inventory.md +10 -10
- package/docs/copy-registry.json +13 -13
- package/docs/module-api-changelog.md +4 -0
- package/modules/autonomy/db.js +19 -0
- package/modules/autonomy/routes/autonomy.js +28 -0
- package/modules/government/catalog.js +2 -2
- package/modules/hall-ui/public/atlas.html +1 -1
- package/modules/hall-ui/public/blockers.html +1 -1
- package/modules/hall-ui/public/board-room.html +1 -1
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/copy-desk.html +1 -1
- package/modules/hall-ui/public/deploy.html +1 -1
- package/modules/hall-ui/public/diagrams.html +1 -1
- package/modules/hall-ui/public/drachmae.html +1 -1
- package/modules/hall-ui/public/fleet.html +1 -1
- package/modules/hall-ui/public/gate.html +1 -1
- package/modules/hall-ui/public/goals.html +1 -1
- package/modules/hall-ui/public/government.html +1 -1
- package/modules/hall-ui/public/idea.html +1 -1
- package/modules/hall-ui/public/ideas.html +1 -1
- package/modules/hall-ui/public/index.html +1 -1
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/people.html +1 -1
- package/modules/hall-ui/public/primer.html +1 -1
- package/modules/hall-ui/public/profile.html +1 -1
- package/modules/hall-ui/public/project-settings.html +1 -1
- package/modules/hall-ui/public/ranks.html +1 -1
- package/modules/hall-ui/public/roadmap.html +1 -1
- package/modules/hall-ui/public/roster.html +1 -1
- package/modules/hall-ui/public/sessions.html +1 -1
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/shell.js +36 -5
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/task.html +1 -1
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/work.html +1 -1
- package/modules/lifecycle/ship-assurance.js +17 -1
- package/modules/provisioning/core-upgrade-authz.js +85 -0
- package/modules/provisioning/core-upgrade.js +2 -1
- package/modules/provisioning/provisioning.js +4 -4
- package/modules/provisioning/routes/core-upgrade.js +12 -6
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +20 -0
- package/scripts/gds/provision-core-upgrade.js +12 -4
- package/src/bongos/auth.js +8 -2
- package/src/bongos/core-update.js +23 -1
- package/src/bongos/routes/core-update.js +51 -4
- package/src/module-api.js +1 -1
- package/tests/core_upgrade_owner_door.mjs +444 -0
- package/tests/nav_permission_atoms.mjs +1 -1
- package/tests/provisioning_teardown_intent.mjs +28 -2
- package/tests/routine_observability_api.mjs +195 -0
- package/tests/scouting_page_gate.mjs +11 -3
- package/tests/ship_assurance.mjs +86 -3
|
@@ -185,6 +185,8 @@ export function createClient(opts = {}) {
|
|
|
185
185
|
getAutonomyPrecheck: (args) => request("GET", "/autonomy/precheck", { hasBody: false }, args),
|
|
186
186
|
// GET /autonomy/runners — rank: any-builder — GET /autonomy/runners
|
|
187
187
|
getAutonomyRunners: (args) => request("GET", "/autonomy/runners", { hasBody: false }, args),
|
|
188
|
+
// GET /autonomy/runs — rank: metic+archon — GET /autonomy/runs
|
|
189
|
+
getAutonomyRuns: (args) => request("GET", "/autonomy/runs", { hasBody: false }, args),
|
|
188
190
|
},
|
|
189
191
|
"backup": {
|
|
190
192
|
// GET /backup/status — rank: metic+archon — GET /backup/status
|
|
@@ -346,6 +348,10 @@ export function createClient(opts = {}) {
|
|
|
346
348
|
// GET /core-update — rank: archon — GET /core-update
|
|
347
349
|
getCoreUpdate: (args) => request("GET", "/core-update", { hasBody: false }, args),
|
|
348
350
|
},
|
|
351
|
+
"coreUpgrades": {
|
|
352
|
+
// GET /core-upgrades — rank: archon — GET /core-upgrades
|
|
353
|
+
getCoreUpgrades: (args) => request("GET", "/core-upgrades", { hasBody: false }, args),
|
|
354
|
+
},
|
|
349
355
|
"cost": {
|
|
350
356
|
// POST /cost — rank: any-builder — POST /cost
|
|
351
357
|
postCost: (args) => request("POST", "/cost", { hasBody: true }, args),
|
package/docs/adr/0339-a-projects-owner-upgrades-it-and-a-hosted-project-hands-off-to-the-hub-door.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# ADR 0339 — A project's owner upgrades it, and a hosted project hands off to the hub's door
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-09-26
|
|
5
|
+
- **Task:** [task 1004174](https://cloudbongos.com/builders#/task/1004174) (goal 1000090 — BONGOS-V2)
|
|
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
|
+
- **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
|
+
- **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
|
+
## Context
|
|
11
|
+
|
|
12
|
+
The deploy door is `POST` and `GET /provisioning/instances/:id/core-upgrade` on the control plane, fronted by the hub's `/deploy` page. It was gated on `core.pin.move` alone. That atom has an archon floor and `system:true`: the catalog forbids granting it to metic, and no custom rank can hold it.
|
|
13
|
+
|
|
14
|
+
That produced two dead ends.
|
|
15
|
+
|
|
16
|
+
1. **The owner of a hosted project below Archon could see they were behind and could never act on it.** On a hosted project the banner (task 1004045) prints "Core X is available" with no action, because that project does not run the provisioning module. The door lives on the hub, and on the hub the owner (erikwils is Xenos; willHermesLines is Metic) is refused by the atom.
|
|
17
|
+
2. **A hosted project's own hall had a "Deploy" link that opened a page with nothing behind it.** The page's calls are provisioning routes, and a tenant has none.
|
|
18
|
+
|
|
19
|
+
Task 1004174's own text settled where the act must happen. It stays on the control plane, because ADR 0293 D1 and ADR 0043 both turn on the web tier never gaining a shell. The hosted project hands off rather than acting.
|
|
20
|
+
|
|
21
|
+
## Decision
|
|
22
|
+
|
|
23
|
+
### D1 — The owner of a hosted project may move that project's core, from the hub
|
|
24
|
+
|
|
25
|
+
The two per-project routes (the preview `GET` and the move `POST`) are gated by an OR, implemented in `modules/provisioning/core-upgrade-authz.js`:
|
|
26
|
+
|
|
27
|
+
1. **Ownership is asked first.** The caller is admitted if the row's `owner_builder_id` is the caller and the row is a tenant shape (`co-tenant` or `cloud-host`).
|
|
28
|
+
2. **Every other caller meets the unmodified `requirePermission('core.pin.move')`** and its unchanged refusal. That includes callers who are not the owner, a missing row, an unparseable id, and a database error during the ownership read.
|
|
29
|
+
|
|
30
|
+
This is the shape ADR 0328 Decision 2 and ADR 0210's `requireScoutingReader` already use. The atom is still spelled in each route's middleware list, where `route-rank-check.js` and `gen-api-docs.js` read it. The consequences:
|
|
31
|
+
|
|
32
|
+
- A non-owner below Archon gets exactly the 403 they always got, and learns nothing about whether the id exists.
|
|
33
|
+
- The Archon path is untouched.
|
|
34
|
+
- The widening can only admit.
|
|
35
|
+
|
|
36
|
+
### D2 — The platform's own row stays on the atom
|
|
37
|
+
|
|
38
|
+
`OWNER_SHAPES` excludes `control-plane`. Moving the platform changes the code that drives every hosted project, so only a holder of `core.pin.move` may do it. `GET /provisioning/control-plane` keeps the atom alone.
|
|
39
|
+
|
|
40
|
+
For Lars this is no restriction: he is both the platform's owner and an Archon, which is his ruling that the two are the same.
|
|
41
|
+
|
|
42
|
+
### D3 — A hosted project hands its owner to the hub, and gains nothing
|
|
43
|
+
|
|
44
|
+
`GET /api/bongos/core-update` (core) now also answers `deploy_url`: `<hub origin>/deploy?project=<slug>`.
|
|
45
|
+
|
|
46
|
+
- It is built from the two values provisioning already writes into a federated project's `web.env`: the hub origin and the hub client id, which is the slug (ADR 0246).
|
|
47
|
+
- It is null on an instance with no hub, such as a self-hosted instance or the hub itself.
|
|
48
|
+
- The client secret is never read for it.
|
|
49
|
+
|
|
50
|
+
The hall uses that address in two places, and only where it has no door of its own (the provisioning module is off):
|
|
51
|
+
|
|
52
|
+
- **The banner's "Upgrade" links there.**
|
|
53
|
+
- **The rail's "Deploy" item** is dropped where the provisioning module is off, and re-pointed at that address once it is known.
|
|
54
|
+
|
|
55
|
+
The hub's `/deploy?project=<slug>` page (task 1004171) was built as exactly this seam.
|
|
56
|
+
|
|
57
|
+
The hub's `/deploy` page shell is gated by `requireCorePinPage`. It now declares `alsoAdmits: 'isProjectOwner'`, the door `/people` uses: it admits the shell for an owner of any live project. Which project the owner may read or move is still the routes' decision, made per request against that project's row.
|
|
58
|
+
|
|
59
|
+
### D4 — The actor says which door was used, and still names the builder
|
|
60
|
+
|
|
61
|
+
An owner's move is recorded as `api:owner:<id>`, and an Archon's as `api:archon:<id>`. The runner's `requestedByOf` accepts both and passes the id through as `--requested-by`, so the `core_upgrades` ledger attributes the move either way (ADR 0293 D5).
|
|
62
|
+
|
|
63
|
+
## Rejected
|
|
64
|
+
|
|
65
|
+
- **A tenant-side API that authenticates back to the control plane and performs the upgrade.** It is rejected in writing, as the task asked. It would be a new cross-instance authentication surface on the most privileged action in the system, and it would give a tenant's web process a path to the act ADR 0293 D1 keeps on the control plane. The hand-off costs one navigation and adds no new capability anywhere.
|
|
66
|
+
- **Granting `core.pin.move` to owners.** The atom is `system:true` precisely so it cannot be handed down, and "may move core pins" is not "may move this one project's pin". Ownership is a separate axis, as ADR 0151 §3 keeps it.
|
|
67
|
+
- **Letting an owner move the platform row.** The platform row is not the owner's project in the sense the ruling means. Its only owner is the Archon who holds the atom anyway.
|
|
68
|
+
- **Asking the platform-identity membership ledger instead of `owner_builder_id`.** ADR 0328 Phase 2 (task 1004161) will widen project authority to members through that port. The ruling here is "owner", which the row already records, so this ADR takes the column and leaves the widening to that task.
|
|
69
|
+
|
|
70
|
+
## Consequences
|
|
71
|
+
|
|
72
|
+
- **erikwils (hoodify-finance) and willHermesLines (mercury) can upgrade their own projects.** They open `https://cloudbongos.com/deploy?project=<slug>` on the hub. The hub half works as soon as the platform runs a core carrying this ADR. The in-hall link reaches a hosted project only once that project runs such a core, because the banner ships inside the core. Until then the owner reaches the door by its address.
|
|
73
|
+
- **An owner's upgrade restarts their own site.** The runner's health gate and auto-rollback apply unchanged.
|
|
74
|
+
- **ADR 0328 Phase 1 must absorb this gate, not route around it.** When task 1004159 lands `requireProjectOwner` for the `/provisioning/instances/:id...` routes, the two core-upgrade routes should move onto it with the atom as their override. That keeps the same owner-OR-atom answer, and the platform row stays atom-only. Until then `requireOwnProjectOrPin` is the only owner gate on them. Task 1004160's `project_scope_missing` check lists `/provisioning/instances/:id` as a prefix, so it would flag these two routes. That is correct: it is the reminder to fold them in, not a sign that they are unguarded.
|
|
75
|
+
- **The page shell admits any live project owner.** An owner without the atom who opens `/deploy` without `?project=` sees the sealed state, because `/provisioning/control-plane` refuses them. The page is a shell, and every datum behind it is gated per request.
|
|
76
|
+
- **Proof:** `tests/core_upgrade_owner_door.mjs` covers each case:
|
|
77
|
+
- the owner below Archon, admitted;
|
|
78
|
+
- the Archon on another's project, admitted by the atom;
|
|
79
|
+
- the non-owner below Archon, refused byte-for-byte as before, whether the id exists or not;
|
|
80
|
+
- the platform row, owner or not, refused without the atom;
|
|
81
|
+
- a failing ownership read, which falls to the atom;
|
|
82
|
+
- the actor labels, and the runner's attribution parse;
|
|
83
|
+
- the page shell admitting an owner and still refusing a stranger;
|
|
84
|
+
- the `deploy_url`, and the hall's banner and rail on a hosted project and on the platform.
|
package/docs/adr/README.md
CHANGED
|
@@ -430,3 +430,4 @@ This keeps the decision history honest and traceable.
|
|
|
430
430
|
| 0336 | [**A guild is a hub-side group whose members each consent twice, and its collective record is only ever the sum of what those members already show** ([task 1002299](https://cloudbongos.com/builders#/task/1002299), goal 1000110 — the R23 design spike for goal 1000045's C7/C8/C9). No platform guild existed (every "guild" in the tree is Discord's). Decisions: (1) three hub tables in `platform-identity`, in their own `guilds.js` (the 1,500-line ratchet), distinct from instance-local `goal_members`: guilds (slug, name, `visibility ∈ public|unlisted` with **no default**), members (`membership_kind ∈ owner|member`, never `role` per ADR 0174; a partial unique index holds exactly one owner; a per-member `shown_publicly`), and requests; (2) two consents to join, no self-join, through ADR 0202's connections lifecycle verbatim (silent decline, 90-day swallowed re-ask, 30-day read-time expiry); `accountActiveSql` floors the feature; an **unlisted guild 404s to everyone on the public read, members included**, and takes invites only, because a slug is guessable; (3) the public roster is `shown_publicly AND accountVisibleSql`, and widening a guild to public changes no member's flag but the flipping owner's, so consent given to a small audience is never reused for a large one; (4) **the privacy resolution — NOT ratified; superseded by [ADR 0337](0337-the-hub-account-is-the-person-a-hall-account-is-their-seat-in-one-project.md) D4.4:** it proposed that a member is counted iff shown AND `rollupVisibleSql`, read-time, `no-store`, never stored, and N and M are both lengths of lists the reader can see. The guild record is therefore always a sum of numbers already on members' own public profiles, so nothing can be subtracted out. All-or-nothing is rejected (one member blanks everyone and hiding becomes costly), as is per-member consent to count hidden numbers (it breaks "hide_stats beats everything"). The trade-off: guilds of privacy-minded builders look smaller and rank lower. A union count of all members' projects is refused because it reveals shared private projects; (5) the namespace is `/g/<slug>`, `g` is reserved in the SEO spec's project-slug list, the slug is fixed in V1, and `tests/guild_namespace_reserved.mjs` pins the two documents together; (6) a guild engages a project only through the individual door: a guild application is each member's own vouched application, labelled through ADR 0260's live applicant-profile read (no new instance field); inviting a guild fans out ordinary individual invites to its public roster at that moment, **never a guild-level pre-approval** (that would let a guild owner decide admission to someone else's project); (7) the map ranks public guilds by size and counted works shipped, read-time, with a slug tiebreak, and R29 narrows to the visual. Scope changes for R24–R37 are tabled in the ADR, including R28's dependency on the abandoned R11 and R29/R31's archived orb goals.](0336-a-guilds-record-is-the-sum-of-what-its-members-already-show.md) | platform identity / privacy / social graph |
|
|
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
|
+
| 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 |
|
package/docs/api/openapi.json
CHANGED
|
@@ -105,6 +105,10 @@
|
|
|
105
105
|
"name": "core-update",
|
|
106
106
|
"description": "Endpoints under `/api/bongos/core-update`."
|
|
107
107
|
},
|
|
108
|
+
{
|
|
109
|
+
"name": "core-upgrades",
|
|
110
|
+
"description": "Endpoints under `/api/bongos/core-upgrades`."
|
|
111
|
+
},
|
|
108
112
|
{
|
|
109
113
|
"name": "cost",
|
|
110
114
|
"description": "Endpoints under `/api/bongos/cost`."
|
|
@@ -2128,6 +2132,47 @@
|
|
|
2128
2132
|
]
|
|
2129
2133
|
}
|
|
2130
2134
|
},
|
|
2135
|
+
"/autonomy/runs": {
|
|
2136
|
+
"get": {
|
|
2137
|
+
"operationId": "get_autonomy_runs",
|
|
2138
|
+
"tags": [
|
|
2139
|
+
"autonomy"
|
|
2140
|
+
],
|
|
2141
|
+
"summary": "GET /autonomy/runs",
|
|
2142
|
+
"description": "The gate's past decisions — did a routine fire, and what did it decide, and why (task 1002669). READ-ONLY and behind the SAME atom as the precheck above (`autonomy.precheck`, Metic+): whoever may ask the gate the question may read its past answers, and a new atom would need a migration for no change in audience. Adds no gate anywhere — pure observability over rows the precheck already writes. ?routine=<name> narrows to one routine; ?limit=1..100 (default 20), newest first.\n\n**Rank:** `metic+archon` — Metic or Archon rank (review/triage powers).\n\n**Permissions:** `autonomy.precheck` (all required).",
|
|
2143
|
+
"x-rank": "metic+archon",
|
|
2144
|
+
"x-source": "modules/autonomy/routes/autonomy.js",
|
|
2145
|
+
"x-permissions": [
|
|
2146
|
+
"autonomy.precheck"
|
|
2147
|
+
],
|
|
2148
|
+
"responses": {
|
|
2149
|
+
"200": {
|
|
2150
|
+
"description": "Success.",
|
|
2151
|
+
"content": {
|
|
2152
|
+
"application/json": {
|
|
2153
|
+
"schema": {
|
|
2154
|
+
"$ref": "#/components/schemas/GetAutonomyRunsResponse"
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
},
|
|
2159
|
+
"400": {
|
|
2160
|
+
"$ref": "#/components/responses/BadRequest"
|
|
2161
|
+
},
|
|
2162
|
+
"401": {
|
|
2163
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
2164
|
+
},
|
|
2165
|
+
"403": {
|
|
2166
|
+
"$ref": "#/components/responses/Forbidden"
|
|
2167
|
+
}
|
|
2168
|
+
},
|
|
2169
|
+
"security": [
|
|
2170
|
+
{
|
|
2171
|
+
"builderSession": []
|
|
2172
|
+
}
|
|
2173
|
+
]
|
|
2174
|
+
}
|
|
2175
|
+
},
|
|
2131
2176
|
"/backup/status": {
|
|
2132
2177
|
"get": {
|
|
2133
2178
|
"operationId": "get_backup_status",
|
|
@@ -5126,6 +5171,47 @@
|
|
|
5126
5171
|
]
|
|
5127
5172
|
}
|
|
5128
5173
|
},
|
|
5174
|
+
"/core-upgrades": {
|
|
5175
|
+
"get": {
|
|
5176
|
+
"operationId": "get_core_upgrades",
|
|
5177
|
+
"tags": [
|
|
5178
|
+
"core-upgrades"
|
|
5179
|
+
],
|
|
5180
|
+
"summary": "GET /core-upgrades",
|
|
5181
|
+
"description": "GET /core-upgrades — the instance's own core-upgrade ledger, newest first: when the pin last moved, from and to which version, and whether a person or the unattended sweep moved it (task 1002669). READ-ONLY. Gated on the SAME atom as /core-update above and the deploy door, for the same first reason: it names the exact core this box has run and when, which is a vulnerability-window disclosure (ADR 0043). No new atom, so no migration. ?limit=1..100 (default 20).\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `core.pin.move` (all required).",
|
|
5182
|
+
"x-rank": "archon",
|
|
5183
|
+
"x-source": "src/bongos/routes/core-update.js",
|
|
5184
|
+
"x-permissions": [
|
|
5185
|
+
"core.pin.move"
|
|
5186
|
+
],
|
|
5187
|
+
"responses": {
|
|
5188
|
+
"200": {
|
|
5189
|
+
"description": "Success.",
|
|
5190
|
+
"content": {
|
|
5191
|
+
"application/json": {
|
|
5192
|
+
"schema": {
|
|
5193
|
+
"$ref": "#/components/schemas/GetCoreUpgradesResponse"
|
|
5194
|
+
}
|
|
5195
|
+
}
|
|
5196
|
+
}
|
|
5197
|
+
},
|
|
5198
|
+
"400": {
|
|
5199
|
+
"$ref": "#/components/responses/BadRequest"
|
|
5200
|
+
},
|
|
5201
|
+
"401": {
|
|
5202
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
5203
|
+
},
|
|
5204
|
+
"403": {
|
|
5205
|
+
"$ref": "#/components/responses/Forbidden"
|
|
5206
|
+
}
|
|
5207
|
+
},
|
|
5208
|
+
"security": [
|
|
5209
|
+
{
|
|
5210
|
+
"builderSession": []
|
|
5211
|
+
}
|
|
5212
|
+
]
|
|
5213
|
+
}
|
|
5214
|
+
},
|
|
5129
5215
|
"/cost": {
|
|
5130
5216
|
"post": {
|
|
5131
5217
|
"operationId": "post_cost",
|
|
@@ -13829,7 +13915,7 @@
|
|
|
13829
13915
|
"provisioning"
|
|
13830
13916
|
],
|
|
13831
13917
|
"summary": "GET /provisioning/control-plane",
|
|
13832
|
-
"description": "GET /provisioning/control-plane — \"which row is this platform, and where does it stand?\" The deploy page's first call: the self row is created once by hand at install time, so its id is per-install and nobody's to memorise.
|
|
13918
|
+
"description": "GET /provisioning/control-plane — \"which row is this platform, and where does it stand?\" The deploy page's first call: the self row is created once by hand at install time, so its id is per-install and nobody's to memorise. The atom ALONE here, with no owner door: this is the platform's own row (ADR 0339).\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `core.pin.move` (all required).",
|
|
13833
13919
|
"x-rank": "archon",
|
|
13834
13920
|
"x-source": "modules/provisioning/routes/core-upgrade.js",
|
|
13835
13921
|
"x-permissions": [
|
|
@@ -14145,7 +14231,7 @@
|
|
|
14145
14231
|
"provisioning"
|
|
14146
14232
|
],
|
|
14147
14233
|
"summary": "GET /provisioning/instances/:id/core-upgrade",
|
|
14148
|
-
"description": "GET the same path — step ONE of the two-step (ADR 0293 D4): what a move would do. GATED THE SAME AS THE POST, deliberately. Reading it discloses the instance's exact core version and how far behind it is, which is a vulnerability-window disclosure — precisely the sort of thing ADR 0043 keeps off unauthenticated surfaces. A preview anyone could read would also let an attacker time a request against a known-stale window. The read being no cheaper than the write costs the owner nothing:
|
|
14234
|
+
"description": "GET the same path — step ONE of the two-step (ADR 0293 D4): what a move would do. GATED THE SAME AS THE POST, deliberately. Reading it discloses the instance's exact core version and how far behind it is, which is a vulnerability-window disclosure — precisely the sort of thing ADR 0043 keeps off unauthenticated surfaces. A preview anyone could read would also let an attacker time a request against a known-stale window. The read being no cheaper than the write costs the owner nothing: whoever may press the button may read what it would do — the same two doors as the POST.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `core.pin.move` (all required).",
|
|
14149
14235
|
"x-rank": "archon",
|
|
14150
14236
|
"x-source": "modules/provisioning/routes/core-upgrade.js",
|
|
14151
14237
|
"x-permissions": [
|
|
@@ -14191,7 +14277,7 @@
|
|
|
14191
14277
|
"provisioning"
|
|
14192
14278
|
],
|
|
14193
14279
|
"summary": "POST /provisioning/instances/:id/core-upgrade",
|
|
14194
|
-
"description": "POST /provisioning/instances/:id/core-upgrade — move the core pin. rank: `core.pin.move` — archon floor AND system:true, so the catalog's own invariant forbids granting it to metic and no custom rank can be handed it without a deliberate, visible edit. BV1.R105 / ADR 0151 is why this is an atom and not `requireRank`: tests/government_require_permission.mjs fails the build on a new requireRank in a modules/*/routes gate. Body: { to: \"1.19.757\" } — and requiring it IS the second step of the two-step the owner asked for (ADR 0293 D4). A request that cannot fire without naming its target cannot fire from a stray click, and \"move to whatever is newest\", resolved at drain time, would be a different act from the one previewed: main moves between the preview and the confirm. What this does NOT check: whether the version is PUBLISHED, and whether the channel policy admits it. Both need the registry, and the only tool that reads it (update-channel.js `listAvailableVersions`) shells out synchronously — it would block the event loop for every other request on this process. It also lives in scripts/gds/, which a module may not require (ADR 0083). The runner enforces both, where it is a CLI and both are free. See ../core-upgrade.js.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `core.pin.move` (all required).",
|
|
14280
|
+
"description": "POST /provisioning/instances/:id/core-upgrade — move the core pin. rank: `core.pin.move` — archon floor AND system:true, so the catalog's own invariant forbids granting it to metic and no custom rank can be handed it without a deliberate, visible edit. BV1.R105 / ADR 0151 is why this is an atom and not `requireRank`: tests/government_require_permission.mjs fails the build on a new requireRank in a modules/*/routes gate. OR THE PROJECT'S OWN OWNER (task 1004174, ADR 0339 — the owner's ruling that only a project's owner upgrades it). Ownership of a TENANT row is asked first; any other caller meets the unmodified `core.pin.move` gate and its unchanged refusal. The platform's own row is not an owner's to move here — it stays on the atom. Body: { to: \"1.19.757\" } — and requiring it IS the second step of the two-step the owner asked for (ADR 0293 D4). A request that cannot fire without naming its target cannot fire from a stray click, and \"move to whatever is newest\", resolved at drain time, would be a different act from the one previewed: main moves between the preview and the confirm. What this does NOT check: whether the version is PUBLISHED, and whether the channel policy admits it. Both need the registry, and the only tool that reads it (update-channel.js `listAvailableVersions`) shells out synchronously — it would block the event loop for every other request on this process. It also lives in scripts/gds/, which a module may not require (ADR 0083). The runner enforces both, where it is a CLI and both are free. See ../core-upgrade.js.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `core.pin.move` (all required).",
|
|
14195
14281
|
"x-rank": "archon",
|
|
14196
14282
|
"x-source": "modules/provisioning/routes/core-upgrade.js",
|
|
14197
14283
|
"x-permissions": [
|
|
@@ -20636,6 +20722,19 @@
|
|
|
20636
20722
|
"none"
|
|
20637
20723
|
]
|
|
20638
20724
|
},
|
|
20725
|
+
"GetAutonomyRunsResponse": {
|
|
20726
|
+
"type": "object",
|
|
20727
|
+
"properties": {
|
|
20728
|
+
"routine": {},
|
|
20729
|
+
"limit": {},
|
|
20730
|
+
"runs": {}
|
|
20731
|
+
},
|
|
20732
|
+
"required": [
|
|
20733
|
+
"routine",
|
|
20734
|
+
"limit",
|
|
20735
|
+
"runs"
|
|
20736
|
+
]
|
|
20737
|
+
},
|
|
20639
20738
|
"GetBackupStatusResponse": {
|
|
20640
20739
|
"type": "object",
|
|
20641
20740
|
"properties": {
|
|
@@ -20992,11 +21091,30 @@
|
|
|
20992
21091
|
"ok": {
|
|
20993
21092
|
"type": "boolean"
|
|
20994
21093
|
},
|
|
20995
|
-
"update": {}
|
|
21094
|
+
"update": {},
|
|
21095
|
+
"deploy_url": {}
|
|
20996
21096
|
},
|
|
20997
21097
|
"required": [
|
|
20998
21098
|
"ok",
|
|
20999
|
-
"update"
|
|
21099
|
+
"update",
|
|
21100
|
+
"deploy_url"
|
|
21101
|
+
]
|
|
21102
|
+
},
|
|
21103
|
+
"GetCoreUpgradesResponse": {
|
|
21104
|
+
"type": "object",
|
|
21105
|
+
"properties": {
|
|
21106
|
+
"ok": {
|
|
21107
|
+
"type": "boolean"
|
|
21108
|
+
},
|
|
21109
|
+
"running": {},
|
|
21110
|
+
"limit": {},
|
|
21111
|
+
"upgrades": {}
|
|
21112
|
+
},
|
|
21113
|
+
"required": [
|
|
21114
|
+
"ok",
|
|
21115
|
+
"running",
|
|
21116
|
+
"limit",
|
|
21117
|
+
"upgrades"
|
|
21000
21118
|
]
|
|
21001
21119
|
},
|
|
21002
21120
|
"GetDiscordChannelsPlanResponse": {
|
|
@@ -27782,9 +27900,9 @@
|
|
|
27782
27900
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
27783
27901
|
}
|
|
27784
27902
|
},
|
|
27785
|
-
"x-endpoint-count":
|
|
27786
|
-
"x-schema-count":
|
|
27903
|
+
"x-endpoint-count": 439,
|
|
27904
|
+
"x-schema-count": 481,
|
|
27787
27905
|
"x-undocumented-bodies": 9,
|
|
27788
|
-
"x-response-schemas":
|
|
27906
|
+
"x-response-schemas": 329,
|
|
27789
27907
|
"x-generated-by": "scripts/gds/gen-api-docs.js"
|
|
27790
27908
|
}
|
package/docs/api-reference.md
CHANGED
|
@@ -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.
|
|
5
|
+
> **Generated from the live route files** — the route file is authoritative. 439 endpoints across 74 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`.
|
|
@@ -84,7 +84,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
84
84
|
| GET | `/api/bongos/auth/web/callback` | `public` | — | OAuth callback; the state cookie + code are the bearer. |
|
|
85
85
|
| GET | `/api/bongos/auth/web/start` | `public` | — | /auth/web — browser flow (used by the /builders page). |
|
|
86
86
|
|
|
87
|
-
## `autonomy` (
|
|
87
|
+
## `autonomy` (8)
|
|
88
88
|
|
|
89
89
|
| Method | Path | Rank | Body | Description |
|
|
90
90
|
|---|---|---|---|---|
|
|
@@ -95,6 +95,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
95
95
|
| POST | `/api/bongos/autonomy/heartbeat` | `any-builder` | `host`, `pid`, `started_at`, `mode`, `consecutive_failures`, `last_event`, `working_task_id` | The runner's check-in, once per loop. |
|
|
96
96
|
| GET | `/api/bongos/autonomy/precheck` | `metic+archon` | — | |
|
|
97
97
|
| GET | `/api/bongos/autonomy/runners` | `any-builder` | — | What the hall renders: the CALLER'S OWN runners, with the pure verdict attached so the page and any future alert cannot disagree about wh… |
|
|
98
|
+
| GET | `/api/bongos/autonomy/runs` | `metic+archon` | — | The gate's past decisions — did a routine fire, and what did it decide, and why (task 1002669). |
|
|
98
99
|
|
|
99
100
|
## `backup` (2)
|
|
100
101
|
|
|
@@ -224,6 +225,12 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
224
225
|
|---|---|---|---|---|
|
|
225
226
|
| GET | `/api/bongos/core-update` | `archon` | — | |
|
|
226
227
|
|
|
228
|
+
## `core-upgrades` (1)
|
|
229
|
+
|
|
230
|
+
| Method | Path | Rank | Body | Description |
|
|
231
|
+
|---|---|---|---|---|
|
|
232
|
+
| GET | `/api/bongos/core-upgrades` | `archon` | — | GET /core-upgrades — the instance's own core-upgrade ledger, newest first: when the pin last moved, from and to which version, and whethe… |
|
|
233
|
+
|
|
227
234
|
## `cost` (1)
|
|
228
235
|
|
|
229
236
|
| Method | Path | Rank | Body | Description |
|
package/docs/copy-inventory.md
CHANGED
|
@@ -594,8 +594,8 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
594
594
|
| `d305f0df6f25` | certain | Jump to | `modules/hall-ui/public/palette.js:226` |
|
|
595
595
|
| `01176c156112` | certain | Jump to a goal or a thought | `modules/hall-ui/public/goal-map.html:81` |
|
|
596
596
|
| `01176c156112` | certain | Jump to a goal or a thought | `modules/hall-ui/public/thinking.html:80` |
|
|
597
|
-
| `2bfc5a50ce88` | certain | Jump to a page or record | `modules/hall-ui/public/shell.js:
|
|
598
|
-
| `eba610d25523` | certain | Jump to… | `modules/hall-ui/public/shell.js:
|
|
597
|
+
| `2bfc5a50ce88` | certain | Jump to a page or record | `modules/hall-ui/public/shell.js:500` |
|
|
598
|
+
| `eba610d25523` | certain | Jump to… | `modules/hall-ui/public/shell.js:502` |
|
|
599
599
|
| `bc779353aa0c` | certain | Karma — peer recognition and approvals, a separate counter from {…}. | `modules/hall-ui/public/profile.js:94` |
|
|
600
600
|
| `de0e1590667f` | certain | Keep all {…} {…} — they are the values the code drops in, and the change cannot land without them. | `modules/hall-ui/public/copy-desk.js:442` |
|
|
601
601
|
| `fbe40b5818a3` | certain | Key removed. | `modules/hall-ui/public/settings.js:1128` |
|
|
@@ -776,7 +776,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
776
776
|
| `261d123970e8` | certain | Open goal #{…} | `modules/hall-ui/public/roadmap.js:112` |
|
|
777
777
|
| `5f3e0b179839` | certain | Open in Sessions | `modules/hall-ui/public/task.js:483` |
|
|
778
778
|
| `9f55e4674ebb` | certain | Open in the copy desk | `modules/hall-ui/public/studio.js:219` |
|
|
779
|
-
| `3366b115217b` | certain | Open navigation | `modules/hall-ui/public/shell.js:
|
|
779
|
+
| `3366b115217b` | certain | Open navigation | `modules/hall-ui/public/shell.js:491` |
|
|
780
780
|
| `855277dff074` | certain | Open task #{…} | `modules/hall-ui/public/goals-render.js:415` |
|
|
781
781
|
| `855277dff074` | certain | Open task #{…} | `modules/hall-ui/public/work.js:1124` |
|
|
782
782
|
| `99c630009152` | certain | Open tasks whose declared files overlap — sequence these before two builders collide. | `modules/hall-ui/public/goals.html:125` |
|
|
@@ -984,12 +984,12 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
984
984
|
| `e57ec24e13ef` | certain | Sign in with GitHub | `modules/hall-ui/public/hall-render.js:367` |
|
|
985
985
|
| `e57ec24e13ef` | certain | Sign in with GitHub | `modules/hall-ui/public/hall-render.js:391` |
|
|
986
986
|
| `e57ec24e13ef` | certain | Sign in with GitHub | `modules/hall-ui/public/hall-render.js:461` |
|
|
987
|
-
| `e57ec24e13ef` | certain | Sign in with GitHub | `modules/hall-ui/public/shell.js:
|
|
988
|
-
| `1883ad7f07fc` | certain | Sign out | `modules/hall-ui/public/shell.js:
|
|
989
|
-
| `1883ad7f07fc` | certain | Sign out | `modules/hall-ui/public/shell.js:
|
|
987
|
+
| `e57ec24e13ef` | certain | Sign in with GitHub | `modules/hall-ui/public/shell.js:461` |
|
|
988
|
+
| `1883ad7f07fc` | certain | Sign out | `modules/hall-ui/public/shell.js:479` |
|
|
989
|
+
| `1883ad7f07fc` | certain | Sign out | `modules/hall-ui/public/shell.js:738` |
|
|
990
990
|
| `8ad669ab2565` | certain | Sign out everywhere | `modules/hall-ui/public/settings.html:171` |
|
|
991
991
|
| `ecc12c1dd4de` | certain | Skill voices | `modules/hall-ui/public/settings.html:350` |
|
|
992
|
-
| `87cee78ca134` | certain | Skip to content | `modules/hall-ui/public/shell.js:
|
|
992
|
+
| `87cee78ca134` | certain | Skip to content | `modules/hall-ui/public/shell.js:729` |
|
|
993
993
|
| `688ca7b6e30f` | certain | Slop — reads as machine-written | `modules/hall-ui/public/copy-desk.html:90` |
|
|
994
994
|
| `82df09a08476` | certain | So the Archon knows who you are | `modules/hall-ui/public/hall-render.js:294` |
|
|
995
995
|
| `7da6a848cd26` | certain | Someone helped | `modules/hall-ui/public/collab.js:296` |
|
|
@@ -1016,7 +1016,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
1016
1016
|
| `5831de503015` | certain | Studio — {{worldName}} | `modules/hall-ui/public/studio.html:10` |
|
|
1017
1017
|
| `f79e1fb8ebd4` | certain | Suggested as you type; leave it on "no goal" and it waits for triage. | `modules/hall-ui/public/ideas.html:84` |
|
|
1018
1018
|
| `a1482eff4ead` | certain | Suggested for you | `modules/hall-ui/public/settings-specialities.js:137` |
|
|
1019
|
-
| `1e40f33483eb` | certain | Switch theme | `modules/hall-ui/public/shell.js:
|
|
1019
|
+
| `1e40f33483eb` | certain | Switch theme | `modules/hall-ui/public/shell.js:506` |
|
|
1020
1020
|
| `93fa2e97dd35` | certain | System default for this skill | `modules/hall-ui/public/settings.js:72` |
|
|
1021
1021
|
| `4894b1d9b0de` | certain | System oversight: people, operations and security. | `modules/hall-ui/public/watch.js:1335` |
|
|
1022
1022
|
| `e604fc3ace79` | certain | Task # | `modules/hall-ui/public/blockers.js:139` |
|
|
@@ -1037,7 +1037,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
1037
1037
|
| `2fc66e722e33` | certain | Tasks open once you have read the builder primer. | `modules/hall-ui/public/work.html:43` |
|
|
1038
1038
|
| `44579eef0c8d` | certain | Tasks — {{worldName}} | `modules/hall-ui/public/work.html:6` |
|
|
1039
1039
|
| `44579eef0c8d` | certain | Tasks — {{worldName}} | `modules/hall-ui/public/work.html:6` |
|
|
1040
|
-
| `2f4f047dc1b4` | certain | Text size | `modules/hall-ui/public/shell.js:
|
|
1040
|
+
| `2f4f047dc1b4` | certain | Text size | `modules/hall-ui/public/shell.js:505` |
|
|
1041
1041
|
| `f420429f942e` | certain | That builder no longer exists. | `modules/hall-ui/public/goals-render.js:1305` |
|
|
1042
1042
|
| `545c59c1deb7` | certain | That is the session you are using right now. Ending it signs you out of this page. | `modules/hall-ui/public/settings-sessions.js:74` |
|
|
1043
1043
|
| `282c3fa2d456` | certain | That is the wording it already has. Change something, or file a flag instead if you only want to mark it. | `modules/hall-ui/public/copy-desk.js:438` |
|
|
@@ -1169,7 +1169,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
1169
1169
|
| `2c1c20785a6e` | certain | Unclear — a person would not know what to do | `modules/hall-ui/public/copy-desk.html:91` |
|
|
1170
1170
|
| `aa445f06cc5e` | certain | Unlink failed: {…} | `modules/hall-ui/public/settings.js:856` |
|
|
1171
1171
|
| `67fbc770b3b3` | certain | Upvote (+1) | `modules/hall-ui/public/builders.js:777` |
|
|
1172
|
-
| `16d7f809be8a` | certain | Use the control below to take it. | `modules/hall-ui/public/shell.js:
|
|
1172
|
+
| `16d7f809be8a` | certain | Use the control below to take it. | `modules/hall-ui/public/shell.js:696` |
|
|
1173
1173
|
| `e7e2a99a2bea` | certain | Use this | `modules/hall-ui/public/settings-specialities.js:148` |
|
|
1174
1174
|
| `e1ecd543a2ca` | certain | Using this speciality. | `modules/hall-ui/public/settings-specialities.js:199` |
|
|
1175
1175
|
| `6200bac6bdca` | certain | View all sessions | `modules/hall-ui/public/watch.html:99` |
|
package/docs/copy-registry.json
CHANGED
|
@@ -192,7 +192,7 @@
|
|
|
192
192
|
"modules/hall-ui/public/hall-render.js:367",
|
|
193
193
|
"modules/hall-ui/public/hall-render.js:391",
|
|
194
194
|
"modules/hall-ui/public/hall-render.js:461",
|
|
195
|
-
"modules/hall-ui/public/shell.js:
|
|
195
|
+
"modules/hall-ui/public/shell.js:461"
|
|
196
196
|
]
|
|
197
197
|
},
|
|
198
198
|
{
|
|
@@ -1581,8 +1581,8 @@
|
|
|
1581
1581
|
"text": "Sign out",
|
|
1582
1582
|
"occurrences": 2,
|
|
1583
1583
|
"at": [
|
|
1584
|
-
"modules/hall-ui/public/shell.js:
|
|
1585
|
-
"modules/hall-ui/public/shell.js:
|
|
1584
|
+
"modules/hall-ui/public/shell.js:479",
|
|
1585
|
+
"modules/hall-ui/public/shell.js:738"
|
|
1586
1586
|
]
|
|
1587
1587
|
},
|
|
1588
1588
|
{
|
|
@@ -6850,7 +6850,7 @@
|
|
|
6850
6850
|
"surface": "builders-hall",
|
|
6851
6851
|
"text": "Jump to a page or record",
|
|
6852
6852
|
"file": "modules/hall-ui/public/shell.js",
|
|
6853
|
-
"line":
|
|
6853
|
+
"line": 500,
|
|
6854
6854
|
"origin": "js-markup",
|
|
6855
6855
|
"confidence": "certain"
|
|
6856
6856
|
},
|
|
@@ -6859,7 +6859,7 @@
|
|
|
6859
6859
|
"surface": "builders-hall",
|
|
6860
6860
|
"text": "Jump to…",
|
|
6861
6861
|
"file": "modules/hall-ui/public/shell.js",
|
|
6862
|
-
"line":
|
|
6862
|
+
"line": 502,
|
|
6863
6863
|
"origin": "js-markup",
|
|
6864
6864
|
"confidence": "certain"
|
|
6865
6865
|
},
|
|
@@ -8488,7 +8488,7 @@
|
|
|
8488
8488
|
"surface": "builders-hall",
|
|
8489
8489
|
"text": "Open navigation",
|
|
8490
8490
|
"file": "modules/hall-ui/public/shell.js",
|
|
8491
|
-
"line":
|
|
8491
|
+
"line": 491,
|
|
8492
8492
|
"origin": "js-markup",
|
|
8493
8493
|
"confidence": "certain"
|
|
8494
8494
|
},
|
|
@@ -10360,7 +10360,7 @@
|
|
|
10360
10360
|
"surface": "builders-hall",
|
|
10361
10361
|
"text": "Sign in with GitHub",
|
|
10362
10362
|
"file": "modules/hall-ui/public/shell.js",
|
|
10363
|
-
"line":
|
|
10363
|
+
"line": 461,
|
|
10364
10364
|
"origin": "js-markup",
|
|
10365
10365
|
"confidence": "certain"
|
|
10366
10366
|
},
|
|
@@ -10369,7 +10369,7 @@
|
|
|
10369
10369
|
"surface": "builders-hall",
|
|
10370
10370
|
"text": "Sign out",
|
|
10371
10371
|
"file": "modules/hall-ui/public/shell.js",
|
|
10372
|
-
"line":
|
|
10372
|
+
"line": 479,
|
|
10373
10373
|
"origin": "js-markup",
|
|
10374
10374
|
"confidence": "certain"
|
|
10375
10375
|
},
|
|
@@ -10378,7 +10378,7 @@
|
|
|
10378
10378
|
"surface": "builders-hall",
|
|
10379
10379
|
"text": "Sign out",
|
|
10380
10380
|
"file": "modules/hall-ui/public/shell.js",
|
|
10381
|
-
"line":
|
|
10381
|
+
"line": 738,
|
|
10382
10382
|
"origin": "js-markup",
|
|
10383
10383
|
"confidence": "certain"
|
|
10384
10384
|
},
|
|
@@ -10405,7 +10405,7 @@
|
|
|
10405
10405
|
"surface": "builders-hall",
|
|
10406
10406
|
"text": "Skip to content",
|
|
10407
10407
|
"file": "modules/hall-ui/public/shell.js",
|
|
10408
|
-
"line":
|
|
10408
|
+
"line": 729,
|
|
10409
10409
|
"origin": "js-text-assign",
|
|
10410
10410
|
"confidence": "certain"
|
|
10411
10411
|
},
|
|
@@ -10648,7 +10648,7 @@
|
|
|
10648
10648
|
"surface": "builders-hall",
|
|
10649
10649
|
"text": "Switch theme",
|
|
10650
10650
|
"file": "modules/hall-ui/public/shell.js",
|
|
10651
|
-
"line":
|
|
10651
|
+
"line": 506,
|
|
10652
10652
|
"origin": "js-markup",
|
|
10653
10653
|
"confidence": "certain"
|
|
10654
10654
|
},
|
|
@@ -10837,7 +10837,7 @@
|
|
|
10837
10837
|
"surface": "builders-hall",
|
|
10838
10838
|
"text": "Text size",
|
|
10839
10839
|
"file": "modules/hall-ui/public/shell.js",
|
|
10840
|
-
"line":
|
|
10840
|
+
"line": 505,
|
|
10841
10841
|
"origin": "js-markup",
|
|
10842
10842
|
"confidence": "certain"
|
|
10843
10843
|
},
|
|
@@ -12025,7 +12025,7 @@
|
|
|
12025
12025
|
"surface": "builders-hall",
|
|
12026
12026
|
"text": "Use the control below to take it.",
|
|
12027
12027
|
"file": "modules/hall-ui/public/shell.js",
|
|
12028
|
-
"line":
|
|
12028
|
+
"line": 696,
|
|
12029
12029
|
"origin": "js-markup",
|
|
12030
12030
|
"confidence": "certain"
|
|
12031
12031
|
},
|
|
@@ -2547,5 +2547,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2547
2547
|
landed since 1.19.1032 with no explicit bump. run 36214617025. (task 1002620)
|
|
2548
2548
|
1.19.1034 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2549
2549
|
landed since 1.19.1033 with no explicit bump. run 36215757254. (task 1002620)
|
|
2550
|
+
1.19.1035 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2551
|
+
landed since 1.19.1034 with no explicit bump. run 36226356336. (task 1002620)
|
|
2552
|
+
1.19.1036 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2553
|
+
landed since 1.19.1035 with no explicit bump. run 36226955285. (task 1002620)
|
|
2550
2554
|
---------------------------------------------------------------------------
|
|
2551
2555
|
```
|
package/modules/autonomy/db.js
CHANGED
|
@@ -44,6 +44,24 @@ async function lastAutonomyHead(routine) {
|
|
|
44
44
|
return rows[0]?.head_sha || null;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// The recent autonomy-gate decisions, newest first — the off-box answer to "did the
|
|
48
|
+
// routine fire, and what did it decide" (task 1002669). Every precheck writes a row
|
|
49
|
+
// here, every SKIP included, so the table is the whole record; before this read
|
|
50
|
+
// existed, finding out needed an SSH session on the host (blocker 1000106). `routine`
|
|
51
|
+
// null means every routine. The (routine, created_at DESC) index serves both shapes.
|
|
52
|
+
async function readAutonomyRuns({ routine = null, limit = 20 } = {}) {
|
|
53
|
+
const { rows } = await pool.query(
|
|
54
|
+
`SELECT id, routine, decision, reason, head_sha, claimable_count, enabled, created_at
|
|
55
|
+
FROM autonomy_runs
|
|
56
|
+
WHERE ($1::text IS NULL OR routine = $1)
|
|
57
|
+
ORDER BY created_at DESC, id DESC
|
|
58
|
+
LIMIT $2`,
|
|
59
|
+
[routine, limit]
|
|
60
|
+
);
|
|
61
|
+
// bigserial ids arrive as strings from node-postgres; keep them strings on purpose.
|
|
62
|
+
return rows.map((r) => ({ ...r, id: String(r.id) }));
|
|
63
|
+
}
|
|
64
|
+
|
|
47
65
|
// ── the Autobongos fence (task 1003908, ADR 0307 §6) ─────────────────────────
|
|
48
66
|
//
|
|
49
67
|
// These back the one control surface the runner host cannot write to. Everything
|
|
@@ -162,6 +180,7 @@ async function readRunnerHeartbeats(builderId) {
|
|
|
162
180
|
module.exports = {
|
|
163
181
|
recordAutonomyRun,
|
|
164
182
|
lastAutonomyHead,
|
|
183
|
+
readAutonomyRuns,
|
|
165
184
|
recordRunnerHeartbeat,
|
|
166
185
|
readRunnerHeartbeats,
|
|
167
186
|
readFence,
|
|
@@ -42,6 +42,16 @@ const { validateOrRespond } = api;
|
|
|
42
42
|
//
|
|
43
43
|
// rank: archon — autonomy is an ops control surface, and a precheck records an
|
|
44
44
|
// autonomy_runs row + git-fetches. Keep it archon-scoped (ADR 0016).
|
|
45
|
+
// ?limit for GET /autonomy/runs: an integer 1..100, else the default 20. Clamped rather
|
|
46
|
+
// than refused — a read an operator types by hand should answer, not argue.
|
|
47
|
+
const RUNS_DEFAULT_LIMIT = 20;
|
|
48
|
+
const RUNS_MAX_LIMIT = 100;
|
|
49
|
+
function runsLimit(raw) {
|
|
50
|
+
const n = Number.parseInt(String(raw ?? ''), 10);
|
|
51
|
+
if (!Number.isFinite(n)) return RUNS_DEFAULT_LIMIT;
|
|
52
|
+
return Math.min(RUNS_MAX_LIMIT, Math.max(1, n));
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
module.exports = function buildAutonomyRouter() {
|
|
46
56
|
const router = express.Router();
|
|
47
57
|
|
|
@@ -58,6 +68,24 @@ module.exports = function buildAutonomyRouter() {
|
|
|
58
68
|
}
|
|
59
69
|
});
|
|
60
70
|
|
|
71
|
+
// The gate's past decisions — did a routine fire, and what did it decide, and why
|
|
72
|
+
// (task 1002669). READ-ONLY and behind the SAME atom as the precheck above
|
|
73
|
+
// (`autonomy.precheck`, Metic+): whoever may ask the gate the question may read its
|
|
74
|
+
// past answers, and a new atom would need a migration for no change in audience.
|
|
75
|
+
// Adds no gate anywhere — pure observability over rows the precheck already writes.
|
|
76
|
+
// ?routine=<name> narrows to one routine; ?limit=1..100 (default 20), newest first.
|
|
77
|
+
router.get('/autonomy/runs', auth.requireBuilder, auth.requirePermission('autonomy.precheck'), async (req, res) => {
|
|
78
|
+
const routine = typeof req.query.routine === 'string' && req.query.routine ? req.query.routine.slice(0, 64) : null;
|
|
79
|
+
const limit = runsLimit(req.query.limit);
|
|
80
|
+
try {
|
|
81
|
+
const runs = await db.readAutonomyRuns({ routine, limit });
|
|
82
|
+
res.json({ routine, limit, runs });
|
|
83
|
+
} catch (err) {
|
|
84
|
+
log.error('[gds] GET /autonomy/runs', err);
|
|
85
|
+
res.fail('autonomy_runs_unreadable', { status: 503, message: 'could not read the autonomy decisions' });
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
61
89
|
// ── the Autobongos fence (task 1003908, ADR 0307 §6) ───────────────────────
|
|
62
90
|
//
|
|
63
91
|
// These four routes ARE the fence. Everything the unattended runner is allowed
|