@bongos/core 1.18.3 → 1.18.19

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 (471) hide show
  1. package/.bongos-core.json +1576 -286
  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 +4 -2
  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 +6 -1
  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/0144-devbox-rehome-onto-cloudbongos-plane.md +41 -0
  27. package/docs/adr/0144-federated-single-logout-backchannel.md +42 -0
  28. package/docs/adr/0145-devbox-app-branding-driven-module.md +44 -0
  29. package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +62 -0
  30. package/docs/adr/0146-configurable-reward-mode-cost-plus-only.md +53 -0
  31. package/docs/adr/0147-standalone-live-docs-regen.md +39 -0
  32. package/docs/adr/0148-task-scoped-box-source-access.md +48 -0
  33. package/docs/adr/0149-bongos-dev-local-launcher.md +57 -0
  34. package/docs/adr/0150-box-first-boot-bringup-vendored-instances.md +68 -0
  35. package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +229 -0
  36. package/docs/adr/0152-landing-gate-served-by-the-core-app.md +92 -0
  37. package/docs/adr/0152-metic-task-abandonment.md +67 -0
  38. package/docs/adr/0153-sequential-chain-runner.md +51 -0
  39. package/docs/adr/0154-goal-owner-criterion-authoring.md +86 -0
  40. package/docs/adr/README.md +10 -0
  41. package/docs/api/openapi.json +843 -17
  42. package/docs/api-reference.md +23 -10
  43. package/docs/architecture.md +4 -2
  44. package/docs/branding-contract.md +3 -1
  45. package/docs/canonical-permissions.md +21 -8
  46. package/docs/file-map.md +8 -0
  47. package/docs/onboarding/diagrams/01-task-lifecycle.mmd +2 -2
  48. package/docs/onboarding/diagrams/02-rank-ladder.mmd +3 -1
  49. package/docs/onboarding/diagrams/05-versioning.mmd +1 -3
  50. package/docs/onboarding/diagrams/assertions.json +4 -7
  51. package/docs/onboarding/drachmae-and-karma.md +3 -3
  52. package/docs/onboarding/primer.md +17 -16
  53. package/docs/onboarding/slash-commands.md +124 -0
  54. package/docs/recipes/builder-box-lifecycle.md +23 -0
  55. package/docs/recipes/devbox-app-release.md +14 -4
  56. package/docs/recipes/instance-first-run.md +16 -0
  57. package/docs/recipes/local-dev.md +81 -0
  58. package/docs/recipes/ops-gotchas.md +19 -1
  59. package/docs/recipes/overnight-builder.md +1 -1
  60. package/docs/recipes/parallel-goal-waves.md +174 -0
  61. package/docs/recipes/ship-and-regrade.md +2 -2
  62. package/docs/recipes/standalone-live-docs.md +48 -0
  63. package/docs/recipes/work-on-a-task-from-your-dev-box.md +108 -0
  64. package/migrations/003_pms.sql +6 -7
  65. package/migrations/006_pms_v2.sql +3 -31
  66. package/migrations/core_193_task_needs_rebase.sql +28 -0
  67. package/migrations/core_194_confirmed_backlog_clawback.sql +63 -0
  68. package/migrations/core_195_idea_triage_provenance.sql +57 -0
  69. package/migrations/core_196_session_reward_topup.sql +69 -0
  70. package/modules/autonomy/pollers/routine-timers.js +9 -8
  71. package/modules/builder-settings/wandering-prefs.js +61 -18
  72. package/modules/dev-box/app/README.md +73 -0
  73. package/modules/dev-box/app/assets/tray/mac-alertTemplate.png +0 -0
  74. package/modules/dev-box/app/assets/tray/mac-alertTemplate@2x.png +0 -0
  75. package/modules/dev-box/app/assets/tray/mac-busyTemplate.png +0 -0
  76. package/modules/dev-box/app/assets/tray/mac-busyTemplate@2x.png +0 -0
  77. package/modules/dev-box/app/assets/tray/mac-offTemplate.png +0 -0
  78. package/modules/dev-box/app/assets/tray/mac-offTemplate@2x.png +0 -0
  79. package/modules/dev-box/app/assets/tray/mac-onTemplate.png +0 -0
  80. package/modules/dev-box/app/assets/tray/mac-onTemplate@2x.png +0 -0
  81. package/modules/dev-box/app/assets/tray/win-alert.png +0 -0
  82. package/modules/dev-box/app/assets/tray/win-busy.png +0 -0
  83. package/modules/dev-box/app/assets/tray/win-off.png +0 -0
  84. package/modules/dev-box/app/assets/tray/win-on.png +0 -0
  85. package/modules/dev-box/app/build-resources/dmg-background.png +0 -0
  86. package/modules/dev-box/app/build-resources/dmg-background@2x.png +0 -0
  87. package/modules/dev-box/app/build-resources/icon.png +0 -0
  88. package/modules/dev-box/app/electron-builder.tmpl.yml +95 -0
  89. package/modules/dev-box/app/electron-builder.yml +95 -0
  90. package/modules/dev-box/app/package-lock.json +5291 -0
  91. package/modules/dev-box/app/package.json +30 -0
  92. package/modules/dev-box/app/renderer/app.js +319 -0
  93. package/modules/dev-box/app/renderer/index.html +45 -0
  94. package/modules/dev-box/app/renderer/styles.css +246 -0
  95. package/modules/dev-box/app/renderer/theme.generated.css +16 -0
  96. package/modules/dev-box/app/scripts/apply-dmg-backdrop.sh +82 -0
  97. package/modules/dev-box/app/scripts/dmgbuild-settings.py +39 -0
  98. package/modules/dev-box/app/scripts/gen-brand.js +138 -0
  99. package/modules/dev-box/app/scripts/gen-dmg-backdrop.py +323 -0
  100. package/modules/dev-box/app/scripts/gen-icons.js +286 -0
  101. package/modules/dev-box/app/scripts/vendor-client.js +23 -0
  102. package/modules/dev-box/app/src/box-controller.js +287 -0
  103. package/modules/dev-box/app/src/brand.generated.json +13 -0
  104. package/modules/dev-box/app/src/brand.js +16 -0
  105. package/modules/dev-box/app/src/config.js +19 -0
  106. package/modules/dev-box/app/src/gds-client.js +90 -0
  107. package/modules/dev-box/app/src/main.js +610 -0
  108. package/modules/dev-box/app/src/pairing.js +57 -0
  109. package/modules/dev-box/app/src/preload.js +29 -0
  110. package/modules/dev-box/app/src/session-store.js +58 -0
  111. package/modules/dev-box/app/src/ssh-setup.js +569 -0
  112. package/modules/dev-box/app/src/task-picker.js +70 -0
  113. package/modules/dev-box/app/src/tray.js +99 -0
  114. package/modules/dev-box/app/src/updater.js +55 -0
  115. package/modules/dev-box/app/src/vendor/bongos-client.cjs +698 -0
  116. package/modules/dev-box/app/test/unit.mjs +526 -0
  117. package/modules/dev-box/box-access.js +121 -4
  118. package/modules/dev-box/boxes.js +20 -0
  119. package/modules/dev-box/module.json +1 -1
  120. package/modules/dev-box/routes/box.js +87 -3
  121. package/modules/economy/credits.js +116 -25
  122. package/modules/economy/reward.js +8 -0
  123. package/modules/economy/streak.js +2 -1
  124. package/modules/governance/CLAUDE.md +15 -0
  125. package/modules/governance/catalog.js +419 -0
  126. package/modules/governance/config.js +174 -0
  127. package/modules/governance/db.js +125 -0
  128. package/modules/governance/migrations/governance_001_tables.sql +81 -0
  129. package/modules/governance/migrations/governance_002_seed_and_backfill.sql +103 -0
  130. package/modules/governance/migrations/governance_003_task_abandon_metic.sql +28 -0
  131. package/modules/governance/migrations/governance_004_criterion_create.sql +39 -0
  132. package/modules/governance/migrations/governance_005_resync_builder_rank_roles.sql +56 -0
  133. package/modules/governance/module.json +10 -0
  134. package/modules/governance/protected-surfaces.js +88 -0
  135. package/modules/governance/protected-surfaces.json +80 -0
  136. package/modules/governance/rank-roles.js +83 -0
  137. package/modules/governance/resolver.js +221 -0
  138. package/modules/governance/routes/governance.js +89 -0
  139. package/modules/governance/routes/role-sync.js +49 -0
  140. package/modules/governance/session-scopes.js +127 -0
  141. package/modules/governance/session-scopes.json +38 -0
  142. package/modules/hall-ui/public/atlas.css +117 -0
  143. package/modules/hall-ui/public/atlas.html +3 -114
  144. package/modules/hall-ui/public/brand-apply.js +34 -6
  145. package/modules/hall-ui/public/builders.js +187 -219
  146. package/modules/hall-ui/public/diagrams.html +2 -0
  147. package/modules/hall-ui/public/dom-utils.js +27 -0
  148. package/modules/hall-ui/public/drachmae.html +2 -0
  149. package/modules/hall-ui/public/drachmae.js +54 -1
  150. package/modules/hall-ui/public/gate.css +98 -0
  151. package/modules/hall-ui/public/gate.html +3 -95
  152. package/modules/hall-ui/public/goal-inbox.js +4 -1
  153. package/modules/hall-ui/public/goals-page.js +626 -114
  154. package/modules/hall-ui/public/goals.css +79 -1
  155. package/modules/hall-ui/public/goals.html +38 -11
  156. package/modules/hall-ui/public/hall-widgets.js +62 -52
  157. package/modules/hall-ui/public/harbor.css +123 -0
  158. package/modules/hall-ui/public/harbor.html +3 -120
  159. package/modules/hall-ui/public/index.html +11 -4
  160. package/modules/hall-ui/public/instances-panel.js +4 -1
  161. package/modules/hall-ui/public/modules.css +63 -0
  162. package/modules/hall-ui/public/modules.html +3 -60
  163. package/modules/hall-ui/public/new-project-wizard.js +7 -3
  164. package/modules/hall-ui/public/not-ready.html +2 -0
  165. package/modules/hall-ui/public/pair.css +73 -0
  166. package/modules/hall-ui/public/pair.html +3 -70
  167. package/modules/hall-ui/public/palette.js +302 -0
  168. package/modules/hall-ui/public/primer.css +13 -0
  169. package/modules/hall-ui/public/primer.html +2 -0
  170. package/modules/hall-ui/public/profile.html +2 -0
  171. package/modules/hall-ui/public/ranks.html +2 -0
  172. package/modules/hall-ui/public/roadmap.css +179 -0
  173. package/modules/hall-ui/public/roadmap.html +9 -172
  174. package/modules/hall-ui/public/roadmap.js +329 -316
  175. package/modules/hall-ui/public/sessions.css +16 -0
  176. package/modules/hall-ui/public/sessions.html +3 -13
  177. package/modules/hall-ui/public/settings.html +2 -0
  178. package/modules/hall-ui/public/settings.js +4 -4
  179. package/modules/hall-ui/public/shell.js +143 -18
  180. package/modules/hall-ui/public/style.css +231 -39
  181. package/modules/hall-ui/public/task-detail.js +347 -26
  182. package/modules/hall-ui/public/task.html +6 -1
  183. package/modules/hall-ui/public/watch.html +2 -0
  184. package/modules/hall-ui/public/work.html +8 -6
  185. package/modules/hall-ui/public/work.js +1 -1
  186. package/modules/ideas/inbox.js +61 -11
  187. package/modules/ideas/routes/inbox.js +23 -0
  188. package/modules/lifecycle/claim-eligibility.js +72 -0
  189. package/modules/lifecycle/db.js +519 -139
  190. package/modules/lifecycle/done-when.js +18 -3
  191. package/modules/lifecycle/github-push.js +19 -2
  192. package/modules/lifecycle/goal-advisory.js +114 -0
  193. package/modules/lifecycle/goal-authz.js +62 -0
  194. package/modules/lifecycle/lifecycle.js +9 -0
  195. package/modules/lifecycle/publish-reconciler.js +109 -6
  196. package/modules/lifecycle/routes/claims.js +68 -23
  197. package/modules/lifecycle/routes/done-when.js +110 -15
  198. package/modules/lifecycle/routes/goals.js +8 -38
  199. package/modules/lifecycle/routes/tasks.js +38 -6
  200. package/modules/lifecycle/ship-card.js +6 -0
  201. package/modules/onboarding/onboarding-state.js +1 -1
  202. package/modules/platform-identity/CLAUDE.md +15 -0
  203. package/modules/platform-identity/hub-device.js +147 -0
  204. package/modules/platform-identity/hub-keys.js +151 -0
  205. package/modules/platform-identity/migrations/platform_identity_001_tables.sql +114 -0
  206. package/modules/platform-identity/migrations/platform_identity_002_client_origin_index.sql +18 -0
  207. package/modules/platform-identity/migrations/platform_identity_003_project_memberships.sql +42 -0
  208. package/modules/platform-identity/migrations/platform_identity_004_projects.sql +44 -0
  209. package/modules/platform-identity/migrations/platform_identity_005_builder_activity.sql +42 -0
  210. package/modules/platform-identity/module.json +18 -0
  211. package/modules/platform-identity/platform-identity.js +531 -0
  212. package/modules/platform-identity/pollers/code-sweep.js +43 -0
  213. package/modules/platform-identity/routes/my-projects.js +140 -0
  214. package/modules/platform-identity/routes/projects.js +107 -0
  215. package/modules/platform-identity/routes/scouting.js +35 -0
  216. package/modules/platform-identity/routes/sso.js +402 -0
  217. package/modules/platform-identity/tests/platform-identity.mjs +388 -0
  218. package/modules/platform-identity/ui/.gitkeep +0 -0
  219. package/modules/security/routes/reports.js +10 -0
  220. package/modules/sessions/db.js +166 -21
  221. package/modules/sessions/module.json +1 -1
  222. package/modules/sessions/pollers/session-reward-reconcile.js +78 -0
  223. package/modules/sessions/routes/sessions.js +33 -0
  224. package/package-lock.json +2 -2
  225. package/package.json +1 -1
  226. package/public-landing/assets/anim/idle/frame_00.webp +0 -0
  227. package/public-landing/assets/anim/idle/frame_01.webp +0 -0
  228. package/public-landing/assets/anim/idle/frame_02.webp +0 -0
  229. package/public-landing/assets/anim/idle/frame_03.webp +0 -0
  230. package/public-landing/assets/anim/idle/frame_04.webp +0 -0
  231. package/public-landing/assets/anim/idle/frame_05.webp +0 -0
  232. package/public-landing/assets/anim/idle/frame_06.webp +0 -0
  233. package/public-landing/assets/anim/idle/frame_07.webp +0 -0
  234. package/public-landing/assets/anim/idle/frame_08.webp +0 -0
  235. package/public-landing/assets/anim/idle/frame_09.webp +0 -0
  236. package/public-landing/assets/anim/idle/frame_10.webp +0 -0
  237. package/public-landing/assets/anim/idle/frame_11.webp +0 -0
  238. package/public-landing/assets/anim/idle/frame_12.webp +0 -0
  239. package/public-landing/assets/anim/idle/frame_13.webp +0 -0
  240. package/public-landing/assets/anim/idle/frame_14.webp +0 -0
  241. package/public-landing/assets/anim/idle/frame_15.webp +0 -0
  242. package/public-landing/assets/anim/idle/frame_16.webp +0 -0
  243. package/public-landing/assets/anim/idle/frame_17.webp +0 -0
  244. package/public-landing/assets/anim/idle/frame_18.webp +0 -0
  245. package/public-landing/assets/anim/idle/frame_19.webp +0 -0
  246. package/public-landing/assets/anim/idle/frame_20.webp +0 -0
  247. package/public-landing/assets/anim/idle/frame_21.webp +0 -0
  248. package/public-landing/assets/anim/idle/frame_22.webp +0 -0
  249. package/public-landing/assets/anim/idle/frame_23.webp +0 -0
  250. package/public-landing/assets/anim/idle/frame_24.webp +0 -0
  251. package/public-landing/assets/anim/idle/frame_25.webp +0 -0
  252. package/public-landing/assets/anim/idle/frame_26.webp +0 -0
  253. package/public-landing/assets/anim/idle/frame_27.webp +0 -0
  254. package/public-landing/assets/anim/idle/frame_28.webp +0 -0
  255. package/public-landing/assets/anim/idle/frame_29.webp +0 -0
  256. package/public-landing/assets/anim/idle/frame_30.webp +0 -0
  257. package/public-landing/assets/anim/idle/frame_31.webp +0 -0
  258. package/public-landing/assets/anim/idle/frame_32.webp +0 -0
  259. package/public-landing/assets/anim/idle/frame_33.webp +0 -0
  260. package/public-landing/assets/anim/idle/frame_34.webp +0 -0
  261. package/public-landing/assets/anim/idle/frame_35.webp +0 -0
  262. package/public-landing/assets/anim/idle/frame_36.webp +0 -0
  263. package/public-landing/assets/anim/idle/frame_37.webp +0 -0
  264. package/public-landing/assets/anim/idle/frame_38.webp +0 -0
  265. package/public-landing/assets/anim/idle/frame_39.webp +0 -0
  266. package/public-landing/assets/anim/idle/frame_40.webp +0 -0
  267. package/public-landing/assets/anim/idle/frame_41.webp +0 -0
  268. package/public-landing/assets/anim/idle/frame_42.webp +0 -0
  269. package/public-landing/assets/anim/idle/frame_43.webp +0 -0
  270. package/public-landing/create.html +51 -58
  271. package/public-landing/gate/README.md +137 -0
  272. package/public-landing/gate/dispmaps/bar.png +0 -0
  273. package/public-landing/gate/dispmaps/flat.png +0 -0
  274. package/public-landing/gate/dispmaps/key.png +0 -0
  275. package/public-landing/gate/index.html +587 -0
  276. package/public-landing/gate/previews/cloud-bongos.jpg +0 -0
  277. package/public-landing/gate/previews/off-the-boats.jpg +0 -0
  278. package/public-landing/gate/space.css +799 -0
  279. package/public-landing/gate/space.js +1826 -0
  280. package/public-landing/gate/sprites/enter.png +0 -0
  281. package/public-landing/gate/sprites/search.png +0 -0
  282. package/public-landing/gate/sprites/terminal-blank.png +0 -0
  283. package/public-landing/gate/sprites/tile.png +0 -0
  284. package/public-landing/world/assets/clouds/cloud-island-large.png +0 -0
  285. package/public-landing/world/assets/clouds/cloud-puff.png +0 -0
  286. package/public-landing/world/assets/creatures/creature-whale-cargo.png +0 -0
  287. package/public-landing/world/assets/creatures/creature-whale-glide.png +0 -0
  288. package/public-landing/world/assets/plates/plate-clouds-near.png +0 -0
  289. package/public-landing/world/assets/plates/scene-establishing.png +0 -0
  290. package/scripts/gds/abandon.js +6 -4
  291. package/scripts/gds/api.js +10 -5
  292. package/scripts/gds/api.ps1 +26 -0
  293. package/scripts/gds/api.sh +6 -0
  294. package/scripts/gds/audit-ships.js +7 -1
  295. package/scripts/gds/backfill-sessions.js +78 -18
  296. package/scripts/gds/backup.js +23 -1
  297. package/scripts/gds/box-connect-lib.js +124 -31
  298. package/scripts/gds/box-sync.js +66 -0
  299. package/scripts/gds/box.js +225 -53
  300. package/scripts/gds/cf-tunnel.js +145 -6
  301. package/scripts/gds/claim.js +34 -3
  302. package/scripts/gds/cli-lib.js +161 -27
  303. package/scripts/gds/code.js +6 -2
  304. package/scripts/gds/deploy-divergence.js +209 -0
  305. package/scripts/gds/dev-lib.js +309 -0
  306. package/scripts/gds/dev.js +322 -0
  307. package/scripts/gds/doctor.js +90 -61
  308. package/scripts/gds/fetch-art-key.js +1 -1
  309. package/scripts/gds/fetch-sound-prefs.js +2 -2
  310. package/scripts/gds/fitness.js +228 -12
  311. package/scripts/gds/gds-db-backup.service +16 -1
  312. package/scripts/gds/gds-db-offsite.service +9 -1
  313. package/scripts/gds/gen-api-client.js +1 -1
  314. package/scripts/gds/gen-api-docs.js +36 -14
  315. package/scripts/gds/gen-diagrams.js +45 -28
  316. package/scripts/gds/gen-file-map.js +2 -1
  317. package/scripts/gds/gen-freshness.js +32 -0
  318. package/scripts/gds/gen-repo-map.js +3 -2
  319. package/scripts/gds/gen-session-index.js +14 -5
  320. package/scripts/gds/hooks/pre-push.js +2 -2
  321. package/scripts/gds/init.js +60 -3
  322. package/scripts/gds/install-git-hooks.js +1 -1
  323. package/scripts/gds/key-card.js +15 -6
  324. package/scripts/gds/key-status.js +1 -1
  325. package/scripts/gds/linkify-refs.js +35 -9
  326. package/scripts/gds/login.js +16 -1
  327. package/scripts/gds/paste-token.js +7 -1
  328. package/scripts/gds/preflight.js +126 -0
  329. package/scripts/gds/provision.js +123 -12
  330. package/scripts/gds/publish-manifest.js +7 -1
  331. package/scripts/gds/reauth.js +7 -3
  332. package/scripts/gds/regen-instance-docs.js +47 -0
  333. package/scripts/gds/run-unit-tests.js +4 -2
  334. package/scripts/gds/seed-bongos-v1-seo-tasks.js +104 -0
  335. package/scripts/gds/seed-bv1-profiles-tasks.js +126 -0
  336. package/scripts/gds/sequence.js +425 -0
  337. package/scripts/gds/session-cost.js +10 -1
  338. package/scripts/gds/setup.js +31 -5
  339. package/scripts/gds/shell.js +5 -3
  340. package/scripts/gds/ship.js +319 -29
  341. package/scripts/gds/smoke-gds.js +139 -8
  342. package/scripts/gds/start.js +171 -22
  343. package/scripts/gds/status.js +1 -1
  344. package/scripts/gds/triage.js +10 -9
  345. package/scripts/gds/upgrade.js +124 -2
  346. package/scripts/migrate.sh +99 -14
  347. package/scripts/status-mirror-sync.js +114 -84
  348. package/src/bongos/api-errors.js +1 -0
  349. package/src/bongos/auth.js +447 -102
  350. package/src/bongos/db-kernel.js +27 -0
  351. package/src/bongos/db.js +39 -0
  352. package/src/bongos/module-scope-map.js +27 -1
  353. package/src/bongos/permission-path-check.js +136 -102
  354. package/src/bongos/repo-info.js +47 -11
  355. package/src/bongos/route-rank-check.js +429 -46
  356. package/src/bongos/routes/_helpers.js +12 -1
  357. package/src/bongos/routes/auth.js +219 -2
  358. package/src/bongos/routes/backup.js +58 -2
  359. package/src/bongos/routes/me.js +35 -1
  360. package/src/bongos/serve-internal.js +84 -15
  361. package/src/branding.js +32 -0
  362. package/src/instance-config.js +30 -0
  363. package/src/module-api.js +124 -1
  364. package/src/platform-server.js +86 -9
  365. package/tests/abandon_task.mjs +59 -3
  366. package/tests/api_cli_flags.mjs +53 -0
  367. package/tests/auth_page_gate.mjs +13 -0
  368. package/tests/backfill_sessions.mjs +127 -1
  369. package/tests/backup_cli.mjs +54 -0
  370. package/tests/bongos_box_connect.mjs +77 -0
  371. package/tests/box_access.mjs +130 -1
  372. package/tests/box_credential.mjs +125 -0
  373. package/tests/box_host_keys.mjs +24 -0
  374. package/tests/box_infra_resolve.mjs +149 -0
  375. package/tests/box_scope_session.mjs +6 -2
  376. package/tests/box_sync.mjs +55 -0
  377. package/tests/box_task_scope.mjs +99 -0
  378. package/tests/branding.mjs +12 -0
  379. package/tests/cf_ruleset_preflight.mjs +142 -0
  380. package/tests/cf_tunnel.mjs +37 -0
  381. package/tests/claim_gate_rebase.mjs +98 -0
  382. package/tests/clawback_confirmed_backlog.mjs +103 -0
  383. package/tests/cli_lib_formatters.mjs +20 -0
  384. package/tests/confirm_attribution.mjs +30 -46
  385. package/tests/credit_grant.mjs +198 -10
  386. package/tests/criterion_authoring_gate.mjs +272 -0
  387. package/tests/criterion_progress.mjs +33 -1
  388. package/tests/dev_lib.mjs +253 -0
  389. package/tests/devbox_artifact_gate.mjs +75 -0
  390. package/tests/devbox_dmg_backdrop.mjs +137 -0
  391. package/tests/devbox_icons.mjs +304 -0
  392. package/tests/devbox_installer_brand.mjs +232 -0
  393. package/tests/devbox_key_register.mjs +234 -0
  394. package/tests/docs_openapi_route.mjs +110 -0
  395. package/tests/doctor_hooks.mjs +141 -0
  396. package/tests/extract_json.mjs +140 -0
  397. package/tests/fitness.mjs +89 -0
  398. package/tests/gen_freshness.mjs +96 -0
  399. package/tests/goal_advisory.mjs +251 -0
  400. package/tests/goal_criterion_confirm_ui.mjs +269 -0
  401. package/tests/goal_routes.mjs +59 -4
  402. package/tests/goal_tier.mjs +12 -3
  403. package/tests/governance_catalog.mjs +129 -0
  404. package/tests/governance_claim_eligibility.mjs +262 -0
  405. package/tests/governance_config.mjs +187 -0
  406. package/tests/governance_ownership_scope.mjs +410 -0
  407. package/tests/governance_page_gates.mjs +324 -0
  408. package/tests/governance_parity.mjs +336 -0
  409. package/tests/governance_principals.mjs +232 -0
  410. package/tests/governance_protected_surfaces.mjs +208 -0
  411. package/tests/governance_require_permission.mjs +223 -0
  412. package/tests/governance_resolver.mjs +84 -0
  413. package/tests/governance_role_sync.mjs +231 -0
  414. package/tests/governance_seed.mjs +127 -0
  415. package/tests/governance_session_scope.mjs +434 -0
  416. package/tests/governance_vanilla_boot.mjs +203 -0
  417. package/tests/grade_attribution.mjs +7 -7
  418. package/tests/hall_audit.mjs +223 -0
  419. package/tests/hall_nav.mjs +191 -0
  420. package/tests/hall_palette.mjs +206 -0
  421. package/tests/hall_signout.mjs +124 -0
  422. package/tests/hook_user_agents.mjs +10 -0
  423. package/tests/idea_triage.mjs +162 -0
  424. package/tests/idp_device_exchange.mjs +93 -0
  425. package/tests/init.mjs +51 -0
  426. package/tests/instance_config.mjs +65 -0
  427. package/tests/instance_mismatch_guard.mjs +23 -6
  428. package/tests/instance_release_config.mjs +104 -0
  429. package/tests/linkify_refs.mjs +15 -2
  430. package/tests/migrate_root_resolution.mjs +124 -1
  431. package/tests/module_contributions.mjs +55 -0
  432. package/tests/module_loader.mjs +10 -5
  433. package/tests/module_scope_active_claims.mjs +94 -0
  434. package/tests/needs_rebase.mjs +92 -0
  435. package/tests/one_active_claim_per_session.mjs +76 -0
  436. package/tests/override_attribution.mjs +10 -8
  437. package/tests/override_request_ownership.mjs +8 -4
  438. package/tests/parse_cookie_decode.mjs +42 -0
  439. package/tests/pay_on_land.mjs +129 -0
  440. package/tests/platform_boot.mjs +100 -1
  441. package/tests/post_login_landing.mjs +42 -0
  442. package/tests/preflight_checks.mjs +72 -0
  443. package/tests/provision.mjs +132 -7
  444. package/tests/publish_branch_route.mjs +53 -0
  445. package/tests/publish_reconciler.mjs +187 -2
  446. package/tests/repo_info_binding.mjs +248 -0
  447. package/tests/reward_gate.mjs +11 -2
  448. package/tests/reward_mode_cost_plus_only.mjs +116 -0
  449. package/tests/reward_mode_surfacing.mjs +168 -0
  450. package/tests/route_permission_check.mjs +301 -0
  451. package/tests/route_rank_check.mjs +254 -12
  452. package/tests/route_validation.mjs +30 -0
  453. package/tests/sequence.mjs +267 -0
  454. package/tests/session_digest.mjs +44 -0
  455. package/tests/session_index.mjs +18 -6
  456. package/tests/session_records.mjs +39 -1
  457. package/tests/session_reward_on_land.mjs +381 -0
  458. package/tests/session_reward_reconcile.mjs +229 -0
  459. package/tests/ship_api_client_pathspec.mjs +100 -0
  460. package/tests/ship_base_flag.mjs +93 -0
  461. package/tests/ship_ci_deploy.mjs +80 -3
  462. package/tests/ship_upstream_deletion.mjs +57 -0
  463. package/tests/smoke_target.mjs +233 -0
  464. package/tests/start_env_guard.mjs +87 -0
  465. package/tests/start_rebase_warning.mjs +103 -0
  466. package/tests/status_mirror_sync.mjs +122 -0
  467. package/tests/stop_refcheck.mjs +19 -1
  468. package/tests/task_goal_link.mjs +15 -6
  469. package/tests/upgrade.mjs +139 -0
  470. package/tests/web_admission_status.mjs +162 -0
  471. package/tests/write_validation_gaps.mjs +110 -0
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: planning-session
3
- description: Run a structured planning session for an upcoming GDS version — set scope criteria, brainstorm tasks, rank them, and upload everything to the GDS in one atomic shot. Triggers when the user says "/planning-session", "open a planning session", "let's plan V[N]", "plan the next version", or "scope a new version". Metic+ rank only (Metic and Archon; not Xenos).
3
+ description: Run a structured planning session for an upcoming GDS version — set scope criteria, draft a written spec, interview the owner in depth to resolve every non-obvious decision, then seed the ranked task list from that spec. Triggers when the user says "/planning-session", "open a planning session", "let's plan V[N]", "plan the next version", or "scope a new version". Metic+ rank only (Metic and Archon; not Xenos).
4
4
  ---
