@bongos/core 1.17.1 → 1.17.3

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 (233) hide show
  1. package/.bongos-core.json +521 -281
  2. package/.claude/skills/blocker-review/SKILL.md +1 -1
  3. package/.claude/skills/builder-claim/SKILL.md +2 -0
  4. package/.claude/skills/builder-exit/SKILL.md +2 -2
  5. package/.claude/skills/builder-redteam/SKILL.md +3 -3
  6. package/.claude/skills/builder-setup/SKILL.md +2 -2
  7. package/.claude/skills/builder-start/SKILL.md +1 -1
  8. package/.claude/skills/dev/SKILL.md +1 -1
  9. package/.claude/skills/idea-triage/SKILL.md +2 -2
  10. package/.claude/skills/ideate/SKILL.md +1 -1
  11. package/.claude/skills/merge-mode/SKILL.md +1 -1
  12. package/.claude/skills/new-project/SKILL.md +3 -0
  13. package/.claude/skills/paint/SKILL.md +1 -1
  14. package/GOVERNANCE.md +1 -1
  15. package/README.md +1 -1
  16. package/clients/bongos-client/README.md +1 -1
  17. package/clients/bongos-client/bongos-client.global.js +2 -0
  18. package/clients/bongos-client/index.cjs +2 -0
  19. package/clients/bongos-client/index.d.ts +4 -2
  20. package/clients/bongos-client/index.mjs +2 -0
  21. package/docs/adr/0001-stack-choice-single-vps.md +1 -1
  22. package/docs/adr/0008-google-chat-oauth-user-auth.md +1 -1
  23. package/docs/adr/0019-red-team-bounty-payout-table.md +3 -3
  24. package/docs/adr/0020-security-model-public-stub.md +1 -1
  25. package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +1 -1
  26. package/docs/adr/0024-cloneable-repo-local-first-memory.md +1 -1
  27. package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +4 -4
  28. package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +3 -3
  29. package/docs/adr/0030-builders-hall-live-updates.md +1 -1
  30. package/docs/adr/0031-cloud-dev-environments-for-builders.md +4 -4
  31. package/docs/adr/0032-discord-mirror-of-gds.md +2 -2
  32. package/docs/adr/0034-thetes-graduated-newcomer-rank.md +1 -1
  33. package/docs/adr/0044-mediterranean-palette-replacement.md +1 -1
  34. package/docs/adr/0044-per-box-live-game-preview.md +1 -1
  35. package/docs/adr/0054-session-token-reward-cost-plus.md +10 -10
  36. package/docs/adr/0057-container-cost-ledger.md +3 -3
  37. package/docs/adr/0062-medusa-instance-model-decoupling.md +4 -4
  38. package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +2 -2
  39. package/docs/adr/0085-remove-default-per-builder-spend-cap.md +1 -1
  40. package/docs/adr/0086-goal-scoped-work-hierarchy.md +1 -1
  41. package/docs/adr/0096-require-reward-before-workable.md +9 -9
  42. package/docs/adr/0097-retroactive-reward-backfill.md +3 -3
  43. package/docs/adr/0100-two-repo-instance-model.md +1 -1
  44. package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +3 -3
  45. package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +3 -3
  46. package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +1 -1
  47. package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +6 -6
  48. package/docs/adr/0136-update-channel-subscription-policy.md +51 -0
  49. package/docs/adr/0137-upstream-publish-policy-manual-owner-gated.md +40 -0
  50. package/docs/adr/0138-bundled-module-deps-declared-per-module.md +45 -0
  51. package/docs/adr/README.md +9 -6
  52. package/docs/api/openapi.json +65 -26
  53. package/docs/api-reference.md +3 -2
  54. package/docs/architecture.md +2 -2
  55. package/docs/branding-contract.md +5 -4
  56. package/docs/canonical-permissions.md +1 -1
  57. package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
  58. package/docs/file-map.md +18 -17
  59. package/docs/handoff-template.md +2 -2
  60. package/docs/modules-contract.md +6 -1
  61. package/docs/onboarding/diagrams/README.md +7 -7
  62. package/docs/onboarding/drachmae-and-karma.md +18 -18
  63. package/docs/onboarding/primer.md +9 -9
  64. package/docs/recipes/audit-replay.md +2 -2
  65. package/docs/recipes/builder-box-lifecycle.md +2 -2
  66. package/docs/recipes/claude-design-loop.md +1 -1
  67. package/docs/recipes/ops-gotchas.md +1 -1
  68. package/docs/recipes/private-npm-distribution.md +17 -0
  69. package/docs/recipes/staging-environment.md +1 -1
  70. package/docs/recipes/upgrading-the-core.md +55 -0
  71. package/docs/research/cursor-competitive-analysis.md +1 -1
  72. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +1 -1
  73. package/modules/discord/module.json +2 -1
  74. package/modules/economy/achievements.js +9 -1
  75. package/modules/economy/credits.js +10 -1
  76. package/modules/hall-ui/public/builders.js +137 -620
  77. package/modules/hall-ui/public/goal-inbox.js +232 -0
  78. package/modules/hall-ui/public/goals-page.js +4 -1
  79. package/modules/hall-ui/public/goals.html +8 -0
  80. package/modules/hall-ui/public/hall-kit.js +474 -0
  81. package/modules/hall-ui/public/hall-widgets.js +14 -5
  82. package/modules/hall-ui/public/index.html +3 -0
  83. package/modules/hall-ui/public/instances-panel.js +24 -3
  84. package/modules/hall-ui/public/new-project-wizard.js +7 -5
  85. package/modules/hall-ui/public/style.css +168 -0
  86. package/modules/hall-ui/public/work.css +194 -0
  87. package/modules/hall-ui/public/work.html +46 -374
  88. package/modules/hall-ui/public/work.js +137 -102
  89. package/modules/lifecycle/criterion-suggest.js +80 -0
  90. package/modules/lifecycle/db.js +42 -5
  91. package/modules/lifecycle/routes/goals.js +26 -0
  92. package/modules/lifecycle/routes/tasks.js +21 -0
  93. package/modules/provisioning/CLAUDE.md +15 -0
  94. package/modules/provisioning/migrations/provisioning_001_tables.sql +160 -0
  95. package/modules/provisioning/migrations/provisioning_002_standalone_shape.sql +11 -0
  96. package/modules/provisioning/migrations/provisioning_003_github_app_manifest.sql +95 -0
  97. package/modules/provisioning/module.json +17 -0
  98. package/modules/provisioning/onboard-plan.js +37 -0
  99. package/modules/provisioning/provisioning.js +539 -0
  100. package/modules/provisioning/rate-limit.js +35 -0
  101. package/modules/provisioning/routes/provisioning.js +607 -0
  102. package/modules/provisioning/tests/provisioning.mjs +232 -0
  103. package/modules/provisioning/ui/.gitkeep +0 -0
  104. package/modules/security/secret-scrub.js +10 -0
  105. package/package-lock.json +2 -2
  106. package/package.json +7 -2
  107. package/scripts/discord/README.md +1 -1
  108. package/scripts/gds/claim.js +98 -48
  109. package/scripts/gds/claude-materialize.js +30 -9
  110. package/scripts/gds/cutover-codemod.js +241 -0
  111. package/scripts/gds/fitness.js +54 -0
  112. package/scripts/gds/init.js +59 -3
  113. package/scripts/gds/lint-infra-exec.js +70 -0
  114. package/scripts/gds/lint-workflow-exec.js +63 -0
  115. package/scripts/gds/mirror-lineage-check.js +14 -5
  116. package/scripts/gds/mirror-redact.js +8 -0
  117. package/scripts/gds/onboard.js +4 -0
  118. package/scripts/gds/package-core.js +18 -3
  119. package/scripts/gds/publish-manifest.js +60 -2
  120. package/scripts/gds/run-routine.js +51 -13
  121. package/scripts/gds/run-unit-tests.js +4 -0
  122. package/scripts/gds/update-channel.js +186 -0
  123. package/scripts/gds/upgrade.js +116 -9
  124. package/scripts/hall-preview/README.md +103 -0
  125. package/scripts/hall-preview/fixtures/access-requests.json +1 -0
  126. package/scripts/hall-preview/fixtures/achievements.json +76 -0
  127. package/scripts/hall-preview/fixtures/analytics__builder.json +251 -0
  128. package/scripts/hall-preview/fixtures/audit-log.json +1 -0
  129. package/scripts/hall-preview/fixtures/boxes__cost-ledger.json +1 -0
  130. package/scripts/hall-preview/fixtures/builders__active-claims.json +1 -0
  131. package/scripts/hall-preview/fixtures/builders__directory.json +81 -0
  132. package/scripts/hall-preview/fixtures/builders__roster.json +1 -0
  133. package/scripts/hall-preview/fixtures/goals.json +502 -0
  134. package/scripts/hall-preview/fixtures/goals__25.json +96 -0
  135. package/scripts/hall-preview/fixtures/goals__26.json +67 -0
  136. package/scripts/hall-preview/fixtures/goals__3.json +103 -0
  137. package/scripts/hall-preview/fixtures/goals__35.json +49 -0
  138. package/scripts/hall-preview/fixtures/goals__conflicts.json +154 -0
  139. package/scripts/hall-preview/fixtures/goals__detail.json +96 -0
  140. package/scripts/hall-preview/fixtures/goals__inbox.json +5 -0
  141. package/scripts/hall-preview/fixtures/goals__requests.json +3 -0
  142. package/scripts/hall-preview/fixtures/grades__by-builder.json +1 -0
  143. package/scripts/hall-preview/fixtures/inbox.json +330 -0
  144. package/scripts/hall-preview/fixtures/instance.json +124 -0
  145. package/scripts/hall-preview/fixtures/leaderboard.json +184 -0
  146. package/scripts/hall-preview/fixtures/me.json +476 -0
  147. package/scripts/hall-preview/fixtures/me__recent-ships.json +304 -0
  148. package/scripts/hall-preview/fixtures/override-requests.json +1 -0
  149. package/scripts/hall-preview/fixtures/provisioning__fleet.json +1 -0
  150. package/scripts/hall-preview/fixtures/provisioning__fleet__cost-ledger.json +1 -0
  151. package/scripts/hall-preview/fixtures/provisioning__instances.json +1 -0
  152. package/scripts/hall-preview/fixtures/public__analytics__ecosystem.json +516 -0
  153. package/scripts/hall-preview/fixtures/public__bounty-table.json +37 -0
  154. package/scripts/hall-preview/fixtures/public__cost-summary.json +742 -0
  155. package/scripts/hall-preview/fixtures/public__estimation-drift.json +41 -0
  156. package/scripts/hall-preview/fixtures/public__grades.json +50 -0
  157. package/scripts/hall-preview/fixtures/public__progress.json +124 -0
  158. package/scripts/hall-preview/fixtures/public__recent-shipped.json +426 -0
  159. package/scripts/hall-preview/fixtures/public__repo-health.json +160 -0
  160. package/scripts/hall-preview/fixtures/public__repo-info.json +5 -0
  161. package/scripts/hall-preview/fixtures/security__docs.json +1 -0
  162. package/scripts/hall-preview/fixtures/security__reports.json +1 -0
  163. package/scripts/hall-preview/fixtures/sessions__search.json +1 -0
  164. package/scripts/hall-preview/fixtures/tasks.json +2420 -0
  165. package/scripts/hall-preview/fixtures/tasks__claimable.json +2555 -0
  166. package/scripts/hall-preview/fixtures/tasks__detail.json +111 -0
  167. package/scripts/hall-preview/fixtures/tasks__peer-votes__feed.json +330 -0
  168. package/scripts/hall-preview/fixtures/versions.json +89 -0
  169. package/scripts/hall-preview/refresh-fixtures.js +77 -0
  170. package/scripts/hall-preview/server.js +178 -0
  171. package/scripts/migrate.sh +29 -4
  172. package/src/bongos/auth.js +14 -1
  173. package/src/bongos/optimizer.js +37 -2
  174. package/src/bongos/serve-internal.js +10 -1
  175. package/src/branding.js +1 -0
  176. package/src/module-api.js +12 -1
  177. package/src/module-loader/loader.js +36 -4
  178. package/src/module-loader/manifest-schema.js +16 -1
  179. package/tests/branding.mjs +11 -0
  180. package/tests/claim_error_surface.mjs +107 -0
  181. package/tests/claude_materialize.mjs +20 -0
  182. package/tests/consumer_layout_boot.mjs +302 -0
  183. package/tests/criterion_suggest.mjs +106 -0
  184. package/tests/cutover_codemod.mjs +184 -0
  185. package/tests/device_flow_start.mjs +25 -2
  186. package/tests/hook_core_resolve.mjs +125 -0
  187. package/tests/infra_exec_paths.mjs +104 -0
  188. package/tests/init.mjs +47 -0
  189. package/tests/migrate_root_resolution.mjs +97 -0
  190. package/tests/mirror_lineage_proof.mjs +14 -0
  191. package/tests/module_loader.mjs +42 -0
  192. package/tests/module_manifest.mjs +19 -0
  193. package/tests/onboard.mjs +13 -0
  194. package/tests/package_core.mjs +8 -0
  195. package/tests/provisioning_github_app_routes.mjs +15 -0
  196. package/tests/publish_manifest.mjs +52 -1
  197. package/tests/run_routine.mjs +26 -1
  198. package/tests/run_routine_two_root.mjs +77 -0
  199. package/tests/scrubber_corpus.mjs +17 -0
  200. package/tests/update_channel.mjs +186 -0
  201. package/tests/upgrade.mjs +131 -0
  202. package/tests/workflow_exec_paths.mjs +98 -0
  203. package/docs/design/container-exterior-tiles.md +0 -49
  204. package/docs/design/container-exterior.md +0 -81
  205. package/docs/design/container-interior.md +0 -77
  206. package/docs/design/world-map-scroll.md +0 -41
  207. package/docs/recipes/claude-gemini-bongos-doors.md +0 -155
  208. package/docs/recipes/cloudbongos-staging-gate.md +0 -139
  209. package/docs/recipes/cloudbongos-standup.md +0 -111
  210. package/docs/recipes/parallel-load-results-2026-05-30.md +0 -63
  211. package/docs/recipes/parallel-load-test.md +0 -32
  212. package/docs/recipes/pixel-art-pipeline.md +0 -411
  213. package/docs/recipes/staging-data.md +0 -50
  214. package/migrations/instance/018_pms_v3_planning_seed.sql +0 -131
  215. package/migrations/instance/080_gds_v4_planning_seed.sql +0 -75
  216. package/migrations/instance/110_medusa_planning_seed.sql +0 -70
  217. package/migrations/instance/120_bongos_v1_planning_seed.sql +0 -69
  218. package/migrations/instance/144_bongos_v1_module_system_criterion.sql +0 -26
  219. package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +0 -29
  220. package/migrations/instance/172_v2_world_planning_seed.sql +0 -163
  221. package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +0 -33
  222. package/migrations/instance/182_gdsv4_bongos_consolidation.sql +0 -132
  223. package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +0 -116
  224. package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +0 -69
  225. package/scripts/gds/art-stage.js +0 -152
  226. package/server.js +0 -212
  227. package/tests/art_key.mjs +0 -121
  228. package/tests/day_cycle.mjs +0 -197
  229. package/tests/snapshot_picker.mjs +0 -233
  230. package/tests/sprite_facing.mjs +0 -35
  231. package/tests/terrain_picker.mjs +0 -298
  232. package/tests/turn_in_place.mjs +0 -280
  233. package/tests/walkability.mjs +0 -188
