@bongos/core 1.17.0

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 (1142) hide show
  1. package/.bongos-core.json +5727 -0
  2. package/.claude/skills/blocker-review/SKILL.md +91 -0
  3. package/.claude/skills/blocker-solve/SKILL.md +96 -0
  4. package/.claude/skills/builder-backup/SKILL.md +54 -0
  5. package/.claude/skills/builder-box/SKILL.md +45 -0
  6. package/.claude/skills/builder-claim/SKILL.md +76 -0
  7. package/.claude/skills/builder-connect/SKILL.md +59 -0
  8. package/.claude/skills/builder-cost/SKILL.md +47 -0
  9. package/.claude/skills/builder-end/SKILL.md +81 -0
  10. package/.claude/skills/builder-exit/SKILL.md +88 -0
  11. package/.claude/skills/builder-key/SKILL.md +40 -0
  12. package/.claude/skills/builder-reauth/SKILL.md +50 -0
  13. package/.claude/skills/builder-redteam/SKILL.md +109 -0
  14. package/.claude/skills/builder-release/SKILL.md +41 -0
  15. package/.claude/skills/builder-setup/SKILL.md +62 -0
  16. package/.claude/skills/builder-ship/SKILL.md +79 -0
  17. package/.claude/skills/builder-stage/SKILL.md +51 -0
  18. package/.claude/skills/builder-start/SKILL.md +46 -0
  19. package/.claude/skills/close-box/SKILL.md +43 -0
  20. package/.claude/skills/design-sync/SKILL.md +69 -0
  21. package/.claude/skills/dev/SKILL.md +49 -0
  22. package/.claude/skills/feedback/SKILL.md +32 -0
  23. package/.claude/skills/figma-design-sync/SKILL.md +74 -0
  24. package/.claude/skills/goal-review/SKILL.md +89 -0
  25. package/.claude/skills/idea-triage/SKILL.md +144 -0
  26. package/.claude/skills/ideate/SKILL.md +82 -0
  27. package/.claude/skills/merge-mode/SKILL.md +169 -0
  28. package/.claude/skills/new-project/SKILL.md +108 -0
  29. package/.claude/skills/otb-character-review/SKILL.md +71 -0
  30. package/.claude/skills/otb-design-review/SKILL.md +47 -0
  31. package/.claude/skills/otb-feedback-capture/SKILL.md +45 -0
  32. package/.claude/skills/otb-figma-sync/SKILL.md +54 -0
  33. package/.claude/skills/otb-tile-generate/SKILL.md +45 -0
  34. package/.claude/skills/paint/SKILL.md +70 -0
  35. package/.claude/skills/planning-session/SKILL.md +299 -0
  36. package/.claude/skills/priority-session/SKILL.md +134 -0
  37. package/.claude/skills/read-session-export/SKILL.md +58 -0
  38. package/.claude/skills/recall/SKILL.md +52 -0
  39. package/.claude/skills/session-handoff/SKILL.md +46 -0
  40. package/.claude/skills/status/SKILL.md +33 -0
  41. package/.devcontainer/Dockerfile +69 -0
  42. package/.devcontainer/README.md +73 -0
  43. package/.devcontainer/devcontainer-lock.json +19 -0
  44. package/.devcontainer/devcontainer.json +93 -0
  45. package/.devcontainer/healthcheck.sh +84 -0
  46. package/.devcontainer/init-firewall.sh +198 -0
  47. package/.devcontainer/post-create.sh +153 -0
  48. package/.dockerignore +36 -0
  49. package/.env.local.example +32 -0
  50. package/.gitattributes +83 -0
  51. package/.gitignore +91 -0
  52. package/CLAUDE.md +242 -0
  53. package/CODE_OF_CONDUCT.md +46 -0
  54. package/CONTRIBUTING.md +51 -0
  55. package/Dockerfile +46 -0
  56. package/GOVERNANCE.md +44 -0
  57. package/LICENSE +661 -0
  58. package/README.md +88 -0
  59. package/bin/bongos.js +222 -0
  60. package/clients/bongos-client/README.md +48 -0
  61. package/clients/bongos-client/bongos-client.global.js +617 -0
  62. package/clients/bongos-client/examples/hello-world.mjs +62 -0
  63. package/clients/bongos-client/index.cjs +619 -0
  64. package/clients/bongos-client/index.d.ts +793 -0
  65. package/clients/bongos-client/index.mjs +614 -0
  66. package/clients/bongos-client/package.json +32 -0
  67. package/config/branding.neutral.json +60 -0
  68. package/config/design-tokens.neutral.json +51 -0
  69. package/config/design-tokens.schema.json +96 -0
  70. package/config/modules.neutral.json +9 -0
  71. package/docker-compose.yml +52 -0
  72. package/docker-entrypoint.sh +30 -0
  73. package/docs/adr/0001-stack-choice-single-vps.md +45 -0
  74. package/docs/adr/0002-digitalocean-over-hetzner.md +27 -0
  75. package/docs/adr/0003-cloudflare-origin-cert-over-letsencrypt.md +35 -0
  76. package/docs/adr/0004-amazonprimea-name-and-trademark-acceptance.md +45 -0
  77. package/docs/adr/0005-invisible-other-players-in-v1.md +37 -0
  78. package/docs/adr/0006-singleton-worldroom-plus-queueroom.md +30 -0
  79. package/docs/adr/0007-persistent-identity-via-localstorage-uuid.md +31 -0
  80. package/docs/adr/0008-family-based-tile-generation.md +86 -0
  81. package/docs/adr/0008-google-chat-oauth-user-auth.md +37 -0
  82. package/docs/adr/0009-autotile-architecture.md +181 -0
  83. package/docs/adr/0010-pms-architecture.md +70 -0
  84. package/docs/adr/0011-terrain-id-rendering-model.md +174 -0
  85. package/docs/adr/0012-ground-object-cell-split.md +208 -0
  86. package/docs/adr/0013-paths-as-object-overlays-with-autotile-dispatch.md +158 -0
  87. package/docs/adr/0014-families-canonical-over-vocabulary.md +103 -0
  88. package/docs/adr/0015-task-dependencies-and-auto-promotion.md +125 -0
  89. package/docs/adr/0016-trust-boundary-server-enforced-permissions.md +132 -0
  90. package/docs/adr/0017-code-simplification-and-repo-cleanliness.md +74 -0
  91. package/docs/adr/0018-three-rank-model-goes-live.md +97 -0
  92. package/docs/adr/0019-red-team-bounty-payout-table.md +52 -0
  93. package/docs/adr/0020-security-model-public-stub.md +70 -0
  94. package/docs/adr/0021-per-builder-skill-model-preferences.md +99 -0
  95. package/docs/adr/0022-secrets-policy.md +124 -0
  96. package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +118 -0
  97. package/docs/adr/0024-cloneable-repo-local-first-memory.md +277 -0
  98. package/docs/adr/0024-multi-agent-system-architecture.md +125 -0
  99. package/docs/adr/0025-offsite-backup-vendor-digitalocean-spaces.md +59 -0
  100. package/docs/adr/0025-structured-criterion-task-link.md +44 -0
  101. package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +117 -0
  102. package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +170 -0
  103. package/docs/adr/0028-honest-llm-spend-accounting.md +109 -0
  104. package/docs/adr/0029-status-page-outage-resilience.md +59 -0
  105. package/docs/adr/0030-builders-hall-live-updates.md +59 -0
  106. package/docs/adr/0031-cloud-dev-environments-for-builders.md +222 -0
  107. package/docs/adr/0032-discord-mirror-of-gds.md +50 -0
  108. package/docs/adr/0033-discord-bot-service-principal.md +82 -0
  109. package/docs/adr/0034-thetes-graduated-newcomer-rank.md +53 -0
  110. package/docs/adr/0035-builder-onboarding-three-paths.md +128 -0
  111. package/docs/adr/0036-builders-subdomain-and-ui-reorg.md +40 -0
  112. package/docs/adr/0037-discord-channel-management.md +51 -0
  113. package/docs/adr/0038-chromebook-ttyd-cloudflare-tunnel.md +111 -0
  114. package/docs/adr/0039-setup-first-onboarding-ux.md +49 -0
  115. package/docs/adr/0040-remote-control-default-browser-onramp.md +47 -0
  116. package/docs/adr/0041-temporary-grader-bypass-killswitch.md +40 -0
  117. package/docs/adr/0042-builder-self-deploy-ci-auto-merge.md +82 -0
  118. package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +74 -0
  119. package/docs/adr/0044-mediterranean-palette-replacement.md +73 -0
  120. package/docs/adr/0044-per-box-live-game-preview.md +57 -0
  121. package/docs/adr/0045-devbox-desktop-app.md +133 -0
  122. package/docs/adr/0046-sandbox-first-review-gate.md +72 -0
  123. package/docs/adr/0047-discord-bugs-intake-anti-abuse.md +36 -0
  124. package/docs/adr/0048-works-in-progress-ia-split.md +32 -0
  125. package/docs/adr/0049-split-parallel-safety-contract.md +46 -0
  126. package/docs/adr/0050-device-flow-admission-invite-gated-by-default.md +43 -0
  127. package/docs/adr/0051-full-session-transcript-corpus.md +57 -0
  128. package/docs/adr/0052-sandbox-for-everyone-game-only-preview.md +70 -0
  129. package/docs/adr/0053-scoped-dev-box-session.md +55 -0
  130. package/docs/adr/0054-session-token-reward-cost-plus.md +63 -0
  131. package/docs/adr/0055-server-mediated-branch-publish.md +47 -0
  132. package/docs/adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md +62 -0
  133. package/docs/adr/0057-container-cost-ledger.md +28 -0
  134. package/docs/adr/0057-discord-archon-approval-channels.md +64 -0
  135. package/docs/adr/0058-automatic-gate-surface-gatekeeper.md +64 -0
  136. package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +37 -0
  137. package/docs/adr/0060-gds-retrieval-layer.md +97 -0
  138. package/docs/adr/0061-context-layer-decomposition.md +61 -0
  139. package/docs/adr/0062-medusa-instance-model-decoupling.md +107 -0
  140. package/docs/adr/0063-generated-repo-map-symbol-skeleton.md +44 -0
  141. package/docs/adr/0064-rename-medusa-to-cloud-bongos.md +49 -0
  142. package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +69 -0
  143. package/docs/adr/0066-generated-file-map-sections.md +51 -0
  144. package/docs/adr/0067-session-start-fast-forward-pull.md +43 -0
  145. package/docs/adr/0068-shared-art-key-for-newcomers.md +38 -0
  146. package/docs/adr/0069-hall-live-channel-sse-decouple.md +35 -0
  147. package/docs/adr/0070-deterministic-session-card-delivery.md +44 -0
  148. package/docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md +59 -0
  149. package/docs/adr/0072-bongos-app-mac-signed-first-windows-deferred.md +35 -0
  150. package/docs/adr/0072-dev-box-code-staleness-visibility.md +39 -0
  151. package/docs/adr/0073-builder-needs-signal-and-byok-gemini-key.md +64 -0
  152. package/docs/adr/0073-secrets-scan-exclude-uri-detector.md +37 -0
  153. package/docs/adr/0074-memory-map-stays-light.md +32 -0
  154. package/docs/adr/0075-per-system-cost-attribution.md +37 -0
  155. package/docs/adr/0076-in-session-deterministic-compaction.md +58 -0
  156. package/docs/adr/0077-content-addressed-llm-cache.md +32 -0
  157. package/docs/adr/0078-deterministic-first-cron.md +48 -0
  158. package/docs/adr/0079-value-gated-autonomous-engagement.md +39 -0
  159. package/docs/adr/0080-llm-cache-api-transport-and-trust-model.md +46 -0
  160. package/docs/adr/0081-tool-agnostic-design-layer.md +62 -0
  161. package/docs/adr/0082-productized-key-storage-provisioning.md +32 -0
  162. package/docs/adr/0082-server-side-merge-conflict-auto-resolution.md +55 -0
  163. package/docs/adr/0083-modular-architecture-strangler-build-plan.md +143 -0
  164. package/docs/adr/0084-auto-derived-per-task-rank-floor.md +86 -0
  165. package/docs/adr/0085-remove-default-per-builder-spend-cap.md +39 -0
  166. package/docs/adr/0086-goal-scoped-work-hierarchy.md +123 -0
  167. package/docs/adr/0087-bongos-app-architecture-and-handoff-contract.md +49 -0
  168. package/docs/adr/0087-compete-on-governance-not-tooling-cursor.md +65 -0
  169. package/docs/adr/0088-consistent-character-generative-animation.md +169 -0
  170. package/docs/adr/0089-modular-multi-model-adversarial-grader.md +179 -0
  171. package/docs/adr/0090-metic-task-authoring.md +73 -0
  172. package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +106 -0
  173. package/docs/adr/0092-hosting-module-and-on-prem-target.md +117 -0
  174. package/docs/adr/0093-tranche-2-core-carve-sequence.md +72 -0
  175. package/docs/adr/0094-repo-atlas-self-drawing-codebase-map.md +49 -0
  176. package/docs/adr/0095-borrowed-memory-and-retrieval-concepts.md +65 -0
  177. package/docs/adr/0095-cross-agent-context-management.md +58 -0
  178. package/docs/adr/0096-require-reward-before-workable.md +209 -0
  179. package/docs/adr/0097-one-active-claim-per-session-and-worktree-binding.md +46 -0
  180. package/docs/adr/0097-retroactive-reward-backfill.md +124 -0
  181. package/docs/adr/0098-public-mirror-publish-manifest.md +92 -0
  182. package/docs/adr/0099-delayed-redacted-mirror-export.md +55 -0
  183. package/docs/adr/0100-two-repo-instance-model.md +60 -0
  184. package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +90 -0
  185. package/docs/adr/0102-finish-bounding-the-kernel.md +36 -0
  186. package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +70 -0
  187. package/docs/adr/0103-gdsv4-bongos-consolidation.md +28 -0
  188. package/docs/adr/0104-trust-gds-api-channel-in-auto-mode.md +42 -0
  189. package/docs/adr/0105-instance-seed-migrations-out-of-core.md +47 -0
  190. package/docs/adr/0106-goal-owner-manager-authority.md +84 -0
  191. package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +83 -0
  192. package/docs/adr/0108-instance-composition-configurable-root.md +87 -0
  193. package/docs/adr/0109-self-describing-openapi-and-hosted-docs.md +44 -0
  194. package/docs/adr/0110-untrack-whole-file-generated-nav-docs.md +49 -0
  195. package/docs/adr/0111-instance-hosting-provisioning-module.md +135 -0
  196. package/docs/adr/0112-private-goals-invitations-join-requests.md +72 -0
  197. package/docs/adr/0113-sandbox-studio-descope-superseded-by-0044-0052.md +41 -0
  198. package/docs/adr/0114-instance-docs-discovery-contract.md +32 -0
  199. package/docs/adr/0115-scheduled-routines-portability.md +31 -0
  200. package/docs/adr/0116-api-error-envelope-and-code-taxonomy.md +62 -0
  201. package/docs/adr/0117-api-versioning-and-deprecation-policy.md +50 -0
  202. package/docs/adr/0118-api-contract-source-of-truth-code-first.md +47 -0
  203. package/docs/adr/0119-api-pagination-contract.md +34 -0
  204. package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +108 -0
  205. package/docs/adr/0121-greenfield-vs-brownfield-onboarding-adopt-existing-repo.md +97 -0
  206. package/docs/adr/0122-onboarding-diagram-renders-deploy-rendered-off-git.md +43 -0
  207. package/docs/adr/0123-box-idle-sweep-autosave-before-destroy.md +36 -0
  208. package/docs/adr/0124-typed-api-response-bodies.md +37 -0
  209. package/docs/adr/0125-control-plane-scaffolds-standalone-instance-repo.md +36 -0
  210. package/docs/adr/0126-dedicated-cloudbongos-control-plane-droplet.md +30 -0
  211. package/docs/adr/0127-cross-box-fleet-observability.md +64 -0
  212. package/docs/adr/0128-provisioning-runner-privilege-and-db-auth-model.md +46 -0
  213. package/docs/adr/0129-cloudbongos-control-plane-pull-deploy.md +34 -0
  214. package/docs/adr/0130-provision-remote-exec-over-ssh.md +61 -0
  215. package/docs/adr/0131-rank-scoped-skill-visibility.md +47 -0
  216. package/docs/adr/0132-cohost-fleet-control-plane-migration.md +54 -0
  217. package/docs/adr/0133-github-app-manifest-onboarding-signin.md +42 -0
  218. package/docs/adr/0134-private-first-npm-distribution.md +38 -0
  219. package/docs/adr/README.md +208 -0
  220. package/docs/api/openapi.json +13720 -0
  221. package/docs/api-reference.md +437 -0
  222. package/docs/architecture.md +244 -0
  223. package/docs/branding-contract.md +66 -0
  224. package/docs/branding-fill-prompt.md +25 -0
  225. package/docs/canonical-permissions.md +241 -0
  226. package/docs/design/container-exterior-tiles.md +49 -0
  227. package/docs/design/container-exterior.md +81 -0
  228. package/docs/design/container-interior.md +77 -0
  229. package/docs/design/modular-architecture/00-research-report.md +107 -0
  230. package/docs/design/modular-architecture/01-architecture.md +125 -0
  231. package/docs/design/modular-architecture/02-module-map.md +116 -0
  232. package/docs/design/modular-architecture/03-builder-flows.md +104 -0
  233. package/docs/design/modular-architecture/04-module-lifecycle.md +62 -0
  234. package/docs/design/modular-architecture/README.md +27 -0
  235. package/docs/design/vanilla-hall-ui-redesign-scope.md +284 -0
  236. package/docs/design/world-map-scroll.md +41 -0
  237. package/docs/design-contract.md +320 -0
  238. package/docs/file-map.md +418 -0
  239. package/docs/handoff-template.md +92 -0
  240. package/docs/modules-contract.md +293 -0
  241. package/docs/onboarding/browser-terminal-guide.md +73 -0
  242. package/docs/onboarding/diagrams/01-task-lifecycle.mmd +28 -0
  243. package/docs/onboarding/diagrams/02-rank-ladder.mmd +54 -0
  244. package/docs/onboarding/diagrams/03-drachmae-karma.mmd +37 -0
  245. package/docs/onboarding/diagrams/04-architecture.mmd +51 -0
  246. package/docs/onboarding/diagrams/05-versioning.mmd +29 -0
  247. package/docs/onboarding/diagrams/README.md +94 -0
  248. package/docs/onboarding/diagrams/assertions.json +170 -0
  249. package/docs/onboarding/diagrams/puppeteer-config.json +1 -0
  250. package/docs/onboarding/diagrams/render-config.json +9 -0
  251. package/docs/onboarding/drachmae-and-karma.md +178 -0
  252. package/docs/onboarding/primer.md +202 -0
  253. package/docs/project-context.template.md +67 -0
  254. package/docs/recipes/README.md +35 -0
  255. package/docs/recipes/audit-replay.md +100 -0
  256. package/docs/recipes/bongos-cli-release.md +66 -0
  257. package/docs/recipes/builder-box-lifecycle.md +152 -0
  258. package/docs/recipes/claude-design-loop.md +143 -0
  259. package/docs/recipes/claude-gemini-bongos-doors.md +155 -0
  260. package/docs/recipes/cloudbongos-staging-gate.md +139 -0
  261. package/docs/recipes/cloudbongos-standup.md +111 -0
  262. package/docs/recipes/devbox-app-release.md +93 -0
  263. package/docs/recipes/devbox-app-windows-test.md +128 -0
  264. package/docs/recipes/failed-ship-recovery-proof.md +102 -0
  265. package/docs/recipes/figma-design-loop.md +129 -0
  266. package/docs/recipes/gds-db-backup.md +255 -0
  267. package/docs/recipes/instance-deploy.md +37 -0
  268. package/docs/recipes/managed-settings-remote-control.md +416 -0
  269. package/docs/recipes/memory-backup.md +71 -0
  270. package/docs/recipes/memory-sync-conflicts.md +98 -0
  271. package/docs/recipes/multi-builder-merge.md +78 -0
  272. package/docs/recipes/ops-gotchas.md +212 -0
  273. package/docs/recipes/overnight-builder.md +53 -0
  274. package/docs/recipes/packaging-the-core.md +49 -0
  275. package/docs/recipes/parallel-load-results-2026-05-30.md +63 -0
  276. package/docs/recipes/parallel-load-test.md +32 -0
  277. package/docs/recipes/pixel-art-pipeline.md +411 -0
  278. package/docs/recipes/private-npm-distribution.md +79 -0
  279. package/docs/recipes/search-index-ingestion.md +67 -0
  280. package/docs/recipes/self-host.md +60 -0
  281. package/docs/recipes/ship-and-regrade.md +72 -0
  282. package/docs/recipes/staging-data.md +50 -0
  283. package/docs/recipes/staging-environment.md +215 -0
  284. package/docs/recipes/upgrading-the-core.md +58 -0
  285. package/docs/research/cursor-competitive-analysis.md +255 -0
  286. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +227 -0
  287. package/migrations/003_pms.sql +284 -0
  288. package/migrations/004_pms_cost_idempotency.sql +13 -0
  289. package/migrations/005_pms_smoke_filter.sql +44 -0
  290. package/migrations/006_pms_v2.sql +378 -0
  291. package/migrations/007_pms_v2_hierarchy_trigger.sql +59 -0
  292. package/migrations/008_pms_v2_migration_allocator.sql +27 -0
  293. package/migrations/009_pms_v2_blockers_table.sql +68 -0
  294. package/migrations/010_uptime.sql +29 -0
  295. package/migrations/011_backfill_v2_v3_done_when.sql +20 -0
  296. package/migrations/012_pms_v2_task_lifecycle_states.sql +82 -0
  297. package/migrations/013_claim_locking.sql +22 -0
  298. package/migrations/014_pms_task_discipline.sql +86 -0
  299. package/migrations/015_pms_estimation_calibration.sql +140 -0
  300. package/migrations/016_pms_task_grades.sql +60 -0
  301. package/migrations/017_version_progress_exclude_abandoned.sql +49 -0
  302. package/migrations/019_rename_pms_v3_to_gds_v3.sql +65 -0
  303. package/migrations/020_task_dependencies.sql +99 -0
  304. package/migrations/021_v3_renumber_and_deps.sql +224 -0
  305. package/migrations/022_v3_reconcile_dep_gated_status.sql +41 -0
  306. package/migrations/023_pms_rank.sql +30 -0
  307. package/migrations/025_builder_exit_status.sql +15 -0
  308. package/migrations/027_builders_preferred_disciplines.sql +46 -0
  309. package/migrations/028_tasks_parallel_safe.sql +71 -0
  310. package/migrations/029_rank_three_live.sql +32 -0
  311. package/migrations/030_vulnerability_reports.sql +61 -0
  312. package/migrations/031_reward_simplification.sql +57 -0
  313. package/migrations/032_repo_health_snapshots.sql +56 -0
  314. package/migrations/033_audit_log.sql +64 -0
  315. package/migrations/034_lifecycle_breakdown_leaf_only.sql +62 -0
  316. package/migrations/035_auth_token_hygiene.sql +66 -0
  317. package/migrations/037_builder_skill_model_prefs.sql +44 -0
  318. package/migrations/038_task_override_requests.sql +51 -0
  319. package/migrations/039_newcomer_friendly_column.sql +124 -0
  320. package/migrations/040_builder_karma.sql +58 -0
  321. package/migrations/041_kind_multipliers_and_idea_bonus.sql +42 -0
  322. package/migrations/042_criterion_proposal_workflow.sql +78 -0
  323. package/migrations/043_builder_onboarding_observability.sql +66 -0
  324. package/migrations/044_tasks_requires_rank.sql +97 -0
  325. package/migrations/045_builder_onboarding_state.sql +147 -0
  326. package/migrations/046_cost_log_builder_attribution.sql +42 -0
  327. package/migrations/054_builder_memory.sql +108 -0
  328. package/migrations/055_task_criteria.sql +90 -0
  329. package/migrations/058_peer_votes.sql +41 -0
  330. package/migrations/059_onboarding_pick_disciplines.sql +59 -0
  331. package/migrations/060_access_requests.sql +46 -0
  332. package/migrations/061_backfill_override_ship_attribution.sql +29 -0
  333. package/migrations/062_session_records.sql +34 -0
  334. package/migrations/063_session_records_tool_errors_idx.sql +11 -0
  335. package/migrations/064_grade_attempts.sql +18 -0
  336. package/migrations/065_bfg_principal.sql +58 -0
  337. package/migrations/066_live_notify_triggers.sql +69 -0
  338. package/migrations/067_builder_boxes.sql +117 -0
  339. package/migrations/067_discord_bot_foundation.sql +69 -0
  340. package/migrations/068_thetes_requires_rank.sql +27 -0
  341. package/migrations/069_builder_ssh_keys.sql +66 -0
  342. package/migrations/070_box_intents.sql +101 -0
  343. package/migrations/071_box_first_provision_approval.sql +46 -0
  344. package/migrations/072_onboarding_ship_three_remove_primer.sql +80 -0
  345. package/migrations/073_box_terminal_access.sql +46 -0
  346. package/migrations/075_builder_sound_prefs.sql +28 -0
  347. package/migrations/078_box_claude_active.sql +22 -0
  348. package/migrations/079_box_first_connected_at.sql +20 -0
  349. package/migrations/081_tasks_needs_migration.sql +34 -0
  350. package/migrations/084_tasks_security_sensitive.sql +24 -0
  351. package/migrations/085_security_engagement_docs.sql +34 -0
  352. package/migrations/086_rename_disciplines.sql +125 -0
  353. package/migrations/088_builders_anthropic_link.sql +28 -0
  354. package/migrations/089_builders_monthly_budget.sql +19 -0
  355. package/migrations/090_box_scoped_sessions.sql +38 -0
  356. package/migrations/091_session_token_reward.sql +44 -0
  357. package/migrations/093_tasks_sandbox_review.sql +22 -0
  358. package/migrations/102_remove_box_first_provision_approval.sql +58 -0
  359. package/migrations/103_search_chunks.sql +90 -0
  360. package/migrations/104_builder_box_blocked.sql +34 -0
  361. package/migrations/105_box_host_keys.sql +35 -0
  362. package/migrations/111_medusa_customer0_framing.sql +35 -0
  363. package/migrations/112_drop_track_check.sql +25 -0
  364. package/migrations/113_merge_lease.sql +16 -0
  365. package/migrations/114_cloudbongos_rename_live_strings.sql +32 -0
  366. package/migrations/118_currency_label_decoupling.sql +23 -0
  367. package/migrations/119_builder_behavior_prefs.sql +31 -0
  368. package/migrations/121_box_code_version.sql +37 -0
  369. package/migrations/122_builder_gemini_key.sql +30 -0
  370. package/migrations/123_cost_log_tiers.sql +33 -0
  371. package/migrations/124_cost_baseline.sql +45 -0
  372. package/migrations/125_llm_cache.sql +54 -0
  373. package/migrations/126_autonomy_runs.sql +33 -0
  374. package/migrations/143_cost_calibration.sql +63 -0
  375. package/migrations/145_backfill_task_requires_rank.sql +84 -0
  376. package/migrations/160_goal_tier.sql +88 -0
  377. package/migrations/163_polymorphic_dependencies.sql +187 -0
  378. package/migrations/164_event_sound_prefs.sql +20 -0
  379. package/migrations/165_task_module_key.sql +15 -0
  380. package/migrations/171_claims_published_head_sha.sql +24 -0
  381. package/migrations/174_close_orphaned_claims_on_terminal_tasks.sql +30 -0
  382. package/migrations/175_task_grades_diff_hash.sql +9 -0
  383. package/migrations/176_promotion_respects_open_blockers.sql +58 -0
  384. package/migrations/176_ui_discipline.sql +40 -0
  385. package/migrations/177_require_reward_before_workable.sql +76 -0
  386. package/migrations/178_reward_gate_auto_assign_revert_autopromote.sql +61 -0
  387. package/migrations/179_search_chunk_usefulness.sql +33 -0
  388. package/migrations/180_one_active_claim_per_session.sql +54 -0
  389. package/migrations/181_cost_log_skill_name.sql +33 -0
  390. package/migrations/184_claim_release_requested.sql +25 -0
  391. package/migrations/185_module_upstreaming_goal_wiring.sql +59 -0
  392. package/migrations/187_goal_sort_order.sql +30 -0
  393. package/migrations/187_tasks_kind_check_add_verify.sql +21 -0
  394. package/migrations/README.md +88 -0
  395. package/migrations/core_188_goal_visibility_and_membership_requests.sql +71 -0
  396. package/migrations/core_189_core_upgrades_ledger.sql +37 -0
  397. package/migrations/core_189_credit_log_task_id_index.sql +19 -0
  398. package/migrations/core_190_rebuild_claimable_task_views.sql +71 -0
  399. package/migrations/instance/018_pms_v3_planning_seed.sql +131 -0
  400. package/migrations/instance/080_gds_v4_planning_seed.sql +75 -0
  401. package/migrations/instance/110_medusa_planning_seed.sql +70 -0
  402. package/migrations/instance/120_bongos_v1_planning_seed.sql +69 -0
  403. package/migrations/instance/144_bongos_v1_module_system_criterion.sql +26 -0
  404. package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +29 -0
  405. package/migrations/instance/172_v2_world_planning_seed.sql +163 -0
  406. package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +33 -0
  407. package/migrations/instance/182_gdsv4_bongos_consolidation.sql +132 -0
  408. package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +116 -0
  409. package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +69 -0
  410. package/modules/autonomy/CLAUDE.md +49 -0
  411. package/modules/autonomy/db.js +50 -0
  412. package/modules/autonomy/module.json +13 -0
  413. package/modules/autonomy/pollers/routine-timers.js +146 -0
  414. package/modules/autonomy/routes/autonomy.js +37 -0
  415. package/modules/builder-settings/CLAUDE.md +58 -0
  416. package/modules/builder-settings/builder-needs.js +115 -0
  417. package/modules/builder-settings/db.js +168 -0
  418. package/modules/builder-settings/display-name.js +84 -0
  419. package/modules/builder-settings/event-sound-prefs.js +169 -0
  420. package/modules/builder-settings/interaction-prefs.js +201 -0
  421. package/modules/builder-settings/model-alloc-prefs.js +147 -0
  422. package/modules/builder-settings/module.json +10 -0
  423. package/modules/builder-settings/render-prefs.js +103 -0
  424. package/modules/builder-settings/routes/settings.js +417 -0
  425. package/modules/builder-settings/settings.js +52 -0
  426. package/modules/builder-settings/skill-prefs.js +196 -0
  427. package/modules/builder-settings/sound-prefs.js +178 -0
  428. package/modules/builder-settings/wandering-prefs.js +282 -0
  429. package/modules/dev-box/CLAUDE.md +38 -0
  430. package/modules/dev-box/box-access.js +275 -0
  431. package/modules/dev-box/box-credential.js +94 -0
  432. package/modules/dev-box/box-onboard.js +486 -0
  433. package/modules/dev-box/boxes.js +842 -0
  434. package/modules/dev-box/db.js +39 -0
  435. package/modules/dev-box/module.json +14 -0
  436. package/modules/dev-box/routes/box.js +977 -0
  437. package/modules/discord/CLAUDE.md +50 -0
  438. package/modules/discord/auth.js +54 -0
  439. package/modules/discord/bug-attachments.js +210 -0
  440. package/modules/discord/db.js +96 -0
  441. package/modules/discord/discord-approvals.js +145 -0
  442. package/modules/discord/discord-audit.js +29 -0
  443. package/modules/discord/discord-bot.js +545 -0
  444. package/modules/discord/discord-bugs.js +257 -0
  445. package/modules/discord/discord-channels.js +412 -0
  446. package/modules/discord/discord-inbound.js +147 -0
  447. package/modules/discord/discord-message-buffer.js +54 -0
  448. package/modules/discord/discord-reaction.js +186 -0
  449. package/modules/discord/discord-role-sync.js +318 -0
  450. package/modules/discord/module.json +14 -0
  451. package/modules/discord/pollers/discord-bot.js +19 -0
  452. package/modules/discord/routes/bug-attachments.js +44 -0
  453. package/modules/discord/routes/discord.js +102 -0
  454. package/modules/discord/ship-broadcast.js +78 -0
  455. package/modules/discord/webhook.js +74 -0
  456. package/modules/economy/CLAUDE.md +48 -0
  457. package/modules/economy/achievements.js +594 -0
  458. package/modules/economy/cost-classify.js +331 -0
  459. package/modules/economy/cost-summary-shape.js +90 -0
  460. package/modules/economy/cost.js +438 -0
  461. package/modules/economy/credits.js +430 -0
  462. package/modules/economy/migrations/economy_001_fix_gds_shipper_description.sql +91 -0
  463. package/modules/economy/module.json +10 -0
  464. package/modules/economy/reward.js +61 -0
  465. package/modules/economy/routes/cost.js +97 -0
  466. package/modules/economy/routes/leaderboard.js +26 -0
  467. package/modules/economy/routes/reward.js +42 -0
  468. package/modules/economy/streak.js +285 -0
  469. package/modules/grading/CLAUDE.md +42 -0
  470. package/modules/grading/db.js +39 -0
  471. package/modules/grading/grader-rubric.json +151 -0
  472. package/modules/grading/grader-workers/efficiency.js +213 -0
  473. package/modules/grading/grader-workers/extract-json.js +80 -0
  474. package/modules/grading/grader-workers/fence.js +100 -0
  475. package/modules/grading/grader-workers/hacker.js +239 -0
  476. package/modules/grading/grader-workers/index.js +183 -0
  477. package/modules/grading/grader-workers/narc.js +207 -0
  478. package/modules/grading/grader-workers/quality.js +198 -0
  479. package/modules/grading/grader-workers/rubric.js +20 -0
  480. package/modules/grading/grader-workers/worker-prompt.js +89 -0
  481. package/modules/grading/grader-workers/worker-verdict.js +50 -0
  482. package/modules/grading/grader.js +1790 -0
  483. package/modules/grading/module.json +12 -0
  484. package/modules/grading/routes/grade.js +51 -0
  485. package/modules/hall-ui/CLAUDE.md +61 -0
  486. package/modules/hall-ui/module.json +14 -0
  487. package/modules/hall-ui/public/atlas.html +180 -0
  488. package/modules/hall-ui/public/atlas.js +336 -0
  489. package/modules/hall-ui/public/box-panel.js +423 -0
  490. package/modules/hall-ui/public/brand-apply.js +117 -0
  491. package/modules/hall-ui/public/builders.js +3028 -0
  492. package/modules/hall-ui/public/chime.wav +0 -0
  493. package/modules/hall-ui/public/copy-on-click.js +174 -0
  494. package/modules/hall-ui/public/cursors/arrow.png +0 -0
  495. package/modules/hall-ui/public/cursors/hand-pointer.png +0 -0
  496. package/modules/hall-ui/public/cursors/magnifier-out.png +0 -0
  497. package/modules/hall-ui/public/cursors/magnifier.png +0 -0
  498. package/modules/hall-ui/public/diagram-viewer.css +125 -0
  499. package/modules/hall-ui/public/diagram-viewer.js +330 -0
  500. package/modules/hall-ui/public/diagrams.html +113 -0
  501. package/modules/hall-ui/public/dom-utils.js +212 -0
  502. package/modules/hall-ui/public/drachmae.html +68 -0
  503. package/modules/hall-ui/public/drachmae.js +136 -0
  504. package/modules/hall-ui/public/gate.html +143 -0
  505. package/modules/hall-ui/public/gate.js +228 -0
  506. package/modules/hall-ui/public/goals-page.js +1297 -0
  507. package/modules/hall-ui/public/goals.html +376 -0
  508. package/modules/hall-ui/public/goals.js +119 -0
  509. package/modules/hall-ui/public/hall-widgets.js +189 -0
  510. package/modules/hall-ui/public/harbor.html +167 -0
  511. package/modules/hall-ui/public/harbor.js +335 -0
  512. package/modules/hall-ui/public/index.html +116 -0
  513. package/modules/hall-ui/public/instances-panel.js +172 -0
  514. package/modules/hall-ui/public/md-reader.js +234 -0
  515. package/modules/hall-ui/public/modules.html +119 -0
  516. package/modules/hall-ui/public/modules.js +154 -0
  517. package/modules/hall-ui/public/new-project-wizard.js +186 -0
  518. package/modules/hall-ui/public/not-ready.html +48 -0
  519. package/modules/hall-ui/public/pair.html +119 -0
  520. package/modules/hall-ui/public/pair.js +132 -0
  521. package/modules/hall-ui/public/primer.css +404 -0
  522. package/modules/hall-ui/public/primer.html +85 -0
  523. package/modules/hall-ui/public/primer.js +641 -0
  524. package/modules/hall-ui/public/profile.html +85 -0
  525. package/modules/hall-ui/public/profile.js +236 -0
  526. package/modules/hall-ui/public/ranks.html +69 -0
  527. package/modules/hall-ui/public/ranks.js +206 -0
  528. package/modules/hall-ui/public/roadmap.html +209 -0
  529. package/modules/hall-ui/public/roadmap.js +375 -0
  530. package/modules/hall-ui/public/sessions.html +92 -0
  531. package/modules/hall-ui/public/sessions.js +222 -0
  532. package/modules/hall-ui/public/settings.html +640 -0
  533. package/modules/hall-ui/public/settings.js +1219 -0
  534. package/modules/hall-ui/public/shell.js +495 -0
  535. package/modules/hall-ui/public/style.css +1748 -0
  536. package/modules/hall-ui/public/task-detail.js +253 -0
  537. package/modules/hall-ui/public/task.html +83 -0
  538. package/modules/hall-ui/public/task.js +326 -0
  539. package/modules/hall-ui/public/watch.html +333 -0
  540. package/modules/hall-ui/public/watch.js +859 -0
  541. package/modules/hall-ui/public/work.html +469 -0
  542. package/modules/hall-ui/public/work.js +1292 -0
  543. package/modules/ideas/CLAUDE.md +37 -0
  544. package/modules/ideas/blockers.js +100 -0
  545. package/modules/ideas/inbox.js +459 -0
  546. package/modules/ideas/module.json +10 -0
  547. package/modules/ideas/routes/blockers.js +120 -0
  548. package/modules/ideas/routes/inbox.js +230 -0
  549. package/modules/lifecycle/CLAUDE.md +63 -0
  550. package/modules/lifecycle/conflict-resolve.js +436 -0
  551. package/modules/lifecycle/db.js +4970 -0
  552. package/modules/lifecycle/done-when.js +355 -0
  553. package/modules/lifecycle/github-push.js +969 -0
  554. package/modules/lifecycle/goal-conflicts.js +133 -0
  555. package/modules/lifecycle/hierarchy.js +104 -0
  556. package/modules/lifecycle/lifecycle.js +58 -0
  557. package/modules/lifecycle/merge-lock.js +261 -0
  558. package/modules/lifecycle/migrations/lifecycle_001_goal_first_leads.sql +28 -0
  559. package/modules/lifecycle/migrations/lifecycle_002_backfill_orphan_task_goals.sql +36 -0
  560. package/modules/lifecycle/module.json +13 -0
  561. package/modules/lifecycle/pollers/publish-reconciler.js +20 -0
  562. package/modules/lifecycle/publish-reconciler.js +418 -0
  563. package/modules/lifecycle/routes/analytics.js +63 -0
  564. package/modules/lifecycle/routes/claims.js +506 -0
  565. package/modules/lifecycle/routes/dependencies.js +82 -0
  566. package/modules/lifecycle/routes/done-when.js +136 -0
  567. package/modules/lifecycle/routes/gate-approvals.js +197 -0
  568. package/modules/lifecycle/routes/goals.js +1419 -0
  569. package/modules/lifecycle/routes/lifecycle.js +43 -0
  570. package/modules/lifecycle/routes/tasks.js +1703 -0
  571. package/modules/lifecycle/routes/versions.js +128 -0
  572. package/modules/lifecycle/ship-card.js +505 -0
  573. package/modules/lifecycle/ship-preflight.js +225 -0
  574. package/modules/lifecycle/task-classifier.js +512 -0
  575. package/modules/lifecycle/version-close.js +106 -0
  576. package/modules/memory/CLAUDE.md +40 -0
  577. package/modules/memory/learnings.js +275 -0
  578. package/modules/memory/memory.js +572 -0
  579. package/modules/memory/module.json +12 -0
  580. package/modules/memory/routes/learnings.js +90 -0
  581. package/modules/memory/routes/memory.js +916 -0
  582. package/modules/memory/routes/search.js +188 -0
  583. package/modules/memory/search-chunker.js +252 -0
  584. package/modules/memory/search.js +320 -0
  585. package/modules/onboarding/CLAUDE.md +55 -0
  586. package/modules/onboarding/approval-broadcast.js +59 -0
  587. package/modules/onboarding/db.js +54 -0
  588. package/modules/onboarding/module.json +10 -0
  589. package/modules/onboarding/newcomer-restock.js +212 -0
  590. package/modules/onboarding/onboarding-state.js +532 -0
  591. package/modules/onboarding/onboarding.js +508 -0
  592. package/modules/onboarding/port.js +63 -0
  593. package/modules/onboarding/routes/access-requests.js +208 -0
  594. package/modules/onboarding/routes/onboarding.js +54 -0
  595. package/modules/security/CLAUDE.md +44 -0
  596. package/modules/security/module.json +10 -0
  597. package/modules/security/routes/reports.js +251 -0
  598. package/modules/security/secret-scrub.js +201 -0
  599. package/modules/security/security.js +294 -0
  600. package/modules/sessions/CLAUDE.md +39 -0
  601. package/modules/sessions/bfg.js +357 -0
  602. package/modules/sessions/db.js +326 -0
  603. package/modules/sessions/module.json +10 -0
  604. package/modules/sessions/pulse.js +149 -0
  605. package/modules/sessions/routes/sessions.js +331 -0
  606. package/modules/status-ui/CLAUDE.md +47 -0
  607. package/modules/status-ui/module.json +14 -0
  608. package/modules/status-ui/public/README.md +29 -0
  609. package/modules/status-ui/public/cursors/arrow.png +0 -0
  610. package/modules/status-ui/public/cursors/hand-pointer.png +0 -0
  611. package/modules/status-ui/public/index.html +363 -0
  612. package/modules/status-ui/public/snapshots/.gitkeep +0 -0
  613. package/modules/status-ui/public/status.js +1375 -0
  614. package/modules/status-ui/public/style.css +1342 -0
  615. package/package-lock.json +975 -0
  616. package/package.json +28 -0
  617. package/public-docs/index.html +35 -0
  618. package/public-docs/redoc.standalone.js +1838 -0
  619. package/public-docs/redoc.standalone.js.LICENSE.txt +102 -0
  620. package/public-landing/buddha.png +0 -0
  621. package/public-landing/create.html +868 -0
  622. package/public-landing/index.html +168 -0
  623. package/scripts/bongos-mcp.js +28 -0
  624. package/scripts/cron/style_guide_audit.sh +134 -0
  625. package/scripts/discord/README.md +52 -0
  626. package/scripts/discord/lib.js +80 -0
  627. package/scripts/discord/post.js +51 -0
  628. package/scripts/gds/CLAUDE.md +144 -0
  629. package/scripts/gds/abandon.js +58 -0
  630. package/scripts/gds/adopt-detect.js +123 -0
  631. package/scripts/gds/adopt-import.js +111 -0
  632. package/scripts/gds/adopt-preflight.js +121 -0
  633. package/scripts/gds/api.js +78 -0
  634. package/scripts/gds/architect-audit.js +288 -0
  635. package/scripts/gds/art-stage.js +152 -0
  636. package/scripts/gds/audit-authorship.sh +243 -0
  637. package/scripts/gds/audit-deps.js +121 -0
  638. package/scripts/gds/audit-exports.js +128 -0
  639. package/scripts/gds/audit-replay.sh +161 -0
  640. package/scripts/gds/audit-ships.js +251 -0
  641. package/scripts/gds/autonomy-gate.js +135 -0
  642. package/scripts/gds/backfill-cost.js +165 -0
  643. package/scripts/gds/backfill-sessions.js +351 -0
  644. package/scripts/gds/backfill-task-rewards.js +408 -0
  645. package/scripts/gds/backup.js +94 -0
  646. package/scripts/gds/bfg-principal-token.js +65 -0
  647. package/scripts/gds/box-auth-check.js +160 -0
  648. package/scripts/gds/box-connect-lib.js +453 -0
  649. package/scripts/gds/box.js +1258 -0
  650. package/scripts/gds/build-bongos.js +94 -0
  651. package/scripts/gds/capture.js +123 -0
  652. package/scripts/gds/cf-tunnel.js +419 -0
  653. package/scripts/gds/ci-grade.js +82 -0
  654. package/scripts/gds/claim-recall.js +112 -0
  655. package/scripts/gds/claim.js +333 -0
  656. package/scripts/gds/classify-discipline.js +153 -0
  657. package/scripts/gds/claude-materialize.js +176 -0
  658. package/scripts/gds/cleanup-orphans.js +74 -0
  659. package/scripts/gds/cli-lib.js +518 -0
  660. package/scripts/gds/code.js +101 -0
  661. package/scripts/gds/codemod-rename-src-gds.js +145 -0
  662. package/scripts/gds/conductor-dispatch.js +426 -0
  663. package/scripts/gds/context-pack.js +228 -0
  664. package/scripts/gds/coreB-carve-proof.sh +716 -0
  665. package/scripts/gds/cost.js +47 -0
  666. package/scripts/gds/db-backup-nightly.sh +160 -0
  667. package/scripts/gds/db-backup-offsite.sh +152 -0
  668. package/scripts/gds/demote.js +40 -0
  669. package/scripts/gds/design-sync.js +62 -0
  670. package/scripts/gds/diagnose-achievements.js +118 -0
  671. package/scripts/gds/diagram-facts.js +319 -0
  672. package/scripts/gds/discipline-modes.json +25 -0
  673. package/scripts/gds/discord-channels.js +66 -0
  674. package/scripts/gds/do-api.js +176 -0
  675. package/scripts/gds/docs-entropy.js +403 -0
  676. package/scripts/gds/doctor.js +389 -0
  677. package/scripts/gds/feedback-latest.js +94 -0
  678. package/scripts/gds/fetch-art-key.js +106 -0
  679. package/scripts/gds/fetch-sound-prefs.js +88 -0
  680. package/scripts/gds/figma-design-sync.js +61 -0
  681. package/scripts/gds/fitness.js +1446 -0
  682. package/scripts/gds/gate-review.js +322 -0
  683. package/scripts/gds/gating.js +325 -0
  684. package/scripts/gds/gds-db-backup.service +24 -0
  685. package/scripts/gds/gds-db-backup.timer +20 -0
  686. package/scripts/gds/gds-db-offsite.service +29 -0
  687. package/scripts/gds/gds-db-offsite.timer +18 -0
  688. package/scripts/gds/gen-api-client.js +508 -0
  689. package/scripts/gds/gen-api-docs.js +1037 -0
  690. package/scripts/gds/gen-atlas.js +366 -0
  691. package/scripts/gds/gen-diagrams.js +608 -0
  692. package/scripts/gds/gen-file-map.js +196 -0
  693. package/scripts/gds/gen-repo-map.js +519 -0
  694. package/scripts/gds/gen-session-index.js +210 -0
  695. package/scripts/gds/git-merge-regen.js +147 -0
  696. package/scripts/gds/grade-smoke.js +205 -0
  697. package/scripts/gds/hooks/pre-push.js +169 -0
  698. package/scripts/gds/http-api-client.js +88 -0
  699. package/scripts/gds/init.js +903 -0
  700. package/scripts/gds/install-git-hooks.js +114 -0
  701. package/scripts/gds/key-card.js +213 -0
  702. package/scripts/gds/key-status.js +126 -0
  703. package/scripts/gds/land-watch.js +168 -0
  704. package/scripts/gds/learning-capture.js +145 -0
  705. package/scripts/gds/lib.sh +44 -0
  706. package/scripts/gds/linkify-refs.js +473 -0
  707. package/scripts/gds/local-preview-lib.js +159 -0
  708. package/scripts/gds/local-preview.js +95 -0
  709. package/scripts/gds/login.js +225 -0
  710. package/scripts/gds/main-audit.js +279 -0
  711. package/scripts/gds/me.js +88 -0
  712. package/scripts/gds/memory-map.js +174 -0
  713. package/scripts/gds/merge-lock.js +71 -0
  714. package/scripts/gds/migration-namespace.js +200 -0
  715. package/scripts/gds/mirror-lineage-check.js +319 -0
  716. package/scripts/gds/mirror-redact.js +305 -0
  717. package/scripts/gds/module.js +482 -0
  718. package/scripts/gds/newcomer-floor.config.json +13 -0
  719. package/scripts/gds/newcomer-floor.js +415 -0
  720. package/scripts/gds/newcomer-floor.templates.json +86 -0
  721. package/scripts/gds/newcomer-floor.test.js +235 -0
  722. package/scripts/gds/next-number.js +163 -0
  723. package/scripts/gds/oauth-secret.js +197 -0
  724. package/scripts/gds/onboard.js +217 -0
  725. package/scripts/gds/onboarding-analyze.js +226 -0
  726. package/scripts/gds/onboarding-config.js +178 -0
  727. package/scripts/gds/onboarding-ship.js +92 -0
  728. package/scripts/gds/package-core.js +684 -0
  729. package/scripts/gds/paste-token.js +131 -0
  730. package/scripts/gds/portability-smoke-art.sh +85 -0
  731. package/scripts/gds/portability-smoke-memory.sh +147 -0
  732. package/scripts/gds/provision.js +1324 -0
  733. package/scripts/gds/publish-manifest.js +307 -0
  734. package/scripts/gds/pulse.js +309 -0
  735. package/scripts/gds/push-main.js +45 -0
  736. package/scripts/gds/read-session-export.js +359 -0
  737. package/scripts/gds/reauth.js +149 -0
  738. package/scripts/gds/recall.js +135 -0
  739. package/scripts/gds/release.js +71 -0
  740. package/scripts/gds/render-ideas.js +173 -0
  741. package/scripts/gds/repo-metrics.js +363 -0
  742. package/scripts/gds/resolve-skill-model.js +57 -0
  743. package/scripts/gds/run-routine.js +197 -0
  744. package/scripts/gds/run-unit-tests.js +178 -0
  745. package/scripts/gds/sandbox-stage.js +653 -0
  746. package/scripts/gds/search-ingest-db.js +209 -0
  747. package/scripts/gds/search-ingest-md.js +225 -0
  748. package/scripts/gds/security-baseline-check.sh +180 -0
  749. package/scripts/gds/seed-adopt-tasks.js +75 -0
  750. package/scripts/gds/seed-api-contract-goal-tasks.js +141 -0
  751. package/scripts/gds/seed-bongos-app-tasks.js +294 -0
  752. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +81 -0
  753. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +100 -0
  754. package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +307 -0
  755. package/scripts/gds/seed-bongos-module-system-tasks.js +346 -0
  756. package/scripts/gds/seed-bongos-tasks.js +214 -0
  757. package/scripts/gds/seed-gds-v4-tasks.js +624 -0
  758. package/scripts/gds/seed-governance-tasks.js +340 -0
  759. package/scripts/gds/seed-medusa-tasks.js +440 -0
  760. package/scripts/gds/seed-module-upstreaming.js +219 -0
  761. package/scripts/gds/seed-productization-tasks.js +235 -0
  762. package/scripts/gds/seed-provisioning-tasks.js +83 -0
  763. package/scripts/gds/seed-staging.sh +104 -0
  764. package/scripts/gds/seed-v2-world-tasks.js +283 -0
  765. package/scripts/gds/seed-v3-tasks.js +1981 -0
  766. package/scripts/gds/session-cost.js +393 -0
  767. package/scripts/gds/session-digest.js +179 -0
  768. package/scripts/gds/session-eval.js +576 -0
  769. package/scripts/gds/session.js +404 -0
  770. package/scripts/gds/setup.js +504 -0
  771. package/scripts/gds/shell.js +100 -0
  772. package/scripts/gds/ship.js +3618 -0
  773. package/scripts/gds/smoke-batch-claim.sh +213 -0
  774. package/scripts/gds/smoke-batch-release.sh +296 -0
  775. package/scripts/gds/smoke-box.sh +150 -0
  776. package/scripts/gds/smoke-claim-consistency.sh +212 -0
  777. package/scripts/gds/smoke-dependencies.sh +84 -0
  778. package/scripts/gds/smoke-gds.js +125 -0
  779. package/scripts/gds/smoke-write.sh +168 -0
  780. package/scripts/gds/start.js +782 -0
  781. package/scripts/gds/status.js +365 -0
  782. package/scripts/gds/triage.js +366 -0
  783. package/scripts/gds/upgrade.js +421 -0
  784. package/scripts/gds/validate-design.js +254 -0
  785. package/scripts/gds/version-close.js +549 -0
  786. package/scripts/migrate.sh +183 -0
  787. package/scripts/migrate_cost_ledger.sh +178 -0
  788. package/scripts/public-mirror-export.js +291 -0
  789. package/scripts/render-diagrams.sh +88 -0
  790. package/scripts/security/dep-audit.js +276 -0
  791. package/scripts/setup-builder.js +274 -0
  792. package/scripts/setup-builder.sh +28 -0
  793. package/scripts/snapshots/backfill-history.mjs +292 -0
  794. package/scripts/snapshots/maybe-render-on-deploy.sh +66 -0
  795. package/scripts/snapshots/render-pre-art-eras.mjs +329 -0
  796. package/scripts/snapshots/render-world.mjs +322 -0
  797. package/scripts/status-mirror-sync.js +192 -0
  798. package/scripts/status-probe.mjs +185 -0
  799. package/server.js +212 -0
  800. package/src/asset-version.js +71 -0
  801. package/src/bongos/CLAUDE.md +64 -0
  802. package/src/bongos/api-errors.js +281 -0
  803. package/src/bongos/api-path-404.js +67 -0
  804. package/src/bongos/api-prefix.js +38 -0
  805. package/src/bongos/app-pair.js +172 -0
  806. package/src/bongos/auth.js +979 -0
  807. package/src/bongos/cascade-dispatch.js +123 -0
  808. package/src/bongos/db-kernel.js +252 -0
  809. package/src/bongos/db.js +911 -0
  810. package/src/bongos/goal-scope-check.js +120 -0
  811. package/src/bongos/hierarchy-config.js +189 -0
  812. package/src/bongos/live-channel.js +145 -0
  813. package/src/bongos/llm-cache.js +260 -0
  814. package/src/bongos/llm-pricing.js +220 -0
  815. package/src/bongos/metrics.js +286 -0
  816. package/src/bongos/middleware/audit.js +274 -0
  817. package/src/bongos/middleware/error-envelope.js +93 -0
  818. package/src/bongos/middleware/rate-limit.js +195 -0
  819. package/src/bongos/module-scope-map.js +271 -0
  820. package/src/bongos/optimizer.js +166 -0
  821. package/src/bongos/path-match.js +47 -0
  822. package/src/bongos/permission-path-check.js +248 -0
  823. package/src/bongos/pool.js +55 -0
  824. package/src/bongos/repo-info.js +91 -0
  825. package/src/bongos/route-rank-check.js +420 -0
  826. package/src/bongos/routes/CLAUDE.md +43 -0
  827. package/src/bongos/routes/_helpers.js +369 -0
  828. package/src/bongos/routes/audit-log.js +59 -0
  829. package/src/bongos/routes/auth.js +755 -0
  830. package/src/bongos/routes/backup.js +104 -0
  831. package/src/bongos/routes/builders.js +526 -0
  832. package/src/bongos/routes/healthz.js +16 -0
  833. package/src/bongos/routes/instance.js +129 -0
  834. package/src/bongos/routes/live.js +125 -0
  835. package/src/bongos/routes/llm-cache.js +119 -0
  836. package/src/bongos/routes/me.js +380 -0
  837. package/src/bongos/routes/modules.js +131 -0
  838. package/src/bongos/routes/optimizer.js +54 -0
  839. package/src/bongos/routes/public.js +476 -0
  840. package/src/bongos/routes/security.js +207 -0
  841. package/src/bongos/routes.js +166 -0
  842. package/src/bongos/secret-box.js +177 -0
  843. package/src/bongos/sensitive-surfaces.js +30 -0
  844. package/src/bongos/serve-internal.js +889 -0
  845. package/src/bongos/uptime-poller.js +90 -0
  846. package/src/bongos-downloads.js +70 -0
  847. package/src/branding.js +182 -0
  848. package/src/build-info.js +77 -0
  849. package/src/devbox-downloads.js +67 -0
  850. package/src/instance-config.js +200 -0
  851. package/src/module-api.js +366 -0
  852. package/src/module-loader/loader.js +268 -0
  853. package/src/module-loader/manifest-schema.js +140 -0
  854. package/src/module-loader/provenance.js +28 -0
  855. package/src/module-loader/semver.js +100 -0
  856. package/src/module-seams.js +291 -0
  857. package/src/modules.js +254 -0
  858. package/src/platform-server.js +135 -0
  859. package/src/ui/adapters/claude-design/index.js +333 -0
  860. package/src/ui/adapters/figma/index.js +328 -0
  861. package/tests/abandon_task.mjs +138 -0
  862. package/tests/achievements_reconcile.mjs +167 -0
  863. package/tests/adopt_detect.mjs +141 -0
  864. package/tests/adopt_import.mjs +132 -0
  865. package/tests/adopt_preflight.mjs +105 -0
  866. package/tests/anti_grid.mjs +89 -0
  867. package/tests/api_client.mjs +231 -0
  868. package/tests/api_docs.mjs +283 -0
  869. package/tests/api_error_envelope_buildcheck.mjs +56 -0
  870. package/tests/api_error_envelope_middleware.mjs +99 -0
  871. package/tests/api_error_registry.mjs +108 -0
  872. package/tests/api_pagination_contract.mjs +51 -0
  873. package/tests/api_path_404.mjs +96 -0
  874. package/tests/app_pair.mjs +168 -0
  875. package/tests/architect.mjs +140 -0
  876. package/tests/art_key.mjs +121 -0
  877. package/tests/art_stage.mjs +121 -0
  878. package/tests/asset_version.mjs +94 -0
  879. package/tests/atlas.mjs +69 -0
  880. package/tests/audit_deps.mjs +74 -0
  881. package/tests/audit_middleware.mjs +385 -0
  882. package/tests/auth_admission_gate.mjs +164 -0
  883. package/tests/auth_anthropic_identity.mjs +95 -0
  884. package/tests/auth_duplicate_cookie.mjs +56 -0
  885. package/tests/auth_error_brand.mjs +77 -0
  886. package/tests/auth_flow_slice1.mjs +223 -0
  887. package/tests/auth_inactive_builder.mjs +94 -0
  888. package/tests/auth_page_gate.mjs +92 -0
  889. package/tests/auth_session_ttl.mjs +155 -0
  890. package/tests/autonomous_fit_protected_paths.mjs +115 -0
  891. package/tests/autonomy_gate.mjs +85 -0
  892. package/tests/autotile_variants.mjs +256 -0
  893. package/tests/autotile_xverify.mjs +133 -0
  894. package/tests/backfill_sessions.mjs +101 -0
  895. package/tests/backfill_task_rewards.mjs +152 -0
  896. package/tests/backup_cli.mjs +104 -0
  897. package/tests/bfg.mjs +327 -0
  898. package/tests/bfg_write.mjs +423 -0
  899. package/tests/bongos_box_connect.mjs +89 -0
  900. package/tests/bongos_dispatch.mjs +74 -0
  901. package/tests/bongos_downloads.mjs +118 -0
  902. package/tests/bongos_login.mjs +34 -0
  903. package/tests/box_access.mjs +186 -0
  904. package/tests/box_auth_check.mjs +114 -0
  905. package/tests/box_code_staleness.mjs +116 -0
  906. package/tests/box_connect_e2e.mjs +196 -0
  907. package/tests/box_cost.mjs +70 -0
  908. package/tests/box_dns_repoint.mjs +151 -0
  909. package/tests/box_host_keys.mjs +102 -0
  910. package/tests/box_onboard.mjs +317 -0
  911. package/tests/box_scope_session.mjs +115 -0
  912. package/tests/box_ship_permissions.mjs +71 -0
  913. package/tests/box_terminal_ssrf.mjs +90 -0
  914. package/tests/boxes.mjs +1255 -0
  915. package/tests/branding.mjs +88 -0
  916. package/tests/bug_attachments.mjs +189 -0
  917. package/tests/build_info.mjs +88 -0
  918. package/tests/builder_needs.mjs +99 -0
  919. package/tests/cap_newcomer_tasks.mjs +114 -0
  920. package/tests/cascade-dispatch.mjs +95 -0
  921. package/tests/cf_tunnel.mjs +459 -0
  922. package/tests/claim_recall.mjs +150 -0
  923. package/tests/claims_bind_session.mjs +47 -0
  924. package/tests/claude_materialize.mjs +148 -0
  925. package/tests/cli_box_scope.mjs +52 -0
  926. package/tests/cli_lib_formatters.mjs +87 -0
  927. package/tests/cli_token_reissue.mjs +147 -0
  928. package/tests/client_bundle_route.mjs +47 -0
  929. package/tests/cloud_bongos_pack.mjs +85 -0
  930. package/tests/conductor.mjs +496 -0
  931. package/tests/confirm_attribution.mjs +156 -0
  932. package/tests/conflict_resolve.mjs +462 -0
  933. package/tests/context_pack.mjs +240 -0
  934. package/tests/cost.mjs +94 -0
  935. package/tests/cost_audit.mjs +122 -0
  936. package/tests/cost_budget_status.mjs +78 -0
  937. package/tests/cost_reconcile.mjs +102 -0
  938. package/tests/cost_summary_shape.mjs +94 -0
  939. package/tests/credit_grant.mjs +376 -0
  940. package/tests/criterion_progress.mjs +220 -0
  941. package/tests/criterion_proposal.mjs +109 -0
  942. package/tests/criterion_ref_parse.mjs +53 -0
  943. package/tests/currency_label.mjs +119 -0
  944. package/tests/day_cycle.mjs +197 -0
  945. package/tests/dependencies_migration.mjs +77 -0
  946. package/tests/dependencies_polymorphic.mjs +212 -0
  947. package/tests/deploy_instance.mjs +78 -0
  948. package/tests/devbox_downloads.mjs +122 -0
  949. package/tests/diff_derived_signals.mjs +115 -0
  950. package/tests/discord_approvals.mjs +174 -0
  951. package/tests/discord_autojoin.mjs +158 -0
  952. package/tests/discord_bot.mjs +94 -0
  953. package/tests/discord_bugs.mjs +297 -0
  954. package/tests/discord_channels.mjs +337 -0
  955. package/tests/discord_foundation.mjs +76 -0
  956. package/tests/discord_inbound.mjs +190 -0
  957. package/tests/discord_message_buffer.mjs +87 -0
  958. package/tests/discord_oauth.mjs +55 -0
  959. package/tests/discord_reaction.mjs +170 -0
  960. package/tests/discord_role_sync.mjs +151 -0
  961. package/tests/display_name.mjs +123 -0
  962. package/tests/dns_preflight.mjs +74 -0
  963. package/tests/event_sound_prefs.mjs +194 -0
  964. package/tests/eviction_policy.mjs +279 -0
  965. package/tests/figma_adapter.mjs +199 -0
  966. package/tests/file_map.mjs +91 -0
  967. package/tests/first_admin_bootstrap.mjs +40 -0
  968. package/tests/fitness.mjs +435 -0
  969. package/tests/fitness_two_root.mjs +104 -0
  970. package/tests/fixtures/session-506-digest.json +34 -0
  971. package/tests/gate_approvals.mjs +451 -0
  972. package/tests/gate_review.mjs +152 -0
  973. package/tests/git_merge_regen.mjs +151 -0
  974. package/tests/github_push_ancestry.mjs +119 -0
  975. package/tests/github_push_land_proof.mjs +127 -0
  976. package/tests/github_push_merge_driver.mjs +175 -0
  977. package/tests/goal_abuse_matrix.mjs +187 -0
  978. package/tests/goal_achievement.mjs +146 -0
  979. package/tests/goal_conflicts.mjs +305 -0
  980. package/tests/goal_dependencies_read.mjs +73 -0
  981. package/tests/goal_member_roles.mjs +420 -0
  982. package/tests/goal_membership_requests.mjs +332 -0
  983. package/tests/goal_routes.mjs +203 -0
  984. package/tests/goal_scope_check.mjs +167 -0
  985. package/tests/goal_tier.mjs +312 -0
  986. package/tests/goal_wall_proof.mjs +112 -0
  987. package/tests/grade_attempts.mjs +73 -0
  988. package/tests/grade_attribution.mjs +117 -0
  989. package/tests/grade_diff_hash.mjs +191 -0
  990. package/tests/grade_server_authoritative.mjs +305 -0
  991. package/tests/grade_unavailable_display.mjs +66 -0
  992. package/tests/grader.mjs +1960 -0
  993. package/tests/grader_bypass.mjs +57 -0
  994. package/tests/grader_panel.mjs +252 -0
  995. package/tests/grader_prompt_fencing.mjs +192 -0
  996. package/tests/helpers.mjs +52 -0
  997. package/tests/hierarchy-config.mjs +81 -0
  998. package/tests/init.mjs +463 -0
  999. package/tests/instance_config.mjs +76 -0
  1000. package/tests/instance_manifest.mjs +110 -0
  1001. package/tests/interaction_prefs.mjs +72 -0
  1002. package/tests/key-card.mjs +110 -0
  1003. package/tests/key-status.mjs +45 -0
  1004. package/tests/land_watch.mjs +115 -0
  1005. package/tests/lifecycle-card.mjs +145 -0
  1006. package/tests/lifecycle_breakdown_view.mjs +236 -0
  1007. package/tests/linkify_refs.mjs +264 -0
  1008. package/tests/live_channel.mjs +128 -0
  1009. package/tests/live_sse.mjs +122 -0
  1010. package/tests/llm-cache-route.mjs +110 -0
  1011. package/tests/llm-cache.mjs +140 -0
  1012. package/tests/llm-pricing.mjs +152 -0
  1013. package/tests/local_preview.mjs +136 -0
  1014. package/tests/main_audit.mjs +137 -0
  1015. package/tests/memory_isolation.mjs +431 -0
  1016. package/tests/memory_map.mjs +107 -0
  1017. package/tests/memory_pull.mjs +429 -0
  1018. package/tests/merge_lease.mjs +100 -0
  1019. package/tests/merge_lock.mjs +312 -0
  1020. package/tests/metrics.mjs +147 -0
  1021. package/tests/migration_allocation.mjs +146 -0
  1022. package/tests/migration_namespace.mjs +185 -0
  1023. package/tests/migrations_fresh_replay_guard.mjs +38 -0
  1024. package/tests/mirror_lineage_fulltree.mjs +45 -0
  1025. package/tests/mirror_lineage_proof.mjs +72 -0
  1026. package/tests/mirror_redact.mjs +193 -0
  1027. package/tests/model_alloc_prefs.mjs +63 -0
  1028. package/tests/module-scope-map.mjs +88 -0
  1029. package/tests/module_api.mjs +110 -0
  1030. package/tests/module_cli.mjs +292 -0
  1031. package/tests/module_contributions.mjs +148 -0
  1032. package/tests/module_loader.mjs +286 -0
  1033. package/tests/module_manifest.mjs +194 -0
  1034. package/tests/module_owned_tests.mjs +105 -0
  1035. package/tests/module_provenance.mjs +34 -0
  1036. package/tests/module_route_rank.mjs +147 -0
  1037. package/tests/module_seams.mjs +68 -0
  1038. package/tests/modules.mjs +156 -0
  1039. package/tests/modules_route.mjs +38 -0
  1040. package/tests/newcomer_floor.mjs +17 -0
  1041. package/tests/newcomer_restock.mjs +80 -0
  1042. package/tests/next_number.mjs +154 -0
  1043. package/tests/oauth_secret.mjs +60 -0
  1044. package/tests/onboard.mjs +70 -0
  1045. package/tests/onboarding_gate.mjs +267 -0
  1046. package/tests/onboarding_observability.mjs +344 -0
  1047. package/tests/onboarding_route_signals.mjs +175 -0
  1048. package/tests/onboarding_state.mjs +346 -0
  1049. package/tests/one_active_claim_per_session.mjs +111 -0
  1050. package/tests/orphaned_claim_ship.mjs +135 -0
  1051. package/tests/override_attribution.mjs +142 -0
  1052. package/tests/override_request_ownership.mjs +235 -0
  1053. package/tests/package_core.mjs +435 -0
  1054. package/tests/parallel-load.mjs +402 -0
  1055. package/tests/path_match.mjs +62 -0
  1056. package/tests/permission_path.mjs +151 -0
  1057. package/tests/platform_boot.mjs +167 -0
  1058. package/tests/pre_compact.mjs +60 -0
  1059. package/tests/preview_server.mjs +127 -0
  1060. package/tests/profile_route.mjs +197 -0
  1061. package/tests/provision.mjs +805 -0
  1062. package/tests/provisioning_github_app_routes.mjs +98 -0
  1063. package/tests/public_mirror_export.mjs +124 -0
  1064. package/tests/public_task_resolver.mjs +112 -0
  1065. package/tests/publish_branch_route.mjs +422 -0
  1066. package/tests/publish_manifest.mjs +184 -0
  1067. package/tests/publish_reconciler.mjs +728 -0
  1068. package/tests/rank_gate.mjs +463 -0
  1069. package/tests/rate_limit_public.mjs +217 -0
  1070. package/tests/read_session_export.mjs +89 -0
  1071. package/tests/recall_cli.mjs +82 -0
  1072. package/tests/recall_hints.mjs +119 -0
  1073. package/tests/recent_shipped_window.mjs +80 -0
  1074. package/tests/regrade_eligibility.mjs +202 -0
  1075. package/tests/render_prefs.mjs +122 -0
  1076. package/tests/repo_map.mjs +92 -0
  1077. package/tests/reward_gate.mjs +284 -0
  1078. package/tests/route_rank_check.mjs +243 -0
  1079. package/tests/route_validation.mjs +490 -0
  1080. package/tests/routine_timers.mjs +72 -0
  1081. package/tests/rubric_fixtures.mjs +140 -0
  1082. package/tests/run_routine.mjs +69 -0
  1083. package/tests/sandbox_stage.mjs +582 -0
  1084. package/tests/scrubber_corpus.mjs +257 -0
  1085. package/tests/search_chunker.mjs +209 -0
  1086. package/tests/search_ingest.mjs +96 -0
  1087. package/tests/search_ingest_db.mjs +88 -0
  1088. package/tests/search_isolation.mjs +204 -0
  1089. package/tests/search_route.mjs +95 -0
  1090. package/tests/secret_box.mjs +189 -0
  1091. package/tests/security_docs.mjs +186 -0
  1092. package/tests/security_route.mjs +108 -0
  1093. package/tests/served_paths_shipped.mjs +118 -0
  1094. package/tests/session-cards.mjs +142 -0
  1095. package/tests/session_506_regression.mjs +69 -0
  1096. package/tests/session_caps.mjs +238 -0
  1097. package/tests/session_cost.mjs +133 -0
  1098. package/tests/session_digest.mjs +73 -0
  1099. package/tests/session_eval.mjs +386 -0
  1100. package/tests/session_index.mjs +105 -0
  1101. package/tests/session_records.mjs +369 -0
  1102. package/tests/session_search.mjs +78 -0
  1103. package/tests/session_start_freshness.mjs +123 -0
  1104. package/tests/setup_smoke.mjs +154 -0
  1105. package/tests/ship_autolinkify.mjs +60 -0
  1106. package/tests/ship_automerge_injection.mjs +174 -0
  1107. package/tests/ship_broadcast_routing.mjs +125 -0
  1108. package/tests/ship_broadcast_server.mjs +175 -0
  1109. package/tests/ship_card.mjs +280 -0
  1110. package/tests/ship_ci_deploy.mjs +374 -0
  1111. package/tests/ship_preflight.mjs +368 -0
  1112. package/tests/ship_premerge.mjs +75 -0
  1113. package/tests/ship_resume.mjs +129 -0
  1114. package/tests/ship_upload_skip.mjs +89 -0
  1115. package/tests/ship_zero_commit.mjs +60 -0
  1116. package/tests/single_host_hall.mjs +98 -0
  1117. package/tests/skill_prefs.mjs +150 -0
  1118. package/tests/smoke_preflight.mjs +66 -0
  1119. package/tests/snapshot_picker.mjs +233 -0
  1120. package/tests/sound_prefs.mjs +198 -0
  1121. package/tests/sprite_facing.mjs +35 -0
  1122. package/tests/status-probe.mjs +89 -0
  1123. package/tests/status_backfill.mjs +94 -0
  1124. package/tests/stop_refcheck.mjs +127 -0
  1125. package/tests/streak.mjs +175 -0
  1126. package/tests/subdomain_auth.mjs +58 -0
  1127. package/tests/task_classifier_vocab.mjs +41 -0
  1128. package/tests/task_create_idempotency.mjs +96 -0
  1129. package/tests/task_goal_link.mjs +93 -0
  1130. package/tests/task_ownership_gate.mjs +125 -0
  1131. package/tests/terrain_picker.mjs +298 -0
  1132. package/tests/touches_overlap.mjs +75 -0
  1133. package/tests/triage_development.mjs +140 -0
  1134. package/tests/turn_in_place.mjs +280 -0
  1135. package/tests/upgrade.mjs +357 -0
  1136. package/tests/verify_task_guard.mjs +64 -0
  1137. package/tests/version_close.mjs +76 -0
  1138. package/tests/versions_route.mjs +93 -0
  1139. package/tests/walkability.mjs +188 -0
  1140. package/tests/wandering_prefs.mjs +176 -0
  1141. package/tests/worktree_disambiguation.mjs +105 -0
  1142. package/tests/worktree_guard.mjs +90 -0
@@ -0,0 +1,30 @@
1
+ # ADR 0126 — Dedicated cloudbongos.com control-plane droplet (infra split from the co-hosting box)
2
+
3
+ **Status:** Accepted — implemented 2026-07-05 (task [#2063](https://example.com/builders#/task/2063)).
4
+
5
+ ## Context
6
+
7
+ cloudbongos.com (Customer 0, the vanilla dogfood instance — [ADR 0062](<redacted>.md) §2, [`docs/recipes/cloudbongos-standup.md`](../recipes/cloudbongos-standup.md)) ran as a **co-tenant on the OTB game droplet** (`REDACTED_IP`): same checkout, port 3002, its own `cloudbongos` DB. The token-holding **control plane** lived on that same box — `/etc/example/box.env` holds the account's DigitalOcean token **and** the Cloudflare token, drained by `scripts/gds/provision.js` (the instance provisioner, [ADR 0111](<redacted>.md)) and `scripts/gds/box.js` (dev boxes).
8
+
9
+ That co-location is the weak point in the trust posture: the powerful, account-wide cloud tokens sat on the **same machine** as the game and any co-hosted third-party instance (`emersonian-circles.`, `staging.`). A compromise of any co-hosted workload could reach <redacted> and droplet creation. The existing plan ([ADR 0100](<redacted>.md)/[0108](<redacted>.md), spine R84→R89) only separated cloudbongos.com as a *side effect* of the deferred "Example split" (R89, [#1728](https://example.com/builders#/task/1728)), keeping it co-tenant "for cost" until then.
10
+
11
+ The owner elected to pull the **infrastructure** separation forward, explicitly accepting a second droplet's cost, for the security division.
12
+
13
+ ## Decision
14
+
15
+ Run cloudbongos.com on its **own dedicated droplet** that is also the **sole token-holding control plane**:
16
+
17
+ - **New droplet** `cloudbongos` — DigitalOcean `REDACTED_IP`, nyc3, `s-1vcpu-2gb` ($12/mo), Ubuntu 24.04, tagged `cloudbongos-control` (deliberately **not** `PROVISION_TAG`, so the provisioning reconciler never treats the control plane as a disposable instance).
18
+ - **Structural SSH separation** — reached only via a dedicated `cloudbongos_ed25519` key, distinct from the example box's key.
19
+ - **Own stack** — Node 22 / PostgreSQL 16 / Caddy, IPv6 egress disabled (so the IPv4-locked Cloudflare token can never be spuriously rejected — `checkDnsTokenScope` uses plain `fetch` with no `-4`, unlike `infra/box-dns-cloudflare.sh`).
20
+ - **Holds the tokens** — `/etc/cloudbongos/box.env` (mode 600) carries a **new account-wide Cloudflare token** (Edit-zone-DNS, all zones, IP-locked to `REDACTED_IP`) + the DigitalOcean token. This is the box that provisions instance subdomains for the hosting/provisioning module ([ADR 0111](<redacted>.md) §2 — tokens on the control plane, never the web tier; mirrors [ADR 0031](<redacted>.md) §6).
21
+ - **The co-hosting box** (the former OTB droplet, `REDACTED_IP`) stays as-is for the game + co-hosted project instances; the cloudbongos co-tenant unit was removed.
22
+
23
+ The checkout is still a clone of `example-owner/example` running `src/platform-server.js` with `GDS_BRANDING_FILE=config/branding.cloudbongos.json` (a **lift-and-shift**, not the ADR 0108 pinned-`@cloudbongos/core` standalone model — that remains the longer-term shape).
24
+
25
+ ## Consequences
26
+
27
+ - The account-wide cloud tokens no longer sit next to the game or third-party workloads — the division the owner asked for. This also **de-risks R89**: cloudbongos.com is already infra-decoupled, so splitting Example can't break it.
28
+ - cloudbongos.com's data was migrated (pg_dump → restore) and DNS cut over (apex + `builders.` + `status.` A records → `REDACTED_IP`, kept proxied); `emersonian-circles.`/`staging.` deliberately stayed on the co-hosting box.
29
+ - **Not yet done (tracked):** the co-hosting box **still holds its own DO token + a narrow (example.com-locked) CF token** for dev-box (`box.js`) + `provision-intent-runner` duties — reaching "zero cloud tokens on the co-hosting box" needs dev-box + instance orchestration to move to this control plane first (`provision.js` does local ops today; remote-orchestrating co-tenant workloads is unbuilt) — task [#2065](https://example.com/builders#/task/2065). The new box has **no deploy automation** yet (it won't track `main` until wired) — task [#2064](https://example.com/builders#/task/2064). The old `cloudbongos` DB is retained on the co-hosting box as a rollback net until a bake period passes.
30
+ - No hardening drop-in on `cloudbongos.service` yet (mirror `infra/example.service.d/hardening.conf` once proven — the standup recipe's standing note).
@@ -0,0 +1,64 @@
1
+ # ADR 0127 — Cross-box fleet observability on the control-plane droplet
2
+
3
+ Status: Accepted (2026-07-05, task [#2059](https://example.com/builders#/task/2059))
4
+
5
+ ## Context
6
+
7
+ Task 2020 stood up Grafana + Prometheus on the co-hosting box, scraping that one
8
+ box's Bongos API. The owner then re-scoped it: the exported metrics (`gds_http`,
9
+ `gds_tasks`, `gds_claims`, `gds_builders`, `gds_auth_failures`) measure the **Bongos
10
+ platform API**, not any single game — so the dashboards are *platform* observability
11
+ and belong on the **cloudbongos** domain, watching **every** instance, not a
12
+ project-specific one.
13
+
14
+ Then [ADR 0126](<redacted>.md) moved
15
+ cloudbongos.com onto a dedicated **control-plane droplet** (REDACTED_IP) that
16
+ holds the account-wide Cloudflare token and serves `*.cloudbongos.com`. That split
17
+ the fleet across two droplets:
18
+
19
+ - **control-plane box** (REDACTED_IP): `cloudbongos` instance.
20
+ - **co-hosting box** (REDACTED_IP): `example` (the game) + `emersonian-circles`.
21
+
22
+ So platform observability must (a) live where a `metrics.cloudbongos.com` surface
23
+ belongs — the control-plane box (it has the cloudbongos origin cert + Caddy + the
24
+ DNS token), and (b) scrape instances on **both** boxes. The apps' `/metrics`
25
+ exporters bind `127.0.0.1` only, and a remote scrape normally needs a `METRICS_TOKEN`
26
+ (Bearer). Both droplets share a DigitalOcean **private VPC** (`10.108.0.0/20`).
27
+
28
+ ## Decision
29
+
30
+ - **Grafana + Prometheus run on the control-plane box.** `metrics.cloudbongos.com`
31
+ (proxied A record → REDACTED_IP, on the `*.cloudbongos.com` origin cert) is
32
+ reverse-proxied to Grafana, Archon-only (Caddy `basic_auth` + Grafana admin login).
33
+ - **Prometheus scrapes the whole fleet with a per-`project` label.** `cloudbongos`
34
+ is local (`127.0.0.1:3002`). The co-hosting box's instances are scraped **over the
35
+ private VPC** via two tiny `socat` TCP forwarders on that box (`metrics-fwd-*`
36
+ systemd units) bound to its private IP (`10.108.0.2:9101→127.0.0.1:3000`,
37
+ `:9102→:3004`), **ufw-locked to the control-plane box's private IP** only.
38
+ - **socat (raw TCP relay), not a Caddy/token proxy, for the cross-box hop.** A raw
39
+ relay preserves the exporter's loopback-with-no-`X-Forwarded-For` semantics, so the
40
+ app serves metrics **without a token and without a restart**. The security boundary
41
+ is the private VPC + the ufw allow-list (only the control-plane box) + the fact that
42
+ the control-plane box is already the most-trusted host in the fleet. The exporter's
43
+ `METRICS_TOKEN` Bearer path is **reserved for future off-VPC / dedicated-droplet
44
+ instances**, which can't use a private forwarder.
45
+ - Dashboards gain a `project` template variable; every query filters by
46
+ `project=~"$project"` (default All), so each panel shows one instance or the fleet.
47
+
48
+ ## Consequences
49
+
50
+ - **+** Clean separation matching ADR 0126: the cloudbongos-branded metrics surface
51
+ lives on the cloudbongos box, not the game box. One fleet-wide pane. Neither
52
+ Prometheus nor Grafana is publicly bound; the cross-box hop never leaves the VPC.
53
+ No live-game restart was needed to wire it.
54
+ - **−** Each socat forwarder exposes the **whole** app port (not just `/metrics`) to
55
+ the control-plane box over the VPC. Accepted: ufw restricts the source to the one
56
+ trusted control-plane IP, the traffic stays on the private VPC, and a compromise of
57
+ the control-plane box is already game-over (it holds the account-wide CF + DO
58
+ tokens). A `/metrics`-only exposure would require a Caddy proxy + `METRICS_TOKEN` +
59
+ restarting the instances — not worth it for this trust posture.
60
+ - **−** Cross-box scraping depends on the DO VPC + the `metrics-fwd-*` units + ufw
61
+ rules on the co-hosting box. If that box is re-provisioned, re-add them (see
62
+ [`infra/grafana/README.md`](../../infra/grafana/README.md)).
63
+ - **Follow-up:** token-based (or DNS-SD) discovery for provisioned / dedicated-droplet
64
+ instances — the general hosting-module case, not yet wired.
@@ -0,0 +1,46 @@
1
+ # ADR 0128 — Provisioning runner privilege + DB-auth model (`PROVISION_SUDO`)
2
+
3
+ **Status:** Accepted — implemented 2026-07-05 (task [#2066](https://example.com/builders#/task/2066), BONGOS-V1, goal 35 / criterion `project-creation-flow`).
4
+
5
+ ## Context
6
+
7
+ [ADR 0111](<redacted>.md) built `scripts/gds/provision.js` — the control-plane runner that drains `provisioning_intents` and composes the [cloudbongos-standup](../recipes/cloudbongos-standup.md) runbook (createdb → GDS-only migrate → per-instance `/etc/<slug>/web.env` → systemd unit → per-instance Caddy snippet → `/healthz`). It was written injectable + dry-run-default and unit-tested, **but never run end-to-end** — every existing co-located instance (`emersonian-circles`, the vanity doors) was hand-wired by an operator. The 2026-07-05 first real greenfield standup attempt ([#2053](https://example.com/builders#/task/2053)–[#2056](https://example.com/builders#/task/2056)) surfaced three ops gaps. Two were resolved on-box (Cloudflare token scope → [ADR 0126](<redacted>.md); the Caddy on-demand-TLS global that the live `/etc/caddy/Caddyfile` lacked). This ADR is the third, load-bearing one.
8
+
9
+ `provision-intent-runner.service` runs as **`User=lars`** (a non-root user). But every mutating step assumed a privilege the runner does not have when driven headlessly:
10
+
11
+ - **`/etc` writes** — `web.env` (`/etc/<slug>/`), the systemd unit (`/etc/systemd/system/`), and the Caddy snippet (`/etc/caddy/sites/`) went through a bare `fs.writeFileSync`. Confirmed on the box: `lars` cannot write under `/etc` (`mkdir /etc/_provtest` → `EACCES`).
12
+ - **`systemctl` / `caddy` reloads** — `daemon-reload`, `enable --now`, `reload caddy`, `disable --now` ran without `sudo`.
13
+ - **`createdb` + `migrate`** — both authenticate to Postgres by **peer auth as the running user**. On this box `lars` is *not* a usable PG role (the app connects via `DATABASE_URL`), so `createdb <slug>` and `migrate.sh`'s `psql` both fail.
14
+
15
+ Two things additionally made a naive "just add `sudo`" fix silently fail: the unit set **`NoNewPrivileges=true`** (which sets `PR_SET_NO_NEW_PRIVS` and *blocks the setuid `sudo` binary from escalating at all*), and `sudo` resets the environment (so a bare `sudo -u postgres PGDATABASE=x ./migrate.sh` would have `sudo` parse `PGDATABASE=x` as a command).
16
+
17
+ The whole point is that this runner must NOT bake operator identity into behavior ([ADR 0016](<redacted>.md)), tests must stay hermetic (no shell/DB/network), and the same code drives co-tenant, standalone, and (via cloud-init) dedicated shapes.
18
+
19
+ ## Decision
20
+
21
+ Add a single config knob, **`PROVISION_SUDO=1`** (alias `PROVISION_PRIVILEGED=1`), read once into `CONFIG.privileged`. **Default OFF** preserves the exact current behavior (bare commands, direct `fs` writes) — so tests, a root context, and the co-tenant-legacy path are byte-for-byte unaffected. When ON, exactly the privileged steps escalate, and **dry-run still logs the exact command** either way:
22
+
23
+ - **`/etc` writes** → the body is staged in a temp file (`os.tmpdir()`, lars-writable) and placed atomically with **`sudo install -D -m <mode> <tmp> <dest>`** (`-D` creates the parent dir, e.g. `/etc/<slug>/`; `-m` sets the mode). The install runs through the *same* injected `exec`, so it shares the dry-run/apply + logging path. `makeWriteFile` escalates only when a call opts in with `{ sudo: true }` — the three `/etc` destinations do; the scaffold's temp/`.gitignore` writes (under `/tmp` and `/srv/<slug>`) stay direct.
24
+ - **`systemctl` / `rm` under `/etc`** → `sudo`-prefixed at the call site (`provisionInstance` + `teardownInstance`).
25
+ - **`createdb` + `migrate`** → run as the **postgres** OS user (`sudo -u postgres …`), which peer-auths as the PG superuser (the Ubuntu default) — so the runner never needs `lars` to be a PG role. `migrate` passes its env via `env PGDATABASE=… MEDUSA_GDS_ONLY=1` and runs the script via `bash …` so the vars survive `sudo`'s env reset. Applies to both the co-tenant (`migrateCmd`) and standalone (`standaloneMigrateCmd`) legs.
26
+
27
+ `infra/provision-intent-runner.service` is updated to make the model operational: **`Environment=PROVISION_SUDO=1`** turns the knob on for the deployed runner, and **`NoNewPrivileges=false`** (with an explanatory comment) is required — a `true` value silently defeats every `sudo` above. `PrivateTmp=true` stays (the `sudo install` temp files live in the service's private `/tmp`, which its sudo children share).
28
+
29
+ **Preconditions** (operational, documented — the same class as "the runner holds the DO/CF tokens"):
30
+
31
+ 1. The runner's user has **passwordless sudo** on the control-plane box (true on `REDACTED_IP`).
32
+ 2. The checkout `migrate` runs from must be **readable by the `postgres` OS user** (on `REDACTED_IP` the standalone base is `/srv/cloudbongos`, world-traversable — *not* under a `700` home).
33
+
34
+ ## Consequences
35
+
36
+ - **Goal-35 automation can complete end-to-end** — this was the blocker for the real greenfield standup ([#2056](https://example.com/builders#/task/2056)) and criterion `project-creation-flow`.
37
+ - **No blast radius when off.** The knob defaults false; all 30 pre-existing unit tests stay green, and any non-runner invocation (a CLI dry-run, a root context) is unchanged. 8 new tests pin both the escalated command shapes (`sudo -u postgres createdb`, `env`+`bash` migrate, `sudo install -D -m`, `sudo systemctl`) and the *absence* of any `sudo` in the default path.
38
+ - **The runner is intentionally less sandboxed** (`NoNewPrivileges=false`, sudo enabled). Accepted: this runner is already the sole holder of the DO/Cloudflare tokens and performs inherently privileged control-plane ops; least-privilege here means *explicit, per-step* `sudo` (not running the whole process as root).
39
+ - **The dedicated-droplet cloud-init path is deliberately unchanged** (`dedicatedUserData`). It runs as root on a fresh droplet — a different privilege + file-perms model — and is out of the co-tenant/standalone scope this task exercised; escalating it is a separate change.
40
+ - **Follow-ups noted from the standup:** the live `/etc/caddy/Caddyfile` drifts from `infra/Caddyfile` with no auto-sync (a deploy-time reconcile is worth considering); the migrate-as-postgres readable-checkout precondition should be asserted by the box provisioning, not just documented.
41
+
42
+ ## Alternatives considered
43
+
44
+ - **Grant `lars` a PG login role + writable `/etc`.** Rejected: non-portable per-box setup, and it weakens the trust boundary — the runner shouldn't *own* `/etc` or be a standing PG superuser; `sudo -u postgres` is scoped to the two DB commands.
45
+ - **Run the whole runner as root** (`User=root`). Rejected: over-privileged for the many non-privileged steps (git, npm, node, healthz, the DNS hook). Per-step `sudo` keeps the default footprint small and every escalation greppable.
46
+ - **Do createdb/migrate via the app `DATABASE_URL` connection** instead of `sudo -u postgres`. A valid option the task description named, and one an instance may adopt — but the runner doesn't hold the app DB creds today and the standup env uses peer auth, so `sudo -u postgres` is the portable default. Left open for a future instance that wires DB creds into the runner's box.env.
@@ -0,0 +1,34 @@
1
+ # ADR 0129 — cloudbongos.com control-plane box deploys by a pull timer, not the CI push
2
+
3
+ **Status:** Accepted — implemented 2026-07-05 (task [#2064](https://example.com/builders#/task/2064)). Follows [ADR 0126](<redacted>.md).
4
+
5
+ ## Context
6
+
7
+ The 2026-07-05 dedicated-droplet migration ([ADR 0126](<redacted>.md), task [#2063](https://example.com/builders#/task/2063)) moved cloudbongos.com onto its own box (`REDACTED_IP`, checkout `/home/lars/cloudbongos`, `cloudbongos.service`, port 3002). The co-hosting box (`REDACTED_IP`) still auto-deploys **example.com** via [`.github/workflows/deploy-prod.yml`](../../.github/workflows/deploy-prod.yml) (SSH → `~/deploy.sh` on merge to `main`, [ADR 0042](<redacted>.md)). That path only touches the co-hosting box. **Nothing pulled `main` onto the new box**, so cloudbongos.com served its boot-time code and drifted — ADR 0126 §Consequences flagged this as task 2064.
8
+
9
+ The task allowed either extending the CI push workflow to also target the new box, **or** a pull-based timer on the box.
10
+
11
+ ## Decision
12
+
13
+ Deploy the control-plane box with a **pull-based systemd timer**, not by extending the CI push.
14
+
15
+ - [`scripts/deploy/deploy-cloudbongos.sh`](../../scripts/deploy/deploy-cloudbongos.sh) — the deploy: `git fetch` + reset to `origin/main` → `npm ci --omit=dev` (only if `package-lock.json` changed) → `PGDATABASE=cloudbongos MEDUSA_GDS_ONLY=1 ./scripts/migrate.sh` → `sudo systemctl restart cloudbongos` → poll `127.0.0.1:3002/healthz`, then rebuild the gitignored Hall nav surfaces. Idempotent, with a fast no-op exit when `HEAD == origin/main`.
16
+ - [`infra/cloudbongos-deploy.service`](../../infra/cloudbongos-deploy.service) + [`infra/cloudbongos-deploy.timer`](../../infra/cloudbongos-deploy.timer) — a `oneshot` service fired every ~2 min (measured from the end of the last run).
17
+
18
+ ### Why pull, not CI push
19
+
20
+ 1. **Blast radius.** The dedicated box exists to shrink the cloud-token / prod-SSH-key exposure (ADR 0126). Extending CI would require storing **this box's** prod SSH key as a GitHub Actions secret — more secret sprawl, against the migration's whole grain. A pull uses the box's **existing** GitHub deploy key (`git@github-deploy:…`), so no new secret leaves the box and the shared `deploy-prod.yml` is untouched.
21
+ 2. **Convention.** It matches the self-healing `*-runner.timer` units already in `infra/` (e.g. `provision-intent-runner.timer`), and the deploy self-installs its own unit changes on the next run (the [ADR 0110](<redacted>.md) self-heal pattern) — no manual re-install.
22
+ 3. **Cost of staleness is low.** Worst case is one tick (~2 min) behind `main` for a Customer-0 dogfood instance. The idle-tick cost is a single `git fetch` + SHA compare (the no-op fast path).
23
+
24
+ ### Two deliberate divergences from `deploy-prod.sh`
25
+
26
+ - **The executed script is a stable copy at `/home/lars/deploy.sh`, not the in-checkout file.** This script `git reset --hard`s its own checkout; a running bash script whose backing file is rewritten mid-run can read garbage. Keeping the executed copy outside the checkout makes the reset harmless — the same reason the co-hosting box hand-installs `deploy-prod.sh`. The copy is refreshed from the checkout at the end of each successful run, so improving the repo script propagates on the next deploy.
27
+ - **The SEC [#863](https://example.com/builders#/task/863) main-audit gate is non-fatal here.** On the co-hosting box it is a hard blocker resolving ranks from the *owning* OTB DB. Here `PGDATABASE=cloudbongos`, so it resolves ranks from the cloudbongos builder set (OTB authors are unknown to it) — it can only ever misfire, and the authoritative preventive gate already runs on the co-hosting box + CI against this **same** shared `main` before it advances. So it runs for the signal but never blocks; a spurious abort must not strand cloudbongos.com on stale code — the very failure 2064 fixes.
28
+
29
+ ## Consequences
30
+
31
+ - cloudbongos.com now tracks `main` within ~2 min of a merge, with no new GitHub secret and no change to the shared prod deploy.
32
+ - **One-time bootstrap is unavoidable** (the box can't install its own first deploy automation): an operator installs `/home/lars/deploy.sh` + the two units over SSH once — see [`docs/recipes/cloudbongos-standup.md`](../recipes/cloudbongos-standup.md) §"Deploy automation". After that it self-heals.
33
+ - When cloudbongos.com moves to the pinned-`@cloudbongos/core` standalone model ([ADR 0108](<redacted>.md)), this script is the seam that converts `git reset --hard` → `git pull` + `npm ci` (the [`deploy-instance.sh`](../../scripts/deploy/deploy-instance.sh) shape) — a one-file change, not a new pipeline.
34
+ - Does not affect task [#2065](https://example.com/builders#/task/2065) (stripping cloud tokens off the co-hosting box); that is orthogonal.
@@ -0,0 +1,61 @@
1
+ # ADR 0130 — provision.js remote-exec over SSH: the control plane orchestrates co-tenant workloads on the co-hosting box
2
+
3
+ **Status:** Accepted — code implemented 2026-07-05 (task [#2065](https://example.com/builders#/task/2065)); **activation (SSH trust + token rotation) is a sequenced owner-op**, see §Activation. Follows [ADR 0126](<redacted>.md).
4
+
5
+ > **Superseded in part by [ADR 0132](<redacted>.md)** (task 2071). The remote-exec *mechanism* here stands, but activation found the co-hosting box runs **five** token-consuming runners (not one), each reading its queue from a **localhost-only** Postgres. So the migration also needs an SSH DB tunnel + control-plane variants of all five runners, and the runner unit named below (`provision-intent-runner-cloudbongos.*`) is replaced by `cohost-provision-intent-runner.*`. **Follow ADR 0132's §Activation, not the §Config + runner move step here.**
6
+
7
+ ## Context
8
+
9
+ [ADR 0126](<redacted>.md) moved cloudbongos.com onto its own dedicated droplet that is also the **sole token-holding control plane** (`/etc/cloudbongos/box.env` holds the account-wide DigitalOcean + Cloudflare tokens). But it left the **co-hosting box** (`REDACTED_IP`) still holding its own DO token + a narrow Cloudflare token, used by two control-plane duties that still run *there*:
10
+
11
+ - `box.js` — dev-box lifecycle (create/destroy droplets, DNS).
12
+ - `provision.js` + `provision-intent-runner` — instance provisioning for co-tenant instances (`emersonian-circles.`, `staging.`) that **run on the co-hosting box**.
13
+
14
+ Reaching the owner's goal — **zero cloud tokens on the co-hosting box** — means moving both duties onto the control plane. The obstacle ADR 0126 named: **`provision.js` does its box-mutating steps LOCALLY** (`createdb`, `migrate`, write `/etc/<slug>/…`, `systemctl`, Caddy, healthz). If it runs on the control plane, those steps would hit the *control-plane* box — but the co-tenant instances live on the *co-hosting* box. So the runner needs a way to execute those steps **on the co-hosting box, remotely.**
15
+
16
+ ## Decision
17
+
18
+ Add a **remote-exec-over-SSH path** to `provision.js` (`scripts/gds/provision.js`), gated behind `PROVISION_REMOTE_HOST` and **OFF by default** (unset ⇒ every step runs locally, byte-identical to today).
19
+
20
+ ### The executor split
21
+
22
+ `provision.js` already runs every runbook step through two injected factories (`makeExec` / `makeWriteFile`). The change threads a **target** through them:
23
+
24
+ - **`exec` / `writeFile` — box-target.** When `PROVISION_REMOTE_HOST` is set, box-mutating steps run on that host over `ssh` (else local). `makeExec` composes `cd <remoteCwd> && <env> <cmd>` and feeds it to `ssh <host> bash -s` via **stdin** — so nothing needs shell-quoting on the way over (the classic remote-exec footgun). `makeWriteFile` base64-encodes the body and decodes it into place with `sudo tee` on the box (no raw secret on a command line).
25
+ - **`controlExec` / `controlWriteFile` — always local (the control plane).** Two steps must NOT cross to the co-hosting box because they need the cloud token / the packaging toolchain that live only on the control plane:
26
+ - the **Cloudflare DNS hook** (`BOX_DNS_HOOK`) — the whole point is that the co-hosting box has no token;
27
+ - the **standalone repo scaffold** (`git clone` / `package-core` / `bongos init` / `git push`).
28
+
29
+ `sudo` (from `PROVISION_SUDO`, [ADR 0128](<redacted>.md)) composes cleanly: for a remote step the `sudo` runs on the co-hosting box (as its passwordless-sudo user). Co-tenant A records point at `PROVISION_PUBLIC_IP` = the **co-hosting box's** IP (where the co-tenant actually runs), which is the "point `PROVISION_PUBLIC_IP` appropriately" clause of the task.
30
+
31
+ ### `box.js` needs no code change
32
+
33
+ `box.js` is entirely **API-driven** (DigitalOcean + Cloudflare clients + the DNS hook) — it does no local box-mutating ops. So the dev-box lifecycle "moves to the control plane" simply by *running there* (it reads the tokens from `/etc/cloudbongos/box.env`) + relocating the `box-intent-runner` timer — a box-side op, no code.
34
+
35
+ ### Why remote-exec (SSH) over the alternatives
36
+
37
+ - **vs. running the runner as-is on the co-hosting box** — that is the status quo, and it *requires* the tokens to stay there. Rejected: it's exactly what we're removing.
38
+ - **vs. a small agent/API on the co-hosting box the control plane calls** — more moving parts, a new listening surface + its own auth. SSH is already the trust primitive for these boxes (the 2063 migration itself was SSH-driven); reuse it.
39
+ - **vs. making every co-tenant a dedicated droplet** (no remote-exec needed) — real money per instance + a migration of the existing co-tenants; out of scope.
40
+
41
+ ## The trust boundary this creates (the owner's call)
42
+
43
+ This gives the **control-plane box SSH command authority over the co-hosting box** (a key from the control plane in the co-hosting box's `authorized_keys`). The arrow points **control-plane → co-hosting**, never the reverse — the token-holding box commands the token-free box, not vice-versa, so a compromise of the co-hosting box still cannot reach the tokens. This is the deliberate posture; the SSH trust is installed as an explicit operator step (below), not by any auto-deploy.
44
+
45
+ ## Activation (sequenced owner-op — do NOT reorder)
46
+
47
+ The code is inert until activated. Because both a remove-tokens step and a runner-move are involved, order matters (tracked in the blocker attached to task 2065):
48
+
49
+ 1. **SSH trust** — put the control-plane box's key in the co-hosting box's `authorized_keys` (control-plane → co-hosting). Verify `ssh lars@REDACTED_IP true` from the control plane.
50
+ 2. **Config + runner move** — install `infra/provision-intent-runner-cloudbongos.{service,timer}` on the control plane (carries `PROVISION_REMOTE_HOST` / `PROVISION_REMOTE_CHECKOUT` / `PROVISION_PUBLIC_IP`), `enable --now` the control-plane timer, and **disable the generic `provision-intent-runner.timer` on the co-hosting box in the same window** (never both — they'd double-drain). Run `box.js` (dev-box duties) from the control plane too.
51
+ 3. **Verify** — provision/reconcile a co-tenant end-to-end from the control plane (its steps land on the co-hosting box; DNS lands from the control plane).
52
+ 4. **Remove + rotate the tokens** — only once (1)–(3) are proven: delete `DO_API_TOKEN` + `CLOUDFLARE_API_TOKEN` from `/etc/example/box.env` and **rotate** them (DigitalOcean + Cloudflare consoles) so the old values are dead even if they leaked. **Irreversible / console-only — the owner does this.**
53
+ 5. **Drop the rollback DB** — after a bake period, drop the retained `cloudbongos` DB on the co-hosting box (ADR 0126 rollback net).
54
+
55
+ ## Consequences
56
+
57
+ - The co-hosting box can reach zero cloud tokens once activated; the control plane orchestrates the co-tenants it hosts over SSH.
58
+ - Default-OFF means this lands safely on `main` and changes nothing until the owner runs the activation — the co-hosting runner keeps working meanwhile.
59
+ - New trust edge (control-plane → co-hosting SSH), accepted as above.
60
+ - ~~Not addressed here (future): a co-tenant that should run *on the control plane* while `PROVISION_REMOTE_HOST` is set — today the flag is global (all co-tenant provisions go to the remote host). Fine for the current fleet (co-tenants live on the co-hosting box); revisit if a control-plane-local co-tenant is ever wanted.~~ **Resolved (task [#2074](https://example.com/builders#/task/2074)).** A **standalone** instance (`hosting_shape='standalone'`, its own repo dir — ADR 0108) IS the control-plane-local case: `scaffoldStandaloneRepo` already builds its repo dir on the control plane, so the follow-up box steps (code sync, migrate, `/etc`, systemd, Caddy, healthz) must run **there too**, not cross to the co-hosting box that never had that dir. `provision.js` now picks the executor **per hosting shape**, not by the global flag: standalone → the control-plane executors (`controlExec`/`controlWriteFile`); co-tenant + dedicated unchanged. A standalone's DNS A record targets `PROVISION_CONTROL_PLANE_IP` (this box), not `PROVISION_PUBLIC_IP` (the co-hosting box); a greenfield `demo.cloudbongos.com` was the driving case (goal 35 criterion 165). The per-instance override is shape-derived, so no new global flag was needed.
61
+ - **TLS companion to the above (task [#2077](https://example.com/builders#/task/2077)).** Because a standalone now runs control-plane-local under the control plane's `*.cloudbongos.com` **wildcard Cloudflare Origin cert**, Caddy already has a matching cert and never fires on-demand ACME — so the co-tenant posture (DNS `proxied=false` + on-demand Let's Encrypt, which needs the challenge to reach the origin) would serve that origin cert to *direct* clients: publicly **untrusted**, and it exposes the control-plane IP. So `provision.js` sets the standalone A record **`proxied=true`** (via a new `BOX_PROXIED` flag on `infra/box-dns-cloudflare.sh`, default off): the Cloudflare edge fronts it with a public cert (origin cert valid behind Full-strict) and the origin IP stays hidden. Co-tenant + dedicated stay `proxied=false` (their on-demand ACME is load-bearing). Same shape-derived split as the executor/IP decision above. Known follow-up: a standalone on a **custom** domain (no wildcard origin cert) would still want `proxied=false` + on-demand ACME — no such instance exists today (idea 528).
@@ -0,0 +1,47 @@
1
+ # 0131 — Rank-scoped skill visibility: feasibility spike + recommended approach
2
+
3
+ - **Status:** Spike outcome — **Proposed** (pending owner go-ahead to build). Documents a feasibility finding so future agents don't re-attempt the approach that doesn't work.
4
+ - **Date:** 2026-07-05
5
+ - **Deciders:** jaxri (Metic), Claude. Owner chose "design spike first" for task 1650.
6
+ - **Task:** [#1650](https://example.com/builders#/task/1650)
7
+
8
+ ## Context
9
+
10
+ Task 1650 asks that a builder's Claude session list **only** the skills their live rank can use. Today every session lists every skill, so a lower-rank builder can invoke a gated skill (e.g. `/planning-session`, `/blocker-review`) and only gets stopped partway through — a confusing dead-end.
11
+
12
+ **This is UX decluttering, not a permission boundary.** Authority is already enforced two ways that stay exactly as-is: the server's `requireRank` (→ 403, [ADR 0016](<redacted>.md)) and each gated skill's own early rank self-check. Hiding a skill from the menu removes a dead-end; it grants and removes nothing. The task's assumed mechanism was **a `SessionStart` hook that filters the skill list by the rank we fetch at session start** (we already run such a hook, `.claude/hooks/session-start.js`).
13
+
14
+ ## Finding (the spike result)
15
+
16
+ **Claude Code hooks cannot filter, hide, remove, or rewrite the skill listing the model sees.** This is unambiguous in the current docs:
17
+
18
+ - Skills are discovered by **directory scan** at session start (`.claude/skills/<name>/SKILL.md`); each skill's `name` + `description` is injected into context as a "skill listing" (the full body loads only on invoke).
19
+ - `SessionStart`'s only skill-relevant outputs are `additionalContext` (inject text) and `reloadSkills: true` (re-scan so **newly-written** skills appear — it can only **add**, never subtract). There is no field to hide or remove a skill.
20
+ - `PreToolUse` fires on the `Skill` tool at **invocation**, not on what's advertised. `UserPromptExpansion` can block a `/skill` **when the user types it**, but doesn't remove it from the menu.
21
+ - Hooks **cannot mutate settings at runtime** — settings are read from files at startup.
22
+
23
+ So the <redacted> design **does not exist**.
24
+
25
+ ## Options that CAN achieve it
26
+
27
+ | # | Mechanism | Hide strength | Cost / caveats |
28
+ |---|---|---|---|
29
+ | **A** | Pre-launch step writes per-builder `skillOverrides: "off"` into `.claude/settings.local.json` **before** `claude` starts | **HARD** (menu + model + Remote Control/SDK) | Must be written by the **launcher** (the wrapper/box bootstrap that already fetches rank), NOT the SessionStart hook. Per-builder file; subject to the workspace-trust dialog; does **not** cover plugin-namespaced skills (`/engineering:*` etc.). |
30
+ | **B** | `Skill(name)` **deny** rules in settings | **HARD** on invocation (still shows in menu) | Belt-and-suspenders enforcement next to the server checks; same "written to a file, not by a live hook" constraint. |
31
+ | **D** | `SessionStart` `additionalContext` — inject "you are rank X; don't use skills P, Q, R" | **SOFT** (advisory) | Zero new infra — rank already comes from the existing hook. Menu unchanged; the model *can* still invoke a listed skill. |
32
+ | **E** | Per-skill self-check + bail (already in place) | menu unchanged, **effect gated** | This is what we do today; composes with server enforcement. |
33
+
34
+ ## Recommendation
35
+
36
+ 1. **Abandon the hook-filter premise** — it's not buildable. Record it here so we don't retry it.
37
+ 2. **Don't invest in the heavy launcher change (A) yet.** Because this is UX-only — the server (ADR 0016) and each skill's self-check already enforce rank — a hard menu hide is a *nicety*, not a fix. Mechanism A rewires the launch path, generates a per-builder `settings.local.json`, and still misses plugin skills, for a purely cosmetic gain.
38
+ 3. **If we want *some* declutter cheaply now,** ship mechanism **D**: extend the existing `session-start.js` hook to emit an `additionalContext` line naming the skills the builder's rank can't use ("these are visible but off-limits to your rank — don't reach for them"). It's a soft nudge, but it removes the dead-end surprise with zero new infra and no trust-dialog/plugin caveats.
39
+ 4. **Revisit A** only if menu clutter becomes a real, reported pain — then move the `skillOverrides` write into whatever launches `claude` (a launcher wrapper or the box bootstrap), driven by the live rank.
40
+
41
+ Either way, the **server rank gate and the per-skill self-checks stay** — consistent with the trust-boundary rule that the DB enforces and markdown/settings only describe.
42
+
43
+ ## References
44
+
45
+ - Claude Code docs: *Extend Claude with skills* (skill listing, `skillOverrides`, `Skill(...)` permissions), *Hooks* (`SessionStart` `additionalContext`/`reloadSkills`; no runtime settings mutation), *Configure permissions* (`Skill(name)` deny rules).
46
+ - Local: `.claude/hooks/session-start.js` (where rank is fetched today), `.claude/settings.json` (hooks/permissions wiring).
47
+ - [ADR 0016](<redacted>.md) — server-enforced permissions (the real gate this UX never replaces).
@@ -0,0 +1,54 @@
1
+ # ADR 0132 — Migrating the co-hosting fleet to the control plane over an SSH DB tunnel
2
+
3
+ **Status:** Accepted — repo half implemented 2026-07-05 (task [#2071](https://example.com/builders#/task/2071)); **units ship additive + not-enabled — activation is a sequenced operator-op** (see §Activation). Extends [ADR 0130](<redacted>.md); completes the "zero cloud tokens on the co-hosting box" goal of [ADR 0126](<redacted>.md) (task 2065 / blocker 64).
4
+
5
+ ## Context
6
+
7
+ [ADR 0130](<redacted>.md) shipped the *code* to run `provision.js` from the control plane and remote-exec box steps over SSH. But when we went to actually strip the tokens (blocker 64), the endgame proved **not a switch-flip**. Three findings:
8
+
9
+ 1. **The co-hosting box (`REDACTED_IP`) runs FIVE token-consuming timers, not one.** ADR 0130 addressed only `provision-intent-runner`. The other four are the whole `box.js` **dev-box lifecycle**: `box-intent-runner` (provision/wake, 1-min), `box-idle-suspend` (15-min), `box-drift-reconcile` (hourly), `box-dormant-reclaim` (daily). Each needs the DO token; none were migrated.
10
+ 2. **Every runner reads its work-queue from the *local* `example` Postgres, which is firewalled to localhost** (`pg_hba`: `host … 127.0.0.1/32 scram-sha-256`; `:5432` is closed to the network — the correct posture). A runner moved to the control plane cannot reach the `box_intents` / `provisioning_intents` queues remotely. This is the real obstacle ADR 0130 did not solve: it moved *box-step execution*, not *queue reading*.
11
+ 3. **`box.js` needs no code change** — its only shell-outs are `scripts/discord/post.js` and the `BOX_DNS_HOOK` (both present on the control plane with its tokens); everything else is DigitalOcean/Cloudflare HTTP. So the blocker is purely *"how does a control-plane runner reach the example queues."*
12
+
13
+ At migration time the fleet was **dormant** — 0 live dev-box droplets, 0 hosted co-tenants, empty provisioning queue — so the cutover risk was low, but the dev-box capability is real (builders connect to dev boxes via Claude Desktop), so it must keep working. The owner chose the full migration over a token-strip-and-defer.
14
+
15
+ ## Decision
16
+
17
+ Give the control plane a secure path into the co-hosting box's `example` Postgres via a **persistent SSH tunnel**, and run **all five runners on the control plane** as `cohost-*` unit variants that read the queues through the tunnel, call the DO/CF APIs with the control-plane tokens, and (for provisioning) remote-exec box steps over SSH per ADR 0130.
18
+
19
+ ### The tunnel
20
+
21
+ `infra/cohost-db-tunnel.service` holds a long-lived `ssh -N -L 127.0.0.1:5433:127.0.0.1:5432 cohost` (Restart=always, ServerAlive keepalives). The runners set `DATABASE_URL=<redacted> (`pool.js` honors `DATABASE_URL` first), so they read/write the example queues through the encrypted forward. **No Postgres port is ever exposed to the network** — the tunnel terminates at the co-hosting box's own localhost.
22
+
23
+ **Why a tunnel, not the alternatives.** (a) *Expose Postgres over DO private networking* — still opens a TCP surface + needs `pg_hba`/credential work, and the two droplets aren't guaranteed same-VPC. (b) *A token-signing broker on the co-hosting box* — leaves runners (and thus tokens' blast radius) on the co-hosting box, the opposite of the goal, and is far more code. (c) *Move the queue tables to the cloudbongos DB* — the OTB web tier enqueues them and can't reach the control-plane DB either (firewall symmetry); it splits the game's data. The tunnel keeps the data where it is, moves only execution, and reuses the SSH trust ADR 0130 already needs.
24
+
25
+ ### The DB credential
26
+
27
+ `pg_hba` already permits `host … 127.0.0.1/32 scram-sha-256`, and the `lars` role had **no password**. Activation sets a scram password on the existing `lars` role (`ALTER ROLE lars WITH PASSWORD …`) and stores it only in the chmod-600 `/etc/cloudbongos/cohost-fleet.env` on the control plane. We reuse `lars` (not a new scoped role) deliberately: it is the **same role the runners already run as** on the co-hosting box (via peer auth), so privileges are identical and nothing can be under-granted. The password widens nothing — the role is reachable only from `127.0.0.1` (the tunnel endpoint), and SSH-as-`lars` is already full box access.
28
+
29
+ ### The units
30
+
31
+ Eleven files in `infra/`: the tunnel + control-plane variants of all five runners (`cohost-box-intent-runner`, `cohost-box-idle-suspend`, `cohost-box-drift-reconcile`, `cohost-box-dormant-reclaim`, `cohost-provision-intent-runner`) with their timers. Each differs from the co-hosting original only in `WorkingDirectory=/home/lars/cloudbongos`, `EnvironmentFile=/etc/cloudbongos/{box.env,cohost-fleet.env}`, and (provision only) the ADR 0130 remote-exec env pointing `PROVISION_REMOTE_HOST=cohost`. **`cohost-provision-intent-runner` supersedes the confusingly-named `provision-intent-runner-cloudbongos.*` from task 2065** (same design, named for the fleet it drives, wired to the example DB via the tunnel; the old files are deleted). The pre-existing `cloudbongos-provision-intent-runner` (task 2056, local `cloudbongos` DB) is unrelated and stays.
32
+
33
+ `deploy-cloudbongos.sh` self-heals these units **install-only** (copy + daemon-reload, never enable) so a redeploy/re-provision keeps them fresh without ever auto-activating (ADR 0129 durability, but activation stays manual).
34
+
35
+ ## Security posture
36
+
37
+ A one-directional **control-plane → co-hosting SSH edge**: the token-holder commands the token-free box, never the reverse. The tunnel + the ADR 0130 remote-exec both ride the single `cohost` key (this box's key in the co-hosting box's `authorized_keys`, restrictable `from="REDACTED_IP"`). After activation + rotation the co-hosting box — the public-facing box that runs the live game — holds **zero account-wide cloud tokens**, which is the whole point (ADR 0126).
38
+
39
+ ## Activation (sequenced operator-op — do NOT reorder)
40
+
41
+ 1. **SSH trust.** On the control plane, generate `~lars/.ssh/cohost_ed25519` + a `cohost` `~/.ssh/config` alias; add its pubkey to `~lars/.ssh/authorized_keys` on the co-hosting box. Verify `sudo -u lars ssh cohost true` from the control plane.
42
+ 2. **DB password + fleet env.** `ALTER ROLE lars WITH PASSWORD …` on the co-hosting box; write `/etc/cloudbongos/cohost-fleet.env` (chmod 600) with `HOME=/home/lars` + `DATABASE_URL=…@127.0.0.1:5433/example`.
43
+ 3. **Tunnel up.** `systemctl enable --now cohost-db-tunnel`; verify `psql "$DATABASE_URL" -c 'select 1'` from the control plane.
44
+ 4. **Enable the 5 `cohost-*` runners** on the control plane AND **disable the 5 generic runners on the co-hosting box in the same window** — never both (double-drain). Run each `cohost-*` once to confirm a clean connect + drain.
45
+ 5. **Verify** end-to-end via `cohost-box-drift-reconcile` from the control plane (DB read via tunnel + DO API + DB write).
46
+ 6. **Bake with the tokens still in place** as the rollback net: any problem ⇒ re-enable the co-hosting timers (their tokens still work) and disable the control-plane ones.
47
+ 7. **Owner, after bake (irreversible, cloud-console — stays blocker 64):** remove `DO_API_TOKEN` + `CLOUDFLARE_API_TOKEN` from `/etc/example/box.env` and **rotate both** in the DigitalOcean + Cloudflare dashboards; then `dropdb cloudbongos` on the co-hosting box (the ADR 0126 rollback DB) once cloudbongos.com has baked healthy on its own droplet.
48
+
49
+ ## Consequences
50
+
51
+ - The co-hosting box's provisioning/dev-box control moves off it entirely; after step 7 it is token-free.
52
+ - One new always-on SSH connection (the tunnel) — negligible cost; auto-reconnects.
53
+ - A runner tick that fires while the tunnel is momentarily down just fails its DB connect and retries next tick (1–2 min) — acceptable, no state corruption (`claimNextIntent` is `FOR UPDATE SKIP LOCKED`).
54
+ - Rollback is a two-command switch (re-enable co-hosting timers, disable control-plane ones) as long as step 7 hasn't run — which is why the token strip/rotate is gated behind a bake.
@@ -0,0 +1,42 @@
1
+ # 0133 — One-click GitHub sign-in for onboarding via the GitHub App Manifest flow
2
+
3
+ - **Status:** Accepted — built in task 2080.
4
+ - **Date:** 2026-07-07
5
+ - **Deciders:** example-owner (owner/Archon), Claude. Owner asked to automate the GitHub step after demo.cloudbongos.com hit `auth_not_configured`.
6
+ - **Task:** [#2080](https://example.com/builders#/task/2080) · **Goal:** 35 (greenfield onboarding), criterion 165.
7
+
8
+ ## Context
9
+
10
+ The last human friction in greenfield onboarding was wiring GitHub sign-in. The owner had to: open GitHub → Developer settings → **create an OAuth App by hand**, set homepage + callback, **generate a client secret**, copy it, and hand it to the box (`oauth-secret.js place`). It is the one step no prior automation removed because **GitHub has no API to create an OAuth App** — so it can't be scripted as-is. It surfaced concretely when demo.cloudbongos.com came up post-[#2078](https://example.com/builders#/task/2078) and reported `auth_configured:false`.
11
+
12
+ ## Decision
13
+
14
+ Use GitHub's **App Manifest flow** — the only real automation path GitHub offers. Instead of a hand-built OAuth App, the owner registers a GitHub **App** from a **pre-filled manifest**: one click, approve on GitHub, and GitHub hands *us* the credentials. Sign-in works unchanged because a GitHub App's user-to-server token hits the same `GET /user` the OAuth-app flow used; GitHub simply ignores the extra `scope` param for Apps, and we only use the token once at sign-in to identify the user before minting our own `builder_session` (so the App token's expiry is irrelevant).
15
+
16
+ **The flow spans the trust boundary ([ADR 0111](<redacted>.md) §2 / [ADR 0016](<redacted>.md)) — deliberately:**
17
+
18
+ 1. **Web tier** (the mothership hall, where the signed-in owner requested the instance) — `POST /api/bongos/provisioning/instances/:id/github-app` (own-scoped) mints a one-time `state` token, stores a `provisioning_oauth_manifests` row (status `pending`, TTL 30 min), and returns the pre-filled manifest + the GitHub form-POST target. The browser POSTs the manifest to GitHub.
19
+ 2. **GitHub** creates the App and redirects the owner's browser to the **mothership** callback `GET /api/bongos/provisioning/github-app/callback?code=&state=` (public — a browser redirect with no session; the unguessable single-use `state` is the authorization, exactly as GitHub's own conversion `code` is "the code IS the auth"). The callback stores the `code`, flips the row to `code_received`, and shows a "finishing setup" page.
20
+ 3. **Control-plane runner** (`provision.js`, the sole token-holder) drains `code_received` rows on its existing timer tick, exchanges the code via `POST https://api.github.com/app-manifests/{code}/conversions` for `client_id`/`client_secret`, writes them into `/etc/<slug>/web.env` (the `oauth-secret.js` placement it already used), restarts the unit, and verifies `/healthz` reports `auth_configured:true`.
21
+
22
+ **The client secret never touches the browser, chat, or the web tier.** Only GitHub's short-lived, single-use `code` is web-tier-visible; the secret is fetched by the control plane and written straight to disk.
23
+
24
+ ### Why DB-backed state, not the in-memory OAuth-state cookie
25
+
26
+ The web tier and the control-plane runner are **separate processes**. The existing web sign-in `state` lives in an apex cookie + memory because one process owns the whole round-trip. Here the callback (web) and the conversion (runner) are different processes, so the `state`/`code` lease is a DB row with `expires_at` (the `merge_lease` / `builder_sessions` pattern), not `deviceFlows`/`pairStore`.
27
+
28
+ ### Why conversion is control-plane-side, not web-side
29
+
30
+ The conversion endpoint is unauthenticated (the code is the auth), so the web tier *could* call it — but the resulting secret must land in `/etc/<slug>/web.env` on the box, which is a control-plane privilege. Doing the exchange on the control plane keeps the secret out of the web tier and DB entirely: the web tier only ever holds the short-lived code.
31
+
32
+ ### Manifest shape
33
+
34
+ `redirect_url` = the **mothership** callback (the instance can't do the exchange). `callback_urls` = the **instance's** own `/api/gds/auth/web/callback` (what `auth.js` actually builds) **and** the `/api/bongos/...` alias, so sign-in works regardless of which prefix a build emits. `default_permissions: {}` (sign-in needs none), `hook_attributes.active:false`, `public:false`. Personal vs org differs only in the POST URL (derived from the repo owner); the App works for sign-in either way.
35
+
36
+ ## Consequences
37
+
38
+ - **Back-compat preserved.** An instance already on an OAuth App keeps working untouched — `loadGithubCreds()` reads the same `<PREFIX>_GITHUB_CLIENT_ID/SECRET`. The manifest path is the new *default* for fresh instances; nothing about `auth.js` changed.
39
+ - **All three onboarding surfaces stay in lockstep** (the goal-35 rule): the hall "Start a project" wizard gets a one-click **Set up GitHub sign-in** button (primary); the `bongos onboard` CLI + the `/new-project` skill present it as recommended with the manual OAuth-app path kept as a documented fallback.
40
+ - **Runner gating.** Conversion only runs once the instance is `active` (its unit exists), so a code that arrives mid-provision waits instead of failing; a dedicated droplet (web.env baked into cloud-init, no post-hoc exec path here) is refused with guidance and uses the manual path.
41
+ - **Residual risk (accepted).** If a valid `pending` `state` leaked, an attacker could return their own App's code and wire the victim instance to their App. Mitigations: the state is 256-bit, minted only for the signed-in owner, single-use, 30-min TTL, never logged — the same posture as the existing OAuth-state cookie. A `code_received` row whose instance never goes active lingers (benign, visible); a TTL sweep for those is a later hardening.
42
+ - **New module surface:** table `provisioning_oauth_manifests` (migration `provisioning_003`), two routes, and the runner's `convertManifestCode`/`placeManifestCreds`/`drainOAuthManifests`. The intent-action CHECK is widened to include `oauth-manifest` for a future intent-driven path, though today the runner drains by scanning the table on the same timer tick.
@@ -0,0 +1,38 @@
1
+ # 0134 — Private-first npm distribution for the core + client (paid scoped, then public at launch)
2
+
3
+ - **Status:** Accepted — publish path + private-by-default config built in task 2089; the real publish is a gated owner step.
4
+ - **Date:** 2026-07-07
5
+ - **Deciders:** example-owner (owner/Archon), Claude. Owner asked to have the npm/CLI onboarding commands ready but kept private pre-launch, choosing paid private npm over the free GitHub Packages option.
6
+ - **Task:** [#2089](https://example.com/builders#/task/2089) · **Goal:** 35 (project-creation flow), criterion 165.
7
+ - **Refines:** [#2025](https://example.com/builders#/task/2025) (the 2026-07-04 *public* unscoped `cloudbongos` decision — now the launch-time go-public step, not superseded) · **Builds on:** [ADR 0108](<redacted>.md) (core-as-npm-dep), [#2053](https://example.com/builders#/task/2053) (vendored-tarball install).
8
+
9
+ ## Context
10
+
11
+ A new owner stands up a standalone instance that depends on `@cloudbongos/core` (ADR 0108), and external programs call the API through `@cloudbongos/client` (ADR 0118). Today neither is on a registry: `package-core.js` produces a real, installable `.tgz`, and provisioning **vendors that tarball** into each instance repo (a `file:` pin `npm ci` resolves — task 2053). That works, but the onboarding experience isn't the clean `npm install @cloudbongos/core` an owner expects, and the client's on-ramp doc referenced a nonexistent "internal registry."
12
+
13
+ The owner wants the npm/CLI commands **ready and usable pre-launch, but not public** — Cloud Bongos shouldn't be installable by the general public before launch. Two prior decisions bear on this: the *public* install name was set to the unscoped **`cloudbongos`** (task 2025, deferred), and the `bongos` + ~10 defensive npm orgs were reserved under the owner's login.
14
+
15
+ One npm rule forces the shape: **unscoped packages are always public — only *scoped* packages can be private, and only on a paid plan.** So the unscoped `cloudbongos` name *cannot* be the private form; the private artifact must stay scoped.
16
+
17
+ ## Decision
18
+
19
+ Publish **`@cloudbongos/core`** and **`@cloudbongos/client`** as **scoped, private** npm packages during pre-launch, on a **paid** `cloudbongos` npm org. Both already use the `@cloudbongos` scope (an org the owner holds), so **no rename is needed now**.
20
+
21
+ - **Private by default in code, not just by flag.** The synthesized core `package.json` (`buildPackageJson`) and the generated client `package.json` (`gen-api-client.js`) both carry `publishConfig: { access: "restricted" }`. `package-core.js --publish` additionally passes `--access restricted` on the CLI — belt-and-suspenders so a stray config edit can't silently make the pre-launch artifact public.
22
+ - **The publish is a gated owner step; the tooling holds no token.** `package-core.js --publish` **dry-runs** by default; the real, permanent publish needs `--publish --live` plus the owner's `npm login` and the org on a paid plan. npm owns auth — this repo never stores a token.
23
+ - **Consumers authenticate with an env-fed `.npmrc`:** `//registry.npmjs.org/:_authToken=<redacted> The token expands from the environment, so it never lands in a committed file. Only members of the paid org can install.
24
+ - **The vendored-tarball path stays as the working default/fallback.** Rewiring provision/init to auto-pull the pinned core from the registry (env-fed token on the control plane) is a follow-up — it touches a proven, protected control-plane flow and isn't required for "commands ready + private." Publishing privately + documented auth already delivers a real `npm install`.
25
+ - **Going public at launch is one step**, chosen then: either `npm access public @cloudbongos/core` (keeps the scoped name), or execute task 2025 to *also* publish the unscoped vanity `cloudbongos` for `npm install -g cloudbongos`. Task 2025 is therefore the launch-time go-public leg, not replaced by this.
26
+
27
+ The daily command stays `bongos` regardless of package name (the `bin` mapping in the synthesized package.json is name-independent), so `npm install -g @cloudbongos/core` → `bongos init` works today, and the eventual public `cloudbongos` name changes nothing for users.
28
+
29
+ ## Why paid private npm over the free GitHub Packages alternative
30
+
31
+ The owner chose it deliberately, knowing the trade-off. GitHub Packages is free but ties every consumer to a GitHub token + org membership and a non-default registry; npm private packages give the canonical `npm install` on the default registry with a clean one-flag flip to public — the same registry, name, and command the public launch will use. The recurring per-seat cost (~$7/member/month) is small at pre-launch scale (a handful of trusted early instances) and disappears at launch when the packages go public (public installs need no seat).
32
+
33
+ ## Consequences
34
+
35
+ - Cost: a paid `cloudbongos` npm org seat per person who needs to install during pre-launch. Gone at launch.
36
+ - Owner-only steps (out of the build session; capture as a blocker if they gate verification): put the org on a paid plan; generate an npm access token (automation — read-write to publish, read for CI/provision installs); run `package-core.js --publish --live` (permanent; login + 2FA).
37
+ - Follow-up: wire provision/init to install the pinned core from the private registry (env-fed `NPM_TOKEN`), keeping the vendored tarball as fallback.
38
+ - Full operator runbook — org, plan, token, publish, consumer `.npmrc`, and the go-public flip — is [`docs/recipes/private-npm-distribution.md`](../recipes/private-npm-distribution.md).