@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,132 @@
1
+ # ADR 0016 — Trust boundary: server-enforced permissions
2
+
3
+ **Date:** 2026-05-26
4
+ **Context:** GDS-V3, spike [#229](https://example.com/builders#/task/229) (V3.R03 — Architecture spike: server-enforced trust boundary). Satisfies done-when criterion C7 (`three-ranks-gate-everything` / `permissions-enforced-server-side`).
5
+ **Status:** Accepted.
6
+
7
+ > Numbering note: the spike's done-when named this ADR `0015`, but `0015` was taken by the task-dependencies work before this spike was opened. This ADR is **0016**.
8
+
9
+ ## Problem
10
+
11
+ GDS-V3 opens the system to more than one builder. Today there is exactly one builder (`example-owner`) and every API route trusts any authenticated session equally. Before a second person holds a session token, we need an explicit answer to: **where does authority live, how is it checked, and what is the exact failure mode when a builder edits their own local files to try to grant themselves more authority?**
12
+
13
+ The threat is not a malicious outsider breaching the network — that's a different ADR (security basics, C8). The threat here is the *trusted-but-bounded* builder: someone given a real session who should be able to claim and ship tasks but should NOT be able to create tasks, rewrite methodology, close versions, or touch another builder's claim. A Claude Code builder runs with full write access to their own checkout: they can edit `CLAUDE.md`, edit `.claude/skills/*`, edit `.claude/settings.json`, add hooks, and edit any `src/` file locally. None of that local editing power can be allowed to translate into elevated authority over shared state.
14
+
15
+ So the trust boundary must sit at a place the builder's local machine cannot move: **the server, checking a value the builder cannot write.**
16
+
17
+ ## Decision
18
+
19
+ Authority lives in **one column in the production database** — `builders.rank` — and is checked **server-side, per request, against the database, with no caching**. Everything a builder controls locally (files, skills, hooks, settings) is *outside* the trust boundary and can only ever *call into* server endpoints that re-check rank themselves.
20
+
21
+ ### Where rank lives
22
+
23
+ `builders.rank` (Postgres `text` + `CHECK` enum), on the production DB. It is set only by the Archon-only rank endpoint (`PATCH /api/gds/builders/:id/rank`, task [#232](https://example.com/builders#/task/232) / V3.R07). It is never read from a token, a cookie, a file, an env var, or request body. The session token (`builder_sessions.token`) identifies *who* the builder is; it carries no authority claim of its own. Rank is looked up fresh from `builders` on every privileged request.
24
+
25
+ ### How it's checked
26
+
27
+ `requireRank(...allowed)` middleware (task [#106](https://example.com/builders#/task/106) / V3.R05 defines it; task [#231](https://example.com/builders#/task/231) / V3.R06 applies it to every privileged route) runs *after* `requireBuilder`. `requireBuilder` resolves the session token → `builder_sessions` row → `builders` row, and now also selects `rank`. `requireRank` compares `req.builder.rank` against the allowed set and returns `403 { error: 'rank_forbidden', required: [...], actual }` on mismatch.
28
+
29
+ **No token-side caching of rank.** The rank is read as part of the same `lookupSession` join that authenticates the request, so it is always the live DB value. Consequence: a demotion takes effect on the demoted builder's *very next request* — there is no stale-token window. This is the single most important property of the design, and it is why rank must not be embedded in the token at issuance time.
30
+
31
+ ### What enforces vs. what merely describes
32
+
33
+ | Surface | Role | Inside trust boundary? |
34
+ |---|---|---|
35
+ | `builders.rank` (prod DB) | **the** source of authority | ✅ yes — the boundary itself |
36
+ | `requireRank()` middleware on each route | enforcement point | ✅ yes |
37
+ | `PATCH /builders/:id/rank` (Archon-only) | the *only* writer of rank | ✅ yes |
38
+ | `CLAUDE.md`, `docs/`, ADRs | **describe** the permission model for humans/agents | ❌ no — documentation only |
39
+ | `.claude/skills/*` | call server endpoints; cannot grant authority | ❌ no |
40
+ | `.claude/settings.json`, hooks | local automation; cannot grant authority | ❌ no |
41
+ | session token / cookie | identity, not authority | ❌ no (carries no rank) |
42
+
43
+ The rule that makes this legible: **markdown describes, the database enforces.** If `CLAUDE.md` says "only Archon can create tasks" and the `POST /tasks` route is missing its `requireRank('archon')` check, the *route* is the bug — the markdown is not load-bearing and must never be treated as such. A periodic auditor (below) exists precisely to catch that class of drift.
44
+
45
+ ### Failure mode when a builder edits local files
46
+
47
+ A builder who edits their checkout to try to elevate themselves hits the boundary and fails, every time, in a defined way:
48
+
49
+ - **Edits `CLAUDE.md` to say "Thetes can create tasks":** no effect. `POST /tasks` checks `builders.rank` in the prod DB. The doc is descriptive; the route is enforcing. Result: `403 rank_forbidden`.
50
+ - **Edits a skill (e.g. `.claude/skills/builder-claim`) to call a privileged endpoint:** the endpoint still runs `requireRank` against the DB. The skill is just an HTTP client. Result: `403 rank_forbidden`.
51
+ - **Adds a hook / edits `.claude/settings.json`:** hooks run locally and can only invoke the same API surface. No endpoint trusts local state. Result: no elevation.
52
+ - **Forges or replays a token:** the token maps to a `builders` row whose `rank` is whatever the DB says. A Thetes token is a Thetes token no matter how it's presented. Result: bounded to Thetes.
53
+ - **Writes directly to the DB:** only possible with prod Postgres credentials, which are not in the repo and not held by a Thetes builder. That is the C8 (security-basics / secrets-hygiene) boundary, not this one.
54
+
55
+ In every local-edit case the failure is the same shape — a `403 rank_forbidden` from the server — because the server never consults anything the builder's machine can write.
56
+
57
+ ## Trust-model diagram
58
+
59
+ ```
60
+ builder's local machine (UNTRUSTED for authority)
61
+ ┌───────────────────────────────────────────────────────────────────┐
62
+ │ CLAUDE.md .claude/skills/* settings.json hooks src/ edits │
63
+ │ │ │ │ │ │
64
+ │ │ describe │ call │ automate │ │
65
+ │ ▼ ▼ ▼ ▼ │
66
+ │ (no authority — these can only emit HTTP requests + a token) │
67
+ └───────────────────────────────┬───────────────────────────────────┘
68
+ │ HTTPS + Bearer/cookie token
69
+ │ (token = <redacted>, NOT authority)
70
+ ================================ TRUST BOUNDARY ============================
71
+ │
72
+ ▼
73
+ ┌───────────────────────────────────────────────────────────────────┐
74
+ │ GDS server (TRUSTED) │
75
+ │ │
76
+ │ requireBuilder ── token → builder_sessions → builders (+ rank) │
77
+ │ │ │
78
+ │ ▼ │
79
+ │ requireRank(...allowed) ── compares live builders.rank │
80
+ │ │ │ │
81
+ │ allowed denied → 403 { rank_forbidden, required, actual } │
82
+ │ ▼ │
83
+ │ privileged handler runs │
84
+ │ │
85
+ │ ┌─────────────────────────────────────────────────────────────┐ │
86
+ │ │ Postgres builders.rank ◄── only PATCH /builders/:id/rank │ │
87
+ │ │ (the source of authority) (Archon-only) writes this │ │
88
+ │ └─────────────────────────────────────────────────────────────┘ │
89
+ └───────────────────────────────────────────────────────────────────┘
90
+ ```
91
+
92
+ ## Implementation sub-tasks (C7)
93
+
94
+ These already exist in the GDS as seeded GDS-V3 tasks; this spike sets their `parent_task_id` to [#229](https://example.com/builders#/task/229) so the lineage is explicit. The spike does **not** reshape their scope — it confirms it.
95
+
96
+ | Task | Rank work |
97
+ |---|---|
98
+ | [#106](https://example.com/builders#/task/106) (V3.R05) | `builders.rank` enum column + `requireRank()` middleware + gate write routes + `/me`/CLI surfacing. Live ranks for V3: **Archon** + **Thetes**. |
99
+ | [#231](https://example.com/builders#/task/231) (V3.R06) | Apply `requireRank()` to **every** privileged route; no privileged route left ungated. |
100
+ | [#232](https://example.com/builders#/task/232) (V3.R07) | `PATCH /api/gds/builders/:id/rank` — the single Archon-only writer of rank. |
101
+ | [#266](https://example.com/builders#/task/266) (V3.R44) / [#267](https://example.com/builders#/task/267) (V3.R45) | periodic auditor that asserts no privileged route is missing a rank check; CLAUDE.md trust-boundary disclaimer. (Confirm exact ids at claim time.) |
102
+
103
+ ### Token-issuance design (resolved here so [#106](https://example.com/builders#/task/106)/[#231](https://example.com/builders#/task/231) don't re-litigate it)
104
+
105
+ Tokens stay authority-free. `builder_sessions` issuance is unchanged by the rank work: a token is minted at auth time and identifies a builder. Rank is *not* stamped into the token and *not* cached alongside it. The cost of this choice is one extra column read on the existing `lookupSession` join (already a single query) — negligible — bought in exchange for instant demotion and zero stale-authority windows. This is the deliberate trade and it is not to be "optimized" into a cached/token-embedded rank later without a superseding ADR.
106
+
107
+ ## Alternatives considered
108
+
109
+ **Rank embedded in the session token (JWT-style claim).** Rejected: a stolen/old token would carry stale authority, and demotion couldn't take effect until token expiry. The whole point of putting rank in the DB and reading it per-request is that demotion is instant. The per-request read is one cheap join we already do.
110
+
111
+ **Rank cached in-process keyed by builder id, with TTL.** Rejected for V3: adds a stale window (= the TTL) for demotion, and a cache-invalidation surface, to save a column on a join that is already happening. Premature optimization for a <10-builder system. Revisit only if `lookupSession` ever becomes a measured hotspot.
112
+
113
+ **Enforce permissions in skills / CLAUDE.md (client-side).** Rejected — this is the anti-pattern the whole ADR exists to forbid. Anything the builder's machine can edit cannot be the source of authority.
114
+
115
+ **Filesystem/OS permissions on methodology files.** Partially relevant but orthogonal: methodology files (`CLAUDE.md` etc.) are protected by *who can push to `main` + who can run the deploy*, not by the API. The API trust boundary covers GDS *state* (tasks, claims, ranks, versions). Methodology-file edits are gated by git/deploy access, documented but not API-enforced in V3.
116
+
117
+ ## Consequences
118
+
119
+ **Good:**
120
+ - One column, one middleware, one writer — a small, auditable trust boundary.
121
+ - Demotion is instant (next request) because rank is never cached.
122
+ - Local-file edits are provably inert against shared authority; the failure mode is uniform (`403 rank_forbidden`).
123
+ - A periodic auditor can mechanically assert the boundary is intact (every privileged route has a `requireRank`).
124
+
125
+ **Costs:**
126
+ - Every privileged route must remember to call `requireRank`. A forgotten check is a silent hole — mitigated by the auditor task ([#266](https://example.com/builders#/task/266)/V3.R44) which fails loudly when a privileged route lacks a rank gate.
127
+ - Rank read on every privileged request (one extra column on an existing join). Accepted.
128
+ - The two-rank V3 scope (Archon + Thetes) is deliberately minimal; the full ladder in [#106](https://example.com/builders#/task/106)'s enum is reserved but unimplemented, so promoting anyone to a middle rank is a no-op until those ranks gain route grants. Documented, not a bug. **(Superseded by [ADR 0018](<redacted>.md), task [#360](https://example.com/builders#/task/360): the three-rank `xenos`/`metic`/`archon` model went live — `xenos` is now the default entry rank and `metic` the approved working rank, both wired with route grants. The trust-boundary mechanism in this ADR is unchanged; only the set of live ranks widened.)**
129
+
130
+ **Operationally:**
131
+ - When adding any new write/privileged route, the default is `requireRank('archon')` until a lower rank is explicitly granted — fail closed, not open.
132
+ - `CLAUDE.md` will carry a short disclaimer (task [#267](https://example.com/builders#/task/267)/V3.R45) stating that it *describes* permissions and the DB *enforces* them, so no future reader mistakes the doc for the source of truth.
@@ -0,0 +1,74 @@
1
+ # 0017 — Code simplification & repo cleanliness as a maintained property
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-05-27
5
+ - **Deciders:** Lars Kristensen (Archon), Claude
6
+ - **Track:** `internal` (GDS)
7
+ - **Context task:** GDS-V3 [#351](https://example.com/builders#/task/351) (V3.R90). Parent of [#352](https://example.com/builders#/task/352) (V3.R91, substrate), [#353](https://example.com/builders#/task/353) (V3.R92, grader economy lens), [#354](https://example.com/builders#/task/354) (V3.R93, reward), [#355](https://example.com/builders#/task/355) (V3.R94, janitor). Plan: `~/.claude/plans/i-believe-that-a-valiant-giraffe.md`.
8
+
9
+ ## Context
10
+
11
+ AI-written code accrues bulk. It over-writes, reaches for abstraction it doesn't need, and leaves dead code behind — and then the same agent struggles to read and edit its own output later. The cheaper it is to keep the codebase small and legible, the more reliably an autonomous builder can keep shipping into it. Simplicity is therefore not a stylistic preference here; it is a precondition for the GDS scaling to multiple builders without the repo collapsing under its own weight.
12
+
13
+ Three gaps make simplicity hard to sustain today:
14
+
15
+ 1. **Simplicity is invisible to the reward system.** The ship-time grader (`src/bongos/grader.js`) scores exactly two axes — `functional_fidelity` and `code_quality` (threshold 6.0, both must pass). Neither measures economy, diff size, or complexity. Diff stats are *already computed* at ship time (`scripts/gds/ship.js` `computeDiffShortstat` → stored in `task_grades.signals.diff_stats`) but never scored.
16
+ 2. **The incentive is backwards.** `src/bongos/streak.js` *excludes* `kind='cleanup'` from streak credit — the system mildly penalizes the exact work we want to encourage.
17
+ 3. **Cleanliness is reactive and weak.** `/merge-mode` only merges already-built branches. The `overnight-code-review` routine flags dead code as a low-priority, high-confidence afterthought. There is no complexity / dead-code / lint tooling anywhere — `package.json` carried only `"start"` and zero devDependencies before this ADR.
18
+
19
+ ## Decision
20
+
21
+ We will treat simplicity the way the GDS already treats correctness: **prevent it inline, reward it, and maintain it autonomously.** Three layers, sharing one cheap measurement substrate:
22
+
23
+ - **PREVENT** ([#353](https://example.com/builders#/task/353)/V3.R92) — the grader gains an *economy* lens at ship time: it judges whether the change is the simplest one that achieves the task, penalizing unnecessary abstraction, premature generalization, duplicated/dead code, and diffs larger than the task warrants. Caught at the cheapest moment, while the author still has full context.
24
+ - **REWARD** ([#354](https://example.com/builders#/task/354)/V3.R93) — stop excluding `cleanup` from streaks; credit net-negative ships (more lines removed than added); add a "Subtractor" achievement. Simplification becomes a rewarded act, not an unpaid chore.
25
+ - **MAINTAIN** ([#355](https://example.com/builders#/task/355)/V3.R94) — a weekly autonomous `repo-simplify-sweep` routine measures the repo, files findings to `idea_inbox`, and auto-fixes a *narrow, safe class* (confirmed dead files) end-to-end so builders never have to think about it.
26
+
27
+ All three read one substrate ([#352](https://example.com/builders#/task/352)/V3.R91, `scripts/gds/repo-metrics.js` + a `repo_health_snapshots` table + a `/public/repo-health` surface): per-file size, LOC growth by directory, dead-code counts, and branch hygiene.
28
+
29
+ ### Advisory first, then a gate (the economy score)
30
+
31
+ The economy score ships **advisory first**: recorded on every grade (as a sub-score in `task_grades.rubric_scores`, jsonb — no migration) and feeding `code_quality`, but **not** independently hard-blocking. A legitimately large-but-necessary feature must not be blocked on day one by an uncalibrated threshold. After a few weeks of real scores, a follow-up task promotes economy to a third both-must-pass axis at the existing `grader.js` gate. This mirrors how every gate in this system earned its teeth — measure, calibrate, then enforce.
32
+
33
+ ### Adopt knip as the dead-code detector
34
+
35
+ We will adopt **knip** (dev-only) as the one tool the substrate and janitor lean on. Rationale:
36
+
37
+ - **It targets the exact failure mode.** Unused exports and unreferenced files are the residue of AI over-writing — code written, then orphaned. Reliable dead-file/dead-export detection is genuinely hard to hand-roll (it requires building and walking the import graph); knip does it.
38
+ - **Zero production cost.** knip is in `devDependencies`. The droplet deploy runs `npm ci --omit=dev`, so knip and its dependency tree never reach production. No runtime, no monthly cost — consistent with the $5K budget posture. (Its transitive dev-tree does carry npm-audit advisories; these are dev-only and are the concern of the dependency-scan task V3.R38, not prod.)
39
+ - **Config lives in `package.json`, not a new file.** knip reads a `"knip"` key in `package.json`. Embedding it there — rather than adding a root `knip.json` — keeps the footprint minimal, which is the very ethos this ADR encodes. (The task description floated `knip.json`; the package.json key is the simpler in-scope choice and is what shipped.)
40
+
41
+ The committed config declares entry points (CLI scripts, tests, the browser `public/game/main.js`, the status/builders pages) and the project globs, and lists `phaser` + `colyseus.js` under `ignoreDependencies` because those are loaded as vendored browser globals via `<script>` tags (`public/index.html`), not statically imported — so knip would otherwise report them as unused. The config was trimmed to remove every pattern knip flagged as redundant; it now emits no configuration hints.
42
+
43
+ ### Baseline knip run (the "first janitor backlog") — and a precision rule it taught us
44
+
45
+ Running knip against the current repo produced:
46
+
47
+ - **Unused files (2, high precision):** `src/bongos/active-claims.js` (referenced only in seed-script *prose*, never `require`d) and `src/bongos/pulse.js` (referenced only by the separate CLI `scripts/gds/pulse.js` via an HTTP route, never imported). Both are genuine orphan candidates. They are **not** removed under this task — V3.R90's scope (`touches: docs/adr/, package.json, package-lock.json`) excludes editing `src/`. They are recorded here as the first janitor backlog for V3.R94 to triage/remove.
48
+ - **"Unused exports" (143, low precision in this repo):** dominated by **false positives**. This codebase is largely CommonJS consumed via namespace member-access (`const db = require('./db'); db.createTask(...)`), which knip cannot statically trace, so it reports the individual exports as unused even though they are called. Spot-verified: `createTask` is invoked from `src/bongos/routes/tasks.js`.
49
+ - **"Unlisted binaries (1): knip":** an artifact of running via `npx` with no local `node_modules`; it resolves once `npm ci` installs knip into `node_modules/.bin`. Not a real finding.
50
+
51
+ **The precision rule this establishes (load-bearing for V3.R94):** the janitor's **autonomous auto-fix class is restricted to unused *files* (and, later, confirmed unused *dependencies*)** — high-precision, reversible deletions. Unused-*export* findings are **advisory only**: filed for human/triage review, never auto-removed, because under CommonJS namespace access they are unreliable. This is exactly why the janitor auto-fixes a deliberately narrow class and files everything judgment-heavy.
52
+
53
+ ## Alternatives considered
54
+
55
+ - **ESLint / a full linter instead of knip.** Rejected as the first tool. ESLint enforces style and catches per-file lint issues but does not build a project-wide reachability graph, so it does not find orphaned files or cross-module dead exports — the actual AI-residue problem. A linter may still be adopted later for a different purpose; it is not a substitute here.
56
+ - **Hand-rolled dead-code detection (git/grep heuristics only).** Rejected for the dead-code signal. Reliable unused-export/unreferenced-file detection means parsing and walking the import graph; a grep heuristic is crude and misses re-exports, dynamic paths, and the CJS cases knip at least surfaces. We *do* keep git/`wc` shell-outs for the cheap size/growth/branch-hygiene metrics in the substrate — those don't need a tool.
57
+ - **Make the economy score a hard gate immediately.** Rejected. An uncalibrated simplicity threshold would block legitimately large features on day one and erode trust in the grader. Advisory-first, then harden, is the safer path and matches precedent.
58
+ - **Keep cleanliness purely reactive (extend `/merge-mode` or `overnight-code-review`).** Rejected as insufficient. The user's explicit goal is that builders should *not* have to think about cleanliness; a reactive merge tool and a correctness-first review routine do not actively reduce bulk. A dedicated, scheduled, partly-autonomous janitor is the mechanism that removes the human from the loop.
59
+
60
+ ## Consequences
61
+
62
+ **Good:**
63
+ - Simplicity becomes measured (substrate), rewarded (incentive flip), prevented (grader), and maintained (janitor) — four reinforcing pressures instead of zero.
64
+ - The first tool in a zero-tooling repo is a deliberately scoped, dev-only one with no production or monthly cost.
65
+ - The baseline run already produced a concrete, verified backlog and a precision rule that de-risks the janitor's autonomy.
66
+
67
+ **Costs / commitments:**
68
+ - knip's dev dependency tree adds npm-audit surface (dev-only; owned by V3.R38, not prod).
69
+ - The economy gate must actually be hardened after calibration, or it stays a toothless number — a follow-up task tracks this (filed under V3.R92).
70
+ - The janitor's auto-fix autonomy is bounded by the precision rule above; broadening it beyond unused files/dependencies would need its own decision, because export-level and refactor-level "simplifications" are not safe to apply unattended in a CJS codebase.
71
+
72
+ **Operationally:**
73
+ - Run dead-code detection with `npm run knip`. For the trustworthy signal, scope to files/dependencies (`knip --include files,dependencies`); treat the exports report as advisory.
74
+ - The ADR index that records permissions/architecture decisions is `docs/adr/README.md`; this ADR is indexed there. (CLAUDE.md references ADRs in prose but is not edited here — it is outside this task's declared `touches`.)
@@ -0,0 +1,97 @@
1
+ # ADR 0018 — The three-rank model goes live (Xenos → Metic → Archon)
2
+
3
+ **Date:** 2026-05-27
4
+ **Context:** Task [#360](https://example.com/builders#/task/360), follow-up to the V3.R86 ([#305](https://example.com/builders#/task/305)) CLAUDE.md audit. Advances GDS-V3 criterion
5
+ C2 (`three-ranks-gate-everything`). Builds on (and partially supersedes) [ADR 0016](<redacted>.md).
6
+ **Status:** Accepted.
7
+
8
+ ## Problem
9
+
10
+ The V3.R86 audit surfaced that the project carried **two conflicting rank models**:
11
+
12
+ - **Enforced** (migration 023 / task [#106](https://example.com/builders#/task/106)): a deliberately-minimal **two-rank** model — `archon`
13
+ plus `thetes` as the default for any new builder, with `xenos` used only as the
14
+ deactivation/offboarding tier (migration 025). `metic` was reserved but unwired.
15
+ - **Planned** (the V3 planning seed's criterion C2 + the skills): a **three-rank** model — **Xenos**
16
+ (default, sandboxed: read-only + ship only explicitly-open tasks), **Metic** (Archon-approved
17
+ working rank: full claim/ship + idea triage + blocker review + planning/priority sessions),
18
+ **Archon** (rank promotion, ratification, version close, infra).
19
+
20
+ The two models *disagreed on fundamentals*: the default rank (`thetes` vs `xenos`), the name of the
21
+ approved working rank (`thetes` vs `metic`), and the role of `xenos` (exit tier vs entry tier).
22
+ Several skills (`priority-session`, `planning-session`) gate on a `Metic+` rank that wasn't live, and
23
+ `priority-session`'s gate (`xenos`→block, `metic|archon`→proceed) didn't even handle a live `thetes`.
24
+ This is exactly the doc↔DB drift ADR 0016 warns about, except here the *plan of record* (criterion
25
+ C2) was the three-rank model while the *implementation* shipped two.
26
+
27
+ Lars chose to resolve it by **wiring the three-rank model for real** rather than ratifying the
28
+ two-rank reality.
29
+
30
+ ## Decision
31
+
32
+ Three ranks are now LIVE: **`archon`** (top), **`metic`** (approved working rank), **`xenos`**
33
+ (sandboxed entry default). `thetes` becomes reserved. The 16-value CHECK enum (migration 023) is
34
+ unchanged — `metic` and `xenos` were already reserved values, so going live is a code + default
35
+ change, not an enum migration.
36
+
37
+ ### What each live rank can do
38
+
39
+ | Operation | Xenos | Metic | Archon |
40
+ |---|:--:|:--:|:--:|
41
+ | Read public surfaces, `/me` | ✅ | ✅ | ✅ |
42
+ | File an idea / blocker, capture a learning, log cost | ✅ | ✅ | ✅ |
43
+ | Claim + ship **own** work | only `xenos_claimable` tasks | any ready task | any ready task |
44
+ | Idea triage (`PATCH /inbox/:id`) | ❌ | ✅ | ✅ |
45
+ | Blocker review (`POST /blockers/:id/{resolve,link}`) | ❌ | ✅ | ✅ |
46
+ | Planning / priority sessions | ❌ | ✅ | ✅ |
47
+ | Create / promote / edit tasks, deps, confirm, done-when scope | ❌ | ❌ | ✅ |
48
+ | Grant/revoke rank, offboard, version close, infra | ❌ | ❌ | ✅ |
49
+
50
+ > **Update (2026-06-26, [ADR 0090](<redacted>.md)):** the *"Create / promote / edit tasks, deps"* part of row 7 moved to **✅ for Metic** — a Metic may now author + shape tasks (`POST /tasks`, `PATCH /tasks/:id`, `POST /tasks/:id/promote`, and the `tasks/:id/{dependencies,criteria}` CRUD). `confirm` (grader-bypass), `done-when` *scope*-setting, abandon, rank, and version-close stay Archon-only (row 8 is unchanged). The table above is preserved as the 2026 record; ADR 0090 is the current authority.
51
+
52
+ ### Mechanisms
53
+
54
+ - **Default flip (migration 029):** `builders.rank` DEFAULT `'thetes'` → `'xenos'`. Not retroactive;
55
+ affects only builders created from now on. Blast radius today is zero (only `example-owner`/archon exists).
56
+ - **Xenos sandbox (migration 029 + `db.claimTask`/`claimTasksBatch`):** new column
57
+ `tasks.xenos_claimable boolean NOT NULL DEFAULT false`. A `xenos` may claim a task only if it's
58
+ `true`; otherwise the claim path throws `XENOS_RESTRICTED` (→ 403). An Archon opens a task to Xenos
59
+ via `PATCH /api/gds/tasks/:id { xenos_claimable: true }`. This is a **row-level** rule, not a route
60
+ gate — it can't live in `requireRank` because it depends on the specific task being claimed.
61
+ - **Metic route grants:** the triage/review routes criterion C2 assigns to Metic widened from
62
+ `requireRank('archon')` to `requireRank('metic','archon')`: `PATCH /inbox/:id`,
63
+ `POST /blockers/:id/{resolve,link}`. Everything that mutates *plan/scope* (task create/promote/edit,
64
+ dependencies, confirm, done-when, rank, version close) stays Archon-only — the fail-closed default.
65
+
66
+ ### Why this didn't need skill changes
67
+
68
+ Adopting the three-rank model makes the skills' *existing* rank checks correct without edits:
69
+ `priority-session`'s gate (`xenos`→stop, `metic|archon`→proceed) is now exactly right because `metic`
70
+ is a real promotable rank and `xenos` is the real default. The per-skill *enforcement flips* that are
71
+ still advisory (e.g. `planning-session` → V3.R88) remain their own tasks; this ADR makes the ranks
72
+ they reference real.
73
+
74
+ ## Consequences
75
+
76
+ **Good:**
77
+ - Target (criterion C2) and shipped now agree; the doc↔DB divergence the audit found is closed.
78
+ - A new teammate starts sandboxed and is *deliberately* promoted to Metic before they can ship freely
79
+ — the "vet before they can ship" property C2 wanted.
80
+ - The trust boundary is unchanged in shape: authority still lives in `builders.rank`, checked
81
+ server-side per request with no caching (ADR 0016). This ADR only widens *which* ranks are granted.
82
+
83
+ **Costs / follow-ups:**
84
+ - New surface to keep gated: any future Metic-eligible review route must remember `requireRank('metic','archon')`;
85
+ any plan-mutating route stays `archon`. The periodic auditor ([#266](https://example.com/builders#/task/266)/[#267](https://example.com/builders#/task/267)) covers the "no ungated
86
+ privileged route" half but does **not** assert the *correct* rank — that stays a review concern.
87
+ - **Not** in scope here (tracked separately): per-skill enforcement flips (`planning-session` V3.R88),
88
+ marking criterion C2 fully satisfied (Archon does that after verifying the `/builders` hall shows
89
+ rank + the auditor is green), and updating the onboarding rank-ladder diagram
90
+ (`docs/onboarding/diagrams/02-rank-ladder.mmd`, which lives on a newer `main` than this branch).
91
+
92
+ ## Supersedes
93
+
94
+ The "two-rank V3 scope (Archon + Thetes) is deliberately minimal" bullet in
95
+ [ADR 0016 §Consequences](<redacted>.md#consequences) is
96
+ superseded: the middle/entry ranks are no longer all reserved-and-unwired — `metic` and `xenos` are
97
+ live as of this ADR.
@@ -0,0 +1,52 @@
1
+ # ADR 0019 — Red-team bounty payout table by severity
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-05-27
5
+ - **Deciders:** Lars, autonomous builder (V3.R65 / [#284](https://example.com/builders#/task/284))
6
+
7
+ ## Context
8
+
9
+ GDS-V3's incentive structure (criterion C9) adds a **red-team bounty**: a builder who finds and reports a security vulnerability against the system earns drachmae for it. The mechanism that *files* a report (`vulnerability_reports`, R63 / [#282](https://example.com/builders#/task/282)) and the mechanism that *auto-confirms and pays* one (R68) both need to agree on a single thing — **how many drachmae a report is worth, given its severity.**
10
+
11
+ Without one authoritative table, each consumer would invent its own constants and they would drift. We also need the numbers to be **tunable** by an Archon (the only rank that controls economy levers): if the bounty proves too generous or too stingy in practice, adjusting it should be an environment change, not a code edit and redeploy.
12
+
13
+ Drachmae are the project's in-world currency, stored as integer `delta` in `credit_log` (migrations/003_pms.sql). A bounty payout is therefore a plain integer count of drachmae in the same unit as a task's `credits_reward`. The "10c / 50c" shorthand in the task spec maps to 10 / 50 drachmae; there is no sub-drachma denomination.
14
+
15
+ ## Decision
16
+
17
+ We will define the bounty payout table in `src/bongos/security.js` as four **default** integer amounts, each overridable by an environment variable:
18
+
19
+ | Severity | Default drachmae | Env override |
20
+ |---|---|---|
21
+ | low | 10 | `GDS_BOUNTY_LOW` |
22
+ | medium | 50 | `GDS_BOUNTY_MEDIUM` |
23
+ | high | 200 | `GDS_BOUNTY_HIGH` |
24
+ | critical | 1000 | `GDS_BOUNTY_CRITICAL` |
25
+
26
+ `security.js` exports `bountyTable()` (the flat `{low,medium,high,critical}` map, env applied) and `bountyTableDetailed()` (ordered rows carrying the default, the live value, and whether it was overridden) so that R68's award logic and the /builders hall both read the same source. The env merge happens once at module load, validated as a non-negative integer with fallback to the default — a typo in the env can never silently zero or negative-pay a bounty.
27
+
28
+ The table is surfaced read-only on the `/builders` hall under a **"Red-team rewards"** heading, served by a public read endpoint (`GET /api/gds/public/bounty-table`), mirroring how `/public/grades` exposes the grader rubric as a single source of truth.
29
+
30
+ ### Why these tier amounts
31
+
32
+ The four tiers span two orders of magnitude (10 → 1000), which is the right shape for a bounty: it must be cheap to reward a flood of low-severity nitpicks without draining the treasury, yet pay a genuinely motivating sum for the rare catastrophic find.
33
+
34
+ - **low = 10** — roughly the floor of a trivial task reward. Enough to acknowledge a real but cosmetic finding (info leak with no exploit path, minor misconfig) without inviting noise-farming.
35
+ - **medium = 50** — ~5× low. A real flaw that needs specific conditions; comparable to a small bug-fix task.
36
+ - **high = 200** — ~4× medium. Privilege escalation, broad data exposure, auth bypass — work that would have cost us materially if shipped.
37
+ - **critical = 1000** — 5× high, 100× low. RCE, full account/rank takeover, treasury drain. Deliberately the single largest payout in the economy so a builder who finds one is unambiguously rewarded above any normal task.
38
+
39
+ The geometric spacing (≈4–5× per step) matches industry bug-bounty convention (e.g. CVSS-banded payouts) and keeps the ranking legible: each tier is visibly "a different league," not a smooth gradient a reporter would argue over.
40
+
41
+ ## Alternatives considered
42
+
43
+ - **Hardcoded constants, no env override.** Simplest, but fails the done-when tunability requirement — and the right number is genuinely uncertain until we see real reports, so we want to retune without a deploy.
44
+ - **A `bounty_payouts` DB table editable via an API.** More flexible (Archon edits via UI, audit trail). Rejected as over-engineered for V3: there are exactly four numbers and they change rarely; an env var is the cheapest lever that still satisfies "Archon can tune without code." A DB-backed table can supersede this later if retune frequency justifies it.
45
+ - **Linear amounts (e.g. 10/20/30/40).** Rejected — the whole point of a severity bounty is to make a critical find pay dramatically more than a cosmetic one; linear spacing under-rewards the finds we most want.
46
+
47
+ ## Consequences
48
+
49
+ - One module (`src/bongos/security.js`) is the source of truth for bounty amounts. R68's award logic imports `bountyTable()` rather than re-deriving constants — no drift.
50
+ - An Archon retunes any tier by setting the env var on the droplet and restarting the process (consistent with every other GDS env knob; takes effect next restart, not live).
51
+ - The /builders hall shows the live table — builders always see the current bounty, and an overridden tier is visibly marked so the displayed number is never stale relative to prod config.
52
+ - The amounts are a starting point, not gospel. If reports cluster at one tier or the treasury feels the cost, retune via env first; promote to a DB-backed editable table only if env churn becomes a chore.
@@ -0,0 +1,70 @@
1
+ # ADR 0020 — Security model — public stub (full ADR is server-side)
2
+
3
+ **Date:** 2026-05-28
4
+ **Context:** Task [#287](https://example.com/builders#/task/287) (V3.R68), GDS-V3 criterion C9. Companion to [ADR 0019](<redacted>.md) (bounty table), [ADR 0018](<redacted>.md) (rank model), [ADR 0016](<redacted>.md) (server-enforced trust boundary).
5
+ **Status:** Accepted.
6
+
7
+ ## Problem
8
+
9
+ A security ADR worth writing is a security ADR worth attacking. The threat model — every authenticated surface, every privileged write, every assumption the server-enforced trust boundary leans on, and the specific defenses each leg relies on — is the most attacker-useful document in the project. Committing the full version to the public repo would hand a roadmap to anyone clipping the project.
10
+
11
+ But we *also* need this document to exist and be readable by trusted builders (Archon, Metic) — otherwise the system has no shared model of how it defends itself, and every new privileged route ends up reinventing the threat-list ad hoc. The red-team bounty (criterion C9) only makes sense if Metics know roughly where the surface is.
12
+
13
+ We've already adopted [ADR 0016](<redacted>.md): authority lives on the server, not in the repo. The same logic applies to the security ADR itself — its content should live where its enforcement does.
14
+
15
+ ## Decision
16
+
17
+ The **full security ADR is server-side**, served by a Metic+-gated endpoint and stored *outside this repo*. This file is the **public stub**: enough framing that a reader (or future builder) understands the structure and knows where to look, but with no specifics an attacker could weaponize.
18
+
19
+ ### What lives where
20
+
21
+ | Surface | Where | Who reads it |
22
+ |---|---|---|
23
+ | Public stub (this file) | `docs/adr/<redacted>.md`, in the repo | anyone with the repo |
24
+ | Full security ADR | A markdown file on the droplet at the path named by `GDS_SECURITY_ADR_PATH` (recommended: `/etc/example/security-adr.md`, owned by the deploy user, `chmod 600`) | the server process, on read; Metic+ via API |
25
+ | Public read endpoint | none | — |
26
+ | Authenticated read endpoint | `GET /api/gds/security/adr` — `requireBuilder` + `requireRank('metic','archon')` — returns the markdown body verbatim under `{ adr_md, source: <path>, fetched_at }` | Metic, Archon |
27
+ | Missing-file handling | If `GDS_SECURITY_ADR_PATH` is unset or the file is unreadable, the endpoint returns `404 { error: 'security_adr_not_provisioned', hint: '…' }` with the same rank gate in front (so existence-or-not isn't leaked to a Xenos) | — |
28
+
29
+ ### What's in the full ADR (categories, not contents)
30
+
31
+ The full ADR is structured as:
32
+
33
+ 1. **Trust boundary mechanics** — the actual implementation of [ADR 0016](<redacted>.md) per route: which routes are gated, by what rank, where the rank read lives in the request lifecycle, and what fails closed.
34
+ 2. **Threat model** — the set of attackers we model (sandboxed builder, malicious Metic, leaked GitHub OAuth, supply-chain compromise, lost laptop) and what each can and cannot do under the current design.
35
+ 3. **Defense-in-depth inventory** — per privileged surface, the specific layers in front of it (rank check + audit log + rate limit + input validation + content TTL + …) and why each layer was chosen. This is the section that would most directly aid an attacker.
36
+ 4. **Known weaknesses** — the specific places where a defense is thinner than we'd like, with the reasons we haven't fixed them yet (deferred to a later version, cost/benefit, etc.). Highest sensitivity.
37
+ 5. **Red-team bounty alignment** — how a confirmed vulnerability_report maps onto the table in [ADR 0019](<redacted>.md), where the auto-confirmation path lives (R67/R68), and which surfaces are explicit invitations vs. out-of-scope (e.g. droplet-host vulns vs. application vulns).
38
+
39
+ Each section is updated when the underlying mechanism changes. The full ADR is the *living* document; this stub is the *pointer*.
40
+
41
+ ### Why not just chmod the repo file?
42
+
43
+ The Example repo is on GitHub. Marking a single file private is awkward (git history exposes it; collaborators see everything). The cleanest available primitive is "the file is on the droplet, the server reads it, the API gates access." That collapses to the same trust boundary [ADR 0016](<redacted>.md) already enforces for everything else.
44
+
45
+ ### This is not security-through-obscurity
46
+
47
+ The defense doesn't depend on the ADR's secrecy. Every protection mentioned in the full ADR is independently enforced in code (rank middleware, audit log, input validation, etc.). Withholding the document raises the cost of an attacker's reconnaissance — it doesn't *create* the defense. The bounty table ([ADR 0019](<redacted>.md)) names the gain for the attacker who reverse-engineers it anyway: a high-severity finding pays out 1000 drachmae. The system *wants* serious red-teamers; what it doesn't want is to hand them the map for free.
48
+
49
+ ## Alternatives considered
50
+
51
+ - **Commit the full ADR to the repo.** Simplest. Rejected for the reason above: highest-leverage document for an attacker.
52
+ - **Encrypted file in the repo (e.g. age-encrypted blob).** Possible, but key-management overhead for every Metic + the encrypted blob is still public. The trust boundary already gives us "authenticated reads," so reusing it is cheaper.
53
+ - **Private companion repo.** Considered. Adds a second-repo coordination problem (every Metic needs access; secrets-in-repo policy needs to cover two repos; CI doesn't see it). The droplet-file approach concentrates surface area without sacrificing access.
54
+ - **Notion/Google Doc.** Rejected for the same reason all project state lives in the GDS + git: third-party SaaS dependencies for canonical authority drift over time. The droplet is already the source of truth for everything else server-side.
55
+
56
+ ## Consequences
57
+
58
+ - The full security ADR exists at `GDS_SECURITY_ADR_PATH` on the droplet, not in the repo. Provisioning is a one-time Archon action; the file persists across deploys (it lives outside the repo working tree).
59
+ - New builders see the public stub (this file) when reading the ADR index. The stub tells them how to read the full ADR once promoted to Metic+.
60
+ - Any change to the *real* defenses (new gated route, new redaction rule, new rate-limit knob) updates the full ADR on the droplet. Significant structural changes (new threat-model attacker, new defense category) also update this public stub.
61
+ - The `GET /api/gds/security/adr` endpoint exists *now* (V3.R68 / [#287](https://example.com/builders#/task/287)) but returns the not-provisioned placeholder until an Archon writes the file. That's intentional — the endpoint is the contract, the file is the content.
62
+ - A Xenos hitting the endpoint sees `403 rank_forbidden` whether or not the file is provisioned — the rank gate runs before the file-existence check, so existence of the document isn't leaked downward.
63
+
64
+ ## Cross-references
65
+
66
+ - [ADR 0016](<redacted>.md) — the server-enforced trust boundary the security model rests on.
67
+ - [ADR 0018](<redacted>.md) — the three-rank model whose gates the security ADR documents.
68
+ - [ADR 0019](<redacted>.md) — the payout table a confirmed vulnerability_report maps onto.
69
+ - Migration [<redacted>.sql](../../migrations/<redacted>.sql) — the report intake table (R63).
70
+ - Migration [033_audit_log.sql](../../migrations/033_audit_log.sql) — the audit ledger every privileged write lands in (R35).
@@ -0,0 +1,99 @@
1
+ # ADR 0021 — Per-builder skill model preferences + skill-efficiency audit
2
+
3
+ **Date:** 2026-05-28
4
+ **Context:** Task [#304](https://example.com/builders#/task/304) (V3.R85), GDS-V3 cost-discipline cross-cutting. Promotes idea_inbox [#21](https://example.com/builders#/idea/21); pulls forward a minimal slice of PMS-V4 idea [#30](https://example.com/builders#/idea/30).
5
+ **Status:** Accepted (mechanism only; per-skill refactor + execution-time hook deferred to follow-up tasks).
6
+
7
+ ## Problem
8
+
9
+ Today every slash-command skill runs on whichever model the user launched. Two things are wrong with that:
10
+
11
+ 1. **Mechanism vs judgment is conflated.** A skill like `/builder-claim` is structurally a shell around `scripts/gds/claim.js` — there is no LLM judgment in claiming a task. Yet it runs on whatever model the user's session is on (typically Opus 4.7), which burns budget on parsing + formatting that a `node` invocation does for free. Conversely, `/planning-session` IS the judgment — it sets a whole version's scope-truth — and demoting it for cost saving would be exactly the wrong move.
12
+ 2. **There's no per-builder lever.** CLAUDE.md §2 documents a project-wide policy ("default to Opus, Haiku for plumbing") that doesn't survive contact with multi-builder reality. A builder who wants Sonnet for everything except priority-session has no way to express that without editing skill files.
13
+
14
+ The cross-cutting ask in [#304](https://example.com/builders#/task/304) is to make the trade-off explicit per skill AND tunable per builder.
15
+
16
+ ## Decision
17
+
18
+ We will ship the **mechanism**: a per-builder storage + UI + API surface for picking a model per skill, plus an audit-classified set of system defaults. The **per-skill refactor** (extracting mechanism into pure scripts) and the **execution-time hook** (skills actually reading the preference at invocation) are filed as follow-up tasks and tracked separately.
19
+
20
+ The split is deliberate. The storage + UI + audit is load-bearing infrastructure — once it exists, the per-skill refactors can land independently (different skill, different week, different builder). The reverse order doesn't work: refactoring a skill without somewhere to encode the preference produces an orphaned commit.
21
+
22
+ ### What ships now
23
+
24
+ 1. **Migration 037 — `builders.skill_model_prefs jsonb`** (single column, default `'{}'`). A jsonb map from skill name → model token. Per-builder, sparse — missing keys fall back to the system default.
25
+ 2. **`src/bongos/skill-prefs.js`** — pure module. Exports `ALLOWED_MODELS`, `KNOWN_SKILLS`, `SKILL_DEFAULTS`, `getDefault()`, `getForBuilder()`, `listEffective()`, `validatePatch()`, `applyPatch()`. The single source of truth that the API, the UI, and any future skill hook read from.
26
+ 3. **`GET /api/gds/me/skill-prefs`** — returns `{ prefs, effective, defaults, known_skills, allowed_models }`. The UI consumes `effective` (which already merges override > default) plus `allowed_models` (drives the dropdown options).
27
+ 4. **`PATCH /api/gds/me/skill-prefs`** — body is `{ <skill>: <model> | null }`. `null` clears the override; missing skills are untouched (partial updates are first-class). Unknown skill names or unknown models → 422 with a structured errors array.
28
+ 5. **`/builders` profile UI** — new section "The Voice Behind Each Skill" rendering one row per skill with the system default + a dropdown for the builder's override.
29
+ 6. **This ADR** — captures the audit + the design + the deferred items.
30
+
31
+ ### What's deferred (follow-up tasks)
32
+
33
+ - **Per-skill refactor.** Each skill listed below as `default: 'script'` should actually be a script wrapper — today most of them already are (the `builder-*` slash commands shell out to `scripts/gds/*.js`), but the SKILL.md files still invite the LLM to parse the JSON output. Refactor per-skill is one-task-per-skill.
34
+ - **Execution-time hook.** Skills currently don't read `skill_model_prefs` when they run. The intended hook: each SKILL.md gets a top-line `Subagent model:` line resolved against `getForBuilder()` at invocation time, and any `Agent` tool call inside the skill passes the resolved model explicitly. That requires touching each SKILL.md plus a small helper script.
35
+ - **Cost measurement before/after.** Today we have `cost_log` rows by `category` but not by `(category, skill)`. Adding a skill-attribution column + a measurement window post-rollout is its own task.
36
+
37
+ These three are filed as new tasks at idea_inbox (kind=cleanup or refactor) so the deferred work is visible.
38
+
39
+ ### Audit — what each skill is structurally
40
+
41
+ The audit pass walked every `.claude/skills/*/SKILL.md`, classified each step as **mechanism** (deterministic; no model judgment needed) or **judgment** (the model is the load-bearing thing), and picked a system default:
42
+
43
+ | Skill | Default | Why |
44
+ |---|---|---|
45
+ | `builder-start` | script | wraps `start.js` — format-output only |
46
+ | `builder-claim` | script | wraps `claim.js` — atomic DB write |
47
+ | `builder-release` | script | wraps `release.js` |
48
+ | `builder-exit` | script | wraps `onboarding-ship.js` (offboarding flow) |
49
+ | `builder-cost` | script | wraps `cost.js` — direct row insert |
50
+ | `otb-figma-sync` | script | direct Figma API push |
51
+ | `builder-ship` | sonnet | mostly mechanism, but drafts handoff notes + value summary (light judgment) |
52
+ | `idea-triage` | opus | walks the inbox and proposes promote/discard/merge verdicts — heavy judgment |
53
+ | `blocker-review` | opus | similar — walks blockers, drafts resolutions |
54
+ | `merge-mode` | opus | resolves merge conflicts, decides which branches go first |
55
+ | `planning-session` | opus | sets a version's scope — the highest-judgment skill in the project |
56
+ | `priority-session` | opus | reweights the inbox via plain-speech survey |
57
+ | `otb-builder-setup` | sonnet | long-form env walk-through; once-per-builder |
58
+ | `otb-tile-generate` | sonnet | orchestrates Gemini image gen + review; light judgment |
59
+ | `otb-design-review` | sonnet | orchestrates Gemini vision; light judgment |
60
+ | `otb-feedback-capture` | sonnet | converts speech to style-guide rule; medium judgment |
61
+
62
+ Six skills sit at `script` — the cleanest cost wins, and the simplest to hook (just don't invoke the LLM at all). Five sit at `opus` — the project-default and the right call. Five sit at `sonnet` — middle tier, where the budget lever is most useful.
63
+
64
+ ### Why jsonb on `builders` and not a separate table
65
+
66
+ - The natural read shape is "what does THIS builder prefer for skill X" — keyed on builder primary key. A separate table forces a join.
67
+ - Sparse + irregular (most builders won't override most skills). jsonb's natural shape.
68
+ - Adding a new skill = one line in `KNOWN_SKILLS` + one line in `SKILL_DEFAULTS`. No backfill, no migration. A table would force coordinated schema + code change every time.
69
+ - Analytics queries ("how many builders override planning-session?") are rare enough to do via jsonb operators when needed.
70
+
71
+ If V4 retires per-skill defaults in favor of per-skill-*kind* defaults (the broader idea [#30](https://example.com/builders#/idea/30) reshape), the jsonb stays — only the helper changes.
72
+
73
+ ### Why these four model tokens
74
+
75
+ `opus`, `sonnet`, `haiku`, `script`. The first three match the project-wide subagent routing vocabulary (CLAUDE.md §2). `script` is the deliberate "no LLM" sentinel — important because a skill marked `script` doesn't just save tokens, it commits to running deterministically. Without it, the only way to express "this skill has no judgment moment" would be to remove it from the matrix, which loses the audit signal.
76
+
77
+ ## Alternatives considered
78
+
79
+ - **Per-skill defaults only, no per-builder override.** Simpler. Rejected — the ask in [#304](https://example.com/builders#/task/304) is explicitly "builder-toggleable." A project-wide policy + the ability to deviate is what aligns multi-builder reality with cost discipline.
80
+ - **Separate `builder_skill_prefs` table.** More flexible for analytics, easier to migrate one preference type without touching jsonb shape. Rejected for V3 — see above. Can supersede this later if analytics frequency justifies it.
81
+ - **Resolve overrides only at skill-execution time, no GET endpoint.** Possible, but then the /builders UI has no source of truth — it'd have to mirror `SKILL_DEFAULTS` in JS, which is exactly the kind of drift the helper module exists to prevent.
82
+ - **Validate model tokens via Postgres CHECK constraint on the jsonb.** Rejected — jsonb CHECK is awkward to express, and the API-level validation catches the same class of errors with a structured error message. The DB layer is defensive (uses jsonb's type system to reject non-string values), not authoritative.
83
+ - **Ship the full refactor + hookup atomically.** Tempting (one PR, complete done-when). Rejected because (a) [#304](https://example.com/builders#/task/304) is genuinely a multi-task project (1 mechanism PR + ~6 per-skill refactor PRs + 1 hook PR + 1 measurement PR), (b) the mechanism is independently useful (the audit alone tells builders what the system thinks each skill is for), and (c) shipping the mechanism gives every subsequent skill task a stable consumer.
84
+
85
+ ## Consequences
86
+
87
+ - A builder can deviate from CLAUDE.md §2's default-Opus posture per skill, via the /builders UI. Power-users tune; new builders inherit sensible defaults.
88
+ - The audit (the table above) is now in code, not just CLAUDE.md prose — visible at `src/bongos/skill-prefs.js` and rendered in the UI. Stays honest as new skills land (the `KNOWN_SKILLS` sanity check at module load catches drift).
89
+ - Today, the storage exists but nothing reads `effective` at skill-execution time. The per-builder choice has no effect until the hookup task lands. The UI surfaces this honestly — the dropdown says "Set X → Sonnet" but the runtime still uses whatever model the user launched. Acceptable as the bootstrapping step.
90
+ - The `script` default for six skills is a *commitment* — those skills should not invoke the LLM for judgment. The next time one of them is edited, the editor sees `default: 'script'` in this ADR and adjusts the SKILL.md to delegate to the wrapper script.
91
+ - Adding a new skill in V4: one line in `KNOWN_SKILLS`, one line in `SKILL_DEFAULTS`, ship. No migration.
92
+
93
+ ## Cross-references
94
+
95
+ - [Migration 037](../../migrations/<redacted>.sql) — the schema change.
96
+ - [`src/bongos/skill-prefs.js`](../../src/bongos/skill-prefs.js) — the helper module and source of truth for defaults.
97
+ - [`tests/skill_prefs.mjs`](../../tests/skill_prefs.mjs) — unit coverage for the pure helpers.
98
+ - [ADR 0017](<redacted>.md) — same spirit: keep judgment work intentional, mechanism work cheap.
99
+ - CLAUDE.md §2 — the project-wide subagent routing policy this ADR sits beside (not replaces — the policy is the default the matrix opens with).