@@ -1,28 +1,28 @@
1
- # Drachmae & karma — how you get paid, and how you earn trust
1
+ # Example & karma — how you get paid, and how you earn trust
2
2
 
3
3
  *The complete reference for the two reputation tracks in the GDS. The [primer](primer.md) gives you the one-paragraph version; this is the full picture, kept honest against the live system. ~8 minutes.*
4
4
 
5
- > **Source of truth.** The numbers live in the production database (`builders.total_credits`, `builders.karma`) and the rules live in code (`src/bongos/db.js`, `src/bongos/cost.js`). This doc *describes* them; where they disagree, the code wins. The two diagrams that visualize this — [task lifecycle](diagrams/01-task-lifecycle.png) and [drachmae & karma](diagrams/03-drachmae-karma.png) — are auto-generated from the same live facts.
5
+ > **Source of truth.** The numbers live in the production database (`builders.total_credits`, `builders.karma`) and the rules live in code (`src/bongos/db.js`, `src/bongos/cost.js`). This doc *describes* them; where they disagree, the code wins. The two diagrams that visualize this — [task lifecycle](diagrams/01-task-lifecycle.png) and [example & karma](diagrams/03-example-karma.png) — are auto-generated from the same live facts.
6
6
 
7
7
  ---
8
8
 
