@bongos/core 1.20.26 → 1.20.28

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 (54) hide show
  1. package/.bongos-core.json +117 -47
  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 +5 -1
  6. package/clients/bongos-client/index.mjs +2 -0
  7. package/docs/adr/0335-an-invite-is-a-pre-approved-row-on-the-projects-own-instance.md +1 -1
  8. package/docs/adr/0353-a-hub-invite-is-a-notice-of-the-projects-own-invite.md +2 -2
  9. package/docs/adr/0355-a-soft-limit-is-a-rule-with-a-reason-and-nobody-enforces-it.md +30 -0
  10. package/docs/adr/0356-a-recruit-invite-expires-30-days-after-it-is-sent-read-time.md +46 -0
  11. package/docs/adr/README.md +2 -0
  12. package/docs/api/openapi.json +105 -5
  13. package/docs/api-reference.md +3 -2
  14. package/docs/copy-inventory.md +37 -36
  15. package/docs/copy-registry.json +52 -43
  16. package/docs/module-api-changelog.md +4 -0
  17. package/docs/page-readings.json +70 -68
  18. package/migrations/core_266_access_requests_invited_login_idx.sql +31 -0
  19. package/modules/government/board.js +64 -7
  20. package/modules/government/charter.js +232 -0
  21. package/modules/government/routes/government.js +62 -0
  22. package/modules/hall-ui/public/government.js +11 -0
  23. package/modules/hall-ui/public/watch.js +9 -3
  24. package/modules/onboarding/routes/access-requests.js +43 -20
  25. package/modules/platform-identity/migrations/platform_identity_028_purge_pre_notice_invites.sql +65 -0
  26. package/modules/platform-identity/platform-identity.js +12 -8
  27. package/modules/platform-identity/tests/platform-identity.mjs +4 -2
  28. package/modules/provisioning/planet-physics.js +154 -0
  29. package/modules/provisioning/provisioning.js +29 -9
  30. package/modules/provisioning/routes/body-validators.js +25 -7
  31. package/modules/provisioning/routes/provisioning.js +8 -3
  32. package/modules/provisioning/screening.js +62 -0
  33. package/modules/provisioning/soft-limits.js +146 -0
  34. package/package-lock.json +2 -2
  35. package/package.json +1 -1
  36. package/release-notes.json +24 -0
  37. package/scripts/gds/fitness.js +4 -0
  38. package/scripts/gds/login.js +6 -0
  39. package/scripts/gds/run-unit-tests.js +8 -0
  40. package/src/bongos/db-kernel.js +6 -3
  41. package/src/bongos/invite-expiry.js +47 -0
  42. package/src/bongos/route-rank-check.js +3 -0
  43. package/src/module-api.js +10 -1
  44. package/tests/access_requests_invite.mjs +2 -1
  45. package/tests/application_lifecycle.mjs +164 -5
  46. package/tests/bongos_login.mjs +2 -0
  47. package/tests/government_charter_forms.mjs +283 -0
  48. package/tests/hub_invite_notices.mjs +5 -2
  49. package/tests/invite_expiry.mjs +37 -0
  50. package/tests/invite_expiry_db.mjs +196 -0
  51. package/tests/module_api.mjs +1 -0
  52. package/tests/pending_invite_purge_db.mjs +129 -0
  53. package/tests/project_admin_console_model.mjs +12 -5
  54. package/tests/provisioning_planet_physics.mjs +377 -0