5
5
 
6
- You are running a planning session for the Game Development System (GDS). The goal is to leave the session with: (a) a clear set of done-when criteria for a version, (b) a ranked task list that lives in the GDS database, and (c) a durable record of the session for the audit trail.
6
+ You are running a planning session for the Game Development System (GDS). The goal is to leave the session with: (a) a clear set of done-when criteria for a version, (b) a **written spec** (`docs/specs/<ver>-<goal-slug>.md`) that an in-depth interview refines until every non-obvious decision is resolved, (c) a ranked task list **seeded from that spec** that lives in the GDS database, and (d) a durable record of the session for the audit trail.
7
7
 
8
8
  The first planning session — V3 Planning Session #1, 2026-05-12 — is the template this skill encodes. See `docs/session-logs/<redacted>.md` for the precedent and `tasks/227` (V3.R00) for the meta-task pattern.
9
9
 
@@ -29,7 +29,7 @@ This mirrors GDS-V3 criterion C2 (`three-ranks-gate-everything`) and matches the
29
29
 
30
30
  1. Call `GET /api/gds/me` and read `builder.rank`. Compare case-insensitively (lowercase it before testing).
31
31
  2. **If `rank` is present and lowercases to `xenos`** → stop immediately. Tell the builder: *"Planning sessions set the scope-truth of a version — they're a Metic+ operation. You're currently Xenos. You can still **file** a criterion proposal or task idea via `POST /api/gds/inbox` (which lands in idea_inbox for an Archon to ratify at the next planning session); ask an Archon for promotion if you need to run sessions directly."* Do not pull state, do not present criteria, do not propose tasks.