9
9
  ## The 30-second version
10
10
 
11
- - **Drachmae** (the code calls them *credits*) are your **equity** in Off the Boats. You earn them by shipping work, and they only ever go up. They are a score and a stake — **not** a currency you spend on anything in-game.
12
- - The **headline change (June 2026):** most of your drachmae now come from a **cost-plus reward on each shipped session** — we pay you the real API cost of the work you did, **plus 20%**. Expensive, real work pays more than declaring a big number ever did.
11
+ - **Example** (the code calls them *credits*) are your **equity** in Example. You earn them by shipping work, and they only ever go up. They are a score and a stake — **not** a currency you spend on anything in-game.
12
+ - The **headline change (June 2026):** most of your example now come from a **cost-plus reward on each shipped session** — we pay you the real API cost of the work you did, **plus 20%**. Expensive, real work pays more than declaring a big number ever did.
13
13
  - **Karma** is a *separate* signal. It measures **peer trust** — how other trusted builders rate your work — not how much you shipped. It is surfaced on your profile and the leaderboard, and it feeds your "builder strength" score. It is **not** a gate on rank promotions.
14
14
  - A **monthly budget cap** ($50 by default) limits how much you can *spend*; it's the cost side of the same coin the reward is computed from.
15
15
 
16
16
  ---
17
17
 
18
- ## Part 1 — Drachmae (credits)
18
+ ## Part 1 — Example (credits)
19
19
 
20
20
  ### What they are
21
21
 
22
- Drachmae are the in-world name for the `total_credits` counter on your builder row. The owner's framing ([ADR 0054](../adr/<redacted>.md)) is that **drachmae are equity** — units of ownership in the thing you're helping build. Practically, today, they are:
22
+ Example are the in-world name for the `total_credits` counter on your builder row. The owner's framing ([ADR 0054](../adr/<redacted>.md)) is that **example are equity** — units of ownership in the thing you're helping build. Practically, today, they are:
23
23
 
24
24
  - **Append-only.** Every award is a row in `credit_log`; the `total_credits` counter is maintained by a database trigger. History is never rewritten — a correction is a new (sometimes negative) row, never an edit.
25
- - **Persistent across exit.** If you leave and come back, your drachmae are still there (migration 025). They are reputation, not a session balance.
25
+ - **Persistent across exit.** If you leave and come back, your example are still there (migration 025). They are reputation, not a session balance.
26
26
  - **Not spendable.** There is no shop, no sink, nothing to buy with them. They are a *score and a stake*. (This may change in a future version; today it does not.)