@@ -0,0 +1,46 @@
1
+ # ADR 0356 — A recruit invite expires 30 days after it is sent, decided at read time
2
+
3
+ - **Status:** accepted
4
+ - **Date:** 2026-09-30
5
+ - **Task:** [task 1002969](https://cloudbongos.com/builders#/task/1002969) (goal 1000110)
6
+ - **Builds on:** privacy spec D4 (`docs/specs/<redacted>.md`; the owner signed the 30 days), [ADR 0335](0335-an-invite-is-a-pre-approved-row-on-the-projects-own-instance.md) D2 (an invite is a `kind='invite'` row on the project's own instance), [ADR 0353](0353-a-hub-invite-is-a-notice-of-the-projects-own-invite.md) (the hub's `pending` row is a notice of that invite)
7
+ - **Amends:** ADR 0335 D2.5 ("no admission path reads `kind`")
8
+ - **Decided with:** the owner split the original task on 2026-09-30. `seen_at` is [task 1004443](https://cloudbongos.com/builders#/task/1004443); the decline relay is [task 1004444](https://cloudbongos.com/builders#/task/1004444).
9
+
10
+ ## Context
11
+
12
+ An invite writes an `invited` row, and the sign-in gate admits any login holding one. Nothing ever closed it, so an invite sent months ago still let its login walk in. Spec D4 says a recruit invite's door closes after 30 days, enforced when it is read: no sweeper and no cron. ADR 0353 left the hub side of the same question to this task, because an expired invite's hub notice still said "Open project →".
13
+
14
+ ## Decision
15
+
16
+ **D1 — One definition, computed at read time.** `src/bongos/invite-expiry.js` holds `INVITE_EXPIRY_DAYS` (30) and the SQL for "this row is an invite past its window", `kind = 'invite' AND created_at <= now() - interval '30 days'`. The sign-in gate (`hasInvitedAccessRequest`), the waiting-page probe (`accessStateByLogin`), the onboarding routes and the hub all read it: core directly, and modules through the doorway's `inviteExpiry`. Nothing is stored, so the day a door closes cannot drift between readers, and nothing has to run for it to close.
17
+
18
+ **D2 — Only invites expire.** An approved application (`kind = 'application'`) stays open: its applicant asked, and D4 is about invites. Goal invites get no expiry either.
19
+
20
+ **D3 — The gate now reads `kind`, and only to be stricter (amends ADR 0335 D2.5).** D2.5 kept `kind` out of admission because it was descriptive. It is now read in one place, inside the expiry unit, and that unit can only close a door. A row that is anything but an invite behaves exactly as before, so a mis-kinded row fails toward the old gate and never past it. Only server code writes `kind`: the public POST cannot set it. `created_by` is still never read. `tests/application_lifecycle.mjs` enforces both: its admission statements may mention `kind` only inside the expiry unit.
21
+
22
+ **D4 — What an expired invite looks like.**
23
+ - The gate refuses it. The public "already approved?" check and the standing-invite probe no longer count it, so the invitee may apply and the recruiter can re-invite.
24
+ - A re-invite writes a fresh row, which opens a fresh door. The expired row stays as history.
25
+ - The queue marks it `expired` with `expires_at`. The outstanding-invite list keeps it so the sender knows to invite again, and drops it once a newer invite for that login is live. The hall's queue shows "Invite expired" and offers no rescind.
26
+ - The public status probe answers `expired` (`admitted: false`), and `bongos login` stops waiting on it. An older CLI treats an unknown status as "wait" and times out, which is no worse than before.
27
+ - A rescind that leaves only expired rows clears the hub notice.
28
+
29
+ **D5 — The hub's notice follows the door.** `listPendingInvitesForAccount` hides a `pending` notice older than the same 30 days (its `joined_at` is when the project sent the notice). `inviteToProject` restamps `joined_at` only on a `pending` row that is already past the window, so a re-invite shows again. A re-send while the invite is live changes nothing, and a real membership is never touched.
30
+
31
+ ## Consequences
32
+
33
+ - **Invites already older than 30 days close at deploy.** That is the spec's rule applied to existing rows. Their senders re-invite.
34
+ - **Wire skew (ADR 0352).** A newer hub with an older instance hides a notice after 30 days while that instance's door stays open. Only the nudge is lost. An older hub with a newer instance keeps showing an expired notice, which is today's behaviour.
35
+ - **The hub's clock is the notice's, not the invite's.** A notice healed by a late re-send (the hub missed the first) can outlive its invite by up to the gap between them. A lost clear can hide a live notice early. In both cases the next re-invite fixes it.
36
+ - **The outstanding list's cost stays that of its own scan.** "Does this login have a live invite" is a window (`bool_or … OVER (PARTITION BY lower(github_login))`) over the rows the list already reads, not a correlated lookup per row: `access_requests` has no index on `lower(github_login)` outside pending rows, and invite rows are kept as history. The sender filter (`?mine=1`) sits outside the window. Migration `core_266` adds the index those reads lacked, partial on `status = 'invited'` over `lower(github_login)`, which serves the sign-in gate, the standing-invite probe and this list. The owner approved it on 2026-09-30 after a grader finding.
37
+ - **Declining still closes only the hub's notice.** The project's row stays open until it expires. Task 1004444 owns the relay.
38
+
39
+ ## Alternatives considered
40
+
41
+ - **A sweeper that flips expired rows to `dismissed`.** Spec D4 rules it out. It would also mislabel an expiry as a decline in the history.
42
+ - **Expire every `invited` row, applications included.** That is wider than D4, and at deploy it would lock out every applicant approved more than 30 days ago.
43
+ - **Dismiss the expired row when re-inviting.** That keeps the list tidy, but the hall renders `dismissed` as "Declined", which would be false.
44
+ - **Carry the invite's `created_at` to the hub in a header, making its clock exact.** That is a new wire field on the notify route for an edge case a re-invite already heals.
45
+
46
+ Proof: `tests/invite_expiry.mjs` (the definition), `tests/application_lifecycle.mjs` (the gate, queues, probe, re-invite and notice clear, interpreted), `tests/invite_expiry_db.mjs` (the same statements on real Postgres, plus the hub's notice), `tests/hub_invite_notices.mjs` and `modules/platform-identity/tests/platform-identity.mjs` (the notice statement's shape), `tests/bongos_login.mjs` (the CLI stops on `expired`).
@@ -473,3 +473,5 @@ These 20 numbers are each shared by exactly two files. They are **accepted histo
473
473
  | 0352 | [**A rollup report carries its "as of" in a header, and the hub keeps the newest** ([task 1004268](https://cloudbongos.com/builders#/task/1004268), goal 1000110). `POST /sso/activity/rollup` was last-writer-wins with no report timestamp, so a sign-in push read earlier and a ship push read later could land the older totals last. **D1:** the instance's read time rides a `Bongos-Report-As-Of` HEADER, not a body field, because the hub validates the body strictly and hub and instances upgrade independently: a body field from a newer instance would 400 on an older hub and lose the report, while an unknown header is ignored. **D2:** missing or unparseable = unstamped = last-writer-wins, never a 400. **D3:** the guard is a WHERE on the upsert's conflict branch (migration 026, `reported_as_of`, no backfill); a skipped update keeps the row lock, so the task 1004244 snapshot stays in step. **D4:** the stamp is compared only with the same client's, and clamped to the hub's `now()`.](0352-a-rollup-report-carries-its-as-of-in-a-header.md) | platform identity / federation |
474
474
  | 0353 | [**A hub invite is a notice of the project's own invite, and signing in accepts it** ([task 1002818](https://cloudbongos.com/builders#/task/1002818), goal 1000110 — R6 of the admin console wave). The hub's own invite wrote a `pending` membership that no project reads, so an "accepted" invite met a locked door (new projects default to `apply`). **D1:** that row is now a NOTICE the PROJECT writes: its invite route calls `POST /sso/invites/notify` and a dismissal that leaves no invited row calls `/sso/invites/clear` (client credentials, pending rows only, always `{ ok: true }` so no account oracle); core's `notifyHubOfInvite` is fire-and-forget. **D2:** the hub-side accept route is deleted; signing in to the project accepts, and the hub's own sign-in witness turns the row into a membership. **D3 (owner):** `POST /projects/invite` writes nothing and answers `{ invited: false, invite_url }`, the project's hall invite link (`/builders/watch?invite=<login>`, which only pre-fills); the signed-assertion relay is deferred. **D4:** new routes, so an older hub 404s and only the notice is lost (ADR 0352).](0353-a-hub-invite-is-a-notice-of-the-projects-own-invite.md) | platform identity / federation |
475
475
  | 0354 | [**A builder hosts one project for free, and more takes the fleet permission** ([task 1004412](https://cloudbongos.com/builders#/task/1004412), goal 1000106 — working area 1, the owner's ruling of 2026-09-30). The create wizard always asks for `cloud-host`, which task 1003370 had gated behind `provisioning.fleet.manage`, so every new (Xenos) user was refused at "Create my project" — against ADR 0345 decision 1. **D1:** a builder's first live `cloud-host` project needs no permission; a further one needs the fleet permission (a retry of your own slug is the same project; only `torn_down` frees the place; an unreadable count refuses). **D2:** one first-free request per builder at a time (409 `create_in_progress`), held as a Postgres advisory lock so it holds across processes. **D3:** the wizard states `permission_forbidden` and `box_full` in plain words. Nothing yet caps a hosted project's memory.](0354-a-builder-hosts-one-project-free-and-more-takes-the-fleet-permission.md) | provisioning / security / project creation |
476
+ | 0355 | [**A soft limit is a rule with a reason, and nobody enforces it** ([task 1004416](https://cloudbongos.com/builders#/task/1004416), goal 1000121 — BV2.PS02). The startup flow's seven planet-physics answers and what they rule out. **D1:** the answers are more provisioning `detail` keys under `team_shape`'s contract (no defaults, refused loudly, `null` un-answers), with two new kinds — a list (`many`) and a whole number (`count`); the country is a closed ISO list. **D2:** answers must agree only within one request, so a merge patch's edit order never matters. **D3:** one declarative soft-limit table (`soft-limits.js`) — data conditions, `hide`/`grey`/`note`, a reason on every rule — and every resolution says `enforced: false`. **D4:** screening is a seam (`screening.js`) with a deliberately small rule set; a stop is 422 `screened_out` before anything exists. **D5:** the edit route screens a new description too.](0355-a-soft-limit-is-a-rule-with-a-reason-and-nobody-enforces-it.md) | provisioning / project startup |
477
+ | 0356 | [**A recruit invite expires 30 days after it is sent, decided at read time** ([task 1002969](https://cloudbongos.com/builders#/task/1002969), goal 1000110 — privacy spec D4, owner-signed). **D1:** one definition, `src/bongos/invite-expiry.js` (`INVITE_EXPIRY_DAYS` + the SQL), read by the sign-in gate, the waiting-page probe, the onboarding routes and, through the doorway's `inviteExpiry`, the hub. Nothing is stored and nothing sweeps. **D2:** only `kind='invite'` rows expire; approved applications and goal invites do not. **D3:** amends ADR 0335 D2.5: the gate reads `kind` only inside the expiry unit, which can close a door and never open one. **D4:** an expired invite is refused, marked `expired` + `expires_at` in the queues, reported `expired` by the status probe (the CLI stops), and replaced by a re-invite's fresh row. **D5:** the hub hides a `pending` notice past 30 days and a re-invite restamps it. Split out: `seen_at` (task 1004443), the decline relay (task 1004444).](0356-a-recruit-invite-expires-30-days-after-it-is-sent-read-time.md) | platform identity / admission / invites |
@@ -440,7 +440,7 @@
440
440
  "access-requests"
441
441
  ],
442
442
  "summary": "GET /access-requests/invites",
443
- "description": "GET /access-requests/invites[?mine=1] — the outstanding invites: kind='invite', still 'invited' (not rescinded), and no builder row yet (not yet accepted by signing in), each naming its sender; ?mine=1 keeps only the caller's own (ADR 0335 D2; task 1002814). Rescind one with PATCH /access-requests/:id. rank: archon — it names logins that are not members yet.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `access_request.review` (all required).",
443
+ "description": "GET /access-requests/invites[?mine=1] — the outstanding invites: kind='invite', still 'invited' (not rescinded), and no builder row yet (not yet accepted by signing in), each naming its sender; ?mine=1 keeps only the caller's own (ADR 0335 D2; task 1002814). Rescind one with PATCH /access-requests/:id. Each carries `expires_at`, and `expired` once its 30 days are up (task 1002969): listed so the sender knows to invite again, and dropped once a newer invite for the same login is live, since that one already replaced it. rank: archon — it names logins that are not members yet.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `access_request.review` (all required).",
444
444
  "x-rank": "archon",
445
445
  "x-source": "modules/onboarding/routes/access-requests.js",
446
446
  "x-permissions": [
@@ -481,7 +481,7 @@
481
481
  "access-requests"
482
482
  ],
483
483
  "summary": "GET /access-requests/status",
484
- "description": "GET /access-requests/status?github_login=X — PUBLIC. The `bongos login` CLI polls this after filing a request: the device flow's not_approved is TERMINAL (the device_code is spent), so the CLI can't re-poll the flow — it polls this instead, then restarts sign-in once admitted. Exposes nothing the public POST above doesn't already reveal through its 409s (already_member / already_approved). status ∈ member | invited | pending | dismissed | none; admitted = member||invited. rank: public — a would-be builder is by definition outside the system. Declared BEFORE `GET /access-requests` so the literal `/status` path is matched as its own route (not swallowed as a query on the list route). RATE-LIMITED (task 1003339 / ADR 0209). Public + unthrottled, this was a login→membership oracle an attacker could script at line rate to learn who builds here. accountExistenceReadRateLimit is the doorway's SHARED 120/60s per-IP budget: core's GET /auth/web/admission-status (the boolean twin of this answer) mounts the very same instance, so the two cannot be alternated for double the rate. The limiter runs before the queries, so a refused probe costs no DB work. Whether the ANSWER should also collapse — so a caller who is not the subject cannot tell pending/dismissed/none apart — is the owner's call and is filed as a blocker, not decided here.\n\n**Rank:** `public` — No authentication — any caller.",
484
+ "description": "GET /access-requests/status?github_login=X — PUBLIC. The `bongos login` CLI polls this after filing a request: the device flow's not_approved is TERMINAL (the device_code is spent), so the CLI can't re-poll the flow — it polls this instead, then restarts sign-in once admitted. Exposes nothing the public POST above doesn't already reveal through its 409s (already_member / already_approved). status ∈ member | invited | expired | pending | dismissed | none; admitted = member||invited. `expired` is an invite past its 30 days (task 1002969): the door is shut, and the CLI stops waiting rather than polling a door that will not open. rank: public — a would-be builder is by definition outside the system. Declared BEFORE `GET /access-requests` so the literal `/status` path is matched as its own route (not swallowed as a query on the list route). RATE-LIMITED (task 1003339 / ADR 0209). Public + unthrottled, this was a login→membership oracle an attacker could script at line rate to learn who builds here. accountExistenceReadRateLimit is the doorway's SHARED 120/60s per-IP budget: core's GET /auth/web/admission-status (the boolean twin of this answer) mounts the very same instance, so the two cannot be alternated for double the rate. The limiter runs before the queries, so a refused probe costs no DB work. Whether the ANSWER should also collapse — so a caller who is not the subject cannot tell pending/dismissed/none apart — is the owner's call and is filed as a blocker, not decided here.\n\n**Rank:** `public` — No authentication — any caller.",
485
485
  "x-rank": "public",
486
486
  "x-source": "modules/onboarding/routes/access-requests.js",
487
487
  "responses": {
@@ -7898,6 +7898,58 @@
7898
7898
  ]
7899
7899
  }
7900
7900
  },
7901
+ "/government/board/charter": {
7902
+ "post": {
7903
+ "operationId": "post_government_board_charter",
7904
+ "tags": [
7905
+ "government"
7906
+ ],
7907
+ "summary": "POST /government/board/charter",
7908
+ "description": "board.item.open — the genesis charter + legislation choice (task 1004427, spec D10): a form of government and/or its two live settings (franchise, pass rule), built into a whole constitution on top of the live one and filed through the SAME amendment path as the route above — the same atom, the same strict validation, the same self-removal guard. Nothing here changes the constitution; the sitting it opens is what decides.\n\n**Rank:** `metic+archon` — Metic or Archon rank (review/triage powers).\n\n**Permissions:** `board.item.open` (all required).",
7909
+ "x-rank": "metic+archon",
7910
+ "x-source": "modules/government/routes/government.js",
7911
+ "x-permissions": [
7912
+ "board.item.open"
7913
+ ],
7914
+ "requestBody": {
7915
+ "required": false,
7916
+ "content": {
7917
+ "application/json": {
7918
+ "schema": {
7919
+ "$ref": "#/components/schemas/PostGovernmentBoardCharterRequest"
7920
+ }
7921
+ }
7922
+ },
7923
+ "x-validated": true
7924
+ },
7925
+ "responses": {
7926
+ "200": {
7927
+ "description": "Success.",
7928
+ "content": {
7929
+ "application/json": {
7930
+ "schema": {
7931
+ "$ref": "#/components/schemas/PostGovernmentBoardCharterResponse"
7932
+ }
7933
+ }
7934
+ }
7935
+ },
7936
+ "400": {
7937
+ "$ref": "#/components/responses/ValidationFailed"
7938
+ },
7939
+ "401": {
7940
+ "$ref": "#/components/responses/Unauthorized"
7941
+ },
7942
+ "403": {
7943
+ "$ref": "#/components/responses/Forbidden"
7944
+ }
7945
+ },
7946
+ "security": [
7947
+ {
7948
+ "builderSession": []
7949
+ }
7950
+ ]
7951
+ }
7952
+ },
7901
7953
  "/government/board/genesis-stages": {
7902
7954
  "get": {
7903
7955
  "operationId": "get_government_board_genesis_stages",
@@ -24576,6 +24628,7 @@
24576
24628
  "description": {},
24577
24629
  "detail": {},
24578
24630
  "options": {},
24631
+ "soft_limits": {},
24579
24632
  "publish": {},
24580
24633
  "modules": {},
24581
24634
  "type": {}
@@ -24585,6 +24638,7 @@
24585
24638
  "description",
24586
24639
  "detail",
24587
24640
  "options",
24641
+ "soft_limits",
24588
24642
  "publish",
24589
24643
  "modules",
24590
24644
  "type"
@@ -26511,6 +26565,52 @@
26511
26565
  ],
26512
26566
  "additionalProperties": false
26513
26567
  },
26568
+ "PostGovernmentBoardCharterRequest": {
26569
+ "type": "object",
26570
+ "properties": {
26571
+ "form": {
26572
+ "type": "string",
26573
+ "maxLength": 64
26574
+ },
26575
+ "franchise": {
26576
+ "type": "string",
26577
+ "maxLength": 32
26578
+ },
26579
+ "council_rank": {
26580
+ "type": "string",
26581
+ "maxLength": 64
26582
+ },
26583
+ "pass_rule": {
26584
+ "type": "string",
26585
+ "maxLength": 32
26586
+ },
26587
+ "rationale_md": {
26588
+ "type": "string",
26589
+ "maxLength": 5000
26590
+ },
26591
+ "acknowledge_self_removal": {
26592
+ "type": "boolean"
26593
+ }
26594
+ },
26595
+ "additionalProperties": false
26596
+ },
26597
+ "PostGovernmentBoardCharterResponse": {
26598
+ "type": "object",
26599
+ "properties": {
26600
+ "ok": {
26601
+ "type": "boolean"
26602
+ },
26603
+ "amendment": {},
26604
+ "item": {},
26605
+ "reads_as": {}
26606
+ },
26607
+ "required": [
26608
+ "ok",
26609
+ "amendment",
26610
+ "item",
26611
+ "reads_as"
26612
+ ]
26613
+ },
26514
26614
  "PostGovernmentBoardItemsItemIdVotesRequest": {
26515
26615
  "type": "object",
26516
26616
  "properties": {
@@ -29663,9 +29763,9 @@
29663
29763
  "description": "A required dependency/feature is not configured or is temporarily down."
29664
29764
  }
29665
29765
  },
29666
- "x-endpoint-count": 464,
29667
- "x-schema-count": 496,
29766
+ "x-endpoint-count": 465,
29767
+ "x-schema-count": 498,
29668
29768
  "x-undocumented-bodies": 12,
29669
- "x-response-schemas": 336,
29769
+ "x-response-schemas": 337,
29670
29770
  "x-generated-by": "scripts/gds/gen-api-docs.js"
29671
29771
  }
@@ -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. 464 endpoints across 83 route files.
5
+ > **Generated from the live route files** — the route file is authoritative. 465 endpoints across 83 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`.
@@ -310,13 +310,14 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
310
310
  | GET | `/api/bongos/goals/rollups` | `any-builder` | — | GET /goals/rollups?version= — one small row per goal: readiness counters, the last-activity timestamp, the craft set, and the next claima… |
311
311
  | GET | `/api/bongos/goals/suggestions` | `any-builder` | — | GET /goals/suggestions — "which goal should this draft live in?", answered before anything is created (task 1003062 / R07). |
312
312
 
313
- ## `government` (14)
313
+ ## `government` (15)
314
314
 
315
315
  | Method | Path | Rank | Body | Description |
316
316
  |---|---|---|---|---|
317
317
  | GET | `/api/bongos/government/assignments` | `archon` | — | government.manage — every builder↔rank assignment row. |
318
318
  | POST | `/api/bongos/government/assignments` | `archon` | `builder_id`, `rank_key` | government.manage — assign a CUSTOM rank to a builder. |
319
319
  | DELETE | `/api/bongos/government/assignments/:builderId/:rankKey` | `archon` | — | government.manage — remove a custom-rank assignment. |
320
+ | POST | `/api/bongos/government/board/charter` | `metic+archon` | `form`, `franchise`, `council_rank`, `pass_rule`, `rationale_md`, `acknowledge_self_removal` | board.item.open — the genesis charter + legislation choice (task 1004427, spec D10): a form of government and/or its two live settings (f… |
320
321
  | GET | `/api/bongos/government/board/genesis-stages` | `any-builder` | — | board.vote.cast — the founding band's read (task 1004429): each genesis stage's latest sitting, and who it is still waiting on under the … |
321
322
  | GET | `/api/bongos/government/board/items` | `any-builder` | — | board.vote.cast — the Board Room view: open items with their clock, the OPEN BALLOT, the closed history (R16 of goal 1000069). |
322
323
  | POST | `/api/bongos/government/board/items` | `metic+archon` | `subject_type`, `proposal`, `rationale_md`, `acknowledge_self_removal` | board.item.open — put an AMENDMENT to the board (R14 of goal 1000069, ADR 0175 §7). |
@@ -4,13 +4,13 @@
4
4
  > Deterministic on a given tree — regenerate and commit rather than hand-editing.
5
5
  > Machine-readable twin: [`copy-registry.json`](copy-registry.json).
6
6
 
7
- **2188 strings** across 3 surfaces · 1888 distinct pieces of copy · 2188 certain, 0 heuristic · 207 shown in more than one place.
7
+ **2189 strings** across 3 surfaces · 1889 distinct pieces of copy · 2189 certain, 0 heuristic · 207 shown in more than one place.
8
8
 
9
9
  ## Surfaces
10
10
 
11
11
  | surface | lives at | files | strings |
12
12
  |---|---|---|---|
13
- | `builders-hall` | `modules/hall-ui/public` | 109 | 1617 |
13
+ | `builders-hall` | `modules/hall-ui/public` | 109 | 1618 |
14
14
  | `status-dashboard` | `modules/status-ui/public` | 4 | 100 |
15
15
  | `landing` | `modules/public-landing/public` | 6 | 471 |
16
16
 
@@ -52,7 +52,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
52
52
  | `a5257c88eb07` | 4x | GitHub username | modules/public-landing/public/projects.html:1009, modules/public-landing/public/projects.html:1010, modules/public-landing/public/projects.html:1497 |
53
53
  | `971f3eb36342` | 4x | How to read the sky | modules/hall-ui/public/goal-map.html:69, modules/hall-ui/public/goal-map.html:108, modules/hall-ui/public/thinking.html:86 |
54
54
  | `3eb67b892dea` | 4x | Percy Jackson | modules/public-landing/public/index.html:806, modules/public-landing/public/index.html:824, modules/public-landing/public/index.html:830 |
55
- | `0887725744f2` | 4x | Restricted. | modules/hall-ui/public/board-room.js:526, modules/hall-ui/public/gate.js:234, modules/hall-ui/public/government.js:879 |
55
+ | `0887725744f2` | 4x | Restricted. | modules/hall-ui/public/board-room.js:526, modules/hall-ui/public/gate.js:234, modules/hall-ui/public/government.js:890 |
56
56
  | `47b6199cc471` | 4x | Show or hide the clock | modules/hall-ui/public/goal-map.html:68, modules/hall-ui/public/goal-map.html:68, modules/hall-ui/public/thinking.html:85 |
57
57
  | `df38941b25a6` | 4x | Sign in with GitHub | modules/public-landing/public/account.html:106, modules/public-landing/public/projects.html:679, modules/public-landing/public/projects.html:781 |
58
58
  | `2ae36be1c531` | 4x | Start a project | modules/public-landing/public/index.html:730, modules/public-landing/public/index.html:894, modules/public-landing/public/projects.html:567 |
@@ -78,7 +78,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
78
78
  | `064c72453555` | 3x | goals · | modules/hall-ui/public/roadmap.js:218, modules/hall-ui/public/sky-interaction.js:38, modules/hall-ui/public/sky-interaction.js:129 |
79
79
  | … | | _167 more in the JSON registry_ | |
80
80
 
81
- ## `builders-hall` — 1617 strings
81
+ ## `builders-hall` — 1618 strings
82
82
 
83
83
  | id | conf | text | where |
84
84
  |---|---|---|---|
@@ -184,18 +184,18 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
184
184
  | `206acb4467a2` | certain | Archive this goal? | `modules/hall-ui/public/goals-render.js:1008` |
185
185
  | `d9dd46194f35` | certain | Argue from mechanism, not vibes. Always name the assumption a number rests on. | `modules/hall-ui/public/settings.html:245` |
186
186
  | `4d3b1bcae3eb` | certain | Artist Review Status | `modules/hall-ui/public/studio.html:125` |
187
- | `5fcfdf8975cf` | certain | As configuration: | `modules/hall-ui/public/government.js:829` |
187
+ | `5fcfdf8975cf` | certain | As configuration: | `modules/hall-ui/public/government.js:839` |
188
188
  | `01a0f29ff406` | certain | As first filed | `modules/hall-ui/public/idea.js:467` |
189
189
  | `9b02ba5e6d23` | certain | Asked of others | `modules/hall-ui/public/collab.html:131` |
190
190
  | `688cc6dd38ee` | certain | Asked of you | `modules/hall-ui/public/collab.html:48` |
191
191
  | `688cc6dd38ee` | certain | Asked of you | `modules/hall-ui/public/collab.html:122` |
192
192
  | `b2656d0b2402` | certain | Asked {…} | `modules/hall-ui/public/collab.js:91` |
193
- | `b2656d0b2402` | certain | Asked {…} | `modules/hall-ui/public/watch.js:511` |
193
+ | `b2656d0b2402` | certain | Asked {…} | `modules/hall-ui/public/watch.js:517` |
194
194
  | `8c8ec2597036` | certain | Assigned {…} to builder {…}. | `modules/hall-ui/public/government.js:463` |
195
195
  | `46714066f2da` | certain | Audit log | `modules/hall-ui/public/watch.html:141` |
196
196
  | `d7c574ba6b2a` | certain | Autobongos runner | `modules/hall-ui/public/gate.html:53` |
197
197
  | `1de02052abf2` | certain | Available from the {…} rank up. | `modules/hall-ui/public/gate.js:237` |
198
- | `1de02052abf2` | certain | Available from the {…} rank up. | `modules/hall-ui/public/government.js:882` |
198
+ | `1de02052abf2` | certain | Available from the {…} rank up. | `modules/hall-ui/public/government.js:893` |
199
199
  | `bdbe9ff6a177` | certain | Awaiting the grader, or a confirmation, before it can ship. | `modules/hall-ui/public/task.js:737` |
200
200
  | `ecfbb10d4ca9` | certain | Awaiting the owner/manager's approval | `modules/hall-ui/public/goals-render.js:943` |
201
201
  | `08afb1257b71` | certain | Back to home | `modules/hall-ui/public/drachmae.html:87` |
@@ -248,7 +248,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
248
248
  | `4b714191b423` | certain | Changes touching protected build surfaces, held for your approval. | `modules/hall-ui/public/gate.js:403` |
249
249
  | `55ad21bd03eb` | certain | Chart the routes | `modules/hall-ui/public/goal-map.html:91` |
250
250
  | `55ad21bd03eb` | certain | Chart the routes | `modules/hall-ui/public/thinking.html:108` |
251
- | `e6982a9ff948` | certain | Charter library | `modules/hall-ui/public/government.js:799` |
251
+ | `e6982a9ff948` | certain | Charter library | `modules/hall-ui/public/government.js:809` |
252
252
  | `12db2eacb3f0` | certain | Check this line (Shift + Enter) | `modules/hall-ui/public/tweak-editor.js:226` |
253
253
  | `98e16fff6561` | certain | Check this {…} line | `modules/hall-ui/public/tweak-editor.js:226` |
254
254
  | `f66f5cdaa732` | certain | Checked against {…} — nothing blocks this move.{…} | `modules/hall-ui/public/deploy.js:294` |
@@ -309,8 +309,8 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
309
309
  | `e269ff7b3144` | certain | Could not add that builder just now. | `modules/hall-ui/public/goals-render.js:1311` |
310
310
  | `7bcaeffb742f` | certain | Could not approve: {…} | `modules/hall-ui/public/gate.js:123` |
311
311
  | `c922293e668c` | certain | Could not assign: {…} | `modules/hall-ui/public/government.js:468` |
312
- | `e1fc7cedf4e7` | certain | Could not change rank: {…} | `modules/hall-ui/public/watch.js:883` |
313
- | `b9e53fbd90e6` | certain | Could not change standing: {…} | `modules/hall-ui/public/watch.js:909` |
312
+ | `e1fc7cedf4e7` | certain | Could not change rank: {…} | `modules/hall-ui/public/watch.js:889` |
313
+ | `b9e53fbd90e6` | certain | Could not change standing: {…} | `modules/hall-ui/public/watch.js:915` |
314
314
  | `1ef1efc15b6c` | certain | Could not change that just now. | `modules/hall-ui/public/goals-render.js:1357` |
315
315
  | `6214998a5ebe` | certain | Could not check for a newer version: {…}. | `modules/hall-ui/public/settings-software-update.js:135` |
316
316
  | `9ab613a308d6` | certain | Could not check for updates: {…}. | `modules/hall-ui/public/settings-software-update.js:180` |
@@ -334,7 +334,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
334
334
  | `8b69e445592a` | certain | Could not load the question labels; showing the answers as stored. | `modules/hall-ui/public/idea.js:458` |
335
335
  | `edd5bafbe075` | certain | Could not load the queue just now. | `modules/hall-ui/public/ideas.js:885` |
336
336
  | `02bb0570996a` | certain | Could not load the ranks. | `modules/hall-ui/public/ranks.js:197` |
337
- | `2878778cf9f3` | certain | Could not load this page. | `modules/hall-ui/public/watch.js:1345` |
337
+ | `2878778cf9f3` | certain | Could not load this page. | `modules/hall-ui/public/watch.js:1351` |
338
338
  | `df4c2f78a3f6` | certain | Could not load this project’s skills — {…} | `modules/hall-ui/public/settings-specialities.js:311` |
339
339
  | `4b0c8d94541c` | certain | Could not load your account. Reload the page to try again. | `modules/hall-ui/public/settings.js:1156` |
340
340
  | `2a9fb4046bc4` | certain | Could not load your rank. Return to the hall and try again. | `modules/hall-ui/public/ranks.js:196` |
@@ -343,7 +343,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
343
343
  | `de244c45d916` | certain | Could not load {…} | `modules/hall-ui/public/task.js:1027` |
344
344
  | `2366356926b4` | certain | Could not mark the primer just now. Try again. | `modules/hall-ui/public/primer.js:259` |
345
345
  | `753987b5da13` | certain | Could not reach the submit endpoint. | `modules/hall-ui/public/modules.js:298` |
346
- | `6f500726f0ac` | certain | Could not read the report: {…} | `modules/hall-ui/public/watch.js:663` |
346
+ | `6f500726f0ac` | certain | Could not read the report: {…} | `modules/hall-ui/public/watch.js:669` |
347
347
  | `21c2f33168a3` | certain | Could not read this project's deploy state: {…} | `modules/hall-ui/public/deploy.js:449` |
348
348
  | `21a782f1af26` | certain | Could not read what this would bring in: {…}. The check below still applies. | `modules/hall-ui/public/deploy.js:368` |
349
349
  | `8b470cebf53d` | certain | Could not remove your key. Try again. | `modules/hall-ui/public/settings.js:977` |
@@ -375,7 +375,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
375
375
  | `e65b392144ac` | certain | Could not set up storage. Try again. | `modules/hall-ui/public/settings.js:956` |
376
376
  | `d4601887a058` | certain | Could not sign out everywhere: {…} | `modules/hall-ui/public/settings-sessions.js:102` |
377
377
  | `3db890b074a7` | certain | Could not update visibility just now. | `modules/hall-ui/public/goals-render.js:1341` |
378
- | `112d12b24879` | certain | Could not verify your access. Go back and try again. | `modules/hall-ui/public/watch.js:1344` |
378
+ | `112d12b24879` | certain | Could not verify your access. Go back and try again. | `modules/hall-ui/public/watch.js:1350` |
379
379
  | `6bd74fd20311` | certain | Could not verify your access. Try again. | `modules/hall-ui/public/sessions.js:436` |
380
380
  | `278e8281c82f` | certain | Could not vote: {…} | `modules/hall-ui/public/board-room.js:396` |
381
381
  | `a48e9f098392` | certain | Could not {…} just now. | `modules/hall-ui/public/goals-render.js:1327` |
@@ -432,7 +432,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
432
432
  | `c15d1f0ddfb6` | certain | Estimation accuracy | `modules/hall-ui/public/watch.html:148` |
433
433
  | `44f928d13699` | certain | Event sounds | `modules/hall-ui/public/settings.html:351` |
434
434
  | `8690c6424585` | certain | Every builder in {{worldName}} — rank, {{currency}}, karma, and active claims. | `modules/hall-ui/public/watch.html:69` |
435
- | `a97b064db76f` | certain | Every closed amendment sitting, ratified and returned alike, with the rule it was decided under. | `modules/hall-ui/public/government.js:839` |
435
+ | `a97b064db76f` | certain | Every closed amendment sitting, ratified and returned alike, with the rule it was decided under. | `modules/hall-ui/public/government.js:850` |
436
436
  | `2ae1eb35611e` | certain | Every done-when criterion for this goal, with its full detail. | `modules/hall-ui/public/goals.html:225` |
437
437
  | `8825f1d90dd1` | certain | Every idea this builder captured — promoted, discarded, merged, or still open. | `modules/hall-ui/public/profile.html:153` |
438
438
  | `25b6c0f9e74e` | certain | Every page is taken or on its way to the site right now. Come back soon. | `modules/hall-ui/public/studio.js:679` |
@@ -529,7 +529,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
529
529
  | `0469a83cf1e8` | certain | How Claude talks to you | `modules/hall-ui/public/settings.html:303` |
530
530
  | `68382894d8f9` | certain | How a planning session seeds each version's task pool, and how a version closes and archives its scope. | `modules/hall-ui/public/diagrams.html:85` |
531
531
  | `0bab9286ea38` | certain | How each builder's shipped work has been graded over the past thirty days. | `modules/hall-ui/public/watch.html:76` |
532
- | `fb7489e8b67c` | certain | How it has changed | `modules/hall-ui/public/government.js:839` |
532
+ | `fb7489e8b67c` | certain | How it has changed | `modules/hall-ui/public/government.js:850` |
533
533
  | `d76a5fcbde7c` | certain | How much the claim and ship cards show. Richer cards explain more and cost more tokens; the confirmation line | `modules/hall-ui/public/settings-render.js:84` |
534
534
  | `160adde1e398` | certain | How much your session cards — what | `modules/hall-ui/public/settings.html:298` |
535
535
  | `ec3f26ff8137` | certain | How planning sessions feed each version's task pool and how a version closes. | `modules/hall-ui/public/diagrams.html:84` |
@@ -541,7 +541,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
541
541
  | `06cb721a03e1` | certain | How the system works — {{worldName}} | `modules/hall-ui/public/diagrams.html:6` |
542
542
  | `06cb721a03e1` | certain | How the system works — {{worldName}} | `modules/hall-ui/public/diagrams.html:6` |
543
543
  | `4f3802e6c81e` | certain | How the whole build is doing — the program at a glance, then each version. Shipped work stays out of the way. | `modules/hall-ui/public/roadmap.js:433` |
544
- | `b536897de6a3` | certain | How this project is governed. | `modules/hall-ui/public/government.js:920` |
544
+ | `b536897de6a3` | certain | How this project is governed. | `modules/hall-ui/public/government.js:931` |
545
545
  | `971f3eb36342` | certain | How to read the sky | `modules/hall-ui/public/goal-map.html:69` |
546
546
  | `971f3eb36342` | certain | How to read the sky | `modules/hall-ui/public/goal-map.html:108` |
547
547
  | `971f3eb36342` | certain | How to read the sky | `modules/hall-ui/public/thinking.html:86` |
@@ -574,6 +574,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
574
574
  | `dad3388b49c9` | certain | Invitation rescinded. | `modules/hall-ui/public/goals-page.js:689` |
575
575
  | `12561be47da9` | certain | Invitation sent — they join once they accept. | `modules/hall-ui/public/goals-render.js:1270` |
576
576
  | `24f9e88c21f6` | certain | Invite by GitHub username | `modules/hall-ui/public/watch.js:295` |
577
+ | `33a35c77d372` | certain | Invite expired {…} — invite them again to reopen the door | `modules/hall-ui/public/watch.js:501` |
577
578
  | `b9cb720ad5d1` | certain | Invited? Sign in | `modules/hall-ui/public/hall-render.js:286` |
578
579
  | `0e48bb2c8c94` | certain | Island index | `modules/hall-ui/public/atlas.html:76` |
579
580
  | `2170b74c6526` | certain | Isometric map of the repository | `modules/hall-ui/public/atlas.html:54` |
@@ -801,7 +802,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
801
802
  | `a2bd76ae030d` | certain | Opens this project's upgrade{…}: you see what would move, confirm it, and it installs, checks itself, and roll | `modules/hall-ui/public/settings-software-update.js:85` |
802
803
  | `569980a263ae` | certain | Optional. This is the ledger link — a copy change ships as a task like every other change. | `modules/hall-ui/public/copy-desk.html:130` |
803
804
  | `f2e9e8f21e8e` | certain | Or add someone without asking… | `modules/hall-ui/public/goals-render.js:1234` |
804
- | `d89d1923ecf9` | certain | Over the last {…} days | `modules/hall-ui/public/watch.js:1182` |
805
+ | `d89d1923ecf9` | certain | Over the last {…} days | `modules/hall-ui/public/watch.js:1188` |
805
806
  | `695ffff13730` | certain | Over time | `modules/hall-ui/public/profile.html:72` |
806
807
  | `5ded44da0cc5` | certain | Override requests | `modules/hall-ui/public/watch.html:136` |
807
808
  | `0046e08db06a` | certain | Owner’s bill / month (est.) | `modules/hall-ui/public/fleet-costs.js:70` |
@@ -814,7 +815,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
814
815
  | `47d609ece51c` | certain | Pending invitations | `modules/hall-ui/public/goals-render.js:1412` |
815
816
  | `a69aff719f1a` | certain | People asking to join. Approve or dismiss each request, re-read the ones you already decided, and take back an | `modules/hall-ui/public/watch.html:62` |
816
817
  | `4a46b478edaf` | certain | Per page | `modules/hall-ui/public/hall-kit.js:74` |
817
- | `e1e10dc5e357` | certain | Permissions is the Archon administration surface. The Constitution and the Board Room are yours to read. | `modules/hall-ui/public/government.js:896` |
818
+ | `e1e10dc5e357` | certain | Permissions is the Archon administration surface. The Constitution and the Board Room are yours to read. | `modules/hall-ui/public/government.js:907` |
818
819
  | `6bc03d97457b` | certain | Pick a priority first. | `modules/hall-ui/public/task.js:913` |
819
820
  | `fcf996d77050` | certain | Pick a rank to see what it may do. The four ladder ranks ship with the platform; a custom rank is yours to sha | `modules/hall-ui/public/government.html:76` |
820
821
  | `45378ea261f6` | certain | Pick one… | `modules/hall-ui/public/settings.html:232` |
@@ -852,7 +853,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
852
853
  | `3f85bdc47099` | certain | Protected module scope — join by request; an Archon admits members | `modules/hall-ui/public/goals-render.js:856` |
853
854
  | `e5c292c8b361` | certain | Provides (seams) | `modules/hall-ui/public/atlas.js:288` |
854
855
  | `4de232a05888` | certain | Raise after | `modules/hall-ui/public/project-settings.js:113` |
855
- | `b9c6def6b120` | certain | Rank set to {…}. | `modules/hall-ui/public/watch.js:877` |
856
+ | `b9c6def6b120` | certain | Rank set to {…}. | `modules/hall-ui/public/watch.js:883` |
856
857
  | `ff50a1395cbc` | certain | Rank: {…} | `modules/hall-ui/public/profile.js:50` |
857
858
  | `6824ec470f99` | certain | Ranks — {{worldName}} | `modules/hall-ui/public/ranks.html:6` |
858
859
  | `6824ec470f99` | certain | Ranks — {{worldName}} | `modules/hall-ui/public/ranks.html:6` |
@@ -860,7 +861,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
860
861
  | `101a51902f53` | certain | Re-issue failed: {…} | `modules/hall-ui/public/settings.js:780` |
861
862
  | `fae2f90927bd` | certain | Read an idea, then decide. An objection needs a reason and the section it faults. | `modules/hall-ui/public/board-room.html:51` |
862
863
  | `b03e17693dcd` | certain | Read it as a table | `modules/hall-ui/public/drachmae.js:148` |
863
- | `b03e17693dcd` | certain | Read it as a table | `modules/hall-ui/public/watch.js:1155` |
864
+ | `b03e17693dcd` | certain | Read it as a table | `modules/hall-ui/public/watch.js:1161` |
864
865
  | `b6fcfdd652a7` | certain | Read it here | `modules/hall-ui/public/work.html:45` |
865
866
  | `053df132e22c` | certain | Read the full ask | `modules/hall-ui/public/collab.js:133` |
866
867
  | `c5f19a888a15` | certain | Read the handoff notes | `modules/hall-ui/public/task.js:490` |
@@ -897,7 +898,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
897
898
  | `7d4149cee474` | certain | Repo Atlas — a self-drawing map of the codebase | `modules/hall-ui/public/atlas.html:6` |
898
899
  | `4d40a68605e1` | certain | Repo atlas | `modules/hall-ui/public/atlas.html:30` |
899
900
  | `52d7d4309540` | certain | Repo health | `modules/hall-ui/public/watch.html:104` |
900
- | `e6629398d47c` | certain | Report {…}. | `modules/hall-ui/public/watch.js:597` |
901
+ | `e6629398d47c` | certain | Report {…}. | `modules/hall-ui/public/watch.js:603` |
901
902
  | `ab456f09c0f6` | certain | Request access | `modules/hall-ui/public/hall-render.js:294` |
902
903
  | `ab456f09c0f6` | certain | Request access | `modules/hall-ui/public/hall-render.js:470` |
903
904
  | `820f47ce5f16` | certain | Request sent | `modules/hall-ui/public/profile-connections.js:95` |
@@ -915,8 +916,8 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
915
916
  | `60d8790ebce8` | certain | Restore the page's words for this {…} line | `modules/hall-ui/public/tweak-editor.js:225` |
916
917
  | `0887725744f2` | certain | Restricted. | `modules/hall-ui/public/board-room.js:526` |
917
918
  | `0887725744f2` | certain | Restricted. | `modules/hall-ui/public/gate.js:234` |
918
- | `0887725744f2` | certain | Restricted. | `modules/hall-ui/public/government.js:879` |
919
- | `0887725744f2` | certain | Restricted. | `modules/hall-ui/public/watch.js:1294` |
919
+ | `0887725744f2` | certain | Restricted. | `modules/hall-ui/public/government.js:890` |
920
+ | `0887725744f2` | certain | Restricted. | `modules/hall-ui/public/watch.js:1300` |
920
921
  | `b99a71747432` | certain | Retire task {…}? It leaves the claimable queue. Promote restores it to the backlog. | `modules/hall-ui/public/task.js:966` |
921
922
  | `b33dde402434` | certain | Retire this goal — you will be asked what happens to any unfinished work | `modules/hall-ui/public/goals-render.js:936` |
922
923
  | `d0d5b4300f28` | certain | Retire this task | `modules/hall-ui/public/task.js:802` |
@@ -957,7 +958,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
957
958
  | `582bdd9435eb` | certain | Select task {…} for bulk actions | `modules/hall-ui/public/work.js:480` |
958
959
  | `d91c8e9be76c` | certain | Select task {…} for bulk claim | `modules/hall-ui/public/goals-render.js:353` |
959
960
  | `7e1d54119e08` | certain | Select task {…} for bulk release | `modules/hall-ui/public/work.js:258` |
960
- | `ae43a132699b` | certain | Selectable today | `modules/hall-ui/public/government.js:799` |
961
+ | `ae43a132699b` | certain | Selectable today | `modules/hall-ui/public/government.js:809` |
961
962
  | `53cc6d8dd23c` | certain | Send invitation | `modules/hall-ui/public/goals-render.js:1214` |
962
963
  | `a39b0f9d86e5` | certain | Serving {…} — read from the box itself, {…}. | `modules/hall-ui/public/deploy.js:433` |
963
964
  | `64a1f055129e` | certain | Session card richness | `modules/hall-ui/public/settings-render.js:83` |
@@ -1030,7 +1031,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1030
1031
  | `a1482eff4ead` | certain | Suggested for you | `modules/hall-ui/public/settings-specialities.js:384` |
1031
1032
  | `1e40f33483eb` | certain | Switch theme | `modules/hall-ui/public/shell.js:491` |
1032
1033
  | `93fa2e97dd35` | certain | System default for this skill | `modules/hall-ui/public/settings.js:72` |
1033
- | `4894b1d9b0de` | certain | System oversight: people, operations and security. | `modules/hall-ui/public/watch.js:1358` |
1034
+ | `4894b1d9b0de` | certain | System oversight: people, operations and security. | `modules/hall-ui/public/watch.js:1364` |
1034
1035
  | `aa8da34fe237` | certain | Take the next page, or pick one from the studio. | `modules/hall-ui/public/tweak-editor.js:564` |
1035
1036
  | `e604fc3ace79` | certain | Task # | `modules/hall-ui/public/blockers.js:139` |
1036
1037
  | `a0f384b022fd` | certain | Task dependencies | `modules/hall-ui/public/goals.html:140` |
@@ -1057,7 +1058,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1057
1058
  | `c0e28f30524d` | certain | That project's own standing, as reported by that project. | `modules/hall-ui/public/profile.js:314` |
1058
1059
  | `e99d4a811e92` | certain | That request is no longer available. | `modules/hall-ui/public/profile-connections.js:314` |
1059
1060
  | `34017119ce22` | certain | That work is genuinely gone | `modules/hall-ui/public/goal-inbox.js:374` |
1060
- | `6e5a324b2972` | certain | That's you | `modules/hall-ui/public/watch.js:826` |
1061
+ | `6e5a324b2972` | certain | That's you | `modules/hall-ui/public/watch.js:832` |
1061
1062
  | `50198c465225` | certain | The 16-value rank enum in three bands, which ranks are live, and the permissions each rank holds. | `modules/hall-ui/public/diagrams.html:59` |
1062
1063
  | `c5e6bdd32fe3` | certain | The Board Room is open to the builders this project’s constitution seats on its board. | `modules/hall-ui/public/board-room.js:529` |
1063
1064
  | `6e93ef49d63f` | certain | The adversarial panel. Each worker reports pass, concerns or fail on its own; the gating workers must all pass | `modules/hall-ui/public/task.js:440` |
@@ -1069,7 +1070,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1069
1070
  | `2dc061096c48` | certain | The copy desk — every flagged string | `modules/hall-ui/public/studio.html:165` |
1070
1071
  | `325daac25a9a` | certain | The day the sky is drawn for | `modules/hall-ui/public/goal-map.html:118` |
1071
1072
  | `325daac25a9a` | certain | The day the sky is drawn for | `modules/hall-ui/public/thinking.html:128` |
1072
- | `bac12faf3328` | certain | The developmental ladder: {…}. Formality is adopted only where informal coordination breaks. | `modules/hall-ui/public/government.js:806` |
1073
+ | `bac12faf3328` | certain | The developmental ladder: {…}. Formality is adopted only where informal coordination breaks. | `modules/hall-ui/public/government.js:816` |
1073
1074
  | `239d641c20fa` | certain | The document | `modules/hall-ui/public/settings-specialities.js:354` |
1074
1075
  | `ffaa4df90f66` | certain | The editor could not load. | `modules/hall-ui/public/tweak-editor.js:712` |
1075
1076
  | `6e2554615883` | certain | The event sounds could not be loaded. Reload the page to try again. | `modules/hall-ui/public/settings.js:391` |
@@ -1117,7 +1118,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1117
1118
  | `d01d36a596b0` | certain | The session log could not be loaded. Try again. | `modules/hall-ui/public/sessions.js:398` |
1118
1119
  | `d01d36a596b0` | certain | The session log could not be loaded. Try again. | `modules/hall-ui/public/sessions.js:450` |
1119
1120
  | `e48a9b77d91b` | certain | The session log opens from a higher rank. | `modules/hall-ui/public/sessions.html:41` |
1120
- | `af664a644b13` | certain | The seven government structures, for getting a team up to speed before deciding when to flip a switch. | `modules/hall-ui/public/government.js:799` |
1121
+ | `af664a644b13` | certain | The seven government structures, for getting a team up to speed before deciding when to flip a switch. | `modules/hall-ui/public/government.js:809` |
1121
1122
  | `6360a5988f26` | certain | The shape and health of the codebase. | `modules/hall-ui/public/watch.html:105` |
1122
1123
  | `fc422cced9e3` | certain | The shared goals you’ve joined. Browse, join, and leave goals — and read their criteria — on the | `modules/hall-ui/public/goals.js:94` |
1123
1124
  | `ac46dc53d95f` | certain | The shared repository the core ships and the modules this project built for itself, each credited to its autho | `modules/hall-ui/public/modules.html:47` |
@@ -1313,7 +1314,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1313
1314
  | `6dadadffa36e` | certain | Your name cannot be blank. | `modules/hall-ui/public/settings.js:606` |
1314
1315
  | `bd77210a8c90` | certain | Your name must be {…} characters or fewer. | `modules/hall-ui/public/settings.js:611` |
1315
1316
  | `c0a01a95e97e` | certain | Your own idea. You may vote, but it can’t be decided by your vote alone, and a vote on your own idea earns no | `modules/hall-ui/public/board-room.js:366` |
1316
- | `5e0ec4cd1cfe` | certain | Your own row carries no controls. Nobody can change their own rank or standing — that guard is what stops the | `modules/hall-ui/public/watch.js:858` |
1317
+ | `5e0ec4cd1cfe` | certain | Your own row carries no controls. Nobody can change their own rank or standing — that guard is what stops the | `modules/hall-ui/public/watch.js:864` |
1317
1318
  | `8fc605026acf` | certain | Your pending join {…}: {…} — awaiting approval. | `modules/hall-ui/public/goal-inbox.js:88` |
1318
1319
  | `e91418db3962` | certain | Your preferences, {…}. | `modules/hall-ui/public/settings.js:630` |
1319
1320
  | `e91418db3962` | certain | Your preferences, {…}. | `modules/hall-ui/public/settings.js:1173` |
@@ -1337,7 +1338,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1337
1338
  | `a02616e47d11` | certain | a year of qualifying ships, in your timezone \u00b7 only you see this one | `modules/hall-ui/public/profile-charts.js:288` |
1338
1339
  | `5070ebfedc48` | certain | access: the hub keeps a key of its own for this repository, so this change and every later upgrade are saved t | `modules/hall-ui/public/deploy.js:250` |
1339
1340
  | `9612c983451f` | certain | achieved · | `modules/hall-ui/public/roadmap.js:288` |
1340
- | `dbfc9e6e921b` | certain | active builder{…}: {…} | `modules/hall-ui/public/government.js:799` |
1341
+ | `dbfc9e6e921b` | certain | active builder{…}: {…} | `modules/hall-ui/public/government.js:809` |
1341
1342
  | `6ea7c97a6583` | certain | alive · | `modules/hall-ui/public/sky-interaction.js:129` |
1342
1343
  | `754babaae931` | certain | and ask in | `modules/hall-ui/public/hall-render.js:804` |
1343
1344
  | `bc960f460250` | certain | and install dependencies ( | `modules/hall-ui/public/hall-render.js:806` |
@@ -1347,7 +1348,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1347
1348
  | `9bf4d3cabf80` | certain | approval queue | `modules/hall-ui/public/approval-queue.js:192` |
1348
1349
  | `ac37199ccdbb` | certain | approve and ship | `modules/hall-ui/public/approval-queue.js:172` |
1349
1350
  | `b4033000c537` | certain | as a table | `modules/hall-ui/public/profile-charts.js:205` |
1350
- | `d7c511423bc0` | certain | as configuration: {…} | `modules/hall-ui/public/government.js:785` |
1351
+ | `d7c511423bc0` | certain | as configuration: {…} | `modules/hall-ui/public/government.js:795` |
1351
1352
  | `6d91bea9b24e` | certain | as of {…} | `modules/hall-ui/public/sky-interaction.js:122` |
1352
1353
  | `a756e47632cd` | certain | at {…} — {…}. The timer above is the fallback that is actually in force. | `modules/hall-ui/public/project-settings.js:103` |
1353
1354
  | `63bd14f73960` | certain | author trusted | `modules/hall-ui/public/gate.js:156` |
@@ -1432,7 +1433,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1432
1433
  | `754bdec368ed` | certain | lowest credits | `modules/hall-ui/public/hall-widgets.js:136` |
1433
1434
  | `bc7923324b96` | certain | manage its visibility in Settings → Profile and privacy | `modules/hall-ui/public/profile.js:290` |
1434
1435
  | `359768b007ee` | certain | map every route in the sky | `modules/hall-ui/public/sky-interaction.js:45` |
1435
- | `5c3fdd34cd02` | certain | means expressible through the real configuration — a rank-based membership plus a pass rule — with no new code | `modules/hall-ui/public/government.js:799` |
1436
+ | `5c3fdd34cd02` | certain | means expressible through the real configuration — a rank-based membership plus a pass rule — with no new code | `modules/hall-ui/public/government.js:809` |
1436
1437
  | `0eefd625d954` | certain | merged into | `modules/hall-ui/public/idea.js:237` |
1437
1438
  | `70c234985d42` | certain | most recent first | `modules/hall-ui/public/hall-widgets.js:134` |
1438
1439
  | `e7213f35cd9a` | certain | move → #{…} {…} | `modules/hall-ui/public/goals-render.js:978` |
@@ -1526,7 +1527,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1526
1527
  | `4d8ee7d68974` | certain | task {…} | `modules/hall-ui/public/idea.js:234` |
1527
1528
  | `4d8ee7d68974` | certain | task {…} | `modules/hall-ui/public/ideas.js:201` |
1528
1529
  | `4d8ee7d68974` | certain | task {…} | `modules/hall-ui/public/ideas.js:782` |
1529
- | `4d8ee7d68974` | certain | task {…} | `modules/hall-ui/public/watch.js:1265` |
1530
+ | `4d8ee7d68974` | certain | task {…} | `modules/hall-ui/public/watch.js:1271` |
1530
1531
  | `e4e423344746` | certain | task · {…} | `modules/hall-ui/public/sky-interaction.js:36` |
1531
1532
  | `e4e423344746` | certain | task · {…} | `modules/hall-ui/public/sky-panel.js:95` |
1532
1533
  | `a41659dc2bee` | certain | tasks remaining | `modules/hall-ui/public/roadmap.js:298` |
@@ -1620,7 +1621,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1620
1621
  | `f5e456c3aaf6` | certain | {…} of {…} turned on. Each one, in a line: | `modules/hall-ui/public/settings-specialities.js:152` |
1621
1622
  | `60743fe1e40d` | certain | {…} per page | `modules/hall-ui/public/hall-kit.js:74` |
1622
1623
  | `771bef3d31b5` | certain | {…} project{…} | `modules/hall-ui/public/fleet.js:39` |
1623
- | `154bc518bab4` | certain | {…} proposed | `modules/hall-ui/public/government.js:695` |
1624
+ | `154bc518bab4` | certain | {…} proposed | `modules/hall-ui/public/government.js:705` |
1624
1625
  | `275f3565c78b` | certain | {…} reset to its default {…} permissions. | `modules/hall-ui/public/government.js:297` |
1625
1626
  | `33afba17ee0f` | certain | {…} seeded | `modules/hall-ui/public/roadmap.js:207` |
1626
1627
  | `732b4c935e36` | certain | {…} sessions | `modules/hall-ui/public/task.js:495` |
@@ -1634,7 +1635,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1634
1635
  | `1a8a6267e490` | certain | {…} unfinished task{…} — say what happens to each | `modules/hall-ui/public/goals-render.js:1015` |
1635
1636
  | `3ad8f32dd43b` | certain | {…} you have sent | `modules/hall-ui/public/profile-connections.js:146` |
1636
1637
  | `8186b562553a` | certain | {…} {…} waiting | `modules/hall-ui/public/work.js:432` |
1637
- | `0d4016a5531c` | certain | {…} {…}{…} | `modules/hall-ui/public/watch.js:497` |
1638
+ | `0d4016a5531c` | certain | {…} {…}{…} | `modules/hall-ui/public/watch.js:503` |
1638
1639
  | `0d4016a5531c` | certain | {…} {…}{…} | `modules/hall-ui/public/work.js:265` |
1639
1640
  | `b3757ba3bb46` | certain | {…} · Stored encrypted; never shown again after saving. | `modules/hall-ui/public/settings.js:834` |
1640
1641
  | `a6e4ed98fbea` | certain | {…} · revoke it any time under Active sessions. | `modules/hall-ui/public/settings.js:766` |
@@ -1651,7 +1652,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1651
1652
  | `c43050b62297` | certain | {…}/100 complete | `modules/hall-ui/public/idea.js:87` |
1652
1653
  | `cbc5a8c686b2` | certain | {…}We store only your GitHub login, avatar, and the work you ship. | `modules/hall-ui/public/hall-render.js:392` |
1653
1654
  | `8e8c7da4f7f5` | certain | {…}criteria met · awaiting review | `modules/hall-ui/public/goals-render.js:163` |
1654
- | `1e275ee0299c` | certain | {…}s only | `modules/hall-ui/public/government.js:896` |
1655
+ | `1e275ee0299c` | certain | {…}s only | `modules/hall-ui/public/government.js:907` |
1655
1656
  | `499916045b19` | certain | {…}{…} asks to join | `modules/hall-ui/public/goal-inbox.js:69` |
1656
1657
  | `97e27ab169ae` | certain | {…}{…} session{…} across {…} builder{…}. | `modules/hall-ui/public/sessions.js:338` |
1657
1658
  | `3d74668f69e5` | certain | {…}{…} · {…} | `modules/hall-ui/public/task.js:667` |