@bongos/core 1.17.0 → 1.17.2

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 (230) hide show
  1. package/.bongos-core.json +363 -312
  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/CLAUDE.md +11 -238
  15. package/GOVERNANCE.md +1 -1
  16. package/README.md +1 -1
  17. package/bin/bongos.js +1 -0
  18. package/clients/bongos-client/README.md +4 -4
  19. package/clients/bongos-client/bongos-client.global.js +14 -1
  20. package/clients/bongos-client/index.cjs +14 -1
  21. package/clients/bongos-client/index.d.ts +19 -2
  22. package/clients/bongos-client/index.mjs +11 -1
  23. package/clients/bongos-client/package.json +1 -1
  24. package/docs/adr/0001-stack-choice-single-vps.md +1 -1
  25. package/docs/adr/0008-google-chat-oauth-user-auth.md +1 -1
  26. package/docs/adr/0019-red-team-bounty-payout-table.md +3 -3
  27. package/docs/adr/0020-security-model-public-stub.md +1 -1
  28. package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +1 -1
  29. package/docs/adr/0024-cloneable-repo-local-first-memory.md +1 -1
  30. package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +4 -4
  31. package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +3 -3
  32. package/docs/adr/0030-builders-hall-live-updates.md +1 -1
  33. package/docs/adr/0031-cloud-dev-environments-for-builders.md +4 -4
  34. package/docs/adr/0032-discord-mirror-of-gds.md +2 -2
  35. package/docs/adr/0034-thetes-graduated-newcomer-rank.md +1 -1
  36. package/docs/adr/0044-mediterranean-palette-replacement.md +1 -1
  37. package/docs/adr/0044-per-box-live-game-preview.md +1 -1
  38. package/docs/adr/0054-session-token-reward-cost-plus.md +10 -10
  39. package/docs/adr/0057-container-cost-ledger.md +3 -3
  40. package/docs/adr/0062-medusa-instance-model-decoupling.md +4 -4
  41. package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +2 -2
  42. package/docs/adr/0085-remove-default-per-builder-spend-cap.md +1 -1
  43. package/docs/adr/0086-goal-scoped-work-hierarchy.md +1 -1
  44. package/docs/adr/0096-require-reward-before-workable.md +9 -9
  45. package/docs/adr/0097-retroactive-reward-backfill.md +3 -3
  46. package/docs/adr/0100-two-repo-instance-model.md +1 -1
  47. package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +3 -3
  48. package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +3 -3
  49. package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +1 -1
  50. package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +6 -6
  51. package/docs/adr/0133-github-app-manifest-onboarding-signin.md +2 -0
  52. package/docs/adr/0134-private-first-npm-distribution.md +20 -6
  53. package/docs/adr/0135-module-upstream-submission-interim-queue.md +34 -0
  54. package/docs/adr/0136-update-channel-subscription-policy.md +51 -0
  55. package/docs/adr/0137-upstream-publish-policy-manual-owner-gated.md +40 -0
  56. package/docs/adr/0138-bundled-module-deps-declared-per-module.md +45 -0
  57. package/docs/adr/README.md +14 -10
  58. package/docs/api/openapi.json +315 -6
  59. package/docs/api-reference.md +10 -5
  60. package/docs/architecture.md +3 -3
  61. package/docs/branding-contract.md +5 -4
  62. package/docs/canonical-permissions.md +1 -1
  63. package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
  64. package/docs/file-map.md +20 -19
  65. package/docs/handoff-template.md +2 -2
  66. package/docs/modules-contract.md +8 -1
  67. package/docs/onboarding/diagrams/README.md +7 -7
  68. package/docs/onboarding/drachmae-and-karma.md +18 -18
  69. package/docs/onboarding/primer.md +9 -9
  70. package/docs/recipes/audit-replay.md +2 -2
  71. package/docs/recipes/builder-box-lifecycle.md +2 -2
  72. package/docs/recipes/claude-design-loop.md +1 -1
  73. package/docs/recipes/instance-deploy.md +4 -4
  74. package/docs/recipes/instance-first-run.md +51 -0
  75. package/docs/recipes/ops-gotchas.md +1 -1
  76. package/docs/recipes/packaging-the-core.md +5 -5
  77. package/docs/recipes/private-npm-distribution.md +39 -12
  78. package/docs/recipes/self-host.md +1 -1
  79. package/docs/recipes/staging-environment.md +1 -1
  80. package/docs/recipes/upgrading-the-core.md +63 -8
  81. package/docs/research/cursor-competitive-analysis.md +1 -1
  82. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +1 -1
  83. package/migrations/core_191_module_submissions.sql +45 -0
  84. package/modules/autonomy/CLAUDE.md +11 -45
  85. package/modules/builder-settings/CLAUDE.md +11 -54
  86. package/modules/dev-box/CLAUDE.md +11 -34
  87. package/modules/discord/CLAUDE.md +11 -46
  88. package/modules/discord/module.json +2 -1
  89. package/modules/economy/CLAUDE.md +11 -44
  90. package/modules/economy/achievements.js +9 -1
  91. package/modules/economy/credits.js +10 -1
  92. package/modules/grading/CLAUDE.md +11 -38
  93. package/modules/hall-ui/CLAUDE.md +11 -57
  94. package/modules/hall-ui/public/builders.js +71 -4
  95. package/modules/hall-ui/public/goal-inbox.js +191 -0
  96. package/modules/hall-ui/public/goals-page.js +227 -22
  97. package/modules/hall-ui/public/goals.html +16 -0
  98. package/modules/hall-ui/public/hall-widgets.js +14 -1
  99. package/modules/hall-ui/public/index.html +3 -0
  100. package/modules/hall-ui/public/new-project-wizard.js +6 -4
  101. package/modules/hall-ui/public/style.css +43 -0
  102. package/modules/ideas/CLAUDE.md +11 -33
  103. package/modules/lifecycle/CLAUDE.md +11 -59
  104. package/modules/lifecycle/routes/goals.js +80 -0
  105. package/modules/memory/CLAUDE.md +11 -36
  106. package/modules/onboarding/CLAUDE.md +11 -51
  107. package/modules/provisioning/CLAUDE.md +15 -0
  108. package/modules/provisioning/migrations/provisioning_001_tables.sql +160 -0
  109. package/modules/provisioning/migrations/provisioning_002_standalone_shape.sql +11 -0
  110. package/modules/provisioning/migrations/provisioning_003_github_app_manifest.sql +95 -0
  111. package/modules/provisioning/module.json +17 -0
  112. package/modules/provisioning/onboard-plan.js +37 -0
  113. package/modules/provisioning/provisioning.js +539 -0
  114. package/modules/provisioning/rate-limit.js +35 -0
  115. package/modules/provisioning/routes/provisioning.js +607 -0
  116. package/modules/provisioning/tests/provisioning.mjs +232 -0
  117. package/modules/provisioning/ui/.gitkeep +0 -0
  118. package/modules/security/CLAUDE.md +11 -40
  119. package/modules/security/secret-scrub.js +10 -0
  120. package/modules/sessions/CLAUDE.md +11 -35
  121. package/modules/status-ui/CLAUDE.md +11 -43
  122. package/package-lock.json +2 -2
  123. package/package.json +7 -2
  124. package/public-landing/create.html +58 -12
  125. package/public-landing/index.html +40 -21
  126. package/scripts/discord/README.md +1 -1
  127. package/scripts/gds/CLAUDE.md +11 -140
  128. package/scripts/gds/claim.js +98 -48
  129. package/scripts/gds/claude-materialize.js +174 -20
  130. package/scripts/gds/claude-md-template.js +84 -0
  131. package/scripts/gds/cli-lib.js +112 -2
  132. package/scripts/gds/cutover-codemod.js +241 -0
  133. package/scripts/gds/fitness.js +54 -0
  134. package/scripts/gds/gen-api-client.js +10 -10
  135. package/scripts/gds/init.js +112 -16
  136. package/scripts/gds/lint-infra-exec.js +70 -0
  137. package/scripts/gds/lint-workflow-exec.js +63 -0
  138. package/scripts/gds/migration-namespace.js +1 -1
  139. package/scripts/gds/mirror-lineage-check.js +14 -5
  140. package/scripts/gds/mirror-redact.js +8 -0
  141. package/scripts/gds/module.js +118 -4
  142. package/scripts/gds/npmrc.js +93 -0
  143. package/scripts/gds/onboard.js +17 -24
  144. package/scripts/gds/package-core.js +74 -17
  145. package/scripts/gds/provision.js +102 -17
  146. package/scripts/gds/publish-manifest.js +60 -2
  147. package/scripts/gds/run-routine.js +51 -13
  148. package/scripts/gds/run-unit-tests.js +4 -0
  149. package/scripts/gds/seed-adopt-tasks.js +1 -1
  150. package/scripts/gds/status.js +6 -1
  151. package/scripts/gds/task.js +166 -0
  152. package/scripts/gds/update-channel.js +186 -0
  153. package/scripts/gds/upgrade.js +172 -25
  154. package/src/bongos/CLAUDE.md +11 -60
  155. package/src/bongos/auth.js +24 -0
  156. package/src/bongos/module-submissions.js +56 -0
  157. package/src/bongos/route-rank-check.js +6 -0
  158. package/src/bongos/routes/CLAUDE.md +11 -39
  159. package/src/bongos/routes/auth.js +6 -1
  160. package/src/bongos/routes/modules.js +123 -21
  161. package/src/bongos/serve-internal.js +10 -1
  162. package/src/branding.js +1 -0
  163. package/src/instance-config.js +1 -1
  164. package/src/module-api.js +24 -1
  165. package/src/module-loader/loader.js +36 -4
  166. package/src/module-loader/manifest-schema.js +16 -1
  167. package/tests/branding.mjs +11 -0
  168. package/tests/claim_error_surface.mjs +107 -0
  169. package/tests/claude_materialize.mjs +125 -0
  170. package/tests/consumer_layout_boot.mjs +302 -0
  171. package/tests/cutover_codemod.mjs +184 -0
  172. package/tests/device_flow_start.mjs +96 -0
  173. package/tests/first_run_engine_check.mjs +79 -0
  174. package/tests/goal_membership_requests.mjs +33 -3
  175. package/tests/hook_core_resolve.mjs +125 -0
  176. package/tests/hook_user_agents.mjs +62 -0
  177. package/tests/infra_exec_paths.mjs +104 -0
  178. package/tests/init.mjs +106 -6
  179. package/tests/instance_mismatch_guard.mjs +101 -0
  180. package/tests/mirror_lineage_proof.mjs +14 -0
  181. package/tests/module_cli.mjs +130 -2
  182. package/tests/module_loader.mjs +42 -0
  183. package/tests/module_manifest.mjs +19 -0
  184. package/tests/module_submissions.mjs +135 -0
  185. package/tests/npmrc.mjs +105 -0
  186. package/tests/onboard.mjs +62 -0
  187. package/tests/package_core.mjs +76 -22
  188. package/tests/platform_boot.mjs +5 -2
  189. package/tests/provision.mjs +107 -8
  190. package/tests/provisioning_github_app_routes.mjs +44 -2
  191. package/tests/publish_manifest.mjs +52 -1
  192. package/tests/run_routine.mjs +26 -1
  193. package/tests/run_routine_two_root.mjs +77 -0
  194. package/tests/scrubber_corpus.mjs +17 -0
  195. package/tests/served_paths_shipped.mjs +2 -2
  196. package/tests/task_cli.mjs +99 -0
  197. package/tests/update_channel.mjs +186 -0
  198. package/tests/upgrade.mjs +220 -25
  199. package/tests/workflow_exec_paths.mjs +98 -0
  200. package/docs/design/container-exterior-tiles.md +0 -49
  201. package/docs/design/container-exterior.md +0 -81
  202. package/docs/design/container-interior.md +0 -77
  203. package/docs/design/world-map-scroll.md +0 -41
  204. package/docs/recipes/claude-gemini-bongos-doors.md +0 -155
  205. package/docs/recipes/cloudbongos-staging-gate.md +0 -139
  206. package/docs/recipes/cloudbongos-standup.md +0 -111
  207. package/docs/recipes/parallel-load-results-2026-05-30.md +0 -63
  208. package/docs/recipes/parallel-load-test.md +0 -32
  209. package/docs/recipes/pixel-art-pipeline.md +0 -411
  210. package/docs/recipes/staging-data.md +0 -50
  211. package/migrations/instance/018_pms_v3_planning_seed.sql +0 -131
  212. package/migrations/instance/080_gds_v4_planning_seed.sql +0 -75
  213. package/migrations/instance/110_medusa_planning_seed.sql +0 -70
  214. package/migrations/instance/120_bongos_v1_planning_seed.sql +0 -69
  215. package/migrations/instance/144_bongos_v1_module_system_criterion.sql +0 -26
  216. package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +0 -29
  217. package/migrations/instance/172_v2_world_planning_seed.sql +0 -163
  218. package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +0 -33
  219. package/migrations/instance/182_gdsv4_bongos_consolidation.sql +0 -132
  220. package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +0 -116
  221. package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +0 -69
  222. package/scripts/gds/art-stage.js +0 -152
  223. package/server.js +0 -212
  224. package/tests/art_key.mjs +0 -121
  225. package/tests/day_cycle.mjs +0 -197
  226. package/tests/snapshot_picker.mjs +0 -233
  227. package/tests/sprite_facing.mjs +0 -35
  228. package/tests/terrain_picker.mjs +0 -298
  229. package/tests/turn_in_place.mjs +0 -280
  230. package/tests/walkability.mjs +0 -188
@@ -1,6 +1,9 @@
1
- // @cloudbongos/client (CommonJS build) — GENERATED from index.mjs by
1
+ // @bongos/client (CommonJS build) — GENERATED from index.mjs by
2
2
  // scripts/gds/gen-api-client.js. DO NOT EDIT BY HAND. Same behavior as the ESM
3
3
  // build; only the module bindings differ. For require()-based consumers.
4
+ // @bongos/client — GENERATED from the OpenAPI spec by
5
+ // scripts/gds/gen-api-client.js (task 1995 / ADR 0118). DO NOT EDIT BY HAND —
6
+ // regenerate on spec change. Zero deps; uses the platform fetch.
4
7
  'use strict';
5
8
 
6
9
  const API_VERSION = "v1";
@@ -303,10 +306,14 @@ function createClient(opts = {}) {
303
306
  patchGoalsIdMembersBuilderId: (args) => request("PATCH", "/goals/{id}/members/{builderId}", { hasBody: true }, args),
304
307
  // POST /goals/{id}/reopen — rank: metic+archon — POST /goals/:id/reopen
305
308
  postGoalsIdReopen: (args) => request("POST", "/goals/{id}/reopen", { hasBody: true }, args),
309
+ // GET /goals/{id}/requests — rank: any-builder — GET /goals/:id/requests
310
+ getGoalsIdRequests: (args) => request("GET", "/goals/{id}/requests", { hasBody: false }, args),
306
311
  // POST /goals/{id}/requests — rank: any-builder — POST /goals/:id/requests
307
312
  postGoalsIdRequests: (args) => request("POST", "/goals/{id}/requests", { hasBody: true }, args),
308
313
  // POST /goals/{id}/requests/{reqId}/respond — rank: any-builder — POST /goals/:id/requests/:reqId/respond
309
314
  postGoalsIdRequestsReqIdRespond: (args) => request("POST", "/goals/{id}/requests/{reqId}/respond", { hasBody: true }, args),
315
+ // POST /goals/{id}/requests/{reqId}/withdraw — rank: any-builder — POST /goals/:id/requests/:reqId/withdraw
316
+ postGoalsIdRequestsReqIdWithdraw: (args) => request("POST", "/goals/{id}/requests/{reqId}/withdraw", { hasBody: true }, args),
310
317
  // POST /goals/{id}/scope — rank: metic+archon — POST /goals/:id/scope
311
318
  postGoalsIdScope: (args) => request("POST", "/goals/{id}/scope", { hasBody: true }, args),
312
319
  // POST /goals/{id}/tasks — rank: any-builder — POST /goals/:id/tasks
@@ -439,6 +446,8 @@ function createClient(opts = {}) {
439
446
  postModulesKeyEnable: (args) => request("POST", "/modules/{key}/enable", { hasBody: true }, args),
440
447
  // POST /modules/{key}/submit — rank: metic+archon — POST /modules/:key/submit
441
448
  postModulesKeySubmit: (args) => request("POST", "/modules/{key}/submit", { hasBody: true }, args),
449
+ // GET /modules/submissions — rank: metic+archon — GET /modules/submissions
450
+ getModulesSubmissions: (args) => request("GET", "/modules/submissions", { hasBody: false }, args),
442
451
  },
443
452
  "overrideRequests": {
444
453
  // GET /override-requests — rank: archon — GET /override-requests
@@ -453,6 +462,8 @@ function createClient(opts = {}) {
453
462
  getProvisioningFleetCostLedger: (args) => request("GET", "/provisioning/fleet/cost-ledger", { hasBody: false }, args),
454
463
  // GET /provisioning/github-app/callback — rank: public — GET /provisioning/github-app/callback
455
464
  getProvisioningGithubAppCallback: (args) => request("GET", "/provisioning/github-app/callback", { hasBody: false }, args),
465
+ // GET /provisioning/github-app/status — rank: public — GET /provisioning/github-app/status
466
+ getProvisioningGithubAppStatus: (args) => request("GET", "/provisioning/github-app/status", { hasBody: false }, args),
456
467
  // GET /provisioning/health — rank: public — GET /provisioning/health
457
468
  getProvisioningHealth: (args) => request("GET", "/provisioning/health", { hasBody: false }, args),
458
469
  // GET /provisioning/instances — rank: any-builder — GET /provisioning/instances
@@ -467,6 +478,8 @@ function createClient(opts = {}) {
467
478
  postProvisioningInstancesIdGithubApp: (args) => request("POST", "/provisioning/instances/{id}/github-app", { hasBody: true }, args),
468
479
  // POST /provisioning/instances/{id}/teardown — rank: any-builder — POST /provisioning/instances/:id/teardown
469
480
  postProvisioningInstancesIdTeardown: (args) => request("POST", "/provisioning/instances/{id}/teardown", { hasBody: true }, args),
481
+ // GET /provisioning/onboard-plan — rank: public — GET /provisioning/onboard-plan
482
+ getProvisioningOnboardPlan: (args) => request("GET", "/provisioning/onboard-plan", { hasBody: false }, args),
470
483
  // GET /provisioning/tls-check — rank: public — GET /provisioning/tls-check
471
484
  getProvisioningTlsCheck: (args) => request("GET", "/provisioning/tls-check", { hasBody: false }, args),
472
485
  },
@@ -1,4 +1,4 @@
1
- // GENERATED — TypeScript types for @cloudbongos/client (task 1995; field-level
1
+ // GENERATED — TypeScript types for @bongos/client (task 1995; field-level
2
2
  // request typing added in task 2050 / ADR 0118). DO NOT EDIT BY HAND.
3
3
  export declare const API_VERSION: string;
4
4
  export declare const DEFAULT_BASE_URL: string;
@@ -34,6 +34,7 @@ export interface GetDemoHealthResponse { module: unknown; ok: boolean; coreVersi
34
34
  export interface GetDiscordChannelsPlanResponse { ok: boolean; guild_id: unknown; op_count: unknown; ops: unknown; warnings: unknown }
35
35
  export interface GetDoneWhenPendingReviewResponse { criteria: unknown; count: unknown }
36
36
  export interface GetGoalsIdConflictsResponse { ok: boolean; goal_id: unknown; conflicts: unknown; cross_goals_considered: unknown }
37
+ export interface GetGoalsIdRequestsResponse { requests: unknown }
37
38
  export interface GetGoalsIdResponse { goal: unknown; members: unknown; criteria: unknown; dependencies: unknown }
38
39
  export interface GetGoalsResponse { goals: unknown }
39
40
  export interface GetGradesByBuilderResponse { window_days: unknown; builders: unknown }
@@ -54,11 +55,14 @@ export interface GetMemoryBfgBuildersBuilderIdFilesResponse { builder_id: unknow
54
55
  export interface GetMemoryFileResponse { builder_id: unknown; path: unknown; content: unknown; sha256: unknown; byte_len: unknown; mtime: unknown; updated_at: unknown; created_at: unknown }
55
56
  export interface GetMemoryFilesResponse { builder_id: unknown; count: unknown; files: unknown }
56
57
  export interface GetModulesResponse { modules: unknown; own_built: unknown; core_loaded: unknown; submit_pipeline_live: boolean }
58
+ export interface GetModulesSubmissionsResponse { submissions: unknown }
57
59
  export interface GetOverrideRequestsResponse { requests: unknown }
58
60
  export interface GetProvisioningFleetResponse { instances: unknown }
61
+ export interface GetProvisioningGithubAppStatusResponse { ok: boolean; status: unknown; ready: unknown; terminal: unknown; domain: unknown; instance_status: unknown }
59
62
  export interface GetProvisioningHealthResponse { module: unknown; ok: boolean; coreVersion: unknown }
60
63
  export interface GetProvisioningInstancesIdResponse { instance: unknown; open_intent: unknown }
61
64
  export interface GetProvisioningInstancesResponse { instances: unknown }
65
+ export interface GetProvisioningOnboardPlanResponse { mode: unknown; steps: unknown }
62
66
  export interface GetPublicBlockersIdResponse { blocker: unknown }
63
67
  export interface GetPublicBountyTableResponse { table: unknown; currency: unknown }
64
68
  export interface GetPublicGradesResponse { window_days: unknown; rolling: unknown; trend: unknown; threshold: unknown; grader_version: unknown }
@@ -177,6 +181,7 @@ export interface PostGoalsIdMembersResponse { ok: boolean; member: unknown }
177
181
  export interface PostGoalsIdReopenResponse { ok: boolean; goal: unknown }
178
182
  export interface PostGoalsIdRequestsReqIdRespondRequest { action: string }
179
183
  export interface PostGoalsIdRequestsReqIdRespondResponse { ok: boolean; action: unknown; request: unknown; member?: unknown }
184
+ export interface PostGoalsIdRequestsReqIdWithdrawResponse { ok: boolean; request: unknown }
180
185
  export interface PostGoalsIdRequestsRequest { note?: string }
181
186
  export interface PostGoalsIdRequestsResponse { ok: boolean; request: unknown }
182
187
  export interface PostGoalsIdScopeRequest { add: string[] }
@@ -205,6 +210,8 @@ export interface PostMemoryBuildersBuilderIdBfgWriteResponse { ok: boolean; buil
205
210
  export interface PostMemorySyncRequest { files?: unknown[] }
206
211
  export interface PostModulesKeyEnableRequest { enabled?: unknown }
207
212
  export interface PostModulesKeyEnableResponse { ok: boolean; key: unknown; enabled: unknown; note: unknown }
213
+ export interface PostModulesKeySubmitRequest { signed_by?: string }
214
+ export interface PostModulesKeySubmitResponse { ok: boolean; submission: unknown }
208
215
  export interface PostOverrideRequestsIdDecideRequest { decision: string; note?: string }
209
216
  export interface PostProvisioningInstancesIdForceTeardownResponse { ok: boolean; queued: unknown; action: unknown; status: unknown; message: unknown }
210
217
  export interface PostProvisioningInstancesIdGithubAppRequest { account?: string }
@@ -483,10 +490,14 @@ export interface BongosClient {
483
490
  patchGoalsIdMembersBuilderId(args: RequestArgs & { body: PatchGoalsIdMembersBuilderIdRequest }): Promise<PatchGoalsIdMembersBuilderIdResponse>;
484
491
  /** POST /goals/{id}/reopen — rank: metic+archon */
485
492
  postGoalsIdReopen(args?: RequestArgs): Promise<PostGoalsIdReopenResponse>;
493
+ /** GET /goals/{id}/requests — rank: any-builder */
494
+ getGoalsIdRequests(args?: RequestArgs): Promise<GetGoalsIdRequestsResponse>;
486
495
  /** POST /goals/{id}/requests — rank: any-builder */
487
496
  postGoalsIdRequests(args?: RequestArgs & { body?: PostGoalsIdRequestsRequest }): Promise<PostGoalsIdRequestsResponse>;
488
497
  /** POST /goals/{id}/requests/{reqId}/respond — rank: any-builder */
489
498
  postGoalsIdRequestsReqIdRespond(args: RequestArgs & { body: PostGoalsIdRequestsReqIdRespondRequest }): Promise<PostGoalsIdRequestsReqIdRespondResponse>;
499
+ /** POST /goals/{id}/requests/{reqId}/withdraw — rank: any-builder */
500
+ postGoalsIdRequestsReqIdWithdraw(args?: RequestArgs): Promise<PostGoalsIdRequestsReqIdWithdrawResponse>;
490
501
  /** POST /goals/{id}/scope — rank: metic+archon */
491
502
  postGoalsIdScope(args: RequestArgs & { body: PostGoalsIdScopeRequest }): Promise<PostGoalsIdScopeResponse>;
492
503
  /** POST /goals/{id}/tasks — rank: any-builder */
@@ -618,7 +629,9 @@ export interface BongosClient {
618
629
  /** POST /modules/{key}/enable — rank: metic+archon */
619
630
  postModulesKeyEnable(args?: RequestArgs & { body?: PostModulesKeyEnableRequest }): Promise<PostModulesKeyEnableResponse>;
620
631
  /** POST /modules/{key}/submit — rank: metic+archon */
621
- postModulesKeySubmit(args?: RequestArgs): Promise<ApiResponse>;
632
+ postModulesKeySubmit(args?: RequestArgs & { body?: PostModulesKeySubmitRequest }): Promise<PostModulesKeySubmitResponse>;
633
+ /** GET /modules/submissions — rank: metic+archon */
634
+ getModulesSubmissions(args?: RequestArgs): Promise<GetModulesSubmissionsResponse>;
622
635
  };
623
636
  "overrideRequests": {
624
637
  /** GET /override-requests — rank: archon */
@@ -633,6 +646,8 @@ export interface BongosClient {
633
646
  getProvisioningFleetCostLedger(args?: RequestArgs): Promise<ApiResponse>;
634
647
  /** GET /provisioning/github-app/callback — rank: public */
635
648
  getProvisioningGithubAppCallback(args?: RequestArgs): Promise<ApiResponse>;
649
+ /** GET /provisioning/github-app/status — rank: public */
650
+ getProvisioningGithubAppStatus(args?: RequestArgs): Promise<GetProvisioningGithubAppStatusResponse>;
636
651
  /** GET /provisioning/health — rank: public */
637
652
  getProvisioningHealth(args?: RequestArgs): Promise<GetProvisioningHealthResponse>;
638
653
  /** GET /provisioning/instances — rank: any-builder */
@@ -647,6 +662,8 @@ export interface BongosClient {
647
662
  postProvisioningInstancesIdGithubApp(args?: RequestArgs & { body?: PostProvisioningInstancesIdGithubAppRequest }): Promise<PostProvisioningInstancesIdGithubAppResponse>;
648
663
  /** POST /provisioning/instances/{id}/teardown — rank: any-builder */
649
664
  postProvisioningInstancesIdTeardown(args?: RequestArgs): Promise<PostProvisioningInstancesIdTeardownResponse>;
665
+ /** GET /provisioning/onboard-plan — rank: public */
666
+ getProvisioningOnboardPlan(args?: RequestArgs): Promise<GetProvisioningOnboardPlanResponse>;
650
667
  /** GET /provisioning/tls-check — rank: public */
651
668
  getProvisioningTlsCheck(args?: RequestArgs): Promise<ApiResponse>;
652
669
  };
@@ -1,4 +1,4 @@
1
- // @cloudbongos/client — GENERATED from the OpenAPI spec by
1
+ // @bongos/client — GENERATED from the OpenAPI spec by
2
2
  // scripts/gds/gen-api-client.js (task 1995 / ADR 0118). DO NOT EDIT BY HAND —
3
3
  // regenerate on spec change. Zero deps; uses the platform fetch.
4
4
  'use strict';
@@ -303,10 +303,14 @@ export function createClient(opts = {}) {
303
303
  patchGoalsIdMembersBuilderId: (args) => request("PATCH", "/goals/{id}/members/{builderId}", { hasBody: true }, args),
304
304
  // POST /goals/{id}/reopen — rank: metic+archon — POST /goals/:id/reopen
305
305
  postGoalsIdReopen: (args) => request("POST", "/goals/{id}/reopen", { hasBody: true }, args),
306
+ // GET /goals/{id}/requests — rank: any-builder — GET /goals/:id/requests
307
+ getGoalsIdRequests: (args) => request("GET", "/goals/{id}/requests", { hasBody: false }, args),
306
308
  // POST /goals/{id}/requests — rank: any-builder — POST /goals/:id/requests
307
309
  postGoalsIdRequests: (args) => request("POST", "/goals/{id}/requests", { hasBody: true }, args),
308
310
  // POST /goals/{id}/requests/{reqId}/respond — rank: any-builder — POST /goals/:id/requests/:reqId/respond
309
311
  postGoalsIdRequestsReqIdRespond: (args) => request("POST", "/goals/{id}/requests/{reqId}/respond", { hasBody: true }, args),
312
+ // POST /goals/{id}/requests/{reqId}/withdraw — rank: any-builder — POST /goals/:id/requests/:reqId/withdraw
313
+ postGoalsIdRequestsReqIdWithdraw: (args) => request("POST", "/goals/{id}/requests/{reqId}/withdraw", { hasBody: true }, args),
310
314
  // POST /goals/{id}/scope — rank: metic+archon — POST /goals/:id/scope
311
315
  postGoalsIdScope: (args) => request("POST", "/goals/{id}/scope", { hasBody: true }, args),
312
316
  // POST /goals/{id}/tasks — rank: any-builder — POST /goals/:id/tasks
@@ -439,6 +443,8 @@ export function createClient(opts = {}) {
439
443
  postModulesKeyEnable: (args) => request("POST", "/modules/{key}/enable", { hasBody: true }, args),
440
444
  // POST /modules/{key}/submit — rank: metic+archon — POST /modules/:key/submit
441
445
  postModulesKeySubmit: (args) => request("POST", "/modules/{key}/submit", { hasBody: true }, args),
446
+ // GET /modules/submissions — rank: metic+archon — GET /modules/submissions
447
+ getModulesSubmissions: (args) => request("GET", "/modules/submissions", { hasBody: false }, args),
442
448
  },
443
449
  "overrideRequests": {
444
450
  // GET /override-requests — rank: archon — GET /override-requests
@@ -453,6 +459,8 @@ export function createClient(opts = {}) {
453
459
  getProvisioningFleetCostLedger: (args) => request("GET", "/provisioning/fleet/cost-ledger", { hasBody: false }, args),
454
460
  // GET /provisioning/github-app/callback — rank: public — GET /provisioning/github-app/callback
455
461
  getProvisioningGithubAppCallback: (args) => request("GET", "/provisioning/github-app/callback", { hasBody: false }, args),
462
+ // GET /provisioning/github-app/status — rank: public — GET /provisioning/github-app/status
463
+ getProvisioningGithubAppStatus: (args) => request("GET", "/provisioning/github-app/status", { hasBody: false }, args),
456
464
  // GET /provisioning/health — rank: public — GET /provisioning/health
457
465
  getProvisioningHealth: (args) => request("GET", "/provisioning/health", { hasBody: false }, args),
458
466
  // GET /provisioning/instances — rank: any-builder — GET /provisioning/instances
@@ -467,6 +475,8 @@ export function createClient(opts = {}) {
467
475
  postProvisioningInstancesIdGithubApp: (args) => request("POST", "/provisioning/instances/{id}/github-app", { hasBody: true }, args),
468
476
  // POST /provisioning/instances/{id}/teardown — rank: any-builder — POST /provisioning/instances/:id/teardown
469
477
  postProvisioningInstancesIdTeardown: (args) => request("POST", "/provisioning/instances/{id}/teardown", { hasBody: true }, args),
478
+ // GET /provisioning/onboard-plan — rank: public — GET /provisioning/onboard-plan
479
+ getProvisioningOnboardPlan: (args) => request("GET", "/provisioning/onboard-plan", { hasBody: false }, args),
470
480
  // GET /provisioning/tls-check — rank: public — GET /provisioning/tls-check
471
481
  getProvisioningTlsCheck: (args) => request("GET", "/provisioning/tls-check", { hasBody: false }, args),
472
482
  },
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@cloudbongos/client",
2
+ "name": "@bongos/client",
3
3
  "version": "0.0.2",
4
4
  "description": "Generated typed client for the Bongos API (ADR 0118). Do not edit by hand.",
5
5
  "type": "module",
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Context
8
8
 
9
- Off the Boats V1 needs a persistent shared world for up to 100 concurrent players, browser-played, tile-based, with real-money purchases. The total budget for build + first year is $5,000. Monthly recurring cost must stay low and bootstrap-friendly.
9
+ Example V1 needs a persistent shared world for up to 100 concurrent players, browser-played, tile-based, with real-money purchases. The total budget for build + first year is $5,000. Monthly recurring cost must stay low and bootstrap-friendly.
10
10
 
11
11
  We needed an architecture that:
12
12
 
@@ -24,7 +24,7 @@ We will use **User OAuth (as `lars@example.com`)**.
24
24
 
25
25
  ## Alternatives considered
26
26
 
27
- - **Service account with Chat App identity.** Cleanest separation (the bot is its own persona, posts under "Off the Boats Build Bot"). Requires registering the Chat App via Google Cloud's Chat API Configuration page, a "deployment ID," and Workspace admin permission to allow the service account into the space. More setup steps; the bot identity feels less personal for a small team chat where everyone knows Lars.
27
+ - **Service account with Chat App identity.** Cleanest separation (the bot is its own persona, posts under "Example Build Bot"). Requires registering the Chat App via Google Cloud's Chat API Configuration page, a "deployment ID," and Workspace admin permission to allow the service account into the space. More setup steps; the bot identity feels less personal for a small team chat where everyone knows Lars.
28
28
  - **Incoming webhook only (outbound, no auth dance).** Dramatically simpler — paste a URL, POST to it, message appears. Good enough for outbound milestone posts but **cannot read messages, threads, or reactions**. Rejected because the inbound feedback loop is half the value.
29
29
 
30
30
  ## Consequences
@@ -6,17 +6,17 @@
6
6
 
7
7
  ## Context
8
8
 
9
- GDS-V3's incentive structure (criterion C9) adds a **red-team bounty**: a builder who finds and reports a security vulnerability against the system earns drachmae for it. The mechanism that *files* a report (`vulnerability_reports`, R63 / [#282](https://example.com/builders#/task/282)) and the mechanism that *auto-confirms and pays* one (R68) both need to agree on a single thing — **how many drachmae a report is worth, given its severity.**
9
+ GDS-V3's incentive structure (criterion C9) adds a **red-team bounty**: a builder who finds and reports a security vulnerability against the system earns example for it. The mechanism that *files* a report (`vulnerability_reports`, R63 / [#282](https://example.com/builders#/task/282)) and the mechanism that *auto-confirms and pays* one (R68) both need to agree on a single thing — **how many example a report is worth, given its severity.**
10
10
 
11
11
  Without one authoritative table, each consumer would invent its own constants and they would drift. We also need the numbers to be **tunable** by an Archon (the only rank that controls economy levers): if the bounty proves too generous or too stingy in practice, adjusting it should be an environment change, not a code edit and redeploy.
12
12
 
13
- Drachmae are the project's in-world currency, stored as integer `delta` in `credit_log` (migrations/003_pms.sql). A bounty payout is therefore a plain integer count of drachmae in the same unit as a task's `credits_reward`. The "10c / 50c" shorthand in the task spec maps to 10 / 50 drachmae; there is no sub-drachma denomination.
13
+ Example are the project's in-world currency, stored as integer `delta` in `credit_log` (migrations/003_pms.sql). A bounty payout is therefore a plain integer count of example in the same unit as a task's `credits_reward`. The "10c / 50c" shorthand in the task spec maps to 10 / 50 example; there is no sub-drachma denomination.
14
14
 
15
15
  ## Decision
16
16
 
17
17
  We will define the bounty payout table in `src/bongos/security.js` as four **default** integer amounts, each overridable by an environment variable:
18
18
 
19
- | Severity | Default drachmae | Env override |
19
+ | Severity | Default example | Env override |
20
20
  |---|---|---|
21
21
  | low | 10 | `GDS_BOUNTY_LOW` |
22
22
  | medium | 50 | `GDS_BOUNTY_MEDIUM` |
@@ -44,7 +44,7 @@ The Example repo is on GitHub. Marking a single file private is awkward (git his
44
44
 
45
45
  ### This is not security-through-obscurity
46
46
 
47
- The defense doesn't depend on the ADR's secrecy. Every protection mentioned in the full ADR is independently enforced in code (rank middleware, audit log, input validation, etc.). Withholding the document raises the cost of an attacker's reconnaissance — it doesn't *create* the defense. The bounty table ([ADR 0019](<redacted>.md)) names the gain for the attacker who reverse-engineers it anyway: a high-severity finding pays out 1000 drachmae. The system *wants* serious red-teamers; what it doesn't want is to hand them the map for free.
47
+ The defense doesn't depend on the ADR's secrecy. Every protection mentioned in the full ADR is independently enforced in code (rank middleware, audit log, input validation, etc.). Withholding the document raises the cost of an attacker's reconnaissance — it doesn't *create* the defense. The bounty table ([ADR 0019](<redacted>.md)) names the gain for the attacker who reverse-engineers it anyway: a high-severity finding pays out 1000 example. The system *wants* serious red-teamers; what it doesn't want is to hand them the map for free.
48
48
 
49
49
  ## Alternatives considered
50
50
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Problem
8
8
 
9
- Every task in the GDS carries a `credits_reward` value (the in-world "drachmae" payout when the task ships). Before this ADR, that value was paid 1:1 regardless of task kind. A 40-credit `cleanup` ship and a 40-credit `bug` ship both landed exactly 40c. That's a problem for two reasons:
9
+ Every task in the GDS carries a `credits_reward` value (the in-world "example" payout when the task ships). Before this ADR, that value was paid 1:1 regardless of task kind. A 40-credit `cleanup` ship and a 40-credit `bug` ship both landed exactly 40c. That's a problem for two reasons:
10
10
 
11
11
  1. **It silently disincentivises the work we want more of.** Capturing a learning that prevents a future bug, resolving a blocker that was costing the builder days, or landing a decision/ADR are all *higher leverage* per builder-hour than the average feature. Paying them the same says "we don't care which you do." In practice we care a lot.
12
12
  2. **The idea_inbox economy was unfunded.** Anyone could capture an idea, get it triaged into a task, and the task's eventual shipper got 100% of the reward. The capturer earned 0 — even though the idea was the unblocker. Capturing felt like volunteer work.
@@ -57,7 +57,7 @@ A new table `builder_memory(builder_id, path, content TEXT, mtime, sha256, byte_
57
57
 
58
58
  Two trigger points, both transactional boundaries that already exist in the methodology:
59
59
 
60
- - **Push on `/builder-ship`.** After the ship completes successfully (drachmae landed, branch merged or queued), `scripts/gds/ship.js` walks `~/.claude/projects/<project>/memory/*` and calls `POST /api/gds/memory/sync` with each file. If the push fails, ship still succeeds — work is preserved in the GDS row, memory can be resynced next time. Progress visible to the builder ("syncing 3 memory files…"). This is what [#274](https://example.com/builders#/task/274) R55 implements.
60
+ - **Push on `/builder-ship`.** After the ship completes successfully (example landed, branch merged or queued), `scripts/gds/ship.js` walks `~/.claude/projects/<project>/memory/*` and calls `POST /api/gds/memory/sync` with each file. If the push fails, ship still succeeds — work is preserved in the GDS row, memory can be resynced next time. Progress visible to the builder ("syncing 3 memory files…"). This is what [#274](https://example.com/builders#/task/274) R55 implements.
61
61
  - **Pull on `SessionStart` hook + `/builder-start`.** A new hook (or extension of the existing `.claude/hooks/sync-env-local.sh` pattern) calls `GET /api/gds/memory/since?mtime=<local-newest>` and writes any files the server has that are newer than the local copy. This is what [#275](https://example.com/builders#/task/275) R56 implements.
62
62
 
63
63
  No background polling. No Claude-Code-side daemon. No mid-session sync. The two trigger points are predictable, debuggable, and align with the natural commit/restart boundaries builders already think in.
@@ -30,21 +30,21 @@ This ADR records the architecture and, critically, the **boundaries** that turn
30
30
 
31
31
  The BFG gains three capability clusters (6A / 6B / 6C), built as independently-shippable sub-phases. Two cross-cutting rules govern all of them:
32
32
 
33
- - **The BFG is a privileged *system* agent, not a rank bypass.** Its cross-builder powers are the existing Archon-forensic-read posture, extended to a narrow audited write. They are bound to a dedicated **BFG service principal** (a `builders` row flagged as system: cannot claim work, cannot earn drachmae) and are reachable *only* by that principal — never exposed on a self-serve route. No human or agent builder can ask the system to "read/write another builder's memory." **This is an enforcement requirement, not prose intent:** 6C.1's write endpoint must gate on the *exact principal identity*, not on rank — an Archon token (or any rank-escalated / stolen token) must be rejected at the write endpoint, and that refusal must be covered by a test. "Never exposed on a self-serve route" is a property the implementation has to encode, not a promise the ADR can keep on its own.
33
+ - **The BFG is a privileged *system* agent, not a rank bypass.** Its cross-builder powers are the existing Archon-forensic-read posture, extended to a narrow audited write. They are bound to a dedicated **BFG service principal** (a `builders` row flagged as system: cannot claim work, cannot earn example) and are reachable *only* by that principal — never exposed on a self-serve route. No human or agent builder can ask the system to "read/write another builder's memory." **This is an enforcement requirement, not prose intent:** 6C.1's write endpoint must gate on the *exact principal identity*, not on rank — an Archon token (or any rank-escalated / stolen token) must be rejected at the write endpoint, and that refusal must be covered by a test. "Never exposed on a self-serve route" is a property the implementation has to encode, not a promise the ADR can keep on its own.
34
34
  - **Every cross-builder operation — read *and* write — writes an `audit_log` row.** Writes are additionally **namespaced and attributed** so a builder can always see, and delete, exactly what the BFG put there. Nothing the BFG writes ever masquerades as the builder's own note.
35
35
 
36
36
  ### 6A — Hygiene (the original charter, widened)
37
37
 
38
38
  Read-only auditor. Findings land as `idea_inbox` rows (one per finding, like `overnight-code-review`) plus a `docs/audits/bfg-<date>.md` report. The BFG **never** auto-mutates code or DB state — it reports.
39
39
 
40
- - **Doc ↔ reality:** CLAUDE.md claims vs DB (`shipped` task IDs cited, version statuses, the rank enum, drachmae/karma model), `[[link]]` resolution, ADR cross-reference integrity + numbering gaps, `docs/file-map.md` vs the actual tree, onboarding-diagram `assertions.json` vs live facts.
40
+ - **Doc ↔ reality:** CLAUDE.md claims vs DB (`shipped` task IDs cited, version statuses, the rank enum, example/karma model), `[[link]]` resolution, ADR cross-reference integrity + numbering gaps, `docs/file-map.md` vs the actual tree, onboarding-diagram `assertions.json` vs live facts.
41
41
  - **Memory hygiene:** within each builder's *own* memory dir — dangling `[[links]]`, stale frontmatter, internal contradictions, duplicate facts (the same discipline the `consolidate-memory` skill applies, but agent-driven rather than human-invoked).
42
42
  - **DB cleanliness:** cached-counter vs ledger drift (`builders.karma` vs `karma_log`, `total_credits` vs `credit_log`), orphaned rows, long-stale `idea_inbox` / `blockers`. Reported, never silently "fixed."
43
43
 
44
44
  ### 6B — Cross-builder learning ("read the room")
45
45
 
46
46
  - **Read all builders' memory** through a BFG-principal-only, per-read audit-logged endpoint (same shape as the Archon forensic read).
47
- - **Score interaction quality** by blending objective GDS signals (ships, grader pass rate, rework/abandon rate, karma, drachmae, methodology adherence visible in `audit_log` + conductor traces) with memory-quality heuristics.
47
+ - **Score interaction quality** by blending objective GDS signals (ships, grader pass rate, rework/abandon rate, karma, example, methodology adherence visible in `audit_log` + conductor traces) with memory-quality heuristics.
48
48
  - **Extract *transferable* patterns** from top performers — working habits and durable lessons, **not** builder-specific secrets, PII, or anything that only makes sense in that builder's context.
49
49
  - **Propagate** as adoption suggestions to other builders (delivered via the 6C write path as clearly-marked BFG entries, or surfaced in the audit report).
50
50
 
@@ -76,7 +76,7 @@ The BFG runs as a `SKILL.md` scheduled routine (post-ship / pre-cron cadence) an
76
76
  | **6A.2** | Extend the auditor with memory-hygiene + DB cached-vs-ledger drift checks (still report-only). | Hygiene covers all three artifact classes. |
77
77
  | **6B.1** | BFG-principal-only, audit-logged cross-builder memory **read** endpoint + interaction-quality scorer. | "Read the room" exists; reuses the forensic-read audit pattern. |
78
78
  | **6B.2** | Transferable-pattern extraction from top performers + adoption-suggestion generation. | Good practice propagates; the "most creative experience" objective gets teeth. |
79
- | **6C.1** | Migration: BFG service principal (system builder, no-claim/no-drachmae) + cross-builder memory **write** endpoint (audited, namespaced, attributed) + `karma_log` reason `bfg_correction`. | The write substrate + trust-boundary exception land in one reviewable unit. |
79
+ | **6C.1** | Migration: BFG service principal (system builder, no-claim/no-example) + cross-builder memory **write** endpoint (audited, namespaced, attributed) + `karma_log` reason `bfg_correction`. | The write substrate + trust-boundary exception land in one reviewable unit. |
80
80
  | **6C.2** | Wire dream-writes + transparent corrections into the BFG routine; kill-switch; builder-visible attribution; delete affordance. | Dreams + correction work end-to-end, safely. |
81
81
  | **6C.3** | Update [ADR 0024-mas](<redacted>.md) Phase-6 row + CLAUDE.md MAS index line. (Deferred out of [#441](https://example.com/builders#/task/441) — `CLAUDE.md` / `0024` are held by the active Phase-4 claim `#439`.) | The index reflects the shipped BFG. |
82
82
 
@@ -5,7 +5,7 @@
5
5
  - **Deciders:** Lars Kristensen (Archon), Claude
6
6
  - **Track:** `internal` (GDS)
7
7
  - **Context tasks:** GDS-V4 **[#515](https://example.com/builders#/task/515)** (the capability umbrella) · **[#539](https://example.com/builders#/task/539)** (this design task — ADR + task breakdown only, no implementation; mirrors the design-only shape of [#441](<redacted>.md)).
8
- - **Extends:** [ADR 0024 — Multi-Agent System architecture](<redacted>.md) (the BFG is its Phase 6) · [ADR 0026 — The BFG charter](<redacted>.md) (this adds a **new capability cluster, 6D**, to the BFG's "best building experience" objective) · [ADR 0016 — Trust boundary](<redacted>.md) (narrowly extended — session detail now lives server-side and is BFG-readable across builders) · [ADR 0022 — Secrets policy](0022-secrets-policy.md) (scrubbing on upload). Touches `credit_log` (drachmae), `karma_log`, `builders` (rank + tenure), `task_grades` (the upsert-unique gap), `session_logs`.
8
+ - **Extends:** [ADR 0024 — Multi-Agent System architecture](<redacted>.md) (the BFG is its Phase 6) · [ADR 0026 — The BFG charter](<redacted>.md) (this adds a **new capability cluster, 6D**, to the BFG's "best building experience" objective) · [ADR 0016 — Trust boundary](<redacted>.md) (narrowly extended — session detail now lives server-side and is BFG-readable across builders) · [ADR 0022 — Secrets policy](0022-secrets-policy.md) (scrubbing on upload). Touches `credit_log` (example), `karma_log`, `builders` (rank + tenure), `task_grades` (the upsert-unique gap), `session_logs`.
9
9
 
10
10
  ## Context
11
11
 
@@ -39,7 +39,7 @@ When `/builder-ship` lands a task, `ship.js` locates the active Claude Code sess
39
39
  | `session_id` | the Claude Code `sessionId` |
40
40
  | `builder_id` | the shipping builder |
41
41
  | `task_ids[]` | task(s) shipped from this session |
42
- | `drachmae_earned` | the session's `credit_log` delta |
42
+ | `example_earned` | the session's `credit_log` delta |
43
43
  | `total_tokens` | summed transcript `usage` (input + output + cache) |
44
44
  | `duration_seconds` | transcript first→last timestamp (or `session_logs`) |
45
45
  | `started_at` / `ended_at` / `uploaded_at` | timestamps |
@@ -52,7 +52,7 @@ When `/builder-ship` lands a task, `ship.js` locates the active Claude Code sess
52
52
 
53
53
  The server stores and serves; it does **no analysis**. Two endpoints over `session_records`:
54
54
 
55
- - **Search/filter** by *session* fields (`drachmae_earned`, `total_tokens`, `duration`, the derived metrics) **and joined `builders` fields** — **tenure** (`now − created_at`), **rank**, **karma**, **drachmae** (`total_credits`). So queries like *"rank = Xenos AND tenure < 7d AND overhead > 0.7"* (onboarding friction) or *"karma top-decile"* (good-practice mining) are expressible against one corpus.
55
+ - **Search/filter** by *session* fields (`example_earned`, `total_tokens`, `duration`, the derived metrics) **and joined `builders` fields** — **tenure** (`now − created_at`), **rank**, **karma**, **example** (`total_credits`). So queries like *"rank = Xenos AND tenure < 7d AND overhead > 0.7"* (onboarding friction) or *"karma top-decile"* (good-practice mining) are expressible against one corpus.
56
56
  - **Fetch one session's** full scrubbed detail for deep-dive.
57
57
 
58
58
  Cross-builder reads are gated to the **BFG service principal** ([ADR 0026](<redacted>.md) §6B posture — the *exact principal identity*, not rank) and write an **`audit_log` row per read**. A builder may always read their *own* sessions self-serve. Filtering is plain SQL/keyword **for now** (semantic/vector deferred, consistent with [ADR 0024](<redacted>.md)/[0026](<redacted>.md)).
@@ -7,7 +7,7 @@
7
7
 
8
8
  ## Context
9
9
 
10
- The builders hall (`public-builders/`) fetched **every panel exactly once** at `DOMContentLoaded` via `loadAll()` and then never refreshed. Onboarding checklist, standing (drachmae/karma), claimable works, leaderboard, karma feed, bounty table — all frozen until the visitor manually reloaded. The only things that updated without a reload were the two buttons a builder clicks themselves (mark primer read, pick a craft).
10
+ The builders hall (`public-builders/`) fetched **every panel exactly once** at `DOMContentLoaded` via `loadAll()` and then never refreshed. Onboarding checklist, standing (example/karma), claimable works, leaderboard, karma feed, bounty table — all frozen until the visitor manually reloaded. The only things that updated without a reload were the two buttons a builder clicks themselves (mark primer read, pick a craft).
11
11
 
12
12
  The reported symptom: a builder runs `/builder-ship` in the terminal, the "Ship thy first work" onboarding step clears server-side, but the open hall tab keeps showing the stale checklist. The underlying gap is broader than onboarding — the page had **no live-update mechanism at all**.
13
13
 
@@ -87,10 +87,10 @@ Two rules dissolve the "front every box (linear cost) vs. gate by payment (barri
87
87
  | Stage | How they work | Org cost | Builder cost |
88
88
  |---|---|---|---|
89
89
  | **Newcomer** (Xenos / onboarding) | Org provisions an **auto-suspended starter box** so there is zero payment barrier to begin | A bounded ~$5/active-newcomer (suspends when idle; de-provisioned if dormant) | Just their Claude subscription |
90
- | **Proven** (graduated → Metic) | Keeps a box | Transitions toward $0 | **Self-funds** (own DO account, or org provisions + rebills via the `costs` table, deducted from drachmae/earnings) |
90
+ | **Proven** (graduated → Metic) | Keeps a box | Transitions toward $0 | **Self-funds** (own DO account, or org provisions + rebills via the `costs` table, deducted from example/earnings) |
91
91
  | **Established** | Own box, runs it how they like | **$0** | Self-funds (1099 own-tools) |
92
92
 
93
- The barrier to *start* is zero (org pays the first box, per the decision to **not** use Anthropic's Cloud VM for onboarding). Real cost attaches only to builders who are earning. **Scale math:** naïve 100 builders × $30 always-on ≈ $36k/yr (untenable); this model ≈ $0 ongoing + a small bounded starter-box pool. None of it needs new machinery — it rides the rank ladder, the onboarding funnel, the drachmae/credits system, and the cost-logging we already have.
93
+ The barrier to *start* is zero (org pays the first box, per the decision to **not** use Anthropic's Cloud VM for onboarding). Real cost attaches only to builders who are earning. **Scale math:** naïve 100 builders × $30 always-on ≈ $36k/yr (untenable); this model ≈ $0 ongoing + a small bounded starter-box pool. None of it needs new machinery — it rides the rank ladder, the onboarding funnel, the example/credits system, and the cost-logging we already have.
94
94
 
95
95
  ### 6. Security — the container is the rank-gated source-access boundary
96
96
 
@@ -141,7 +141,7 @@ The repo is **private** (today under a personal account — see §7; a move to a
141
141
 
142
142
  ## Open questions (flagged, not blocking)
143
143
 
144
- 1. **Per-builder box ownership transition.** Mechanics of moving a builder from the org-funded starter box to self-funding — recreate on their own DO account vs. org-provisions-and-rebills via the `costs` table. Lean: rebill-via-drachmae for simplicity; revisit.
144
+ 1. **Per-builder box ownership transition.** Mechanics of moving a builder from the org-funded starter box to self-funding — recreate on their own DO account vs. org-provisions-and-rebills via the `costs` table. Lean: rebill-via-example for simplicity; revisit.
145
145
  2. **Onboarding repo-access scoping.** ✅ **RESOLVED 2026-06-05 ([#600](https://example.com/builders#/task/600)) — rank-gated, server-issued, fetched-not-baked.** A Xenos box sparse-checks out only the safe surface; full creds arrive at graduation; the box fetches a scoped credential gated on live rank rather than holding a baked one. See the resolution note below.
146
146
  3. **Auto-suspend implementation.** ✅ **RESOLVED 2026-06-04 ([#598](https://example.com/builders#/task/598)) — snapshot-and-park, NOT Coder.** See the resolution note below.
147
147
  4. **Thin-device on-ramp friction.** ✅ **RESOLVED 2026-06-06 ([#701](https://example.com/builders#/task/701)) — box reports its pairing link UP to the GDS; the builder reads it from the web.** See §9.4 below.
@@ -219,4 +219,4 @@ Not yet created; listed so the build session has a starting decomposition.
219
219
  | Managed-settings + Remote Control service | Distribute the locked `sshConfigs`/`sshHostAllowlist`; always-on `claude rc` for thin devices | C1 |
220
220
  | Rank-gated source access | Box holds the scoped GitHub credential; access granted/revoked by rank; offboarding clawback | C2 / C7 / C9 |
221
221
  | Onboarding primer page ✅ | **Done** — the §"mental model" explainer lives in [`docs/onboarding/primer.md`](../onboarding/primer.md) § "Where your work runs" (extracted in the ADR 0035 rewrite, [#718](https://example.com/builders#/task/718); closed by task 601) | C1 |
222
- | Cost passthrough wiring | Org-funded starter → self-fund transition via `costs`/drachmae | cost |
222
+ | Cost passthrough wiring | Org-funded starter → self-fund transition via `costs`/example | cost |
@@ -1,7 +1,7 @@
1
1
  # ADR 0032 — Discord as a one-way mirror of the GDS (outbound broadcast moves off Google Chat)
2
2
 
3
3
  **Date:** 2026-06-04
4
- **Context:** GDS-V3, task [#607](https://example.com/builders#/task/607) (claim `#482`). Stands up a Discord server for Off the Boats / Example — one server, permission-walled into a player wing and a builder wing — and moves the ship-broadcast off Google Chat. Companion to [ADR 0016](<redacted>.md) (the trust boundary — the load-bearing constraint here), [ADR 0018](<redacted>.md) (Xenos → Metic → Archon, the ranks Discord roles mirror), [ADR 0022](0022-secrets-policy.md) (webhook URLs are secrets, kept out of the repo), and [ADR 0008](0008-google-chat-oauth-user-auth.md) (the Google Chat broadcast this supersedes for outbound).
4
+ **Context:** GDS-V3, task [#607](https://example.com/builders#/task/607) (claim `#482`). Stands up a Discord server for Example / Example — one server, permission-walled into a player wing and a builder wing — and moves the ship-broadcast off Google Chat. Companion to [ADR 0016](<redacted>.md) (the trust boundary — the load-bearing constraint here), [ADR 0018](<redacted>.md) (Xenos → Metic → Archon, the ranks Discord roles mirror), [ADR 0022](0022-secrets-policy.md) (webhook URLs are secrets, kept out of the repo), and [ADR 0008](0008-google-chat-oauth-user-auth.md) (the Google Chat broadcast this supersedes for outbound).
5
5
  **Status:** Accepted. Phase 2 (outbound ship broadcast → Discord) implemented in [#607](https://example.com/builders#/task/607). Phases 3+ (interaction bot, inbound retirement, role sync) scoped below, not yet built.
6
6
  **Track:** `internal` (dev-system / team communication).
7
7
 
@@ -12,7 +12,7 @@ The project is opening to multiple builders (GDS-V3) and will eventually have pl
12
12
  Two existing surfaces are relevant:
13
13
 
14
14
  - The **ship broadcast** posts a plain-language "what shipped" summary to the Example team **Google Chat** space ([ADR 0008](0008-google-chat-oauth-user-auth.md); fired from `scripts/gds/ship.js` on deploy). Google Chat is a closed business space — fine for the Example owners, wrong as a builder+player community hub.
15
- - The **GDS** already holds all authoritative state: ranks, tasks, karma (`peer_upvote` is an existing reason), idea_inbox, drachmae, the builders' hall.
15
+ - The **GDS** already holds all authoritative state: ranks, tasks, karma (`peer_upvote` is an existing reason), idea_inbox, example, the builders' hall.
16
16
 
17
17
  The temptation, standing up Discord, is to let it *own* things — roles that grant power, votes that live in Discord, a second scoreboard. That would fracture the source of truth and — for roles — quietly punch a hole in the trust boundary.
18
18
 
@@ -50,4 +50,4 @@ The promotion reuses the existing rank-change machinery (refactored into a share
50
50
 
51
51
  - **Just raise the newcomer-queue target / fix supply only.** Treats the symptom. A shared pool of N newcomer tasks is always racing consumption; time-boxing the sandbox removes the dependency entirely for everyone past their 3rd ship.
52
52
  - **Auto-promote `xenos` straight to `metic`.** Rejected: Metic carries triage/trust/red-team/infra powers no automatic rule should hand out. The new intermediate rank is exactly the "breadth without trust" tier that makes auto-promotion safe.
53
- - **Promote by drachmae or karma instead of ship count.** Rejected for v1: ship count is the most legible "you've proven you can land work" signal and is already the credit-landing event. A richer policy can layer on later.
53
+ - **Promote by example or karma instead of ship count.** Rejected for v1: ship count is the most legible "you've proven you can land work" signal and is already the credit-landing event. A richer policy can layer on later.
@@ -38,7 +38,7 @@ Rationale (Lars's call, 2026-06-10):
38
38
  prompt must reason about *which* palette applies to *which* tile. That branching is exactly
39
39
  the kind of pipeline complexity the bootstrapped budget and the single-maintainer reality
40
40
  can't carry. One palette = one set of rules everywhere.
41
- - **The world has one look.** Off the Boats is a single, persistent, coherent world. There is
41
+ - **The world has one look.** Example is a single, persistent, coherent world. There is
42
42
  no "Poke Mart interior" context that needs the temperate palette — the FireRed colors were
43
43
  only ever scaffolding for the *structure*, never the intended final hues.
44
44
  - **The bias rule becomes the palette.** Today the style guide *nudges* generations toward
@@ -7,7 +7,7 @@
7
7
 
8
8
  ## Problem
9
9
 
10
- A builder working on the **game** (`public/`, `src/world/`, `src/rooms/`, the art tiles) has no way to *see their change running* before it ships. The only live instance of Off the Boats is production at `example.com`. So the loop today is: edit → ship through the grader/merge/deploy pipeline → look at prod. That is slow, it puts unreviewed game changes one mistake away from players, and a browser-only (Chromebook) builder has no local machine to run the game on at all.
10
+ A builder working on the **game** (`public/`, `src/world/`, `src/rooms/`, the art tiles) has no way to *see their change running* before it ships. The only live instance of Example is production at `example.com`. So the loop today is: edit → ship through the grader/merge/deploy pipeline → look at prod. That is slow, it puts unreviewed game changes one mistake away from players, and a browser-only (Chromebook) builder has no local machine to run the game on at all.
11
11
 
12
12
  What a builder wants is a **sandbox**: run the game live *on their own dev box* and open it in a browser to review the change — never touching the prod server.
13
13
 
@@ -1,4 +1,4 @@
1
- # ADR 0054 — Flat cost-plus session token reward (drachmae as equity)
1
+ # ADR 0054 — Flat cost-plus session token reward (example as equity)
2
2
 
3
3
  **Date:** 2026-06-13
4
4
  **Context:** GDS-V4, task [#1005](https://example.com/builders#/task/1005). Builds on [ADR 0023](<redacted>.md) (per-task kind-multiplied credits), [ADR 0028](<redacted>.md) (the `llm-pricing.js` token→USD table + session-cost capture), and [ADR 0027](<redacted>.md) (the `session_records` upload-on-ship path this reward rides). Complements — does **not** replace — the per-task `credits_reward × kind_multiplier` path. Related future work: the full-transcript capture ADR (planned, task [#1004](https://example.com/builders#/task/1004)) will give this reward a more trustworthy raw-usage source, and the token-feed hardening scoped in task [#1005](https://example.com/builders#/task/1005) itself.
@@ -7,13 +7,13 @@
7
7
 
8
8
  ## Problem
9
9
 
10
- We are about to onboard the first **incentivized** builders. Today the only payout is per-task `credits_reward` — a unitless number an author sets at task-creation time. It rewards declaring a big number, not doing expensive, real work. The owner's decision (2026-06-13) is to pay builders proportionally to the **true economic cost** of the work they did — the API token spend of the session — plus a margin, with drachmae standing in as **equity** in the project. It must go live today, be idempotent and reversible, and be impossible to inflate with a client-sent dollar figure.
10
+ We are about to onboard the first **incentivized** builders. Today the only payout is per-task `credits_reward` — a unitless number an author sets at task-creation time. It rewards declaring a big number, not doing expensive, real work. The owner's decision (2026-06-13) is to pay builders proportionally to the **true economic cost** of the work they did — the API token spend of the session — plus a margin, with example standing in as **equity** in the project. It must go live today, be idempotent and reversible, and be impossible to inflate with a client-sent dollar figure.
11
11
 
12
12
  ## Decision
13
13
 
14
14
  Per **shipped session** (the unit; per-task attribution is a later refinement — see the future-review trigger), grant a flat cost-plus reward:
15
15
 
16
- drachmae = round(true_cost_usd × (1 + REWARD_MARGIN_PCT/100) × 100) // integer cents
16
+ example = round(true_cost_usd × (1 + REWARD_MARGIN_PCT/100) × 100) // integer cents
17
17
  REWARD_MARGIN_PCT = 20
18
18
 
19
19
  - **`true_cost_usd` is computed SERVER-SIDE** from the per-model token counts the ship upload already carries (`session_records.model_usage`), priced via `src/bongos/llm-pricing.js` (the locked API list-price table). The client uploads token *counts*, never a dollar figure — that figure is never trusted from the client.
@@ -21,7 +21,7 @@ Per **shipped session** (the unit; per-task attribution is a later refinement
21
21
  - **Margin is a code constant** (`REWARD_MARGIN_PCT` in `src/bongos/db.js`), owner-changed via a commit, not a settings UI — the same review-trail rationale as `KIND_MULTIPLIERS` ([ADR 0023](<redacted>.md)). A future migration can promote it to a per-builder/per-version table if the economics ever need live tuning. No rank above Archon is introduced; the knob is an owner-scoped policy constant.
22
22
  - **Idempotent per `session_id`**: a new `credit_log.reason = 'session.token_reward'` row carries a `session_id` column backed by a partial-unique index, plus a SELECT fast-path guard inside the upsert transaction. Re-uploading the same session (re-ship, retry) is a true no-op — no double payout.
23
23
  - The existing per-task credit path is untouched. Both the token reward and per-task credits accrue to `builders.total_credits` via the existing `pms_apply_credit` trigger.
24
- - **Drachmae = equity units** (owner framing). No special code — it is the interpretation of `total_credits`.
24
+ - **Example = equity units** (owner framing). No special code — it is the interpretation of `total_credits`.
25
25
 
26
26
  ### Two drachma conventions, one ledger (the load-bearing tension)
27
27
 
@@ -32,12 +32,12 @@ We knowingly accept that a drachma now means two things on the same ledger: a *u
32
32
  A flat cost-plus reward pays **more** for a more expensive session — it can reward token *waste* (thrashing, re-reading, long unproductive loops) as much as productive spend. This was raised and explicitly accepted by the owner, for three reasons:
33
33
 
34
34
  1. **PASS-gated by construction.** Only a *successful ship* uploads a session record, so a session that burned tokens and shipped nothing earns nothing.
35
- 2. **Drachmae are equity, not cash.** A builder who pads cost dilutes a pool they themselves hold; the incentive to waste is bounded by the fact that the payout currency is ownership in the thing being built. Early builders want their percentage to be worth something, so they self-police. Inflating the denominator hurts the inflator.
35
+ 2. **Example are equity, not cash.** A builder who pads cost dilutes a pool they themselves hold; the incentive to waste is bounded by the fact that the payout currency is ownership in the thing being built. Early builders want their percentage to be worth something, so they self-police. Inflating the denominator hurts the inflator.
36
36
  3. **The waste signal already exists.** The BFG session-inefficiency evaluator ([ADR 0027](<redacted>.md)) flags wasteful sessions from the same uploaded digest; a later refinement can gate or discount the reward by a quality/efficiency factor, moving from flat cost-plus to cost-plus-adjusted-for-value. The owner's stated direction is to move toward **market dynamics** (bidding) once the builder pool is genuinely multi-party.
37
37
 
38
38
  ## Consequences
39
39
 
40
- - **Migration 090** adds `session_records.model_usage` + `session_records.token_reward_drachmae`, `credit_log.session_id` + the partial-unique index `uniq_credit_session_token_reward`, and bumps the migration counter.
40
+ - **Migration 090** adds `session_records.model_usage` + `session_records.token_reward_example`, `credit_log.session_id` + the partial-unique index `uniq_credit_session_token_reward`, and bumps the migration counter.
41
41
  - `llm-pricing.js` gains pure, tested `priceModelUsage` + `canonicalizeModelId`.
42
42
  - `db.js` gains `REWARD_MARGIN_PCT`, `computeSessionTokenReward`, `awardSessionTokenReward`, and the transactional `upsertSessionRecordWithReward` (the route now calls it instead of the bare upsert).
43
43
  - `scripts/gds/ship.js` accumulates per-model usage into the digest; `POST /api/gds/sessions` accepts `model_usage`, prices it, and returns `token_reward` on the 201.
@@ -50,14 +50,14 @@ Revisit when: (a) per-task token attribution lands (the unit becomes the task, n
50
50
 
51
51
  ## Amendment — 2026-06-15 (task [#1138](https://example.com/builders#/task/1138)): 1 drachma = $1
52
52
 
53
- **Trigger (c), partial.** An audit of the first incentivized builder's ledger (owner request) found the cents convention had inflated the balance ~100× (one builder, 31 sessions → 295,218 drachmae ≈ $2,952 of cost-plus) and that summing cents-denominated token rewards with the unitless per-task credits made the total incoherent. The owner's decision: **re-denominate the token reward so 1 drachma = $1**, not 1 cent.
53
+ **Trigger (c), partial.** An audit of the first incentivized builder's ledger (owner request) found the cents convention had inflated the balance ~100× (one builder, 31 sessions → 295,218 example ≈ $2,952 of cost-plus) and that summing cents-denominated token rewards with the unitless per-task credits made the total incoherent. The owner's decision: **re-denominate the token reward so 1 drachma = $1**, not 1 cent.
54
54
 
55
55
  **Change to the Decision formula** (supersedes the `× 100` in the formula above):
56
56
 
57
- drachmae = round(true_cost_usd × (1 + REWARD_MARGIN_PCT/100)) // whole drachmae, 1 drachma = $1
57
+ example = round(true_cost_usd × (1 + REWARD_MARGIN_PCT/100)) // whole example, 1 drachma = $1
58
58
  REWARD_MARGIN_PCT = 20 // unchanged
59
59
 
60
- - The trailing `× 100` (cents) is **dropped**. A $100 true-cost session now mints `round(100 × 1.20) = 120` drachmae (was 12,000). A sub-$0.42 session now rounds to 0 (was ~50) — intended.
60
+ - The trailing `× 100` (cents) is **dropped**. A $100 true-cost session now mints `round(100 × 1.20) = 120` example (was 12,000). A sub-$0.42 session now rounds to 0 (was ~50) — intended.
61
61
  - `computeSessionTokenReward` in `src/bongos/db.js` changed accordingly; `tests/credit_grant.mjs` updated; `llm-pricing.js` (the token→USD table) is **unchanged** — only the cents→dollars scale factor moved.
62
- - **History was re-denominated, not left mixed.** Per the "append-only, reversible" rule above, existing `session.token_reward` rows were **not mutated**; a single compensating `credit_log` row (`reason='redenominate.token_reward_dollars'`, `task_id` → [#1138](https://example.com/builders#/task/1138)) restates the running total from cents to dollars, and the `total_credits` trigger nets it automatically. The original cents rows remain as historical record; the `session_records.token_reward_drachmae` display mirror was divided by 100 to match. At amendment time builder `#1` (example-owner) was the only holder of token rewards, so this touched one builder.
62
+ - **History was re-denominated, not left mixed.** Per the "append-only, reversible" rule above, existing `session.token_reward` rows were **not mutated**; a single compensating `credit_log` row (`reason='redenominate.token_reward_dollars'`, `task_id` → [#1138](https://example.com/builders#/task/1138)) restates the running total from cents to dollars, and the `total_credits` trigger nets it automatically. The original cents rows remain as historical record; the `session_records.token_reward_example` display mirror was divided by 100 to match. At amendment time builder `#1` (example-owner) was the only holder of token rewards, so this touched one builder.
63
63
  - **The per-task `credits_reward` path (ADR 0023) is untouched** — it stays a unitless author estimate. The two-conventions tension (§"Two drachma conventions, one ledger") is now *narrower* (both paths read on a ~dollar scale) but not formally reconciled; trigger (c) remains open for a full reconciliation.
@@ -3,11 +3,11 @@
3
3
  **Date:** 2026-06-15
4
4
  **Status:** Accepted
5
5
  **Track:** `internal` (dev-system / cost oversight).
6
- **Context:** GDS-V3, task [#602](https://example.com/builders#/task/602), criterion C-cost. Implements the ledger half of ADR 0031 §5 (cost passthrough). Companion to [ADR 0031](<redacted>.md) (the dev box) and the early-stage billing policy ("tracked, not settled" — both drachmae earnings and container costs are recorded but not actually paid/charged yet).
6
+ **Context:** GDS-V3, task [#602](https://example.com/builders#/task/602), criterion C-cost. Implements the ledger half of ADR 0031 §5 (cost passthrough). Companion to [ADR 0031](<redacted>.md) (the dev box) and the early-stage billing policy ("tracked, not settled" — both example earnings and container costs are recorded but not actually paid/charged yet).
7
7
 
8
8
  ## Problem
9
9
 
10
- Builders run org-provisioned DigitalOcean dev boxes (ADR 0031). We want every box cost event recorded per builder — visible to the builder on their own profile and to the Archon for oversight — so the org can see what each box costs *before* any real self-fund/charge mechanism exists. No payment integration, no drachmae deduction yet.
10
+ Builders run org-provisioned DigitalOcean dev boxes (ADR 0031). We want every box cost event recorded per builder — visible to the builder on their own profile and to the Archon for oversight — so the org can see what each box costs *before* any real self-fund/charge mechanism exists. No payment integration, no example deduction yet.
11
11
 
12
12
  ## Decisions
13
13
 
@@ -24,5 +24,5 @@ Builders run org-provisioned DigitalOcean dev boxes (ADR 0031). We want every bo
24
24
  ## Consequences
25
25
 
26
26
  - The "compute" category in the public cost summary now also includes near-$0 spin-up rows; negligible.
27
- - When a real self-fund/charge mechanism lands (drachmae deduction or DO-account handoff), it reads this ledger — the data is already accruing.
27
+ - When a real self-fund/charge mechanism lands (example deduction or DO-account handoff), it reads this ledger — the data is already accruing.
28
28
  - Pure cost math (`storageCostUsd`, `summarizeBoxCost`) is unit-tested (`tests/box_cost.mjs`); the DB writers ride the box-lifecycle integration smoke.
@@ -17,7 +17,7 @@ Today it is one fused codebase. A file-grounded coupling analysis (2026-06-18) f
17
17
 
18
18
  1. **Process/HTTP** — one Express app + one Colyseus server. The GDS (`/api/gds`, hall, status) mounts host-agnostic *first*; the **game is the fall-through default**, not a module. Good news: `src/rooms/register.js` + `src/preview-server.js` already factor the game-room set out — the cleanest existing seam and the template for the cut.
19
19
  2. **DB** — *one shared `pg` Pool*: `src/bongos/db.js` does `require('../db')` and reuses the game's pool. Game tables (`world_events`, `players`, migrations 001/002) and ~78 GDS tables share one pool and one flat migration sequence. `track` is a 2-value `CHECK (track IN ('product','internal'))` column on `versions`, woven into analytics + hall UI — an OTB-specific taxonomy.
20
- 3. **Brand/identity** — leaked, not single-config. "Example" is hardcoded across ~50 hits / 28 files; `example.com` across ~90 (cookie domain `.example.com`, OAuth origin, `*.dev.` SSH allowlist); "drachmae" in 23 files; "Off the Boats"/"Example" baked into **grader/architect/onboarding LLM prompts**. Only `devbox-app/src/brand.js` honors the single-config ideal.
20
+ 3. **Brand/identity** — leaked, not single-config. "Example" is hardcoded across ~50 hits / 28 files; `example.com` across ~90 (cookie domain `.example.com`, OAuth origin, `*.dev.` SSH allowlist); "example" in 23 files; "Example"/"Example" baked into **grader/architect/onboarding LLM prompts**. Only `devbox-app/src/brand.js` honors the single-config ideal.
21
21
  4. **Methodology/skills** — already clean: `.claude/skills/builder-*` + idea/blocker/planning/status/recall are portable; the four `otb-*` art skills + `stop-sound.js` are host; `art/` is self-contained (no `src/` imports); Discord is already `DISCORD_BOT_ENABLED`-gated.
22
22
 
23
23
  Why a spike-ADR first: 24 structural tasks (R51–R74) depend on this. They need **one** locked boundary, branding-contract schema, and module mechanism to build against, or they will diverge.
@@ -46,7 +46,7 @@ Why a spike-ADR first: 24 structural tasks (R51–R74) depend on this. They need
46
46
 
47
47
  - **Engine entrypoint** (R51, [#1190](https://example.com/builders#/task/1190)): boots Express + `buildGdsRouter()` + hall + status, host-agnostic, **no Colyseus, no game/tile mounts** — sibling to `src/preview-server.js`. Today's `server.js` becomes the *OTB instance boot* (engine + game module).
48
48
  - **A host instance** = branding pack (§3) + feature-module flags (§4) + owner/repo/OAuth binding (R62, [#1201](https://example.com/builders#/task/1201)) + its own DB (R52).
49
- - Customer 0 = vanilla brand, no modules (the dogfood); customer 1 = OTB (game + art + discord + dev-box, drachmae, Greek pack).
49
+ - Customer 0 = vanilla brand, no modules (the dogfood); customer 1 = OTB (game + art + discord + dev-box, example, Greek pack).
50
50
 
51
51
  ### 3. The branding contract (`config/branding.*` — R53 keystone, [#1192](https://example.com/builders#/task/1192))
52
52
 
@@ -54,7 +54,7 @@ One per-instance config; **resolution precedence: env var → instance config
54
54
 
55
55
  - **Identity:** `productName`, `worldName` (the in-world / civilization name), `company` (+ site).
56
56
  - **Domains:** `publicOrigin`, `buildersOrigin`, `statusOrigin`, `cookieDomain`, box subdomain pattern (`*.dev.`/`sandbox-`/`term-`). *(Load-bearing security strings — a swap must not widen cookie/SSH scope.)*
57
- - **Currency label** (R56, [#1195](https://example.com/builders#/task/1195)): "drachmae" → configurable; the cost-plus reward **math is unchanged**.
57
+ - **Currency label** (R56, [#1195](https://example.com/builders#/task/1195)): "example" → configurable; the cost-plus reward **math is unchanged**.
58
58
  - **Tracks:** replace the 2-value `product|internal` CHECK with a configurable set (R52, [#1191](https://example.com/builders#/task/1191)).
59
59
  - **Theme/palette + copy pack:** hall lore/primer/404 copy, Discord persona, and — critically — the **grader/architect/onboarding prompt brand header** must read the project name from config, or a non-OTB instance grades against the wrong project identity.
60
60
 
@@ -103,5 +103,5 @@ R50 (this ADR) → **R51 entrypoint + R52 DB pool** (independent foundations)
103
103
 
104
104
  - A clear, file-grounded target the 24 epics build against — one boundary, one contract, one module mechanism.
105
105
  - The trust boundary + rank enforcement stay core and unchanged; a feature-module must never be able to bypass server-side rank checks (a Path-C assertion).
106
- - **Hardest knots (called out so the epics plan for them):** (1) shared Pool + flat migrations; (2) the brand-saturated, *not* data-driven hall UI (~50 brand hits, drachmae in 23 files) — the largest mechanical job; (3) inverting game-as-default into a mounted module; (4) domains woven into auth/security — config swaps must not widen cookie/SSH scope; (5) brand inside LLM prompts (grader/architect/onboarding).
106
+ - **Hardest knots (called out so the epics plan for them):** (1) shared Pool + flat migrations; (2) the brand-saturated, *not* data-driven hall UI (~50 brand hits, example in 23 files) — the largest mechanical job; (3) inverting game-as-default into a mounted module; (4) domains woven into auth/security — config swaps must not widen cookie/SSH scope; (5) brand inside LLM prompts (grader/architect/onboarding).
107
107
  - **Risk: scope.** Mitigation: R53 keystone first; modules incremental; Path-C enforces no regression; customer-0 dogfood ([#1206](https://example.com/builders#/task/1206)) is the falsifiable proof the cut actually worked.