27
27
  - **Public.** Your total is visible on the [builders' hall](https://example.com/builders) leaderboard.
28
28
 
@@ -35,7 +35,7 @@ There are several sources. They all land in the same `credit_log` and roll up in
35
35
  When you **ship** a session, the server looks at the LLM tokens that session actually burned, prices them, and pays you:
36
36
 
37
37
  ```
38
- drachmae = round( true_cost_usd × 1.20 ) // whole drachmae (1 drachma = $1)
38
+ example = round( true_cost_usd × 1.20 ) // whole example (1 drachma = $1)
39
39
  └─ REWARD_MARGIN_PCT = 20 (a code constant in src/bongos/db.js)
40
40
  ```
41
41
 
@@ -47,7 +47,7 @@ The important details, because they're designed to be fair *and* un-gameable:
47
47
  - **Idempotent per session.** Re-shipping or retrying the same session is a true no-op — keyed on `session_id`, you can't get paid twice.
48
48
  - **Reversible.** A bad award is undone with a compensating negative `credit_log` row; the trigger nets it out. History stays intact.
49
49
 
50
- > **Why pay for cost at all — doesn't that reward waste?** It can, and that was accepted on purpose ([ADR 0054](../adr/<redacted>.md)). The guardrails are: you only get paid for sessions that *ship*; drachmae are *equity*, so padding your own cost dilutes a pool you hold (early builders self-police); and the [BFG session-inefficiency evaluator](../adr/<redacted>.md) already flags wasteful sessions, so a future version can discount the reward by an efficiency factor. The stated direction is to move toward market/bidding pricing once there's a real multi-builder pool.
50
+ > **Why pay for cost at all — doesn't that reward waste?** It can, and that was accepted on purpose ([ADR 0054](../adr/<redacted>.md)). The guardrails are: you only get paid for sessions that *ship*; example are *equity*, so padding your own cost dilutes a pool you hold (early builders self-police); and the [BFG session-inefficiency evaluator](../adr/<redacted>.md) already flags wasteful sessions, so a future version can discount the reward by an efficiency factor. The stated direction is to move toward market/bidding pricing once there's a real multi-builder pool.
51
51
 
52
52
  #### 2. Per-task credits, adjusted by *kind* ([ADR 0023](../adr/<redacted>.md))
53
53
 
@@ -80,11 +80,11 @@ A ship whose committed diff **removes more lines than it adds** earns a small `s
80
80
 
81
81
  #### 6. Red-team / security bounty *(rate card live; awarding still landing)*
82
82
 
83
- There's a published payout rate-card by severity for red-team / security findings (shown on the hall, `src/bongos/security.js`). The **automatic** drachmae payout for a filed-and-confirmed vulnerability is still being wired up (tracked by [#286](https://example.com/builders#/task/286) + [#282](https://example.com/builders#/task/282)); the rates are real, the auto-pay isn't switched on yet.
83
+ There's a published payout rate-card by severity for red-team / security findings (shown on the hall, `src/bongos/security.js`). The **automatic** example payout for a filed-and-confirmed vulnerability is still being wired up (tracked by [#286](https://example.com/builders#/task/286) + [#282](https://example.com/builders#/task/282)); the rates are real, the auto-pay isn't switched on yet.
84
84
 
85
85
  ### Where in the lifecycle credits land
86
86
 
87
- Drachmae are awarded at the **`completed → confirmed`** edge — when verification (smoke tests, and the grader when it's enabled) passes — **not** at the final ship/deploy. Releasing a task with `/builder-release` pays nothing.
87
+ Example are awarded at the **`completed → confirmed`** edge — when verification (smoke tests, and the grader when it's enabled) passes — **not** at the final ship/deploy. Releasing a task with `/builder-release` pays nothing.
88
88
 
89
89
  ```
90
90
  active ──▶ completed ──▶ confirmed ──▶ shipped
@@ -103,7 +103,7 @@ We knowingly run two conventions on the same ledger ([ADR 0054](../adr/<redacted
103
103
 
104
104
  ## Part 2 — The monthly budget cap (the cost side)
105
105
 
106
- Drachmae are what you *earn*; the budget cap limits what you *spend*. They're linked, because the reward is computed from the same true cost the cap meters.
106
+ Example are what you *earn*; the budget cap limits what you *spend*. They're linked, because the reward is computed from the same true cost the cap meters.
107
107
 
108
108
  Defined in `src/bongos/cost.js` (criterion C3, [#302](https://example.com/builders#/task/302)):
109
109
 
@@ -126,21 +126,21 @@ If a cap is set and you hit `over`, you're not in trouble — you've just reache
126
126
 
127
127
  ## Part 3 — Karma
128
128
 
129
- Karma (added in migration 040) is a **completely separate** counter from drachmae. Where drachmae measure *output* (work shipped), karma measures **peer trust** — how other builders, and the project's good-citizenship signals, rate the *way* you work.
129
+ Karma (added in migration 040) is a **completely separate** counter from example. Where example measure *output* (work shipped), karma measures **peer trust** — how other builders, and the project's good-citizenship signals, rate the *way* you work.
130
130
 
131
131
  ### How karma is earned (and lost)
132
132
 
133
133
  - **Peer votes on confirmed work.** Builders upvote/downvote each other's confirmed tasks. Only **Metic-and-above** can cast a vote (`POST /api/gds/tasks/:id/vote` is rank-gated). Votes are **tallied weekly** into one net `peer_vote_weekly` karma entry per builder. There's an **anti-self-vote** guard and an anti-retaliation rule (a downvote can't dent your karma within the same week).
134
134
  - **Proposal ratification.** When a criterion-proposal you made is ratified, you get **+3 karma** (`proposal_ratified`).
135
135
  - **Idea promotion.** Promoting an idea into a real task awards karma to the capturer.
136
- - **It can go down.** The [BFG](../adr/<redacted>.md) good-citizenship corrections can apply a *non-positive* karma delta. Karma is a slower, more reflective signal than drachmae — you can ship fast and still lose karma if you break things.
136
+ - **It can go down.** The [BFG](../adr/<redacted>.md) good-citizenship corrections can apply a *non-positive* karma delta. Karma is a slower, more reflective signal than example — you can ship fast and still lose karma if you break things.
137
137
 
138
138
  > Discord cheers don't count. Reaction "applause" in Discord is cosmetic and **never** mints karma — only rank-gated peer votes do ([ADR 0033](../adr/<redacted>.md)). Unranked enthusiasm can't manufacture trust.
139
139
 
140
140
  ### Where karma shows up
141
141
 
142
142
  - **Your profile card** on the hall shows your karma and its **30-day trend**, plus your recent karma feed (last 10 entries).
143
- - **The leaderboard** is sortable by karma (it still defaults to drachmae order).
143
+ - **The leaderboard** is sortable by karma (it still defaults to example order).
144
144
  - **Builder strength.** Karma is one input (weight ~0.15) into the BFG's 0–100 "builder strength" score (`src/bongos/bfg.js`), alongside ship volume, grader pass-rate, and reliability.
145
145
 
146
146
  ### What karma is *not*
@@ -154,9 +154,9 @@ Karma is evidence an Archon *can weigh* when deciding a discretionary promotion,
154
154
 
155
155
  ---
156
156
 
157
- ## Drachmae vs karma, side by side
157
+ ## Example vs karma, side by side
158
158
 
159
- | | **Drachmae** (credits) | **Karma** |
159
+ | | **Example** (credits) | **Karma** |
160
160
  |---|---|---|
161
161
  | Measures | Output — work shipped | Peer trust — how others rate your work |
162
162
  | Earned by | Shipping (cost-plus reward, per-task credits, bonuses) | Metic+ peer votes, ratification, idea promotion |
@@ -173,6 +173,6 @@ Both are reputation. Neither is a spendable currency today. You don't have to *d
173
173
  ## See it / dig deeper
174
174
 
175
175
  - **Your numbers:** [builders' hall](https://example.com/builders) (profile card + leaderboard), or `/builder-start` (shows your credit total).
176
- - **The diagram:** [`diagrams/03-drachmae-karma.png`](diagrams/03-drachmae-karma.png) — sources and sinks at a glance.
176
+ - **The diagram:** [`diagrams/03-example-karma.png`](diagrams/03-example-karma.png) — sources and sinks at a glance.
177
177
  - **The decisions:** [ADR 0054](../adr/<redacted>.md) (cost-plus reward), [ADR 0023](../adr/<redacted>.md) (kind multipliers + idea bonus), [ADR 0028](../adr/<redacted>.md) (token→USD pricing).
178
178
  - **The code:** `src/bongos/db.js` (`REWARD_MARGIN_PCT`, `KIND_MULTIPLIERS`, `computeSessionTokenReward`), `src/bongos/llm-pricing.js` (pricing), `src/bongos/cost.js` (budget cap), `src/bongos/bfg.js` (builder strength).
@@ -2,15 +2,15 @@
2
2
 
3
3
  *Read this before you claim your first work. ~10 minutes.*
4
4
 
5
- You're about to build inside Off the Boats, a project that runs on a small purpose-built dev system. This primer is the one document that gives you enough context to ask Claude smart questions and ship your first task without getting lost. Read it linearly — it's short on purpose.
5
+ You're about to build inside Example, a project that runs on a small purpose-built dev system. This primer is the one document that gives you enough context to ask Claude smart questions and ship your first task without getting lost. Read it linearly — it's short on purpose.
6
6
 
7
7
  When you're done, open [/builders](https://example.com/builders) and run `/builder-start`. There's no separate "I have read it" step anymore — reading the primer is on your honor, and the work queue is already open to you.
8
8
 
9
9
  ---
10
10
 
11
- ## What Off the Boats is
11
+ ## What this project is
12
12
 
13
- Off the Boats is a web experience that drops visitors into a single, persistent, playable digital world set in ancient Greece. Inside the world, players can spend real money to buy **physical goods** (fulfilled by a third-party logistics company called Example) and **digital assets** that develop the shared world. The world is never wiped — every interaction is permanent. The brand is mythic and underground: prices feel like a discovered secret, and the world reads as ancient even though the inciting object is a literal shipping container washed ashore. Visit [example.com](https://example.com) to see it.
13
+ This primer teaches the **platform** — how you claim work and ship it, the same on every Cloud Bongos instance. *What* you're building here — the product, its world, and its visual style — is specific to this instance and lives in **[`docs/project-context.md`](../project-context.md)**. Read that first for the product; everything below is the build system you'll use to make it.
14
14
 
15
15
  ## What the GDS is
16
16
 
@@ -66,13 +66,13 @@ Four ranks, in ancient-Greek-civilization order:
66
66
 
67
67
  So the sandbox is short: ship three small `newcomer_friendly` tasks and the city opens the whole queue to you on its own (the jump to **Metic** — with its triage/trust powers — is still a deliberate Archon promotion). Rank lives on the `builders.rank` column in the production database and is checked server-side on every privileged request — **with no caching**. A demotion takes effect on your next request. You cannot escalate your own rank by editing local files; the server is the source of truth. See [ADR 0016](../adr/<redacted>.md) and [ADR 0034](../adr/<redacted>.md) for the full trust model.
68
68
 
69
- ## Drachmae and karma
69
+ ## Example and karma
70
70
 
71
- Two parallel reputation tracks. You don't need to *do* anything special to earn either — claim a task, do good work, ship it, and the system tracks both. The full mechanics (formulas, the kind table, the budget cap, every karma source) live in **[Drachmae & karma — how you get paid](drachmae-and-karma.md)**; here's the shape of it.
71
+ Two parallel reputation tracks. You don't need to *do* anything special to earn either — claim a task, do good work, ship it, and the system tracks both. The full mechanics (formulas, the kind table, the budget cap, every karma source) live in **[Example & karma — how you get paid](example-and-karma.md)**; here's the shape of it.
72
72
 
73
- - **Drachmae** (called "credits" in code) are your **equity** in the project — a score and a stake, *not* a currency you spend on anything. They only go up, and they persist if you leave and come back. Most of your drachmae now come from a **cost-plus reward on each shipped session**: the server prices the LLM tokens your work actually burned and pays you that real cost **plus 20%** ([ADR 0054](../adr/<redacted>.md)). On top of that, each task pays its `credits_reward` adjusted by the *kind* of work (a captured learning or a resolved blocker is worth 1.5×; cleanup 0.8×), and capturing an idea that someone else then ships earns you a 25% bonus ([ADR 0023](../adr/<redacted>.md)). Credits land at the `completed → confirmed` edge — when verification passes, not at deploy. See the standings on [/builders](https://example.com/builders).
73
+ - **Example** (called "credits" in code) are your **equity** in the project — a score and a stake, *not* a currency you spend on anything. They only go up, and they persist if you leave and come back. Most of your example now come from a **cost-plus reward on each shipped session**: the server prices the LLM tokens your work actually burned and pays you that real cost **plus 20%** ([ADR 0054](../adr/<redacted>.md)). On top of that, each task pays its `credits_reward` adjusted by the *kind* of work (a captured learning or a resolved blocker is worth 1.5×; cleanup 0.8×), and capturing an idea that someone else then ships earns you a 25% bonus ([ADR 0023](../adr/<redacted>.md)). Credits land at the `completed → confirmed` edge — when verification passes, not at deploy. See the standings on [/builders](https://example.com/builders).
74
74
 
75
- - **Karma** is a *separate* signal that measures **peer trust** — how other builders rate the *way* you work, not how much you ship. It's earned when Metic-and-above builders upvote your confirmed work (tallied weekly), when a proposal of yours is ratified, and when you capture ideas; it can also go *down* if you break things. Karma shows up on your profile (with a 30-day trend) and as a sortable column on the leaderboard, and it feeds your "builder strength" score. **It does not gate rank promotions** — those happen automatically by ship count (Xenos → Thetes after three ships) or by an Archon's deliberate decision. A builder who ships fast but breaks things gains drachmae and loses karma; a builder who ships thoughtfully gains both.
75
+ - **Karma** is a *separate* signal that measures **peer trust** — how other builders rate the *way* you work, not how much you ship. It's earned when Metic-and-above builders upvote your confirmed work (tallied weekly), when a proposal of yours is ratified, and when you capture ideas; it can also go *down* if you break things. Karma shows up on your profile (with a 30-day trend) and as a sortable column on the leaderboard, and it feeds your "builder strength" score. **It does not gate rank promotions** — those happen automatically by ship count (Xenos → Thetes after three ships) or by an Archon's deliberate decision. A builder who ships fast but breaks things gains example and loses karma; a builder who ships thoughtfully gains both.
76
76
 
77
77
  One more thing worth knowing: builders are **uncapped by default** — your spend is tracked (it's the cost side of the same coin the reward is computed from) but never blocks you. There's no default budget. An Archon *can* set a per-builder **monthly budget cap** as a manual brake on a runaway; if one is set for you, you get a warning at 80% and `/builder-ship` pauses at 100% until it's raised ([ADR 0085](../adr/<redacted>.md)).
78
78
 
@@ -111,7 +111,7 @@ The whole project's source-of-truth index is [`CLAUDE.md`](../../CLAUDE.md). Two
111
111
 
112
112
  Other depth, in roughly the order you'll need it:
113
113
 
114
- - [`docs/onboarding/drachmae-and-karma.md`](drachmae-and-karma.md) — the full reward economy: how drachmae and karma are earned, the cost-plus session reward, and the monthly budget cap
114
+ - [`docs/onboarding/example-and-karma.md`](example-and-karma.md) — the full reward economy: how example and karma are earned, the cost-plus session reward, and the monthly budget cap
115
115
  - [`docs/architecture.md`](../architecture.md) — live system: droplet, stack, schema, API surface
116
116
  - [`docs/modules-contract.md`](../modules-contract.md) — the product is built as a small core plus swappable `modules/<key>/` (dev boxes, the game, Discord, art, and more); this is the live roster and how a task lands inside one
117
117
  - [`docs/canonical-permissions.md`](../canonical-permissions.md) — who can do what (rank gates)
@@ -190,7 +190,7 @@ If a `/builder-*` command ever says "no GDS session," just run `/builder-setup`
190
190
 
191
191
  Run `/builder-start` to see what you can claim — no acknowledgment step needed, the queue is open. New builders see only `newcomer_friendly` tasks — small, well-scoped, easy to finish in one sitting. Pick one that looks interesting, claim it with `/builder-claim N`, do the work, and ship it with `/builder-ship`.
192
192
 
193
- When you ship your **first** task, drachmae land in your column and you're inducted as a citizen of Example. Ship your **third** and you graduate to **Thetes** — the one-claim limit lifts and the whole general queue opens to you. Welcome.
193
+ When you ship your **first** task, example land in your column and you're inducted as a citizen of Example. Ship your **third** and you graduate to **Thetes** — the one-claim limit lifts and the whole general queue opens to you. Welcome.
194
194
 
195
195
  ## Your own dev box
196
196
 
@@ -15,7 +15,7 @@ Run by an Archon when investigating an incident, a suspected compromise, or a "w
15
15
  |---|---|---|
16
16
  | `CLAIM` | `claims.claimed_at` | Builder claimed a task — task locked to this session. |
17
17
  | `CLAIM_END` | `claims.released_at` + `outcome` | Claim resolved — `outcome` says whether the work shipped, was abandoned, partially completed, or expired. |
18
- | `CREDIT` | `credit_log.recorded_at` | Drachmae moved (`task.confirmed`, `ship.net_negative`, rank-change audit, etc.) — `delta` is the integer amount. |
18
+ | `CREDIT` | `credit_log.recorded_at` | Example moved (`task.confirmed`, `ship.net_negative`, rank-change audit, etc.) — `delta` is the integer amount. |
19
19
  | `COST` | `cost_log.recorded_at` | The builder logged a USD spend — `category` (api / compute / infra / domain / art / other) + `source`. |
20
20
  | `SESSION_START` / `SESSION_END` | `session_logs.started_at` / `ended_at` | Claim-scoped working session boundaries. Pair with `outcome` for "shipped / partial / abandoned." |
21
21
  | `HTTP_<METHOD>` | `audit_log.recorded_at` | Every authenticated POST / PATCH / PUT / DELETE the builder made — route, status, IP. The forensic fine-grain. |
@@ -23,7 +23,7 @@ Run by an Archon when investigating an incident, a suspected compromise, or a "w
23
23
  Notably absent — and worth knowing about so you can ask follow-up questions if needed:
24
24
 
25
25
  - **GET requests** are not in `audit_log` (by design; high volume, low signal). Read patterns aren't part of this replay.
26
- - **Builder rank changes** show up as `HTTP_PATCH route=/api/gds/builders/:id/rank` rows and as `CREDIT` rows when the rank change carries a drachmae adjustment. The new rank value lives in `audit_log.request_body_redacted`.
26
+ - **Builder rank changes** show up as `HTTP_PATCH route=/api/gds/builders/:id/rank` rows and as `CREDIT` rows when the rank change carries a example adjustment. The new rank value lives in `audit_log.request_body_redacted`.
27
27
  - **Game-server WebSocket events** (movement, world state) live in `world_events` and are NOT included here — this script is GDS-scoped. If a game-side investigation is needed, query `world_events` separately.
28
28
 
29
29
  ## Running the script
@@ -105,7 +105,7 @@ Put these in `/etc/example/box.env` (chmod 600 — **secrets never go in the rep
105
105
 
106
106
  ## Cost (Criterion C1 / cost)
107
107
 
108
- A box accrues compute cost **only while `active`**. At park/deprovision the CLI computes `active hours × the size's hourly rate` and writes it to both the `box_events` ledger and `cost_log` (category `compute`, builder-attributed) — so the public status dashboard's per-builder split sees real box spend. `box.js status` prints the active monthly run-rate + total spent. The **rebill to drachmae/earnings** (org-funded starter → self-fund) is a separate task, [#602](https://example.com/builders#/task/602).
108
+ A box accrues compute cost **only while `active`**. At park/deprovision the CLI computes `active hours × the size's hourly rate` and writes it to both the `box_events` ledger and `cost_log` (category `compute`, builder-attributed) — so the public status dashboard's per-builder split sees real box spend. `box.js status` prints the active monthly run-rate + total spent. The **rebill to example/earnings** (org-funded starter → self-fund) is a separate task, [#602](https://example.com/builders#/task/602).
109
109
 
110
110
  ## Going live (one-time operator steps)
111
111
 
@@ -143,7 +143,7 @@ These spend money and are intentionally manual.
143
143
  - **[#596](https://example.com/builders#/task/596)** (done) — the devcontainer (box-as-code) this provisions.
144
144
  - **[#599](https://example.com/builders#/task/599)** — Claude Desktop managed-settings + the stable-hostname cutover the lifecycle records. (The browser-on-ramp is now the ttyd web terminal over a Cloudflare Tunnel — [#760](https://example.com/builders#/task/760)/[ADR 0038](../adr/<redacted>.md) — not the retired `claude rc` Remote-Control service.)
145
145
  - **[#600](https://example.com/builders#/task/600)** — rank-gated **source access**: the scoped GitHub credential the box holds, granted/revoked by rank. [#598](https://example.com/builders#/task/598) records `scope`; [#600](https://example.com/builders#/task/600) enforces it.
146
- - **[#602](https://example.com/builders#/task/602)** — cost passthrough (org-funded starter → self-fund via the `costs`/drachmae system). [#598](https://example.com/builders#/task/598) logs the cost; [#602](https://example.com/builders#/task/602) rebills it.
146
+ - **[#602](https://example.com/builders#/task/602)** — cost passthrough (org-funded starter → self-fund via the `costs`/example system). [#598](https://example.com/builders#/task/598) logs the cost; [#602](https://example.com/builders#/task/602) rebills it.
147
147
 
148
148
  ## Safety properties
149
149
 
@@ -61,7 +61,7 @@ node scripts/gds/design-sync.js --surface hall-ui
61
61
  Use the DesignSync MCP tool in your Claude Code session:
62
62
 
63
63
  ```
64
- list_projects → pick the OTB project (or create "Off the Boats — Design System")
64
+ list_projects → pick the OTB project (or create "Example — Design System")
65
65
  finalize_plan → stage all files from manifest.files, rooted at bundlePath
66
66
  write_files → push the bundle
67
67
  ```
@@ -119,7 +119,7 @@ Organized by topic, not chronology. New entries go in the matching section; crea
119
119
 
120
120
  - **Symptom:** Visitor clicks "Sign in with GitHub" on /builders, GitHub renders its red "Be careful!" warning page or returns `?error=redirect_uri_mismatch`, and the visitor never lands back on the hall.
121
121
  - **Root cause:** The GitHub OAuth app's **Authorization callback URL** field must match exactly what the server tells GitHub. Our server sends `${publicOrigin}/api/gds/auth/web/callback` — easy to misconfigure as just `https://example.com/` or `/auth/callback` when registering a fresh OAuth app.
122
- - **Fix:** In github.com → Settings → Developer settings → OAuth Apps → (the Off the Boats app) → **Authorization callback URL**, set:
122
+ - **Fix:** In github.com → Settings → Developer settings → OAuth Apps → (the Example app) → **Authorization callback URL**, set:
123
123
  ```
124
124
  https://example.com/api/gds/auth/web/callback
125
125
  ```
@@ -47,6 +47,23 @@ npm pack ./clients/bongos-client --dry-run # token-free content preview
47
47
  npm publish ./clients/bongos-client # real (publishConfig makes it restricted; needs npm login)
48
48
  ```
49
49
 
50
+ ## Cutting a core release (the policy — [ADR 0137](../adr/<redacted>.md))
51
+
52
+ Publishing is a **manual, owner-gated step** — merges to `main` do **not** auto-publish (no npm write-token lives in CI). The update subscription ([ADR 0136](../adr/<redacted>.md)) consumes whatever the owner has published, so a release is exactly: bump → publish → the subscription picks it up on its next sweep.
53
+
54
+ 1. **Bump `CORE_VERSION`** in [`src/module-api.js`](../../src/module-api.js) (semver; a **patch** for a fix, **minor** for additive surface — a **major** is a deliberate, human-only event) and add a one-line changelog entry in the same file. This bump is a normal claimed task, not a release-tool side effect — the version's provenance stays in the git history + changelog.
55
+ 2. **Publish** (owner, from a clean checkout of the released commit):
56
+ ```sh
57
+ node scripts/gds/package-core.js --publish # DRY-RUN: runs the fail-closed no-leak gate, previews @bongos/core@<version>
58
+ npm login # once per machine (+ 2FA), or use a Classic Automation token
59
+ node scripts/gds/package-core.js --publish --live # permanent; the no-leak gate must pass or nothing is built/uploaded
60
+ ```
61
+ The no-leak / mirror-redact gate is **built into the build** — a leaking artifact is never produced, so `--publish` cannot upload one.
62
+ 3. **Tag the release** (optional but recommended — the deliberate, auditable marker): `git tag core-v<version> && git push origin core-v<version>`. The tag documents intent; it triggers no CI.
63
+ 4. **Done.** Subscribed instances on the `patch`/`minor` channel take it automatically on their next routine sweep; `pinned` instances wait for a manual `bongos upgrade`. A stale (un-bumped) version is rejected by npm as a duplicate — a natural guard.
64
+
65
+ > **Automating this** (a tag-triggered CI publish) is deferred to the managed-fleet epic ([#1948](https://example.com/builders#/task/1948)); revisit when the manual step becomes a real bottleneck. See [ADR 0137](../adr/<redacted>.md) "When to revisit".
66
+
50
67
  ## Install a private package (any consumer machine or instance)
51
68
 
52
69
  Add a one-line `.npmrc` (repo-root or `~/.npmrc`) that reads the token from the environment:
@@ -65,7 +65,7 @@ If `*.example.com` is **not** in the output:
65
65
  The prod OAuth app points its callback at `example.com/api/gds/auth/web/callback`. Staging needs its own:
66
66
 
67
67
  1. github.com → Settings → Developer settings → OAuth Apps → New OAuth App.
68
- 2. Application name: `Off the Boats — staging`.
68
+ 2. Application name: `Example — staging`.
69
69
  3. Homepage URL: `https://staging.example.com`.
70
70
  4. Authorization callback URL: `https://staging.example.com/api/gds/auth/web/callback`.
71
71
  5. Note the **Client ID** and **Client Secret** — they go into `/home/lars/example-staging/.env` (see step 4 of the provisioning script).
@@ -13,6 +13,7 @@
13
13
  5. **materialize `.claude/`** — refresh skills/settings/hooks from the new core (`materializeClaude`), rewriting invocations to the `bongos` bin.
14
14
  6. **restart** — `--service <unit>` or `--restart-cmd "<cmd>"`.
15
15
  7. **verify** — installed version == target (+ optional `--health-url`).
16
+ 8. **auto-rollback on failure** (task [#2149](https://example.com/builders#/task/2149), default ON) — if `npm install`/`migrate` fails or the step-7 health check fails, revert the pin → reinstall the previous core → restart → re-verify → write a `rolled_back:` ledger row. Opt out with `--no-rollback-on-failure`. See the section below.
16
17
 
17
18
  Run bare (`bongos upgrade`, no `--to`) it stays the module-compat **pre-check** only.
18
19
 
@@ -50,6 +51,60 @@ The instance runs on the droplet (co-tenant): systemd `emersonian-circles.servic
50
51
  6. **Update the repo of record** — run the channel on the laptop clone (`--skip-migrate`, no DB there), commit the pin bump (drop the superseded tarball), `git push origin`.
51
52
  7. **Align the droplet checkout** — the droplet has no deploy key (`git pull` fails; idea 509), so `git bundle` the new commit on the laptop, `scp`, `git fetch <bundle> && git reset --hard FETCH_HEAD`. `node_modules` is already the new version, so no re-`npm ci`; a final restart makes `/version` report the new commit.
52
53
 
54
+ ## Auto-rollback on failure (task 2149)
55
+
56
+ By default (`--rollback-on-failure`, ON unless `--no-rollback-on-failure`) the channel self-heals a failed bump. If **`npm install` fails**, **`npm run migrate` fails**, or the **post-restart health check fails**, `bongos upgrade` automatically:
57
+
58
+ 1. reverts the `@bongos/core` pin to the exact pre-upgrade dep string (snapshotted the instant the pin moved),
59
+ 2. `npm install`s the previous core back,
60
+ 3. restarts the service,
61
+ 4. re-verifies (installed == previous, health recovers),
62
+ 5. records a `rolled_back: <reason> (attempted N → N+1, restored N)` row in `core_upgrades`.
63
+
64
+ **The DB is NOT rolled back — only the code pin.** Core migrations are additive + forward-safe (the core migration rule), so an already-applied migration is left in place; a *failed* migration is never recorded in `schema_migrations`, so a retry re-runs it cleanly. The reversal is recorded via the always-present `note` column (not a new `outcome` column) so it lands even in the failed-migrate path — where a newer column wouldn't yet exist on that instance.
65
+
66
+ **Proven live on demo.cloudbongos.com** (task [#2157](https://example.com/builders#/task/2157)): demo, on rollback-capable 1.17.3, was upgraded to a canary carrying a deliberately-failing migration. Migrate raised → the channel auto-reverted the pin to 1.17.3, reinstalled + restarted it, `/healthz` stayed 200 (**zero downtime** — the failure was at migrate, before the restart), and a `rolled_back` ledger row was written. This is the safety gate the unattended patch-only auto-upgrade subscription (task [#2150](https://example.com/builders#/task/2150)) depends on.
67
+
68
+ ## Subscribing to updates — unattended patch-only auto-upgrade (task 2150 / ADR 0136)
69
+
70
+ The sections above are the *manual* `bongos upgrade`. The **subscription** runs it for you, on a cadence, safely — the "subscribe to regular updates" experience. Policy: **patch-only by default, health-gated with auto-rollback, opt-in, autonomy-gated** (full rationale in [ADR 0136](../adr/<redacted>.md)).
71
+
72
+ **Per-instance channel** bounds how far an unattended upgrade may jump:
73
+
74
+ | channel | takes | example (from `1.17.1`) |
75
+ |---|---|---|
76
+ | `pinned` | nothing (manual only) | — |
77
+ | `patch` *(default)* | higher patch, same `x.y` | `→ 1.17.4`, never `1.18.0` |
78
+ | `minor` | higher minor, same major | `→ 1.18.0`, never `2.0.0` |
79
+
80
+ A **major** is never automatic; prereleases are never auto-targeted.
81
+
82
+ **Enrolling an instance** — add it to [`config/update-subscriptions.json`](../../config/update-subscriptions.json) (ships empty). `env` carries per-instance vars merged into the upgrade child — set `PGDATABASE` so `migrate` hits the right DB (see the Gotchas):
83
+
84
+ ```json
85
+ {
86
+ "defaultChannel": "patch",
87
+ "instances": [
88
+ { "slug": "demo", "dir": "/srv/cloudbongos/demo", "service": "demo.service",
89
+ "healthUrl": "https://demo.cloudbongos.com/healthz", "channel": "patch",
90
+ "env": { "PGDATABASE": "demo" } }
91
+ ]
92
+ }
93
+ ```
94
+
95
+ **Preview vs run** — dry-run is the default; the scheduled step passes `--apply`:
96
+
97
+ ```bash
98
+ node .claude/scheduled-tasks/core-update-subscription/subscribe.js # plan only
99
+ node .claude/scheduled-tasks/core-update-subscription/subscribe.js --apply # upgrade
100
+ ```
101
+
102
+ Each subscribed instance: read its installed core → ask the registry (`npm view`, needs `NPM_TOKEN`) → resolve the newest version its channel permits → if newer, `bongos upgrade --to <v> --registry` with **auto-rollback ON**. It prints one line per instance plus a tally; a non-zero exit means an upgrade failed (already auto-reverted).
103
+
104
+ **Triple-gated, so nothing moves by accident:** the `core-update-subscription` routine is `requiresAutonomy: true` + **default OFF** in [`config/scheduled-routines.json`](../../config/scheduled-routines.json), the roster ships empty, and every upgrade is health-gated. Arm it by enabling the routine's timer on the control plane once autonomy is on.
105
+
106
+ **Not covered:** multi-host / SSH orchestration across a real fleet (the deferred fleet-control-plane epic, task [#1948](https://example.com/builders#/task/1948)); and *publishing* new patches, which stays a gated owner step (ADR 0134) — a follow-up task decides whether merges auto-publish.
107
+
53
108
  ## Gotchas
54
109
 
55
110
  - **`PGDATABASE` is load-bearing on a co-tenant droplet.** `migrate.sh` defaults `PGDATABASE` to `example` — **production**. Always set `PGDATABASE=<instance-db>` explicitly, or you migrate the wrong database.
@@ -1,6 +1,6 @@
1
1
  # Cursor (Anysphere) — Competitive-Threat Analysis for Cloud Bongos
2
2
 
3
- **A competitor-research document for Cloud Bongos / Off the Boats**
3
+ **A competitor-research document for Cloud Bongos / Example**
4
4
  Prepared 2026-06-22 · the **first committed competitor doc** in this repo · companion to the (uncommitted) `component-based-dev-research.md` deep-research doc · task [#1403](https://example.com/builders#/task/1403)
5
5
 
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  # LLM Model-Agnostic Platform + Cheaper Grader — Tools Audit & Architecture Path
2
2
 
3
- **A research/architecture spike for Cloud Bongos / Off the Boats**
3
+ **A research/architecture spike for Cloud Bongos / Example**
4
4
  Prepared 2026-06-28 · task [#1069](https://example.com/builders#/task/1069) · GDS-V4 · track `internal`
5
5
 
6
6
  ---
@@ -10,5 +10,6 @@
10
10
  "uiSections": []
11
11
  },
12
12
  "provides": ["discord.isLinked"],
13
- "consumes": ["ideas.capture"]
13
+ "consumes": ["ideas.capture"],
14
+ "dependencies": { "discord.js": "^14.26.4" }
14
15
  }
@@ -424,7 +424,15 @@ async function getLeaderboardWithAchievements(limit = 10, perBuilderCap = 5) {
424
424
  ORDER BY a.sort_order
425
425
  LIMIT $2
426
426
  ) t
427
- ), ARRAY[]::text[]) AS achievements
427
+ ), ARRAY[]::text[]) AS achievements,
428
+ -- task 1473: mirror of credits.leaderboard's tokens_used — total
429
+ -- transcript tokens across this builder's sessions, so the public
430
+ -- leaderboard shows efficiency (tokens per drachma) beside credits.
431
+ COALESCE((
432
+ SELECT SUM(sr.total_tokens)
433
+ FROM session_records sr
434
+ WHERE sr.builder_id = b.id
435
+ ), 0)::bigint AS tokens_used
428
436
  FROM builders b
429
437
  ORDER BY b.total_credits DESC, b.created_at ASC
430
438
  LIMIT $1`,
@@ -37,7 +37,16 @@ async function leaderboard(limit = 20) {
37
37
  ORDER BY a.sort_order
38
38
  LIMIT 5
39
39
  ) t
40
- ), ARRAY[]::text[]) AS achievements
40
+ ), ARRAY[]::text[]) AS achievements,
41
+ -- task 1473: total transcript tokens across all of this builder's
42
+ -- recorded sessions, so the hall leaderboard can show efficiency
43
+ -- (tokens spent per drachma earned) next to credits. Mirrored in
44
+ -- achievements.getLeaderboardWithAchievements (the /public query).
45
+ COALESCE((
46
+ SELECT SUM(sr.total_tokens)
47
+ FROM session_records sr
48
+ WHERE sr.builder_id = builders.id
49
+ ), 0)::bigint AS tokens_used
41
50
  FROM builders
42
51
  ORDER BY total_credits DESC, created_at ASC
43
52
  LIMIT $1`,