@bongos/core 1.18.0 → 1.18.18

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 (553) hide show
  1. package/.bongos-core.json +1740 -640
  2. package/.claude/skills/builder-box/SKILL.md +6 -0
  3. package/.claude/skills/builder-sequence/SKILL.md +97 -0
  4. package/.claude/skills/builder-ship/SKILL.md +8 -2
  5. package/.claude/skills/builder-start/SKILL.md +11 -0
  6. package/.claude/skills/builder-sync/SKILL.md +41 -0
  7. package/.claude/skills/fix-task/SKILL.md +64 -0
  8. package/.claude/skills/goal-create/SKILL.md +158 -0
  9. package/.claude/skills/goal-review/SKILL.md +3 -1
  10. package/.claude/skills/idea-triage/SKILL.md +14 -8
  11. package/.claude/skills/merge-mode/SKILL.md +2 -2
  12. package/.claude/skills/new-project/SKILL.md +1 -0
  13. package/.claude/skills/planning-session/SKILL.md +45 -18
  14. package/.env.local.example +4 -3
  15. package/README.md +5 -3
  16. package/bin/bongos.js +1 -0
  17. package/clients/bongos-client/README.md +2 -2
  18. package/clients/bongos-client/bongos-client.global.js +82 -18
  19. package/clients/bongos-client/index.cjs +82 -18
  20. package/clients/bongos-client/index.d.ts +131 -29
  21. package/clients/bongos-client/index.mjs +82 -18
  22. package/config/branding.neutral.json +11 -2
  23. package/config/governance.neutral.json +21 -0
  24. package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +24 -0
  25. package/docs/adr/0090-metic-task-authoring.md +1 -1
  26. package/docs/adr/0142-project-context-is-prose-only.md +41 -0
  27. package/docs/adr/0143-onboarding-repo-picker-oauth-scope.md +35 -0
  28. package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +41 -0
  29. package/docs/adr/0144-federated-single-logout-backchannel.md +42 -0
  30. package/docs/adr/0145-devbox-app-branding-driven-module.md +44 -0
  31. package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +62 -0
  32. package/docs/adr/0146-configurable-reward-mode-cost-plus-only.md +53 -0
  33. package/docs/adr/0147-standalone-live-docs-regen.md +39 -0
  34. package/docs/adr/0148-task-scoped-box-source-access.md +48 -0
  35. package/docs/adr/0149-bongos-dev-local-launcher.md +57 -0
  36. package/docs/adr/0150-box-first-boot-bringup-vendored-instances.md +68 -0
  37. package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +229 -0
  38. package/docs/adr/0152-landing-gate-served-by-the-core-app.md +92 -0
  39. package/docs/adr/0152-metic-task-abandonment.md +67 -0
  40. package/docs/adr/0153-sequential-chain-runner.md +51 -0
  41. package/docs/adr/0154-goal-owner-criterion-authoring.md +86 -0
  42. package/docs/adr/README.md +15 -2
  43. package/docs/api/openapi.json +2648 -483
  44. package/docs/api-reference.md +73 -13
  45. package/docs/architecture.md +4 -2
  46. package/docs/branding-contract.md +3 -1
  47. package/docs/canonical-permissions.md +21 -8
  48. package/docs/file-map.md +15 -7
  49. package/docs/onboarding/diagrams/01-task-lifecycle.mmd +2 -2
  50. package/docs/onboarding/diagrams/02-rank-ladder.mmd +3 -1
  51. package/docs/onboarding/diagrams/05-versioning.mmd +1 -3
  52. package/docs/onboarding/diagrams/assertions.json +4 -7
  53. package/docs/onboarding/drachmae-and-karma.md +3 -3
  54. package/docs/onboarding/primer.md +17 -16
  55. package/docs/onboarding/slash-commands.md +124 -0
  56. package/docs/recipes/builder-box-lifecycle.md +23 -0
  57. package/docs/recipes/devbox-app-release.md +14 -4
  58. package/docs/recipes/instance-first-run.md +16 -0
  59. package/docs/recipes/local-dev.md +81 -0
  60. package/docs/recipes/ops-gotchas.md +19 -1
  61. package/docs/recipes/overnight-builder.md +1 -1
  62. package/docs/recipes/packaging-the-core.md +13 -0
  63. package/docs/recipes/parallel-goal-waves.md +174 -0
  64. package/docs/recipes/ship-and-regrade.md +2 -2
  65. package/docs/recipes/standalone-live-docs.md +48 -0
  66. package/docs/recipes/upgrading-the-core.md +5 -2
  67. package/docs/recipes/work-on-a-task-from-your-dev-box.md +108 -0
  68. package/migrations/003_pms.sql +6 -7
  69. package/migrations/006_pms_v2.sql +3 -31
  70. package/migrations/039_newcomer_friendly_column.sql +5 -0
  71. package/migrations/102_remove_box_first_provision_approval.sql +4 -0
  72. package/migrations/core_192_github_oauth_tokens.sql +33 -0
  73. package/migrations/core_193_task_needs_rebase.sql +28 -0
  74. package/migrations/core_194_confirmed_backlog_clawback.sql +63 -0
  75. package/migrations/core_195_idea_triage_provenance.sql +57 -0
  76. package/migrations/core_196_session_reward_topup.sql +69 -0
  77. package/modules/autonomy/pollers/routine-timers.js +9 -8
  78. package/modules/builder-settings/wandering-prefs.js +61 -18
  79. package/modules/dev-box/app/README.md +73 -0
  80. package/modules/dev-box/app/assets/tray/mac-alertTemplate.png +0 -0
  81. package/modules/dev-box/app/assets/tray/mac-alertTemplate@2x.png +0 -0
  82. package/modules/dev-box/app/assets/tray/mac-busyTemplate.png +0 -0
  83. package/modules/dev-box/app/assets/tray/mac-busyTemplate@2x.png +0 -0
  84. package/modules/dev-box/app/assets/tray/mac-offTemplate.png +0 -0
  85. package/modules/dev-box/app/assets/tray/mac-offTemplate@2x.png +0 -0
  86. package/modules/dev-box/app/assets/tray/mac-onTemplate.png +0 -0
  87. package/modules/dev-box/app/assets/tray/mac-onTemplate@2x.png +0 -0
  88. package/modules/dev-box/app/assets/tray/win-alert.png +0 -0
  89. package/modules/dev-box/app/assets/tray/win-busy.png +0 -0
  90. package/modules/dev-box/app/assets/tray/win-off.png +0 -0
  91. package/modules/dev-box/app/assets/tray/win-on.png +0 -0
  92. package/modules/dev-box/app/build-resources/dmg-background.png +0 -0
  93. package/modules/dev-box/app/build-resources/dmg-background@2x.png +0 -0
  94. package/modules/dev-box/app/build-resources/icon.png +0 -0
  95. package/modules/dev-box/app/electron-builder.tmpl.yml +95 -0
  96. package/modules/dev-box/app/electron-builder.yml +95 -0
  97. package/modules/dev-box/app/package-lock.json +5291 -0
  98. package/modules/dev-box/app/package.json +30 -0
  99. package/modules/dev-box/app/renderer/app.js +319 -0
  100. package/modules/dev-box/app/renderer/index.html +45 -0
  101. package/modules/dev-box/app/renderer/styles.css +246 -0
  102. package/modules/dev-box/app/renderer/theme.generated.css +16 -0
  103. package/modules/dev-box/app/scripts/apply-dmg-backdrop.sh +82 -0
  104. package/modules/dev-box/app/scripts/dmgbuild-settings.py +39 -0
  105. package/modules/dev-box/app/scripts/gen-brand.js +138 -0
  106. package/modules/dev-box/app/scripts/gen-dmg-backdrop.py +323 -0
  107. package/modules/dev-box/app/scripts/gen-icons.js +286 -0
  108. package/modules/dev-box/app/scripts/vendor-client.js +23 -0
  109. package/modules/dev-box/app/src/box-controller.js +287 -0
  110. package/modules/dev-box/app/src/brand.generated.json +13 -0
  111. package/modules/dev-box/app/src/brand.js +16 -0
  112. package/modules/dev-box/app/src/config.js +19 -0
  113. package/modules/dev-box/app/src/gds-client.js +90 -0
  114. package/modules/dev-box/app/src/main.js +610 -0
  115. package/modules/dev-box/app/src/pairing.js +57 -0
  116. package/modules/dev-box/app/src/preload.js +29 -0
  117. package/modules/dev-box/app/src/session-store.js +58 -0
  118. package/modules/dev-box/app/src/ssh-setup.js +569 -0
  119. package/modules/dev-box/app/src/task-picker.js +70 -0
  120. package/modules/dev-box/app/src/tray.js +99 -0
  121. package/modules/dev-box/app/src/updater.js +55 -0
  122. package/modules/dev-box/app/src/vendor/bongos-client.cjs +698 -0
  123. package/modules/dev-box/app/test/unit.mjs +526 -0
  124. package/modules/dev-box/box-access.js +121 -4
  125. package/modules/dev-box/boxes.js +20 -0
  126. package/modules/dev-box/module.json +1 -1
  127. package/modules/dev-box/routes/box.js +87 -3
  128. package/modules/economy/credits.js +116 -25
  129. package/modules/economy/reward.js +8 -0
  130. package/modules/economy/streak.js +2 -1
  131. package/modules/governance/CLAUDE.md +15 -0
  132. package/modules/governance/catalog.js +419 -0
  133. package/modules/governance/config.js +174 -0
  134. package/modules/governance/db.js +125 -0
  135. package/modules/governance/migrations/governance_001_tables.sql +81 -0
  136. package/modules/governance/migrations/governance_002_seed_and_backfill.sql +103 -0
  137. package/modules/governance/migrations/governance_003_task_abandon_metic.sql +28 -0
  138. package/modules/governance/migrations/governance_004_criterion_create.sql +39 -0
  139. package/modules/governance/migrations/governance_005_resync_builder_rank_roles.sql +56 -0
  140. package/modules/governance/module.json +10 -0
  141. package/modules/governance/protected-surfaces.js +88 -0
  142. package/modules/governance/protected-surfaces.json +80 -0
  143. package/modules/governance/rank-roles.js +83 -0
  144. package/modules/governance/resolver.js +221 -0
  145. package/modules/governance/routes/governance.js +89 -0
  146. package/modules/governance/routes/role-sync.js +49 -0
  147. package/modules/governance/session-scopes.js +127 -0
  148. package/modules/governance/session-scopes.json +38 -0
  149. package/modules/hall-ui/public/atlas.css +117 -0
  150. package/modules/hall-ui/public/atlas.html +3 -114
  151. package/modules/hall-ui/public/brand-apply.js +34 -6
  152. package/modules/hall-ui/public/builders.js +187 -219
  153. package/modules/hall-ui/public/diagrams.html +2 -0
  154. package/modules/hall-ui/public/dom-utils.js +27 -0
  155. package/modules/hall-ui/public/drachmae.html +2 -0
  156. package/modules/hall-ui/public/drachmae.js +54 -1
  157. package/modules/hall-ui/public/gate.css +98 -0
  158. package/modules/hall-ui/public/gate.html +3 -95
  159. package/modules/hall-ui/public/goal-inbox.js +4 -1
  160. package/modules/hall-ui/public/goals-page.js +626 -114
  161. package/modules/hall-ui/public/goals.css +79 -1
  162. package/modules/hall-ui/public/goals.html +38 -11
  163. package/modules/hall-ui/public/hall-widgets.js +62 -52
  164. package/modules/hall-ui/public/harbor.css +123 -0
  165. package/modules/hall-ui/public/harbor.html +3 -120
  166. package/modules/hall-ui/public/index.html +11 -4
  167. package/modules/hall-ui/public/instances-panel.js +4 -1
  168. package/modules/hall-ui/public/modules.css +63 -0
  169. package/modules/hall-ui/public/modules.html +3 -60
  170. package/modules/hall-ui/public/my-projects.html +78 -0
  171. package/modules/hall-ui/public/my-projects.js +142 -0
  172. package/modules/hall-ui/public/new-project-wizard.js +7 -3
  173. package/modules/hall-ui/public/not-ready.html +2 -0
  174. package/modules/hall-ui/public/pair.css +73 -0
  175. package/modules/hall-ui/public/pair.html +3 -70
  176. package/modules/hall-ui/public/palette.js +302 -0
  177. package/modules/hall-ui/public/primer.css +13 -0
  178. package/modules/hall-ui/public/primer.html +2 -0
  179. package/modules/hall-ui/public/profile.html +2 -0
  180. package/modules/hall-ui/public/ranks.html +2 -0
  181. package/modules/hall-ui/public/roadmap.css +179 -0
  182. package/modules/hall-ui/public/roadmap.html +9 -172
  183. package/modules/hall-ui/public/roadmap.js +329 -316
  184. package/modules/hall-ui/public/scouting.html +45 -0
  185. package/modules/hall-ui/public/scouting.js +73 -0
  186. package/modules/hall-ui/public/sessions.css +16 -0
  187. package/modules/hall-ui/public/sessions.html +3 -13
  188. package/modules/hall-ui/public/settings.html +2 -0
  189. package/modules/hall-ui/public/settings.js +4 -4
  190. package/modules/hall-ui/public/shell.js +143 -18
  191. package/modules/hall-ui/public/style.css +231 -39
  192. package/modules/hall-ui/public/task-detail.js +347 -26
  193. package/modules/hall-ui/public/task.html +6 -1
  194. package/modules/hall-ui/public/watch.html +2 -0
  195. package/modules/hall-ui/public/work.html +8 -6
  196. package/modules/hall-ui/public/work.js +1 -1
  197. package/modules/ideas/inbox.js +61 -11
  198. package/modules/ideas/routes/inbox.js +23 -0
  199. package/modules/lifecycle/claim-eligibility.js +72 -0
  200. package/modules/lifecycle/db.js +519 -139
  201. package/modules/lifecycle/done-when.js +18 -3
  202. package/modules/lifecycle/github-push.js +19 -2
  203. package/modules/lifecycle/goal-advisory.js +114 -0
  204. package/modules/lifecycle/goal-authz.js +62 -0
  205. package/modules/lifecycle/lifecycle.js +9 -0
  206. package/modules/lifecycle/publish-reconciler.js +109 -6
  207. package/modules/lifecycle/routes/claims.js +68 -23
  208. package/modules/lifecycle/routes/done-when.js +110 -15
  209. package/modules/lifecycle/routes/goals.js +8 -38
  210. package/modules/lifecycle/routes/tasks.js +38 -6
  211. package/modules/lifecycle/ship-card.js +6 -0
  212. package/modules/onboarding/onboarding-state.js +1 -1
  213. package/modules/platform-identity/CLAUDE.md +15 -0
  214. package/modules/platform-identity/hub-device.js +147 -0
  215. package/modules/platform-identity/hub-keys.js +151 -0
  216. package/modules/platform-identity/migrations/platform_identity_001_tables.sql +114 -0
  217. package/modules/platform-identity/migrations/platform_identity_002_client_origin_index.sql +18 -0
  218. package/modules/platform-identity/migrations/platform_identity_003_project_memberships.sql +42 -0
  219. package/modules/platform-identity/migrations/platform_identity_004_projects.sql +44 -0
  220. package/modules/platform-identity/migrations/platform_identity_005_builder_activity.sql +42 -0
  221. package/modules/platform-identity/module.json +18 -0
  222. package/modules/platform-identity/platform-identity.js +531 -0
  223. package/modules/platform-identity/pollers/code-sweep.js +43 -0
  224. package/modules/platform-identity/routes/my-projects.js +140 -0
  225. package/modules/platform-identity/routes/projects.js +107 -0
  226. package/modules/platform-identity/routes/scouting.js +35 -0
  227. package/modules/platform-identity/routes/sso.js +402 -0
  228. package/modules/platform-identity/tests/platform-identity.mjs +388 -0
  229. package/modules/platform-identity/ui/.gitkeep +0 -0
  230. package/modules/security/routes/reports.js +10 -0
  231. package/modules/sessions/db.js +166 -21
  232. package/modules/sessions/module.json +1 -1
  233. package/modules/sessions/pollers/session-reward-reconcile.js +78 -0
  234. package/modules/sessions/routes/sessions.js +33 -0
  235. package/modules/status-ui/public/explore.html +54 -0
  236. package/modules/status-ui/public/explore.js +67 -0
  237. package/package-lock.json +2 -2
  238. package/package.json +1 -1
  239. package/public-landing/assets/anim/idle/frame_00.webp +0 -0
  240. package/public-landing/assets/anim/idle/frame_01.webp +0 -0
  241. package/public-landing/assets/anim/idle/frame_02.webp +0 -0
  242. package/public-landing/assets/anim/idle/frame_03.webp +0 -0
  243. package/public-landing/assets/anim/idle/frame_04.webp +0 -0
  244. package/public-landing/assets/anim/idle/frame_05.webp +0 -0
  245. package/public-landing/assets/anim/idle/frame_06.webp +0 -0
  246. package/public-landing/assets/anim/idle/frame_07.webp +0 -0
  247. package/public-landing/assets/anim/idle/frame_08.webp +0 -0
  248. package/public-landing/assets/anim/idle/frame_09.webp +0 -0
  249. package/public-landing/assets/anim/idle/frame_10.webp +0 -0
  250. package/public-landing/assets/anim/idle/frame_11.webp +0 -0
  251. package/public-landing/assets/anim/idle/frame_12.webp +0 -0
  252. package/public-landing/assets/anim/idle/frame_13.webp +0 -0
  253. package/public-landing/assets/anim/idle/frame_14.webp +0 -0
  254. package/public-landing/assets/anim/idle/frame_15.webp +0 -0
  255. package/public-landing/assets/anim/idle/frame_16.webp +0 -0
  256. package/public-landing/assets/anim/idle/frame_17.webp +0 -0
  257. package/public-landing/assets/anim/idle/frame_18.webp +0 -0
  258. package/public-landing/assets/anim/idle/frame_19.webp +0 -0
  259. package/public-landing/assets/anim/idle/frame_20.webp +0 -0
  260. package/public-landing/assets/anim/idle/frame_21.webp +0 -0
  261. package/public-landing/assets/anim/idle/frame_22.webp +0 -0
  262. package/public-landing/assets/anim/idle/frame_23.webp +0 -0
  263. package/public-landing/assets/anim/idle/frame_24.webp +0 -0
  264. package/public-landing/assets/anim/idle/frame_25.webp +0 -0
  265. package/public-landing/assets/anim/idle/frame_26.webp +0 -0
  266. package/public-landing/assets/anim/idle/frame_27.webp +0 -0
  267. package/public-landing/assets/anim/idle/frame_28.webp +0 -0
  268. package/public-landing/assets/anim/idle/frame_29.webp +0 -0
  269. package/public-landing/assets/anim/idle/frame_30.webp +0 -0
  270. package/public-landing/assets/anim/idle/frame_31.webp +0 -0
  271. package/public-landing/assets/anim/idle/frame_32.webp +0 -0
  272. package/public-landing/assets/anim/idle/frame_33.webp +0 -0
  273. package/public-landing/assets/anim/idle/frame_34.webp +0 -0
  274. package/public-landing/assets/anim/idle/frame_35.webp +0 -0
  275. package/public-landing/assets/anim/idle/frame_36.webp +0 -0
  276. package/public-landing/assets/anim/idle/frame_37.webp +0 -0
  277. package/public-landing/assets/anim/idle/frame_38.webp +0 -0
  278. package/public-landing/assets/anim/idle/frame_39.webp +0 -0
  279. package/public-landing/assets/anim/idle/frame_40.webp +0 -0
  280. package/public-landing/assets/anim/idle/frame_41.webp +0 -0
  281. package/public-landing/assets/anim/idle/frame_42.webp +0 -0
  282. package/public-landing/assets/anim/idle/frame_43.webp +0 -0
  283. package/public-landing/create.html +252 -62
  284. package/public-landing/gate/README.md +137 -0
  285. package/public-landing/gate/dispmaps/bar.png +0 -0
  286. package/public-landing/gate/dispmaps/flat.png +0 -0
  287. package/public-landing/gate/dispmaps/key.png +0 -0
  288. package/public-landing/gate/index.html +587 -0
  289. package/public-landing/gate/previews/cloud-bongos.jpg +0 -0
  290. package/public-landing/gate/previews/off-the-boats.jpg +0 -0
  291. package/public-landing/gate/space.css +799 -0
  292. package/public-landing/gate/space.js +1826 -0
  293. package/public-landing/gate/sprites/enter.png +0 -0
  294. package/public-landing/gate/sprites/search.png +0 -0
  295. package/public-landing/gate/sprites/terminal-blank.png +0 -0
  296. package/public-landing/gate/sprites/tile.png +0 -0
  297. package/public-landing/world/assets/clouds/cloud-island-large.png +0 -0
  298. package/public-landing/world/assets/clouds/cloud-puff.png +0 -0
  299. package/public-landing/world/assets/creatures/creature-whale-cargo.png +0 -0
  300. package/public-landing/world/assets/creatures/creature-whale-glide.png +0 -0
  301. package/public-landing/world/assets/plates/plate-clouds-near.png +0 -0
  302. package/public-landing/world/assets/plates/scene-establishing.png +0 -0
  303. package/scripts/gds/abandon.js +6 -4
  304. package/scripts/gds/api.js +10 -5
  305. package/scripts/gds/api.ps1 +26 -0
  306. package/scripts/gds/api.sh +6 -0
  307. package/scripts/gds/audit-ships.js +7 -1
  308. package/scripts/gds/backfill-sessions.js +78 -18
  309. package/scripts/gds/backup.js +23 -1
  310. package/scripts/gds/box-connect-lib.js +124 -31
  311. package/scripts/gds/box-sync.js +66 -0
  312. package/scripts/gds/box.js +225 -53
  313. package/scripts/gds/cf-tunnel.js +145 -6
  314. package/scripts/gds/claim.js +34 -3
  315. package/scripts/gds/cli-lib.js +161 -21
  316. package/scripts/gds/code.js +6 -2
  317. package/scripts/gds/deploy-divergence.js +209 -0
  318. package/scripts/gds/dev-lib.js +309 -0
  319. package/scripts/gds/dev.js +322 -0
  320. package/scripts/gds/doctor.js +90 -61
  321. package/scripts/gds/fetch-art-key.js +1 -1
  322. package/scripts/gds/fetch-sound-prefs.js +2 -2
  323. package/scripts/gds/fitness.js +228 -12
  324. package/scripts/gds/gds-db-backup.service +16 -1
  325. package/scripts/gds/gds-db-offsite.service +9 -1
  326. package/scripts/gds/gen-api-client.js +1 -1
  327. package/scripts/gds/gen-api-docs.js +36 -14
  328. package/scripts/gds/gen-diagrams.js +45 -28
  329. package/scripts/gds/gen-file-map.js +2 -1
  330. package/scripts/gds/gen-freshness.js +32 -0
  331. package/scripts/gds/gen-repo-map.js +3 -2
  332. package/scripts/gds/gen-session-index.js +14 -5
  333. package/scripts/gds/hooks/pre-push.js +2 -2
  334. package/scripts/gds/init.js +60 -3
  335. package/scripts/gds/install-git-hooks.js +1 -1
  336. package/scripts/gds/key-card.js +15 -6
  337. package/scripts/gds/key-status.js +1 -1
  338. package/scripts/gds/linkify-refs.js +35 -9
  339. package/scripts/gds/lint-migrations.js +102 -0
  340. package/scripts/gds/login.js +58 -11
  341. package/scripts/gds/mirror-redact.js +5 -0
  342. package/scripts/gds/package-core.js +263 -4
  343. package/scripts/gds/paste-token.js +7 -1
  344. package/scripts/gds/preflight.js +126 -0
  345. package/scripts/gds/provision.js +268 -19
  346. package/scripts/gds/publish-manifest.js +22 -1
  347. package/scripts/gds/reauth.js +7 -3
  348. package/scripts/gds/regen-instance-docs.js +47 -0
  349. package/scripts/gds/run-unit-tests.js +42 -16
  350. package/scripts/gds/seed-bongos-v1-seo-tasks.js +104 -0
  351. package/scripts/gds/seed-bv1-profiles-tasks.js +126 -0
  352. package/scripts/gds/sequence.js +425 -0
  353. package/scripts/gds/session-cost.js +10 -1
  354. package/scripts/gds/setup.js +72 -5
  355. package/scripts/gds/shell.js +5 -3
  356. package/scripts/gds/ship.js +433 -59
  357. package/scripts/gds/smoke-gds.js +139 -8
  358. package/scripts/gds/start.js +171 -22
  359. package/scripts/gds/status.js +1 -1
  360. package/scripts/gds/triage.js +10 -9
  361. package/scripts/gds/upgrade.js +271 -7
  362. package/scripts/migrate.sh +10 -0
  363. package/scripts/status-mirror-sync.js +114 -84
  364. package/src/bongos/api-errors.js +1 -0
  365. package/src/bongos/auth.js +809 -107
  366. package/src/bongos/db-kernel.js +27 -0
  367. package/src/bongos/db.js +105 -0
  368. package/src/bongos/github-repos.js +93 -0
  369. package/src/bongos/module-scope-map.js +27 -1
  370. package/src/bongos/permission-path-check.js +136 -102
  371. package/src/bongos/repo-info.js +47 -11
  372. package/src/bongos/route-rank-check.js +429 -46
  373. package/src/bongos/routes/_helpers.js +12 -1
  374. package/src/bongos/routes/auth.js +312 -13
  375. package/src/bongos/routes/backup.js +58 -2
  376. package/src/bongos/routes/github.js +90 -0
  377. package/src/bongos/routes/instance.js +15 -3
  378. package/src/bongos/routes/me.js +35 -1
  379. package/src/bongos/routes.js +2 -0
  380. package/src/bongos/serve-internal.js +84 -15
  381. package/src/branding.js +49 -2
  382. package/src/instance-config.js +46 -0
  383. package/src/module-api.js +140 -1
  384. package/src/platform-server.js +86 -9
  385. package/tests/abandon_task.mjs +59 -3
  386. package/tests/api_cli_flags.mjs +53 -0
  387. package/tests/auth_page_gate.mjs +13 -0
  388. package/tests/backfill_sessions.mjs +127 -1
  389. package/tests/backup_cli.mjs +54 -0
  390. package/tests/bongos_box_connect.mjs +77 -0
  391. package/tests/box_access.mjs +130 -1
  392. package/tests/box_credential.mjs +125 -0
  393. package/tests/box_host_keys.mjs +24 -0
  394. package/tests/box_infra_resolve.mjs +149 -0
  395. package/tests/box_scope_session.mjs +6 -2
  396. package/tests/box_sync.mjs +55 -0
  397. package/tests/box_task_scope.mjs +99 -0
  398. package/tests/branding.mjs +41 -23
  399. package/tests/cf_ruleset_preflight.mjs +142 -0
  400. package/tests/cf_tunnel.mjs +37 -0
  401. package/tests/claim_gate_rebase.mjs +98 -0
  402. package/tests/clawback_confirmed_backlog.mjs +103 -0
  403. package/tests/cli_lib_formatters.mjs +20 -0
  404. package/tests/confirm_attribution.mjs +30 -46
  405. package/tests/credit_grant.mjs +198 -10
  406. package/tests/criterion_authoring_gate.mjs +272 -0
  407. package/tests/criterion_progress.mjs +33 -1
  408. package/tests/dev_lib.mjs +253 -0
  409. package/tests/devbox_artifact_gate.mjs +75 -0
  410. package/tests/devbox_dmg_backdrop.mjs +137 -0
  411. package/tests/devbox_icons.mjs +304 -0
  412. package/tests/devbox_installer_brand.mjs +232 -0
  413. package/tests/devbox_key_register.mjs +234 -0
  414. package/tests/docs_openapi_route.mjs +110 -0
  415. package/tests/doctor_hooks.mjs +141 -0
  416. package/tests/extract_json.mjs +140 -0
  417. package/tests/fitness.mjs +89 -0
  418. package/tests/gen_freshness.mjs +96 -0
  419. package/tests/github_repos_helpers.mjs +91 -0
  420. package/tests/github_token_store.mjs +121 -0
  421. package/tests/goal_advisory.mjs +251 -0
  422. package/tests/goal_criterion_confirm_ui.mjs +269 -0
  423. package/tests/goal_routes.mjs +59 -4
  424. package/tests/goal_tier.mjs +12 -3
  425. package/tests/governance_catalog.mjs +129 -0
  426. package/tests/governance_claim_eligibility.mjs +262 -0
  427. package/tests/governance_config.mjs +187 -0
  428. package/tests/governance_ownership_scope.mjs +410 -0
  429. package/tests/governance_page_gates.mjs +324 -0
  430. package/tests/governance_parity.mjs +336 -0
  431. package/tests/governance_principals.mjs +232 -0
  432. package/tests/governance_protected_surfaces.mjs +208 -0
  433. package/tests/governance_require_permission.mjs +223 -0
  434. package/tests/governance_resolver.mjs +84 -0
  435. package/tests/governance_role_sync.mjs +231 -0
  436. package/tests/governance_seed.mjs +127 -0
  437. package/tests/governance_session_scope.mjs +434 -0
  438. package/tests/governance_vanilla_boot.mjs +203 -0
  439. package/tests/grade_attribution.mjs +7 -7
  440. package/tests/hall_audit.mjs +223 -0
  441. package/tests/hall_nav.mjs +191 -0
  442. package/tests/hall_palette.mjs +206 -0
  443. package/tests/hall_signout.mjs +124 -0
  444. package/tests/hook_user_agents.mjs +10 -0
  445. package/tests/idea_triage.mjs +162 -0
  446. package/tests/idp_device_exchange.mjs +198 -0
  447. package/tests/idp_federation.mjs +100 -0
  448. package/tests/init.mjs +51 -0
  449. package/tests/instance_config.mjs +65 -0
  450. package/tests/instance_mismatch_guard.mjs +23 -6
  451. package/tests/instance_release_config.mjs +104 -0
  452. package/tests/linkify_refs.mjs +15 -2
  453. package/tests/migrations_forward_safe.mjs +86 -0
  454. package/tests/module_api.mjs +1 -1
  455. package/tests/module_contributions.mjs +55 -0
  456. package/tests/module_loader.mjs +10 -5
  457. package/tests/module_scope_active_claims.mjs +94 -0
  458. package/tests/needs_rebase.mjs +92 -0
  459. package/tests/one_active_claim_per_session.mjs +76 -0
  460. package/tests/override_attribution.mjs +10 -8
  461. package/tests/override_request_ownership.mjs +8 -4
  462. package/tests/package_core.mjs +246 -1
  463. package/tests/parse_cookie_decode.mjs +42 -0
  464. package/tests/pay_on_land.mjs +129 -0
  465. package/tests/platform_boot.mjs +100 -1
  466. package/tests/post_login_landing.mjs +42 -0
  467. package/tests/preflight_checks.mjs +72 -0
  468. package/tests/provision.mjs +289 -7
  469. package/tests/pruned_lockfile_integrity.mjs +79 -0
  470. package/tests/publish_branch_route.mjs +53 -0
  471. package/tests/publish_reconciler.mjs +187 -2
  472. package/tests/repo_info_binding.mjs +248 -0
  473. package/tests/reward_gate.mjs +11 -2
  474. package/tests/reward_mode_cost_plus_only.mjs +116 -0
  475. package/tests/reward_mode_surfacing.mjs +168 -0
  476. package/tests/route_permission_check.mjs +301 -0
  477. package/tests/route_rank_check.mjs +254 -12
  478. package/tests/route_validation.mjs +30 -0
  479. package/tests/sequence.mjs +267 -0
  480. package/tests/session_digest.mjs +44 -0
  481. package/tests/session_index.mjs +18 -6
  482. package/tests/session_records.mjs +39 -1
  483. package/tests/session_reward_on_land.mjs +381 -0
  484. package/tests/session_reward_reconcile.mjs +229 -0
  485. package/tests/ship_api_client_pathspec.mjs +100 -0
  486. package/tests/ship_base_flag.mjs +93 -0
  487. package/tests/ship_ci_deploy.mjs +140 -3
  488. package/tests/ship_upstream_deletion.mjs +57 -0
  489. package/tests/smoke_target.mjs +233 -0
  490. package/tests/start_env_guard.mjs +87 -0
  491. package/tests/start_rebase_warning.mjs +103 -0
  492. package/tests/status_mirror_sync.mjs +122 -0
  493. package/tests/stop_refcheck.mjs +19 -1
  494. package/tests/task_goal_link.mjs +15 -6
  495. package/tests/upgrade.mjs +393 -5
  496. package/tests/web_admission_status.mjs +162 -0
  497. package/tests/write_validation_gaps.mjs +110 -0
  498. package/.gitignore +0 -91
  499. package/docs/adr/0139-platform-history-migration-to-cloudbongos.md +0 -94
  500. package/docs/adr/0140-cloudbongos-standalone-reprovision.md +0 -43
  501. package/scripts/hall-preview/fixtures/access-requests.json +0 -20
  502. package/scripts/hall-preview/fixtures/achievements.json +0 -76
  503. package/scripts/hall-preview/fixtures/analytics__builder.json +0 -251
  504. package/scripts/hall-preview/fixtures/audit-log.json +0 -68
  505. package/scripts/hall-preview/fixtures/blockers__detail.json +0 -12
  506. package/scripts/hall-preview/fixtures/box__me.json +0 -5
  507. package/scripts/hall-preview/fixtures/boxes__cost-ledger.json +0 -69
  508. package/scripts/hall-preview/fixtures/builders__active-claims.json +0 -1
  509. package/scripts/hall-preview/fixtures/builders__directory.json +0 -81
  510. package/scripts/hall-preview/fixtures/builders__roster.json +0 -48
  511. package/scripts/hall-preview/fixtures/goals.json +0 -502
  512. package/scripts/hall-preview/fixtures/goals__25.json +0 -96
  513. package/scripts/hall-preview/fixtures/goals__26.json +0 -67
  514. package/scripts/hall-preview/fixtures/goals__3.json +0 -103
  515. package/scripts/hall-preview/fixtures/goals__35.json +0 -49
  516. package/scripts/hall-preview/fixtures/goals__conflicts.json +0 -154
  517. package/scripts/hall-preview/fixtures/goals__detail.json +0 -96
  518. package/scripts/hall-preview/fixtures/goals__inbox.json +0 -5
  519. package/scripts/hall-preview/fixtures/goals__requests.json +0 -3
  520. package/scripts/hall-preview/fixtures/grades__by-builder.json +0 -32
  521. package/scripts/hall-preview/fixtures/inbox.json +0 -330
  522. package/scripts/hall-preview/fixtures/inbox__detail.json +0 -15
  523. package/scripts/hall-preview/fixtures/instance.json +0 -124
  524. package/scripts/hall-preview/fixtures/leaderboard.json +0 -184
  525. package/scripts/hall-preview/fixtures/me.json +0 -476
  526. package/scripts/hall-preview/fixtures/me__art-key__own.json +0 -6
  527. package/scripts/hall-preview/fixtures/me__event-sound-prefs.json +0 -209
  528. package/scripts/hall-preview/fixtures/me__recent-ships.json +0 -304
  529. package/scripts/hall-preview/fixtures/me__render.json +0 -5
  530. package/scripts/hall-preview/fixtures/me__skill-prefs.json +0 -143
  531. package/scripts/hall-preview/fixtures/me__sound-prefs.json +0 -67
  532. package/scripts/hall-preview/fixtures/me__wandering.json +0 -43
  533. package/scripts/hall-preview/fixtures/override-requests.json +0 -15
  534. package/scripts/hall-preview/fixtures/provisioning__fleet.json +0 -1
  535. package/scripts/hall-preview/fixtures/provisioning__fleet__cost-ledger.json +0 -1
  536. package/scripts/hall-preview/fixtures/provisioning__instances.json +0 -1
  537. package/scripts/hall-preview/fixtures/public__analytics__ecosystem.json +0 -516
  538. package/scripts/hall-preview/fixtures/public__bounty-table.json +0 -37
  539. package/scripts/hall-preview/fixtures/public__cost-summary.json +0 -742
  540. package/scripts/hall-preview/fixtures/public__estimation-drift.json +0 -41
  541. package/scripts/hall-preview/fixtures/public__grades.json +0 -50
  542. package/scripts/hall-preview/fixtures/public__progress.json +0 -124
  543. package/scripts/hall-preview/fixtures/public__recent-shipped.json +0 -426
  544. package/scripts/hall-preview/fixtures/public__repo-health.json +0 -160
  545. package/scripts/hall-preview/fixtures/public__repo-info.json +0 -5
  546. package/scripts/hall-preview/fixtures/security__docs.json +0 -10
  547. package/scripts/hall-preview/fixtures/security__reports.json +0 -31
  548. package/scripts/hall-preview/fixtures/sessions__search.json +0 -9
  549. package/scripts/hall-preview/fixtures/tasks.json +0 -2420
  550. package/scripts/hall-preview/fixtures/tasks__claimable.json +0 -2555
  551. package/scripts/hall-preview/fixtures/tasks__detail.json +0 -111
  552. package/scripts/hall-preview/fixtures/tasks__peer-votes__feed.json +0 -330
  553. package/scripts/hall-preview/fixtures/versions.json +0 -89