32
- 3. **If `rank` lowercases to `metic`** → proceed in **Metic-mode**: run the five-phase structure below conversationally, but in Phase 5 write proposals to `idea_inbox` (kind=`criterion-proposal` for criteria, kind=`feature` for tasks) tagged with the target version. Archon ratifies at the next Archon-mode planning session. Do NOT write `done_when_criteria` rows or POST to `/tasks` directly — those are Archon writes.
32
+ 3. **If `rank` lowercases to `metic`** → proceed in **Metic-mode**: run the five-phase structure below conversationally, but in Phase 5 write proposals to `idea_inbox` (kind=`criterion-proposal` for criteria, kind=`feature` for tasks) tagged with the target version. Archon ratifies at the next Archon-mode planning session. Since [ADR 0090](../../../docs/adr/<redacted>.md) a Metic MAY `POST /tasks` directly, and since [ADR 0154](../../../docs/adr/<redacted>.md) a Metic MAY write a `done_when_criteria` row for a goal they own or manage. What still needs an Archon is a VERSION-level criterion (no `goal_id`), one in a goal you don't hold, and creating the version itself. The spec-draft (Phase 3) and the in-depth interview (Phase 4) run identically in Metic-mode — the only difference is the Phase-5 write (you file proposals, you don't seed tasks directly).
33
33
 
34
34
  **For each criterion proposal**, write `body_md` as a JSON object with this exact shape so the `POST /api/gds/inbox/:id/ratify` endpoint (V3.R31 / #252) can parse it cleanly:
35
35
 
@@ -107,6 +107,8 @@ Once criteria are agreed:
107
107
 
108
108
  ### Phase 2.5 — Goals (the module-scoped workspaces) — ADR 0086
109
109
 
110
+ > **Planning a SINGLE goal, not a whole version? Use [`/goal-create`](../goal-create/SKILL.md)** — same decisions (reuse-vs-new, scope wall, criteria, seed tasks), one sitting, no spec file and no migration.
111
+
110
112
  A **goal** is the tier between version and criteria: a shared, joinable, **module-scoped** workspace that several builders work inside (ADR 0086). A version is "done" when all its goals are achieved. Defining goals is now part of planning — it's how the version's criteria get grouped into workspaces with a **scope wall** that bounds what each goal's members may author.
111
113
 
112
114
  For the version being planned, **group the agreed criteria into goals**. For each goal decide, with the user:
@@ -114,8 +116,7 @@ For the version being planned, **group the agreed criteria into goals**. For eac
114
116
  - **Title** — the outcome the goal owns (often 1–3 criteria's worth).
115
117
  - **`scope_modules`** — the module **keys** (NOT file paths) whose files this goal's members may touch. **This is the wall, and it is set here and only here — never self-granted.** Keep it tight: the modules the goal's work actually needs. Widening later goes through an explicit request a trusted rank approves (`POST /goals/:id/scope`; Archon for a `protected` module) — BV1.R64.
116
118
  > **The valid key list is the source of truth in [`src/bongos/module-scope-map.js`](../../../src/bongos/module-scope-map.js) — read it, don't trust this list.** It exports `moduleKeys()` (all keys), `protectedModules()` / `isProtectedModule(key)` (which are PROTECTED), and `scopeForModule(key)` (a key's globs + `protected` flag). Each key maps to path-globs; `protected` is **derived** (the key's globs overlap the trust/ship-pipeline/migration/authz core), and a goal scoped to any protected key is **Archon-only** to create. The current roster (run `node -e "const m=require('./src/bongos/module-scope-map');console.log(m.moduleKeys().map(k=>k+(m.isProtectedModule(k)?' 🔒':'')).join('\n'))"` to print it live):
117
- > - `kernel` 🔒 · `lifecycle` 🔒 · `economy` · `grading` 🔒 · `memory` · `onboarding` 🔒 · `ideas` · `builder-settings` 🔒 · `sessions` · `autonomy` 🔒 · `security` · `hall-ui` · `status-ui` · `game` · `art-pipeline` · `discord` · `dev-box` 🔒
118
- > - 🔒 = **protected** (Archon-only goal creation + Archon-mediated join). The list above is a convenience snapshot of a *derived* result — if it disagrees with `module-scope-map.js`, the file wins; re-run the one-liner.
119
+ > - **No roster is written down here on purpose.** The previous snapshot went stale within a release (it still omitted a key that had been added), which is exactly the failure a "read it live" rule prevents. Run the one-liner above; `protected` is derived from glob overlap, so it changes when the globs change.
119
120
  - **No covering key? → file a module-map prep task FIRST.** Every `scope_modules` entry must be a real key from `moduleKeys()`. If a goal's planned work touches file paths that **no existing key covers** (e.g. a brand-new module dir, or code still fused under `src/bongos/` that isn't yet broken out as its own key), the scope wall cannot place that work. Do **not** invent a key. Instead, **add a prep task to this version** — `kind='refactor'`, scoped to `kernel` (the module that owns `module-scope-map.js`) — to extend `MODULE_GLOBS` so a key covers those paths, and make the dependent goal's tasks depend on it. Adding/editing a key is itself a `kernel`-scoped (Archon-gated) change, so flag it for Archon sign-off in this session.
120
121
  - **Join policy** — a normal-scope goal is **open-join** (any builder); a goal whose scope includes a **`protected`** module is **Archon-mediated** (a non-Archon can't self-join; an Archon admits Metic+ members). Creating a protected-scope goal is itself **Archon-only** — so flag those for Archon sign-off in this session.
121
122
  - **Optional seed tasks / lead** — any obvious first tasks, and who leads.
@@ -124,9 +125,9 @@ Present the goals as a short table (title · scope_modules · join policy · the
124
125
 
125
126
  > **Rescope is "previous or new" at the goal tier too.** If this version succeeds a prior one, you already decided in Phase 1 which prior goals carry forward — those become this version's goals (linked via `succeeded_by_goal_id`); the rest are net-new here.
126
127
 
127
- ### Phase 3 — Brainstorm
128
+ ### Phase 3 — Draft the spec (the brainstorm, written to a file)
128
129
 
129
- For each criterion, list every task that could serve it. Be thorough — the user will narrow. Include:
130
+ Do the full brainstorm below as thinking — but the **output is a written spec file**, not a numbered chat list for approval. For each criterion, list every task that could serve it. Be thorough — the Phase-4 interview will refine and prune. Include:
130
131
 
131
132
  - Existing tasks already queued for the version (you have them from Phase 1)
132
133
  - Open ideas tagged for the version that should be pulled in
@@ -147,13 +148,37 @@ Don't tunnel-vision. Surface lateral options the user might not have thought of:
147
148
 
148
149
  > **`touches[]` is an advisory hint, not a hard fence ([ADR 0049](../../../docs/adr/<redacted>.md)).** Parallel-safety is a *split contract*: for interactive single-human work, `git merge` is the authoritative collision detector and the claim-time overlap signal only warns; only the autonomous `--parallel` runner treats footprint overlap as a hard gate. So don't agonize over predicting every file at planning time — a rough blast-radius is enough, and a wrong prediction is no longer ship-blocking. (Step 7/8 — task [#882](https://example.com/builders#/task/882) — makes the per-task `touches` field optional and backfills it from the committed diff at ship.)
149
150
 
150
- Present the brainstorm **grouped by criterion, with every task numbered** (R## prefix or local numbering). Tags: `[E]` existing, `[I]` idea to pull, `[N]` net-new. Note totals per criterion and flag scope-tension points.
151
+ **Write the brainstorm to a spec file — do NOT present a numbered chat list for e/r/a approval (that step is replaced by the Phase-4 interview).** Write `docs/specs/<ver>-<goal-slug>.md` (create `docs/specs/` if absent; slug = the goal's title kebab-cased). This file is the working document for the rest of the session and is committed in Phase 5. Give it these sections:
152
+
153
+ - **Title + status line** — `# Spec — <goal title> (<ver>, goal <id>) · status: draft`.
154
+ - **Summary** — 2–4 sentences: what we're building and why (the goal's outcome).
155
+ - **Criteria (done-when)** — the goal's criteria verbatim by slug (C1, C2, …); every task links to one.
156
+ - **Design decisions & assumptions** — what we're committing to and why; note grounding from the codebase (existing modules/tables/routes to reuse). Starts from your best defaults; the Phase-4 interview fills and revises this.
157
+ - **Open questions (for the interview)** — the non-obvious decisions still unresolved, each with why-it-matters + the options you see. This is the raw material for Phase 4; empty it as answers land.
158
+ - **Task outline** — grouped by criterion (and phase, if phased), one row per task: `R## · kind · title · one-line done-when · deps:[R##] · criterion_ids:[Cn]`, tagged `[E]`/`[I]`/`[N]`. Mark **spikes** (needs-exploration) and **proofs** (the live demo per criterion).
159
+ - **Dependency graph & ranking** — filled in Phase 4 (topo order + priority tiers).
160
+ - **Out of scope** — what this goal explicitly does NOT do, so the interview and tasks stay bounded.
161
+
162
+ Tell the user the spec is written and where, then move straight to the interview — the spec is shaped THERE, not by chat edits here.
163
+
164
+ ### Phase 4 — Interview in depth, then finalize the spec
165
+
166
+ **This is the heart of the new flow — it replaces asking for task-by-task approval.** Read the spec you just wrote, then interview the owner with the **AskUserQuestion tool** to resolve every non-obvious decision before a single task is seeded.
151
167
 
152
- Ask the user to **edit (e), remove (r), or add (a) tasks BY NUMBER** per criterion. Format the prompt to make this explicit: "Reply per criterion with e/r/a + the task number — e.g. 'C1: e R03, r R07, a [task description]'".
168
+ **Run it as a loop, not a one-shot:**
153
169
 
154
- ### Phase 4 — Rank + dependencies
170
+ 1. From the spec's *Open questions* (plus anything the task outline leaves genuinely undecided), assemble a round of up to **4 questions** and ask them with AskUserQuestion. Put a recommended option first when you have a view; always leave room for "Other."
171
+ 2. Fold the answers into the spec's *Design decisions* (and adjust the task outline if an answer reshapes the work).
172
+ 3. Re-assess: are there still non-obvious, decision-changing questions? If yes, ask another round. **Keep going until nothing material is left** — you should be able to seed every task without guessing. Then stop.
173
+ 4. The owner can end the interview early at any time ("that's enough / seed it"). Tell them this up front.
155
174
 
156
- Once the task list is approved, rank everything AND wire dependencies.
175
+ **Ask only NON-OBVIOUS questions.** A question earns its place only if: the spec is genuinely underspecified on it, reasonable experts would disagree, AND the answer changes what gets built or how it's broken into tasks. Span dimensions across rounds — **data model & schema, API surface & contracts, UI/UX & information architecture, permissions/authz, privacy/consent, performance & scale, failure modes & edge cases, migration/rollout/backfill, naming the user will see, and scope boundaries.**
176
+
177
+ **Do NOT ask** anything answerable by reading the codebase, anything the criteria already settle, yes/no rubber-stamps, or "do you want it to be good?" filler. If you catch yourself about to ask something with one obvious answer, decide it yourself and record it in *Design decisions* instead.
178
+
179
+ > **This interview is the deliberate exception to the usual "decide implementation details yourself" default (see Tone, and CLAUDE.md §2).** The owner has explicitly asked to be consulted in depth here — so probe technical implementation, UX, tradeoffs, and concerns, not just outcomes.
180
+
181
+ When the interview is complete, **rewrite the spec to the same file with `status: final`** — *Open questions* emptied into *Design decisions*, and the task outline updated. Then rank + wire dependencies and record them in the spec's *Dependency graph & ranking* section:
157
182
 
158
183
  **The system has two ordering signals — use both:**
159
184
 
@@ -184,7 +209,7 @@ Confirm what the `priority` column actually allows.
184
209
 
185
210
  The fine-grained N-deep rank lives in the title prefix: `V<ver>.R##` zero-padded so alphabetical sort returns ranking order within a priority bucket.
186
211
 
187
- Initial ranking: produce it yourself based on dependencies and what the user has stated as priority (e.g., "onboard builder #2 early"). Present in tiers. Ask the user to reorder, defer, or pull forward.
212
+ Initial ranking: produce it yourself based on dependencies and what the user stated during the interview (e.g., "onboard builder #2 early"). Record the tiers in the spec's ranking section; the interview already surfaced the user's priority calls, so don't re-litigate — just reflect them.
188
213
 
189
214
  **Critical-path sequencing notes** to surface: which tasks gate which (architecture spikes gate the rest of their criterion; rename should be first; smoke tests should be last in their tier).
190
215
 
@@ -199,9 +224,9 @@ This is what the V3.R02 (task 309) dependency system encodes; Phase 5 writes bot
199
224
 
200
225
  ### Phase 5 — Land it
201
226
 
202
- Once ranking is agreed, do the writes in this exact order:
227
+ Once the spec is finalized (Phase 4), **read `docs/specs/<ver>-<goal-slug>.md` as the source of truth** and do the writes in this exact order. (If the goal and its criteria already exist — e.g. this session planned tasks for a pre-existing goal — skip the goal/criteria creation in step 2 and seed the tasks under the existing goal, linking them via `criterion_ids` + `goal_id`.)
203
228
 
204
- 1. **Create a meta planning-session task** (`source_ref='<ver>-planning-N'`) that backs all the writes — version='<ver>', kind='decision', status='ready', priority=5, the full session described in its body. Claim it.
229
+ 1. **Create a meta planning-session task** (`source_ref='<ver>-planning-N'`) that backs all the writes — version='<ver>', kind='decision', status='ready', priority=5, the full session described in its body. Claim it. (For a long session — a big spec + a multi-round interview — create and claim this meta task **early, at Phase 1**, so the spec-write and interview are themselves covered by a claim. A rebase-gated builder can't claim new work; as Archon, proceed and record the session in the meta task even if the claim is blocked, noting it.)
205
230
 
206
231
  2. **Create the version's goals, then write the criteria migration.** Goals come first (ADR 0086) so the criteria can be parented under them:
207
232
  - **Goals** (via API — `POST /goals`; Archon-only when the scope includes a `protected` module). One per goal from Phase 2.5; **capture each returned goal id**.
@@ -210,7 +235,7 @@ Once ranking is agreed, do the writes in this exact order:
210
235
  # carry-forward goal: add "succeeds_goal_id":<prior_goal_id>
211
236
  ```
212
237
  - **Criteria — the vector depends on whether the instance is LIVE ([ADR 0105](../../../docs/adr/<redacted>.md)):**
213
- - **On a RUNNING instance (the normal case — planning a new goal/version on prod):** create each criterion via the **`POST /api/gds/versions/:id/done-when`** API (Archon), passing `criterion_id` (a stable slug), `criterion_md`, `goal_id` (the goal from above), and optional `sort_order`. This is the ONLY vector that actually lands a NEW criterion on a live DB — a `done_when_criteria` INSERT in a CORE migration **fails the `selfhost-boot` gate** (scope-truth pollution), and one in `migrations/instance/` **silently no-ops on a normal deploy** (ADR 0105 applies instance seeds only under the owner opt-in `GDS_APPLY_INSTANCE_SEEDS=1`, a DR step). A duplicate `criterion_id` returns 409 — treat as "already seeded."
238
+ - **On a RUNNING instance (the normal case — planning a new goal/version on prod):** create each criterion via the **`POST /api/gds/versions/:id/done-when`** API (**Metic+ for a goal you own or manage — [ADR 0154](../../../docs/adr/<redacted>.md); Archon for a version-level criterion, someone else's goal, or a shipped/frozen version**), passing `criterion_id` (a stable slug), `criterion_md`, `goal_id` (the goal from above), and optional `sort_order`. This is the ONLY vector that actually lands a NEW criterion on a live DB — a `done_when_criteria` INSERT in a CORE migration **fails the `selfhost-boot` gate** (scope-truth pollution), and one in `migrations/instance/` **silently no-ops on a normal deploy** (ADR 0105 applies instance seeds only under the owner opt-in `GDS_APPLY_INSTANCE_SEEDS=1`, a DR step). A duplicate `criterion_id` returns 409 — treat as "already seeded."
214
239
  ```
215
240
  node scripts/gds/api.js POST /api/gds/versions/<ver>/done-when --body '{"criterion_id":"<slug>","criterion_md":"...","goal_id":<gid>}'
216
241
  ```
@@ -224,6 +249,8 @@ Once ranking is agreed, do the writes in this exact order:
224
249
  - **Pass `goal_id: <gid>` on each task** so it lands under its goal (not the version's default catch-all). `POST /tasks` now honors `goal_id` (validated to belong to the version); to move an already-created task, `PATCH /tasks/:id` with `{goal_id}` (task 1763). `criterion_ids` accepts a **slug** (the `criterion_id` you set above), a `"Cn"` position, or a numeric id — the slug is position-independent and cleanest.
225
250
  - A main() that POSTs each task **with its `criterion_ids`** (idempotent on `source_ref`; the criterion links are inserted at create, idempotent on `(task_id, criterion_id)`), PATCHes `idea_inbox` for promotions, and after all tasks exist, POSTs `task_dependencies` via `POST /tasks/:id/dependencies` (resolving each R## to the just-created task ID). Idempotent on `(task_id, depends_on_task_id)`. (Need to re-attribute an already-seeded task? `POST /tasks/:id/criteria` with `{criterion_ids:['Cn',...]}`; `DELETE /tasks/:id/criteria/:criterionId` to detach — both Metic+ ([ADR 0090](../../../docs/adr/<redacted>.md)), mirroring the dependency endpoints.)
226
251
 
252
+ > **Seeding contract — validated on goal 1000045 (2026-07-16):** proof-tasks use `kind='verify'` (a deliverable that IS a verification; can't be prematurely confirmed), spikes `kind='spike'`; `POST /tasks` accepts `criterion_ids` + `goal_id` inline and disciplines include `ui`; there is **no `promoted_idea_id`** field on `POST /tasks` — mark a promoted idea via `PATCH /inbox/:id`; **descoping a criterion has no API** (done-when is create/satisfy/unsatisfy only) — remove the row via a direct DB delete (`ssh … "sudo -u postgres psql -d <db> -c \"DELETE FROM done_when_criteria WHERE id=…\""`) under the meta-task claim, capturing the SQL in its notes; and a seed script **must throttle + honor `429` `retry_after`** (per-IP rate limit) — add a base delay between calls and back off on 429, or a large seed dies halfway. A completed reference seed: `scripts/gds/<redacted>.js`.
253
+
227
254
  4. **Apply the migration** (commit + push + deploy, or direct psql via SSH for hot-fix style).
228
255
 
229
256
  5. **Run the seed script.** Verify exit code 0; verify totals via `GET /api/gds/public/progress` and `GET /api/gds/versions/<ver>/done-when`.
@@ -262,7 +289,7 @@ Once ranking is agreed, do the writes in this exact order:
262
289
 
263
290
  If the query returns nothing, stay silent. Don't volunteer info about lower-priority spikes — the next planning session or `/idea-triage` walk will handle those at the right moment.
264
291
 
265
- 8. **Commit + push** the migration + seed script + any new skill files + the session-log entry.
292
+ 8. **Commit + push** the spec file (`docs/specs/<ver>-<goal-slug>.md`) + the migration + seed script + any new skill files + the session-log entry.
266
293
 
267
294
  9. **Ship the meta task** via `/builder-ship` with a clean value-summary.
268
295
 
@@ -284,11 +311,11 @@ Phase 5 writes use the same `POST /tasks`, `PATCH /inbox/:id` shape as `idea-tri
284
311
 
285
312
  ## Tone for the user
286
313
 
287
- Lars is the prompter (see CLAUDE.md §2). Frame criteria and tasks in terms of outcomes and player/builder experience, not implementation. When asking him questions, ask about *what changes when this is true*, not *how would we build it*. Decide implementation details yourself and present them for confirmation.
314
+ Lars is the prompter (see CLAUDE.md §2). Frame criteria and tasks in terms of outcomes and player/builder experience, not implementation. **Exception: the Phase-4 interview is deliberately in-depth** — there the owner has asked to be consulted on implementation, UX, tradeoffs, and concerns, so probe hard (non-obvious questions only). Outside that interview, keep the default: decide implementation details yourself and present them for confirmation.
288
315
 
289
316
  When the user pushes back ("criteria 4/5/6 are weak"), take it seriously and rewrite. Strong outcome criteria are the hard part — the rest of the session is downstream of them.
290
317
 
291
- When the user says "I am ready to rank" or "produce the initial ranking," do it in one shot. Don't bounce back with more clarification questions unless something genuinely ambiguous needs resolving.
318
+ When the user ends the interview ("that's enough" / "seed it"), finalize the spec and seed in one shot — don't re-open settled questions or bounce back for more approval.
292
319
 
293
320
  ## After the session — improvements pass
294
321
 
@@ -20,9 +20,10 @@
20
20
  GOOGLE_AI_STUDIO_KEY=
21
21
 
22
22
  # --- GDS CLI ------------------------------------------------------------------
23
- # Where the /builder-* CLI talks to. Defaults to production when unset; only
24
- # override if you're running the server locally.
25
- # GDS_API_BASE=http://localhost:3000
23
+ # The /builder-* CLI base is NOT read from this file. It resolves (in order):
24
+ # 1. the <PREFIX>_API_BASE env var on the command (e.g. CLOUDBONGOS_API_BASE=https://…)
25
+ # 2. the signed-in session's api_base (set once by `bongos login <instance-url>`)
26
+ # 3. the instance's own branding (config/branding.json → branding.neutral.json)
26
27
 
27
28
  # --- GitHub OAuth (server only) -----------------------------------------------
28
29
  # Needed only if you are running the GDS server yourself (server.js) and want
package/README.md CHANGED
@@ -50,12 +50,14 @@ When it finishes, open Claude Code and run `/builder-start` to see what tasks ar
50
50
 
51
51
  We keep secrets (`.env` files, API keys, private keys) out of the repo with two layers. Both are **instance topology** — the git hook (`.husky/`) and CI (`.github/`) are provided when you stand up an instance and are not shipped in the portable core; the pattern below is the recommended posture:
52
52
 
53
- - **Pre-commit hook** (`.husky/pre-commit`) — scans your *staged* changes before each commit and aborts if it finds a secret. Activate it **once per clone**:
53
+ - **Pre-commit hook** (`.husky/pre-commit`) — scans your *staged* changes before each commit and aborts if it finds a secret. On an instance that ships `.husky/`, activate it **once per clone**:
54
54
 
55
55
  ```sh
56
- git config core.hooksPath .husky
56
+ node scripts/gds/install-git-hooks.js
57
57
  ```
58
58
 
59
+ Prefer that over setting `core.hooksPath` by hand: it no-ops cleanly on a checkout without a `.husky/` (the portable core), whereas pointing `core.hooksPath` at a directory that isn't there leaves git with a dangling hooks path and no gate. `node scripts/gds/doctor.js` reports which case you're in.
60
+
59
61
  It always runs a built-in guard (blocks `.env`, `*.pem`, credential files, obvious key patterns). If [TruffleHog](https://github.com/trufflesecurity/trufflehog) is installed (`brew install trufflehog` on macOS; `scoop install trufflehog` / `choco install trufflehog` or the GitHub release on Windows) it also runs a deep scan; if not, it warns and lets the commit through — CI is the real gate.
60
62
 
61
63
  > **Windows:** git runs the `.husky/pre-commit` hook through the Git-Bash `sh` bundled with Git for Windows, so the hook works if you installed Git for Windows (the usual case). If you don't have a `sh` available, the local hook silently no-ops — CI's full-history TruffleHog scan is then your only gate (and it always runs regardless of platform).
package/bin/bongos.js CHANGED
@@ -86,6 +86,7 @@ const VERBS = {
86
86
  code: { script: 'code.js', group: 'account', summary: 'Open VS Code on your dev box over Remote-SSH (--local for a local clone)' },
87
87
 
88
88
  init: { script: 'init.js', group: 'instance', summary: 'Scaffold a new instance (config + first version + kickoff tasks)' },
89
+ dev: { script: 'dev.js', group: 'instance', summary: 'Run THIS instance locally in one command (Postgres + migrate + server + sign-in)' },
89
90
  onboard: { script: 'onboard.js', group: 'instance', summary: 'Guided zero-to-live walkthrough: init → scaffold → provision → OAuth → verify → brand' },
90
91
  module: { script: 'module.js', group: 'instance', summary: 'Scaffold a new module (bongos module new <key>)' },
91
92
  upgrade: { script: 'upgrade.js', group: 'instance', summary: 'Pull the core to a new version (bump pin→install→migrate→materialize→restart); bare = module-compat pre-check' },
@@ -5,7 +5,7 @@ A **generated**, zero-dependency typed client for the Bongos API — produced fr
5
5
  by hand; it regenerates when the spec changes, so it can never drift from the routes.
6
6
 
7
7
  - API version: **v1** (served at `/api/bongos/v1`)
8
- - 230 operations across 40 resource groups
8
+ - 258 operations across 44 resource groups
9
9
 
10
10
  ## Install
11
11
 
@@ -19,7 +19,7 @@ npm install @bongos/client # internal registry / workspace path
19
19
  import { createClient, ApiError } from '@bongos/client';
20
20
 
21
21
  const api = createClient({
22
- baseUrl: 'https://example.com/api/bongos/v1', // or omit for same-origin (browser)
22
+ baseUrl: 'https://example.com/api/bongos/v1', // your instance origin — or omit for same-origin (browser)
23
23
  token: <redacted>, // Authorization: Bearer <token>
24
24
  });
25
25
 
@@ -115,8 +115,12 @@ function createClient(opts = {}) {
115
115
  postAuthAppPairPoll: (args) => request("POST", "/auth/app-pair/poll", { hasBody: true }, args),
116
116
  // POST /auth/app-pair/start — rank: public — POST /auth/app-pair/start
117
117
  postAuthAppPairStart: (args) => request("POST", "/auth/app-pair/start", { hasBody: true }, args),
118
+ // POST /auth/backchannel-logout — rank: public — POST /auth/backchannel-logout
119
+ postAuthBackchannelLogout: (args) => request("POST", "/auth/backchannel-logout", { hasBody: true }, args),
118
120
  // POST /auth/cli-token/issue — rank: any-builder — POST /auth/cli-token/issue
119
121
  postAuthCliTokenIssue: (args) => request("POST", "/auth/cli-token/issue", { hasBody: true }, args),
122
+ // POST /auth/device/exchange — rank: public — POST /auth/device/exchange
123
+ postAuthDeviceExchange: (args) => request("POST", "/auth/device/exchange", { hasBody: true }, args),
120
124
  // POST /auth/device/poll — rank: public — POST /auth/device/poll
121
125
  postAuthDevicePoll: (args) => request("POST", "/auth/device/poll", { hasBody: true }, args),
122
126
  // POST /auth/device/start — rank: public — POST /auth/device/start
@@ -133,6 +137,8 @@ function createClient(opts = {}) {
133
137
  postAuthRevoke: (args) => request("POST", "/auth/revoke", { hasBody: true }, args),
134
138
  // POST /auth/revoke-all — rank: archon — POST /auth/revoke-all
135
139
  postAuthRevokeAll: (args) => request("POST", "/auth/revoke-all", { hasBody: true }, args),
140
+ // GET /auth/web/admission-status — rank: public — GET /auth/web/admission-status
141
+ getAuthWebAdmissionStatus: (args) => request("GET", "/auth/web/admission-status", { hasBody: false }, args),
136
142
  // GET /auth/web/callback — rank: public — GET /auth/web/callback
137
143
  getAuthWebCallback: (args) => request("GET", "/auth/web/callback", { hasBody: false }, args),
138
144
  // GET /auth/web/start — rank: public — GET /auth/web/start
@@ -181,6 +187,8 @@ function createClient(opts = {}) {
181
187
  getBoxManagedSettings: (args) => request("GET", "/box/managed-settings", { hasBody: false }, args),
182
188
  // GET /box/me — rank: any-builder — GET /box/me
183
189
  getBoxMe: (args) => request("GET", "/box/me", { hasBody: false }, args),
190
+ // GET /box/scope — rank: any-builder — GET /box/scope
191
+ getBoxScope: (args) => request("GET", "/box/scope", { hasBody: false }, args),
184
192
  // GET /box/source-access — rank: any-builder — GET /box/source-access
185
193
  getBoxSourceAccess: (args) => request("GET", "/box/source-access", { hasBody: false }, args),
186
194
  // GET /box/ssh-key — rank: any-builder — GET /box/ssh-key
@@ -248,12 +256,6 @@ function createClient(opts = {}) {
248
256
  // POST /cost — rank: any-builder — POST /cost
249
257
  postCost: (args) => request("POST", "/cost", { hasBody: true }, args),
250
258
  },
251
- "demo": {
252
- // GET /demo/health — rank: public — GET /demo/health
253
- getDemoHealth: (args) => request("GET", "/demo/health", { hasBody: false }, args),
254
- // POST /demo/ping — rank: metic+archon — POST /demo/ping
255
- postDemoPing: (args) => request("POST", "/demo/ping", { hasBody: true }, args),
256
- },
257
259
  "dependencies": {
258
260
  // DELETE /dependencies — rank: archon — DELETE /dependencies
259
261
  deleteDependencies: (args) => request("DELETE", "/dependencies", { hasBody: false }, args),
@@ -280,6 +282,12 @@ function createClient(opts = {}) {
280
282
  // POST /gate-approvals/{pr}/approve — rank: archon — POST /gate-approvals/:pr/approve
281
283
  postGateApprovalsPrApprove: (args) => request("POST", "/gate-approvals/{pr}/approve", { hasBody: true }, args),
282
284
  },
285
+ "github": {
286
+ // GET /github/repos — rank: any-builder — GET /github/repos
287
+ getGithubRepos: (args) => request("GET", "/github/repos", { hasBody: false }, args),
288
+ // POST /github/repos — rank: any-builder — POST /github/repos
289
+ postGithubRepos: (args) => request("POST", "/github/repos", { hasBody: true }, args),
290
+ },
283
291
  "goals": {
284
292
  // GET /goals — rank: any-builder — GET /goals
285
293
  getGoals: (args) => request("GET", "/goals", { hasBody: false }, args),
@@ -347,6 +355,8 @@ function createClient(opts = {}) {
347
355
  getInboxId: (args) => request("GET", "/inbox/{id}", { hasBody: false }, args),
348
356
  // PATCH /inbox/{id} — rank: metic+archon — PATCH /inbox/:id
349
357
  patchInboxId: (args) => request("PATCH", "/inbox/{id}", { hasBody: true }, args),
358
+ // POST /inbox/{id}/ratify — rank: archon — POST /inbox/:id/ratify
359
+ postInboxIdRatify: (args) => request("POST", "/inbox/{id}/ratify", { hasBody: true }, args),
350
360
  },
351
361
  "instance": {
352
362
  // GET /instance — rank: public — GET /instance
@@ -379,16 +389,6 @@ function createClient(opts = {}) {
379
389
  getMeAchievements: (args) => request("GET", "/me/achievements", { hasBody: false }, args),
380
390
  // POST /me/anthropic-link — rank: any-builder — POST /me/anthropic-link
381
391
  postMeAnthropicLink: (args) => request("POST", "/me/anthropic-link", { hasBody: true }, args),
382
- // GET /me/art-key — rank: any-builder — GET /me/art-key
383
- getMeArtKey: (args) => request("GET", "/me/art-key", { hasBody: false }, args),
384
- // DELETE /me/art-key/own — rank: any-builder — DELETE /me/art-key/own
385
- deleteMeArtKeyOwn: (args) => request("DELETE", "/me/art-key/own", { hasBody: false }, args),
386
- // GET /me/art-key/own — rank: any-builder — GET /me/art-key/own
387
- getMeArtKeyOwn: (args) => request("GET", "/me/art-key/own", { hasBody: false }, args),
388
- // PUT /me/art-key/own — rank: any-builder — PUT /me/art-key/own
389
- putMeArtKeyOwn: (args) => request("PUT", "/me/art-key/own", { hasBody: true }, args),
390
- // POST /me/art-key/storage-init — rank: archon — POST /me/art-key/storage-init
391
- postMeArtKeyStorageInit: (args) => request("POST", "/me/art-key/storage-init", { hasBody: true }, args),
392
392
  // PATCH /me/disciplines — rank: any-builder — PATCH /me/disciplines
393
393
  patchMeDisciplines: (args) => request("PATCH", "/me/disciplines", { hasBody: true }, args),
394
394
  // GET /me/display-name — rank: any-builder — GET /me/display-name
@@ -433,6 +433,10 @@ function createClient(opts = {}) {
433
433
  getMemoryBfgBuildersBuilderIdFiles: (args) => request("GET", "/memory/bfg/builders/{builderId}/files", { hasBody: false }, args),
434
434
  // POST /memory/builders/{builderId}/bfg-write — rank: bfg-principal — POST /memory/builders/:builderId/bfg-write
435
435
  postMemoryBuildersBuilderIdBfgWrite: (args) => request("POST", "/memory/builders/{builderId}/bfg-write", { hasBody: true }, args),
436
+ // GET /memory/builders/{builderId}/file — rank: archon — GET /memory/builders/:builderId/file
437
+ getMemoryBuildersBuilderIdFile: (args) => request("GET", "/memory/builders/{builderId}/file", { hasBody: false }, args),
438
+ // GET /memory/builders/{builderId}/files — rank: archon — GET /memory/builders/:builderId/files
439
+ getMemoryBuildersBuilderIdFiles: (args) => request("GET", "/memory/builders/{builderId}/files", { hasBody: false }, args),
436
440
  // DELETE /memory/file — rank: any-builder — DELETE /memory/file
437
441
  deleteMemoryFile: (args) => request("DELETE", "/memory/file", { hasBody: true }, args),
438
442
  // GET /memory/file — rank: any-builder — GET /memory/file
@@ -452,12 +456,38 @@ function createClient(opts = {}) {
452
456
  // GET /modules/submissions — rank: metic+archon — GET /modules/submissions
453
457
  getModulesSubmissions: (args) => request("GET", "/modules/submissions", { hasBody: false }, args),
454
458
  },
459
+ "myProjects": {
460
+ // GET /my-projects — rank: any-builder — GET /my-projects
461
+ getMyProjects: (args) => request("GET", "/my-projects", { hasBody: false }, args),
462
+ // POST /my-projects/{clientId}/leave — rank: any-builder — POST /my-projects/:clientId/leave
463
+ postMyProjectsClientIdLeave: (args) => request("POST", "/my-projects/{clientId}/leave", { hasBody: true }, args),
464
+ // GET /my-projects/invites — rank: any-builder — GET /my-projects/invites
465
+ getMyProjectsInvites: (args) => request("GET", "/my-projects/invites", { hasBody: false }, args),
466
+ // POST /my-projects/invites/{clientId}/accept — rank: any-builder — POST /my-projects/invites/:clientId/accept
467
+ postMyProjectsInvitesClientIdAccept: (args) => request("POST", "/my-projects/invites/{clientId}/accept", { hasBody: true }, args),
468
+ // POST /my-projects/invites/{clientId}/decline — rank: any-builder — POST /my-projects/invites/:clientId/decline
469
+ postMyProjectsInvitesClientIdDecline: (args) => request("POST", "/my-projects/invites/{clientId}/decline", { hasBody: true }, args),
470
+ // POST /my-projects/join — rank: any-builder — POST /my-projects/join
471
+ postMyProjectsJoin: (args) => request("POST", "/my-projects/join", { hasBody: true }, args),
472
+ },
455
473
  "overrideRequests": {
456
474
  // GET /override-requests — rank: archon — GET /override-requests
457
475
  getOverrideRequests: (args) => request("GET", "/override-requests", { hasBody: false }, args),
458
476
  // POST /override-requests/{id}/decide — rank: archon — POST /override-requests/:id/decide
459
477
  postOverrideRequestsIdDecide: (args) => request("POST", "/override-requests/{id}/decide", { hasBody: true }, args),
460
478
  },
479
+ "projects": {
480
+ // GET /projects — rank: archon — GET /projects
481
+ getProjects: (args) => request("GET", "/projects", { hasBody: false }, args),
482
+ // POST /projects — rank: archon — POST /projects
483
+ postProjects: (args) => request("POST", "/projects", { hasBody: true }, args),
484
+ // PATCH /projects/{id}/featured — rank: archon — PATCH /projects/:id/featured
485
+ patchProjectsIdFeatured: (args) => request("PATCH", "/projects/{id}/featured", { hasBody: true }, args),
486
+ // GET /projects/featured — rank: public — GET /projects/featured
487
+ getProjectsFeatured: (args) => request("GET", "/projects/featured", { hasBody: false }, args),
488
+ // POST /projects/invite — rank: archon — POST /projects/invite
489
+ postProjectsInvite: (args) => request("POST", "/projects/invite", { hasBody: true }, args),
490
+ },
461
491
  "provisioning": {
462
492
  // GET /provisioning/fleet — rank: archon — GET /provisioning/fleet
463
493
  getProvisioningFleet: (args) => request("GET", "/provisioning/fleet", { hasBody: false }, args),
@@ -524,6 +554,10 @@ function createClient(opts = {}) {
524
554
  // GET /public/versions — rank: public — GET /public/versions
525
555
  getPublicVersions: (args) => request("GET", "/public/versions", { hasBody: false }, args),
526
556
  },
557
+ "scouting": {
558
+ // GET /scouting — rank: archon — GET /scouting
559
+ getScouting: (args) => request("GET", "/scouting", { hasBody: false }, args),
560
+ },
527
561
  "search": {
528
562
  // POST /search — rank: any-builder — POST /search
529
563
  postSearch: (args) => request("POST", "/search", { hasBody: true }, args),
@@ -531,12 +565,26 @@ function createClient(opts = {}) {
531
565
  postSearchMark: (args) => request("POST", "/search/mark", { hasBody: true }, args),
532
566
  },
533
567
  "security": {
568
+ // GET /security/adr — rank: metic+archon — GET /security/adr
569
+ getSecurityAdr: (args) => request("GET", "/security/adr", { hasBody: false }, args),
534
570
  // GET /security/docs — rank: archon — GET /security/docs
535
571
  getSecurityDocs: (args) => request("GET", "/security/docs", { hasBody: false }, args),
536
572
  // POST /security/docs — rank: archon — POST /security/docs
537
573
  postSecurityDocs: (args) => request("POST", "/security/docs", { hasBody: true }, args),
538
574
  // GET /security/docs/{slug} — rank: archon — GET /security/docs/:slug
539
575
  getSecurityDocsSlug: (args) => request("GET", "/security/docs/{slug}", { hasBody: false }, args),
576
+ // GET /security/reports — rank: archon — GET /security/reports
577
+ getSecurityReports: (args) => request("GET", "/security/reports", { hasBody: false }, args),
578
+ // POST /security/reports — rank: metic+archon — POST /security/reports
579
+ postSecurityReports: (args) => request("POST", "/security/reports", { hasBody: true }, args),
580
+ // POST /security/reports/{id}/confirm — rank: archon — POST /security/reports/:id/confirm
581
+ postSecurityReportsIdConfirm: (args) => request("POST", "/security/reports/{id}/confirm", { hasBody: true }, args),
582
+ // POST /security/reports/{id}/dispute — rank: archon — POST /security/reports/:id/dispute
583
+ postSecurityReportsIdDispute: (args) => request("POST", "/security/reports/{id}/dispute", { hasBody: true }, args),
584
+ // POST /security/reports/{id}/fix — rank: archon — POST /security/reports/:id/fix
585
+ postSecurityReportsIdFix: (args) => request("POST", "/security/reports/{id}/fix", { hasBody: true }, args),
586
+ // POST /security/reports/{id}/link-fix — rank: archon — POST /security/reports/:id/link-fix
587
+ postSecurityReportsIdLinkFix: (args) => request("POST", "/security/reports/{id}/link-fix", { hasBody: true }, args),
540
588
  },
541
589
  "session": {
542
590
  // POST /session/optimize — rank: any-builder — POST /session/optimize
@@ -552,6 +600,22 @@ function createClient(opts = {}) {
552
600
  // GET /sessions/search — rank: archon — GET /sessions/search
553
601
  getSessionsSearch: (args) => request("GET", "/sessions/search", { hasBody: false }, args),
554
602
  },
603
+ "sso": {
604
+ // POST /sso/activity/rollup — rank: public — POST /sso/activity/rollup
605
+ postSsoActivityRollup: (args) => request("POST", "/sso/activity/rollup", { hasBody: true }, args),
606
+ // GET /sso/authorize — rank: public — GET /sso/authorize
607
+ getSsoAuthorize: (args) => request("GET", "/sso/authorize", { hasBody: false }, args),
608
+ // POST /sso/device/poll — rank: public — POST /sso/device/poll
609
+ postSsoDevicePoll: (args) => request("POST", "/sso/device/poll", { hasBody: true }, args),
610
+ // POST /sso/device/start — rank: public — POST /sso/device/start
611
+ postSsoDeviceStart: (args) => request("POST", "/sso/device/start", { hasBody: true }, args),
612
+ // POST /sso/membership/check-in — rank: public — POST /sso/membership/check-in
613
+ postSsoMembershipCheckIn: (args) => request("POST", "/sso/membership/check-in", { hasBody: true }, args),
614
+ // GET /sso/pubkey — rank: public — GET /sso/pubkey
615
+ getSsoPubkey: (args) => request("GET", "/sso/pubkey", { hasBody: false }, args),
616
+ // POST /sso/token — rank: public — POST /sso/token
617
+ postSsoToken: (args) => request("POST", "/sso/token", { hasBody: true }, args),
618
+ },
555
619
  "tasks": {
556
620
  // GET /tasks — rank: any-builder — GET /tasks
557
621
  getTasks: (args) => request("GET", "/tasks", { hasBody: false }, args),
@@ -561,7 +625,7 @@ function createClient(opts = {}) {
561
625
  getTasksId: (args) => request("GET", "/tasks/{id}", { hasBody: false }, args),
562
626
  // PATCH /tasks/{id} — rank: metic+archon — PATCH /tasks/:id
563
627
  patchTasksId: (args) => request("PATCH", "/tasks/{id}", { hasBody: true }, args),
564
- // POST /tasks/{id}/abandon — rank: archon — POST /tasks/:id/abandon
628
+ // POST /tasks/{id}/abandon — rank: metic+archon — POST /tasks/:id/abandon
565
629
  postTasksIdAbandon: (args) => request("POST", "/tasks/{id}/abandon", { hasBody: true }, args),
566
630
  // POST /tasks/{id}/attest-gate — rank: any-builder — POST /tasks/:id/attest-gate
567
631
  postTasksIdAttestGate: (args) => request("POST", "/tasks/{id}/attest-gate", { hasBody: true }, args),
@@ -615,7 +679,7 @@ function createClient(opts = {}) {
615
679
  postVersions: (args) => request("POST", "/versions", { hasBody: true }, args),
616
680
  // GET /versions/{id}/done-when — rank: public — GET /versions/:id/done-when
617
681
  getVersionsIdDoneWhen: (args) => request("GET", "/versions/{id}/done-when", { hasBody: false }, args),
618
- // POST /versions/{id}/done-when — rank: archon — POST /versions/:id/done-when
682
+ // POST /versions/{id}/done-when — rank: metic+archon — POST /versions/:id/done-when
619
683
  postVersionsIdDoneWhen: (args) => request("POST", "/versions/{id}/done-when", { hasBody: true }, args),
620
684
  // GET /versions/{id}/progress — rank: public — GET /versions/:id/progress
621
685
  getVersionsIdProgress: (args) => request("GET", "/versions/{id}/progress", { hasBody: false }, args),