@@ -12,11 +12,11 @@ When you're done, open [/builders](https://example.com/builders) and run `/build
12
12
 
13
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
- ## What the GDS is
15
+ ## What Bongos is
16
16
 
17
- The **Game Development System** (GDS) is the project's internal nervous system. It's a Postgres-backed task database with a small HTTP API, a CLI (the `/builder-*` slash commands), and a public dashboard at [status.example.com](https://status.example.com). Every change to the project — code, docs, art, migrations, even direct DB writes — happens under a **claim** on a GDS task. The claim is what makes parallel work safe (no two builders editing the same files at once) and what gives credit-tracking, cost-tracking, and the karma system something concrete to hang off.
17
+ **Bongos** is the project's internal nervous system. It's a Postgres-backed task database with a small HTTP API, a CLI (the `/builder-*` slash commands), and a public dashboard at [status.example.com](https://status.example.com). Every change to the project — code, docs, art, migrations, even direct DB writes — happens under a **claim** on a Bongos task. The claim is what makes parallel work safe (no two builders editing the same files at once) and what gives credit-tracking, cost-tracking, and the karma system something concrete to hang off.
18
18
 
19
- You don't need to understand the GDS schema to ship work. You just need to know: *claim a task, work on it inside your worktree, ship it.* The CLI handles the rest.
19
+ You don't need to understand the Bongos schema to ship work. You just need to know: *claim a task, work on it inside your worktree, ship it.* The CLI handles the rest.
20
20
 
21
21
  ## The claim → ship lifecycle
22
22
 
@@ -25,8 +25,8 @@ Every piece of work moves through this loop:
25
25
  ```
26
26
  backlog ─────▶ ready ─────▶ active ─────▶ completed ─────▶ confirmed ─────▶ shipped
27
27
  │ │ │ │ │ │
28
- │ │ │ │ │ └─ deployed to example.com
29
- │ │ │ │ └─ verification passed, credits awarded
28
+ │ │ │ │ │ └─ deployed to example.com, credits awarded
29
+ │ │ │ │ └─ verification passed (not yet paid)
30
30
  │ │ │ └─ you said "done", ship.js runs the smoke tests
31
31
  │ │ └─ you ran /builder-claim (locks the task to your session)
32
32
  │ └─ dependencies all shipped (auto-promoted by a DB trigger)
@@ -37,7 +37,7 @@ You drive the middle three states. The system handles the rest.
37
37
 
38
38
  **One claim at a time** while you're a Xenos. New builders hold a single active claim — ship it (or release it) before opening another, so the first work gets carried through. The limit is keyed to your rank: it lifts automatically when you graduate to **Thetes** (after your third shipped task), after which you can hold parallel claims if you want.
39
39
 
40
- When you ship, `ship.js` runs the project's **smoke tests** and the quality grader. If they pass, the task auto-confirms and **credits land** (this is the `completed → confirmed` edge — *not* the final deploy). The final `confirmed → shipped` hop — landing on `main` and deploying — is then handled for you, but *what it takes to land* depends on your rank and what you changed; the next section covers it. (There used to be an up-front `touches[]` "drift scanner" here too; it was retired — `git merge` at land time is the real collision detector. See [ADR 0049](../adr/<redacted>.md).)
40
+ When you ship, `ship.js` runs the project's **smoke tests** and the quality grader. If they pass, the task auto-confirms — verified, but **not yet paid**. **Credits land at the final `confirmed → shipped` hop**, when your code actually merges to `main` and deploys ([ADR 0120](../adr/<redacted>.md) — you're paid for landed code, so a branch that never lands never pays). That hop is handled for you, but *what it takes to land* depends on your rank and what you changed; the next section covers it. (There used to be an up-front `touches[]` "drift scanner" here too; it was retired — `git merge` at land time is the real collision detector. See [ADR 0049](../adr/<redacted>.md).)
41
41
 
42
42
  ## How work lands — and what auto-ships
43
43
 
@@ -51,7 +51,7 @@ The one thing that decides whether your ship is **instant** or **waits for an Ar
51
51
  | **A protected "gate surface"** — migrations, server routes, the ship / deploy plumbing | Auto-merges **only if you are Metic or above** (rank trust). A Xenos or Thetes ship here **waits for an Archon** to approve. |
52
52
  | **The safety core** — the gate's own machinery, the deploy switch, the rank / permission enforcement | **Always** waits for an Archon, whatever your rank. |
53
53
 
54
- So your first tasks **ship with no approval**: the newcomer chores — a tile, a doc fix, a unit test, a batch of ideas — all sit on the safe side of that line, and a clean ship merges and deploys on its own. You only meet the Archon gate if your change reaches into the project's own safety machinery, which builders below Metic are asked to stay clear of anyway ([ADR 0043](../adr/<redacted>.md)). Landing is always the GDS's job: you never run `git push origin main`, `ssh` to the server, or deploy by hand — `/builder-ship` opens the PR and the server does the rest ([ADR 0042](../adr/<redacted>.md)).
54
+ So your first tasks **ship with no approval**: the newcomer chores — a tile, a doc fix, a unit test, a batch of ideas — all sit on the safe side of that line, and a clean ship merges and deploys on its own. You only meet the Archon gate if your change reaches into the project's own safety machinery, which builders below Metic are asked to stay clear of anyway ([ADR 0043](../adr/<redacted>.md)). Landing is always Bongos's job: you never run `git push origin main`, `ssh` to the server, or deploy by hand — `/builder-ship` opens the PR and the server does the rest ([ADR 0042](../adr/<redacted>.md)).
55
55
 
56
56
  ## The rank ladder
57
57
 
@@ -68,9 +68,9 @@ So the sandbox is short: ship three small `newcomer_friendly` tasks and the city
68
68
 
69
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 **[Example & karma — how you get paid](example-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](drachmae-and-karma.md)**; here's the shape of it.
72
72
 
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).
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 `confirmed → shipped` edge — when your code actually merges and deploys, not when verification passes ([ADR 0120](../adr/<redacted>.md)). Which of those two streams actually pays is per-instance config ([ADR 0146](../adr/<redacted><redacted>.md)): the default pays both, while a `cost-plus-only` instance pays the session reward alone and treats each task's `credits_reward` as an advertised estimate only. See the standings on [/builders](https://example.com/builders).
74
74
 
75
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
 
@@ -87,11 +87,11 @@ Claude is your pair-programmer here, but it doesn't know the project until you p
87
87
 
88
88
  What doesn't work well:
89
89
 
90
- - *"How does the GDS work?"* — too open. Claude will hallucinate or read everything inefficiently.
91
- - *"What should I work on?"* — ask `/builder-start` instead. That's the GDS's job, not Claude's.
90
+ - *"How does Bongos work?"* — too open. Claude will hallucinate or read everything inefficiently.
91
+ - *"What should I work on?"* — ask `/builder-start` instead. That's Bongos's job, not Claude's.
92
92
  - *"Is this safe to ship?"* — ask `/builder-ship` (it runs the smoke tests and, when enabled, the quality grader). Or run `/code-review` if you want a second opinion.
93
93
 
94
- **Use slash commands for plumbing, use Claude for thinking.** The `/builder-*` skills know how to talk to the GDS. Claude knows how to read your code and reason about it. Don't ask Claude to do something a slash command already does — it's slower and less reliable.
94
+ **Use slash commands for plumbing, use Claude for thinking.** The `/builder-*` skills know how to talk to Bongos. Claude knows how to read your code and reason about it. Don't ask Claude to do something a slash command already does — it's slower and less reliable. And when you can't tell whether a command is ours or Claude Code's own, [**slash-commands.md**](slash-commands.md) sorts them apart — including the handful that collide.
95
95
 
96
96
  ## What the system remembers for you
97
97
 
@@ -106,12 +106,13 @@ The map stays light on its own: a session-start guard warns if it's drifting lar
106
106
 
107
107
  The whole project's source-of-truth index is [`CLAUDE.md`](../../CLAUDE.md). Two starting points:
108
108
 
109
- - **For *what's true right now*** — go to the GDS DB via `/builder-start` or [/builders](https://example.com/builders). Tasks, claims, ranks, credits, costs all live there. CLAUDE.md is *descriptive*; the DB is *authoritative*.
109
+ - **For *what's true right now*** — go to the Bongos database via `/builder-start` or [/builders](https://example.com/builders). Tasks, claims, ranks, credits, costs all live there. CLAUDE.md is *descriptive*; the DB is *authoritative*.
110
110
  - **For *why we chose what we chose*** — go to [`docs/adr/`](../adr/) (Architecture Decision Records). Each ADR is one decision with the trade-offs that drove it.
111
111
 
112
112
  Other depth, in roughly the order you'll need it:
113
113
 
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
114
+ - [`docs/onboarding/example-and-karma.md`](drachmae-and-karma.md) — the full reward economy: how example and karma are earned, the cost-plus session reward, and the monthly budget cap
115
+ - [`docs/onboarding/slash-commands.md`](slash-commands.md) — which slash commands ship with Claude Code and which are this project's, and what to do about the ones that collide
115
116
  - [`docs/architecture.md`](../architecture.md) — live system: droplet, stack, schema, API surface
116
117
  - [`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
118
  - [`docs/canonical-permissions.md`](../canonical-permissions.md) — who can do what (rank gates)
@@ -169,9 +170,9 @@ Take them in order — each one sets up the next, from "I'm admitted" to "I'm lo
169
170
 
170
171
  Once it finishes, that folder **is** the project. **One catch worth knowing:** the `/builder-*` commands came down *with* the code, but Claude Code only loads them when a session *starts* on a folder that already contains them — and this session started on an *empty* folder. So before the next step, **start a fresh Claude Code session on this same folder**: end this session and open a new one pointing at the folder. (Starting fresh is the clean way — the new session scans the folder from scratch, and the `/builder-*` commands will all be there.)
171
172
 
172
- **4. Enrol yourself and begin.** In the **fresh** session, type `/builder-setup` — or just say *"set up builder"* in plain English — and follow the prompts. It signs you in with GitHub once and registers you in the GDS so the commands know who you are. Then type `/builder-start` to see the works you can claim right now.
173
+ **4. Enrol yourself and begin.** In the **fresh** session, type `/builder-setup` — or just say *"set up builder"* in plain English — and follow the prompts. It signs you in with GitHub once and registers you in Bongos so the commands know who you are. Then type `/builder-start` to see the works you can claim right now.
173
174
 
174
- If a `/builder-*` command ever says "no GDS session," just run `/builder-setup` again — that re-links you. And if `/builder-setup` itself comes back **"unknown command,"** you're almost certainly still in the session that did the cloning — start a fresh session on the folder (end of step 3) and it'll be there.
175
+ If a `/builder-*` command ever says "no Bongos session," just run `/builder-setup` again — that re-links you. And if `/builder-setup` itself comes back **"unknown command,"** you're almost certainly still in the session that did the cloning — start a fresh session on the folder (end of step 3) and it'll be there.
175
176
 
176
177
  > **Prefer a terminal? (the quicker path if you're technical.)** Steps 3–4 above are the no-terminal route. If you're comfortable on a command line, skip them — clone the repo yourself, `cd` into it, and run the bootstrap:
177
178
  >
@@ -0,0 +1,124 @@
1
+ # Slash commands: which are Claude's, which are this project's
2
+
3
+ *A reference page. Skim it once, come back when a command surprises you.*
4
+
5
+ When you type `/` in Claude Code you get one list, but the commands in it come from **two different places** and are maintained by two different people. Claude Code ships some of them; this project ships the rest. They look identical in the menu, which is why a few of them trip people up — see [Easy mix-ups](#easy-mix-ups) at the bottom.
6
+
7
+ ## The 10-second rule
8
+
9
+ | | **Claude Code's own** | **This project's** |
10
+ |---|---|---|
11
+ | Who ships it | Anthropic, inside the Claude Code app | This repository |
12
+ | Where it lives | Inside the app — nothing in this repo | [`.claude/skills/<name>/`](../../.claude/skills/) |
13
+ | What it acts on | Your *session* — context, model, config, account | The *build system* — tasks, claims, ships, ideas |
14
+ | Works in any repo? | Yes, everywhere | No — only in a folder that holds this code |
15
+ | Authoritative list | Type `/help` | The folder listing linked above |
16
+
17
+ **The short version:** if it changes your Claude session, it's Claude's. If it changes project state — a task, a claim, a ship — it's ours. If you can run it in an unrelated repo, it's Claude's.
18
+
19
+ > This is also why the commands "appear by magic" when you clone: they aren't a plugin or a download, they're files in `.claude/skills/` that Claude Code reads when a session **starts** on the folder. Clone mid-session and they won't show up until you start a fresh session — the wrinkle the [primer](primer.md) calls out in step 3.
20
+
21
+ ## This project's commands
22
+
23
+ Every one of these talks to the build system. They're grouped by when you'd reach for them, not alphabetically.
24
+
25
+ ### The work loop — the ones you'll use every session
26
+
27
+ | Command | What it does |
28
+ |---|---|
29
+ | `/builder-start` | List the tasks you can claim right now, filtered for parallel-safety |
30
+ | `/builder-claim N` | Lock task N to your session |
31
+ | `/builder-ship` | Grade, merge, and deploy your claimed task (credits land here) |
32
+ | `/builder-release` | Cancel a claim — the task returns to `ready`, no credits |
33
+ | `/builder-stage` | Preview your work-in-progress on your own sandbox before shipping |
34
+ | `/builder-end` | Close out the session safely — resolve the claim, seal the log |
35
+ | `/status` | Version / criterion progress — "what's left for C8?" |
36
+ | `/recall` | Search the docs + project knowledge before re-solving something |
37
+
38
+ ### Your account and your machine
39
+
40
+ | Command | What it does |
41
+ |---|---|
42
+ | `/builder-setup` | One-time enrolment — signs you in and registers you |
43
+ | `/builder-reauth` | Refresh an expired session |
44
+ | `/builder-key` | Check / set your own API key status |
45
+ | `/builder-box` | Your dev box control panel — wake, create, check cost |
46
+ | `/builder-connect` · `/builder-sync` · `/close-box` | Connect to, re-sync, and tear down that box |
47
+ | `/builder-cost` | Log a cost entry against your claim |
48
+ | `/builder-backup` | Check or trigger a database backup before risky work |
49
+ | `/builder-exit` | Offboard or reactivate a builder *(Archon only)* |
50
+
51
+ ### Triage and planning *(Metic and above)*
52
+
53
+ | Command | What it does |
54
+ |---|---|
55
+ | `/idea-triage` | Walk the idea inbox — promote, discard, or merge each |
56
+ | `/blocker-review` · `/blocker-solve` | Walk open blockers, or drive one to done |
57
+ | `/goal-create` | Plan and create one goal — scope wall, criteria, seed tasks |
58
+ | `/goal-review` | Confirm criteria that are flagged met-pending-review |
59
+ | `/planning-session` | Scope an upcoming version and seed its task list |
60
+ | `/priority-session` | Reweight the inbox from a few plain-speech answers |
61
+ | `/merge-mode` | Manual fallback when a confirmed task didn't land |
62
+
63
+ ### Discipline modes
64
+
65
+ `/dev` (engineering — the default loop), `/paint` (art), `/ideate` (ideation). A claimed task's discipline routes you to one of these.
66
+
67
+ ### Design and art pipeline
68
+
69
+ `/design-sync` and `/figma-design-sync` round-trip the UI design system. The `/otb-*` family — `otb-tile-generate`, `otb-design-review`, `otb-character-review`, `otb-feedback-capture`, `otb-figma-sync` — is the reference instance's pixel-art pipeline; it's only meaningful on an instance that runs that pipeline.
70
+
71
+ ### Session and meta
72
+
73
+ | Command | What it does |
74
+ |---|---|
75
+ | `/session-handoff` | Emit a paste-ready prompt to start a fresh session with |
76
+ | `/read-session-export` | Read a past session's `/export` zip |
77
+ | `/feedback` | Pull in the latest recorded walkthrough bundle |
78
+ | `/new-project` | Zero-to-live runbook for a brand-new instance |
79
+ | `/builder-redteam` | File a security / vulnerability report |
80
+
81
+ ## Claude Code's own commands
82
+
83
+ These work in **any** repository — they have nothing to do with this project. `/help` prints the live, authoritative list for your version; the ones below are simply the ones you'll actually meet.
84
+
85
+ | Command | What it does |
86
+ |---|---|
87
+ | `/help` | List every command available right now — **the authoritative list** |
88
+ | `/clear` · `/compact` | Wipe or condense the conversation context |
89
+ | `/model` · `/config` | Switch model; change app settings |
90
+ | `/login` · `/logout` | Sign in to your **Anthropic** account |
91
+ | `/init` | Write a `CLAUDE.md` for the current codebase |
92
+ | `/cost` · `/usage` · `/context` | Token spend, plan usage, context window |
93
+ | `/doctor` | Diagnose the **Claude Code install** |
94
+ | `/memory` | Edit Claude's memory files |
95
+ | `/mcp` · `/agents` · `/hooks` · `/permissions` | Configure MCP servers, subagents, hooks, tool permissions |
96
+ | `/export` · `/resume` · `/rewind` | Save the transcript; resume or roll back a session |
97
+ | `/review` | Review a GitHub pull request |
98
+ | `/status` | **Claude Code's** session/auth status — see the warning below |
99
+
100
+ ## Easy mix-ups
101
+
102
+ These are the ones that actually cause confusion.
103
+
104
+ **`/status` — the genuine collision.** Both sides define it. Claude Code's `/status` shows your session and auth state; this project's shows version and criterion progress. Which one wins depends on your Claude Code version and how it resolves the name. If you get the wrong one, say *"what's left for C8"* in plain English, or run `node scripts/gds/status.js` directly.
105
+
106
+ **`/login` is Anthropic, not us.** It signs you into your Claude account. To sign into a Cloud Bongos instance, use `bongos login <instance-url>`, or `/builder-setup` for a first-time enrolment.
107
+
108
+ **`/init` writes a `CLAUDE.md`.** It does *not* scaffold a new instance — that's `bongos init`, wrapped by `/new-project`. Running `/init` in this repo would overwrite the project's own `CLAUDE.md`.
109
+
110
+ **`/doctor` checks Claude Code.** For the build system's health — your session, toolchain, git plumbing, environment — run `node scripts/gds/doctor.js`.
111
+
112
+ **`/cost` is Claude's token spend.** To record a project cost against your claim, that's `/builder-cost`.
113
+
114
+ **`/export` vs `/read-session-export`.** Claude's `/export` *writes* a transcript zip; our `/read-session-export` *reads* one back.
115
+
116
+ **`/review` reviews a GitHub PR.** The project's review commands are `/goal-review`, `/blocker-review`, and `/idea-triage` — different jobs entirely.
117
+
118
+ ## Two more things worth knowing
119
+
120
+ **Every command has a plain-English twin.** Each skill lists trigger phrases, so *"what can I work on"* reaches `/builder-start` and *"ship it"* reaches `/builder-ship`. You never have to memorise the slash form.
121
+
122
+ **Same commands, outside Claude.** The work-loop commands are also a terminal CLI: `bongos start`, `bongos claim N`, `bongos ship`. Same actions, same API — usable from any terminal, a Chromebook, or CI. Run `bongos help` for the verb list.
123
+
124
+ **Rank gates are real.** Some commands above refuse below a certain rank — that's enforced by the server on every request, not by the presence of the file on your disk. See [`canonical-permissions.md`](../canonical-permissions.md).
@@ -138,6 +138,29 @@ These spend money and are intentionally manual.
138
138
  > **`box-drift-reconcile.timer` (task [#1289](https://example.com/builders#/task/1289)/[ADR 0071](../adr/<redacted>.md)) is the zombie backstop.** It runs `box.js reconcile-drift --apply` hourly, reading the live DO droplet list and repairing DO⇄DB drift both ways — force-deleting **zombie** droplets (running but no live box row claims them) and marking **ghost** rows destroyed (droplet gone from DO). Reads the SAME `/etc/example/box.env` (needs `DO_API_TOKEN` to enumerate droplets). Without it, the confirm-before-destroyed teardown still prevents *new* zombies, but a pre-existing one (or an out-of-band DO change) only heals on the next manual `reconcile-drift`. Confirm with `journalctl -u box-drift-reconcile.service`.
139
139
  > **Chromebook / browser terminal ([#760](https://example.com/builders#/task/760)/[ADR 0038](../adr/<redacted>.md), superseding the old `claude rc` pairing).** Research proved `claude rc` cannot run headless, so the box instead serves its OWN browser terminal — **ttyd** (127.0.0.1:7681, per-box basic-auth, drops into `/workspace`) exposed over an outbound-only **Cloudflare Tunnel** — where the builder runs normal interactive `claude`. A browser/Chromebook builder gets the URL + credential from `GET /api/gds/box/terminal` after their box is active — no SSH needed. The terminal/cloudflared units are inlined in cloud-init and start at first boot ([#774](https://example.com/builders#/task/774)). The deleted RC bits (`claude-rc.service`, `box-report-pairing.sh`, `/box/pairing(-link)`) are gone.
140
140
 
141
+ ## Cloudflare token: the edge cookie-strip rule (ADR 0053 / SR#11)
142
+
143
+ `provision` applies two zone **rulesets** best-effort: the **cookie-strip Transform Rule** (removes the `Cookie` request header on `term-*`/`sandbox-*`, so the apex session cookie never rides the tunnel onto a box — a host outside the trust boundary) and the **sandbox cache-bypass Cache Rule**. Both need scopes beyond Tunnel + DNS, and a token that lacks them fails **silently** — the box provisions fine and the security control simply isn't there.
144
+
145
+ Since task 1002511, `box.js provision` **read-probes** the ruleset phase before spending a cent (dry-run included) and prints a `⚠⚠ SECURITY` block naming the fix. Read the probe honestly: it is a `GET`, so it can only prove the scope is **missing** (401/403). A readable phase means *readable* — edit scope is not proven until the rule PUT actually runs, which is why the summary line after `✓ named tunnel ready` is the authoritative signal.
146
+
147
+ **Fix — widen the token** (account owner only):
148
+
149
+ > CF dashboard → **My Profile → API Tokens** → edit the token used as `CLOUDFLARE_API_TOKEN` → **Permissions** → add **Zone → Transform Rules → Edit** and **Zone → Cache Rules → Edit** → **Zone Resources → Include → Specific zone → `<your apex zone>`** → Continue → Save. Then re-run `node scripts/gds/box.js provision <login> --apply`.
150
+
151
+ **Fallback — apply the rule by hand** (no token change; do it once per zone):
152
+
153
+ > CF dashboard → the zone → **Rules → Transform Rules → Modify Request Header** → Create rule. Custom filter expression: `starts_with(http.host, "term-") or starts_with(http.host, "sandbox-")` (the exported `COOKIE_STRIP_EXPRESSION`). Action: **Remove** header `Cookie` (phase `http_request_late_transform`). Deploy. Give it the same description the code uses (`COOKIE_STRIP_RULE_DESC`) so a later widened-token run recognises and replaces it instead of adding a duplicate.
154
+
155
+ **Verify:**
156
+
157
+ ```bash
158
+ node scripts/gds/box.js provision <login> # dry-run — prints the probe verdict, spends nothing
159
+ curl -sI https://term-<login>.<apex>/ -H 'Cookie: x=1' # from a box-facing check, confirm the origin sees no Cookie
160
+ ```
161
+
162
+ > `/user/tokens/verify` is **not** a valid check here — an IP-locked token answers "Invalid API Token" there even when it is valid (see the [#725](https://example.com/builders#/task/725) note above). Always probe the real operation.
163
+
141
164
  ## Boundaries (other ADR-0031 tasks)
142
165
 
143
166
  - **[#596](https://example.com/builders#/task/596)** (done) — the devcontainer (box-as-code) this provisions.
@@ -10,7 +10,10 @@ releases repo → a one-line config bump re-points the branded
10
10
  - **Source:** `devbox-app/` in the main (private) repo.
11
11
  - **CI:** `.github/workflows/build-devbox-app.yml` — builds on every push
12
12
  touching `devbox-app/**` (mac dmg arm64+x64 on macos-14, NSIS exe x64+arm64 on
13
- windows-latest) and uploads workflow artifacts. No publishing from CI.
13
+ windows-latest). **Only `main` keeps the artifacts** (3-day retention); a
14
+ `claude/**` run builds both platforms as a CI signal and uploads nothing —
15
+ ~500MB per run had filled the shared Actions storage cap and blocked uploads
16
+ repo-wide. No publishing from CI either way.
14
17
  - **Public releases repo:** named in `config/devbox-app.json`
15
18
  (`releases_repo`). Assets live on GitHub releases there; GitHub's CDN
16
19
  serves the downloads, $0.
@@ -43,13 +46,20 @@ releases repo → a one-line config bump re-points the branded
43
46
 
44
47
  1. Bump `devbox-app/package.json` version (e.g. `1.1.0`) and regenerate
45
48
  icons only if they changed (`npm run icons`).
46
- 2. Push the branch; wait for `build-devbox-app` to go green.
47
- 3. Download the artifacts:
49
+ 2. Land the bump on `main` through the normal GDS flow, then wait for
50
+ `build-devbox-app` to go green **on the `main` run** — that is the run that
51
+ carries the installers.
52
+ 3. Download the artifacts (they expire after 3 days — re-run the workflow on
53
+ `main` via `gh workflow run build-devbox-app.yml --ref main` if they aged out):
48
54
  ```
49
55
  gh run download -R example-owner/example -n devbox-app-mac -D /tmp/devbox-rel
50
56
  gh run download -R example-owner/example -n devbox-app-win -D /tmp/devbox-rel
51
57
  ```
52
- (or build the mac side locally: `cd devbox-app && npm run dist:mac`).
58
+ **These commands only work against a `main` run.** Pointing them at a
59
+ `claude/**` run fails with nothing to download — the upload steps are gated to
60
+ `refs/heads/main` (see §0). To get an installer out of an unmerged branch,
61
+ build it locally instead: `cd modules/dev-box/app && npm run dist:mac` (or
62
+ `npm run dist:win` on Windows).
53
63
  4. Publish to the public releases repo (tag = `v<version>`, must match what
54
64
  `src/devbox-downloads.js` composes):
55
65
  ```
@@ -35,6 +35,22 @@ npx bongos start
35
35
 
36
36
  That's it — `bongos claim <id>` / `bongos ship` now work, scoped to this instance.
37
37
 
38
+ ## If the instance isn't hosted yet — a freshly-created, LOCALHOST project
39
+
40
+ The steps above assume the instance is already **running** at a reachable origin. A project
41
+ straight out of the creation flow is different: its `config/branding.json` `publicOrigin`
42
+ is `http://localhost:<port>`, and **nothing is serving it yet** — so step 2's
43
+ `bongos login http://localhost:<port>` fails with `fetch failed`. That repo is configured
44
+ to run on *your own machine*; stand it up with one command instead:
45
+
46
+ ```bash
47
+ npm install
48
+ npx bongos dev # Postgres → createdb → migrate → server → sign-in, in one step
49
+ ```
50
+
51
+ Full guide: [`docs/recipes/local-dev.md`](local-dev.md) (ADR 0149). Prefer a cloud dev box
52
+ over running locally? Use `bongos box` + `bongos code`.
53
+
38
54
  ## Notes
39
55
 
40
56
  - **Sign in to the RIGHT instance.** `bongos login <url>` writes a per-instance session
@@ -0,0 +1,81 @@
1
+ # Run a project on your own machine — `bongos dev`
2
+
3
+ > The one-command path from a freshly-cloned **standalone instance repo** (one whose
4
+ > `config/branding.json` points at `http://localhost:<port>`) to a running, signed-in
5
+ > instance on your Mac. This is the local counterpart of `bongos onboard` (which
6
+ > stands an instance up in the **cloud**) — see [ADR 0149](../adr/<redacted>.md).
7
+
8
+ ## TL;DR
9
+
10
+ ```bash
11
+ gh repo clone <owner>/<project>
12
+ cd <project>
13
+ npm install
14
+ npx bongos dev
15
+ ```
16
+
17
+ `bongos dev` starts the database, creates this project's database, builds its tables,
18
+ launches the server on the port in `config/branding.json`, and signs you in. Re-running
19
+ it is safe (idempotent). Stop it with `bongos dev stop`.
20
+
21
+ ## Prerequisites (one-time, per machine)
22
+
23
+ - **Node.js ≥ 22** — `node --version`
24
+ - **PostgreSQL 16** — `psql --version`. Install on a Mac with Homebrew:
25
+ ```bash
26
+ brew install postgresql@16
27
+ brew services start postgresql@16 # bongos dev will also try to start it for you
28
+ ```
29
+ - macOS or Linux (migrations use `bash`). On **Windows**, use WSL, or the Docker path in
30
+ [`self-host.md`](self-host.md).
31
+
32
+ ## What `bongos dev` does (and why it's needed)
33
+
34
+ A cloned project ships the code but nothing *running*. The server reads its port from an
35
+ env var and **not** from branding, the migrator and the server default to **different**
36
+ database names, and node-pg defaults to a Linux socket that doesn't exist on a Mac — so a
37
+ by-hand standup is a six-step assembly with three silent mismatches. `bongos dev` does all
38
+ of it from one source of truth (your `config/branding.json`):
39
+
40
+ 1. Ensures Postgres is running (starts it if it isn't).
41
+ 2. Creates the project's database if it doesn't exist.
42
+ 3. Runs migrations to build/refresh the tables.
43
+ 4. Starts the server on the branding port (e.g. `http://localhost:3006`).
44
+ 5. Signs you in to this instance (`--no-login` to skip).
45
+
46
+ ## Commands
47
+
48
+ ```bash
49
+ npx bongos dev # stand it up (idempotent) + sign in
50
+ npx bongos dev status # is it running? what URL? is sign-in configured?
51
+ npx bongos dev stop # stop the background server this launched
52
+ npx bongos dev --foreground # run attached instead (Ctrl-C stops it)
53
+ npx bongos dev --no-login # stand it up but don't sign in
54
+ npx bongos dev --skip-migrate # skip the migration step (already migrated)
55
+ npx bongos dev --port 3011 --db my_scratch # override the port / database name
56
+ ```
57
+
58
+ The server runs in the **background but managed** — `bongos dev status`/`stop` always find
59
+ it, and a second `bongos dev` is a no-op if it's already up. (This is deliberate: an
60
+ *unmanaged* leftover server is how you end up accidentally signing a new project into an
61
+ old one's server.)
62
+
63
+ ## The one step that can need you: a GitHub OAuth App
64
+
65
+ Sign-in uses a GitHub OAuth App. If your machine already ran another Cloud Bongos instance,
66
+ the credentials are usually already present and `bongos dev` just works. If not, it prints
67
+ exact steps: create an OAuth App (Homepage `http://localhost:<port>`, callback
68
+ `http://localhost:<port>/api/gds/auth/web/callback`, tick **Enable Device Flow**), then save
69
+ the Client ID + secret to `~/.config/<configDir>/gds-github.json` as
70
+ `{ "client_id": "…", "client_secret": "…" }` and re-run `bongos dev`.
71
+
72
+ ## Notes
73
+
74
+ - **Sign in as the owner.** `config/branding.json`'s `firstAdmin` is the GitHub account
75
+ auto-seated as owner on first sign-in — `bongos dev` tells you which one.
76
+ - **Switching instances.** Signing in to a local project points your CLI session at it; to
77
+ go back to a hosted instance later, `bongos login https://<that-instance>`.
78
+ - **Multiple projects at once** each get their own database + port, so their `bongos dev`
79
+ servers don't collide.
80
+ - **Prefer the cloud?** `bongos box` + `bongos code` give you a remote dev box instead — no
81
+ local database or server to run.
@@ -147,11 +147,29 @@ Organized by topic, not chronology. New entries go in the matching section; crea
147
147
 
148
148
  ---
149
149
 
150
+ ## Windows / local dev (PowerShell)
151
+
152
+ ### PowerShell 5.1 turns a clean `node scripts/gds/*.js` exit into a false failure
153
+
154
+ - **Symptom:** Running `node scripts/gds/api.js GET /api/gds/me 2>&1` (or the same on `claim.js`/`ship.js`) inside a PowerShell 5.1 session reports failure — `$?` is `$false` and the stderr line surfaces as a `NativeCommandError` — even though node exited 0 and the JSON on stdout is exactly right.
155
+ - **Root cause:** `api.js` prints its status banner to stderr unconditionally, by design (stdout stays clean JSON for piping); `claim.js`/`ship.js` also write diagnostics to stderr during a normal run. PS 5.1 wraps any stderr output from a native command into an `ErrorRecord` once the two streams are merged with `2>&1`, and sets `$?` false regardless of the actual exit code.
156
+ - **Fix:** Never merge streams on these calls. Prefer `scripts/gds/api.ps1` (a thin wrapper that discards stderr and writes clean JSON to stdout, safe to pipe into `ConvertFrom-Json`), or call `node scripts/gds/api.js ...` plain, with no `2>&1`.
157
+ - **Why it bites:** The exit code and JSON body are both fine — only the redirection is wrong — so the failure looks like a real API error and wastes time chasing a phantom bug in the call itself.
158
+
159
+ ### `Out-File`/`>` writes a UTF-8 BOM that breaks `JSON.parse` on re-read
160
+
161
+ - **Symptom:** A JSON body file written from PowerShell (`... | Out-File body.json` or `... > body.json`) and then read back with `--body-file` fails to parse, or parses with an invisible extra character before the first key.
162
+ - **Root cause:** PowerShell's `Out-File`/`>` redirection default to UTF-8 **with a byte-order-mark**. `JSON.parse` does not strip a leading BOM, so the file's first byte is invisible garbage as far as the parser is concerned.
163
+ - **Fix:** Don't write CLI JSON body files with `Out-File`/`>`. Use the Write tool, or `[IO.File]::WriteAllText($path, $json, (New-Object Text.UTF8Encoding($false)))` (explicit no-BOM encoding). `scripts/gds/api.js`'s `--body-file` reader now also strips a leading BOM defensively, but the safest fix is to never write one.
164
+ - **Why it bites:** The file looks completely normal in an editor — the BOM is invisible — so the parse failure looks like a JSON syntax problem, not an encoding one.
165
+
166
+ ---
167
+
150
168
  ## GDS build pipeline
151
169
 
152
170
  ### Two deterministic routines run as in-process server timers, not external cron
153
171
 
154
- - **What:** `peer-vote-tally` (weekly) runs inside the always-on Node process via the autonomy module's poller `modules/autonomy/pollers/routine-timers.js` (ADR 0078 amendment, task 1382; carved into `modules/autonomy/` at BV1.R83) — no `claude -p`, no external cron, no token. The loader's `startModulePollers` starts it (on the game/droplet boot only); it reaches `tallyPeerVotes` through the doorway. It's a no-op anywhere the DB is unreachable (builder machines), so it only does work on the prod droplet.
172
+ - **What:** `peer-vote-tally` (weekly) runs inside the always-on Node process via the autonomy module's poller `modules/autonomy/pollers/routine-timers.js` (ADR 0078 amendment, task 1382; carved into `modules/autonomy/` at BV1.R83) — no `claude -p`, no external cron, no token. The loader's `startModulePollers` starts it from `src/platform-server.js` at boot (task 1002419 — before that fix the call site had been lost with the retired `server.js` and no module poller started at all); it reaches `tallyPeerVotes` through the doorway. It's a no-op anywhere the DB is unreachable (builder machines), so it only does work on the prod droplet.
155
173
  - **Disable / move it out-of-process:** set `ROUTINE_TIMERS_DISABLED=1` in `/etc/example/web-source.env` and restart. Also set it on any **second** always-on instance that shares the `example` DB so the tally can't double-fold (the `FOR UPDATE OF pv` row lock is the hard guard if you forget).
156
174
  - **Run it manually now:** `node scripts/gds/run-routine.js peer-vote-tally` (the dispatcher front door still works). The cadence is boot-anchored ("~90s after boot, then weekly"), not a wall-clock Monday job — frequent deploys re-anchor it, which is harmless (the tally is idempotent).
157
175
 
@@ -33,7 +33,7 @@ curl -sS -X PATCH -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: applicat
33
33
  -d '{"parallel_safe": true}' https://example.com/api/gds/tasks/<id>
34
34
  ```
35
35
 
36
- In parallel mode each worker stops at `confirmed` (credits land) and the runner lands the merges **one at a time** — concurrent merges to `main` are never allowed.
36
+ In parallel mode each worker stops at `confirmed` (verified, not yet paid — [ADR 0120](../adr/<redacted>.md) books credits at land) and the runner lands the merges **one at a time** — concurrent merges to `main` are never allowed. Credits land as each merge completes.
37
37
 
38
38
  ## Reading the morning report
39
39
 
@@ -26,12 +26,25 @@ Every file is **redacted** through the same fail-closed pipeline the public mirr
26
26
  bongos package-core # from HEAD, version = platform CORE_VERSION
27
27
  bongos package-core --ref origin/main --version 1.13.0
28
28
  node scripts/gds/package-core.js --droplet-ip <ip> # add the prod IP as an exact gate literal
29
+ bongos package-core --self-verify # after building, prove the artifact reproduces its pin
30
+ bongos package-core --self-verify --self-verify-boot # ALSO npm-install the .tgz + boot /healthz
29
31
  ```
30
32
 
31
33
  `--ref` chooses the source commit (default `HEAD`), `--out-dir` the output dir (default `dist`), `--version` overrides the stamped version. `stdout` carries a one-line JSON pin (`{ core_version, source_commit, tree_sha256, tarball }`) for CI/scripts to capture; human detail goes to `stderr`.
32
34
 
35
+ `--self-verify` (task [#1002218](https://example.com/builders#/task/1002218), audit H3) closes the produce-side of the integrity loop: after writing the artifact it **unpacks the built `.tgz` and recomputes `tree_sha256`, asserting it equals the manifest** (+ the on-disk `.tgz` bytes vs `tarball.sha256`) — proving the packager's own output reproduces its pin before it is trusted or published (a mismatch exits non-zero, ahead of the `--publish` leg). It is deterministic and network-free. Add `--self-verify-boot` to *also* `npm install` the tarball into a throwaway consumer and boot `/healthz` (reuses [`tests/consumer_layout_boot.mjs`](../../tests/consumer_layout_boot.mjs); needs npm/registry access — the deeper standing CI gate is task [#1002221](https://example.com/builders#/task/1002221)).
36
+
33
37
  If the no-leak gate fails, it names the file + the residual literal. Fix the redaction rules ([`scripts/gds/mirror-redact.js`](../../scripts/gds/mirror-redact.js)) or the manifest exclusions ([`scripts/gds/publish-manifest.js`](../../scripts/gds/publish-manifest.js)) and re-run — do not weaken the gate to force a pass.
34
38
 
39
+ **The neutral floor** (task [#1002217](https://example.com/builders#/task/1002217), audit H4). Because the trunk carries no `config/branding.json`, the *branding-derived* redaction would strip nothing — so `package-core.js` always injects a fixed **`PRIOR_INSTANCE_FLOOR`** (prior-instance tokens/owners) into the doc-redaction + no-leak gate. Published **docs** are de-branded against it and the gate **fails closed** if a floor literal survives, even with no branding.json. **Functional** files still ship verbatim (the R88 fix) and are instead surfaced by the non-fatal `[leak-scan]` (task 1002220). To retire a new prior-instance token, add it to `PRIOR_INSTANCE_FLOOR` (kept in `package-core.js`, never in `mirror-redact.js` — that file's self-leak invariant forbids hardcoded literals).
40
+
41
+ ## Prove it boots (the standing PROVE-PUBLISH gates)
42
+
43
+ Two standing gates keep "a published core boots clean from a bare install" honest (task [#1002221](https://example.com/builders#/task/1002221), audit H1/H2):
44
+
45
+ - **`node scripts/gds/run-unit-tests.js --integration`** — the integration-smoke gate. Runs the heavier integration set (longer per-test budget), including [`tests/consumer_layout_boot.mjs`](../../tests/consumer_layout_boot.mjs), which packages the core, `npm install`s the `.tgz`, and boots `/healthz` from the real consumer layout. Run it per release / on a schedule in an env that provides the services (network, and — for the deeper DB leg tracked as a follow-up — Postgres). The default `run-unit-tests.js` (no flag) stays the fast DB-free unit gate and *excludes* this set.
46
+ - **[`tests/pruned_lockfile_integrity.mjs`](../../tests/pruned_lockfile_integrity.mjs)** — a network-free unit guard (runs in the default gate every PR) that rebuilds the shipped pruned lockfile and asserts every registry package keeps a **well-formed, verbatim `integrity` hash**. This is the exact R88 regression (redaction once blanked those base64 hashes → `npm ci` could no longer verify) caught before a consumer's install ever fails.
47
+
35
48
  ## Consume + pin it (the R85 side)
36
49
 
37
50
  A downstream instance repo: