@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,64 @@
1
+ # ADR 0073 — A consistent "the system needs an input from you" signal, and pragmatic BYOK for the per-builder Gemini key
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-06-20
5
+ - **Track:** internal
6
+ - **Builds on:** [ADR 0068](<redacted>.md) (the shared newcomer key — this is the Phase 2 it explicitly deferred), [ADR 0016](<redacted>.md) (rank enforced server-side, no caching — the entitlement axis here), [ADR 0054](<redacted>.md) (cost-plus economics — *we pay up front* for newcomers, builders pay their own bill after)
7
+ - **Task:** [#1013](https://example.com/builders#/task/1013)
8
+
9
+ ## Context
10
+
11
+ [ADR 0068](<redacted>.md) shipped the *infrastructure* that hands a shared Gemini key to newcomers (rank `xenos`) so their first art task works — **we pay up front.** It closed by naming the deferred half:
12
+
13
+ > the newcomer-facing *experience* (copy explaining we pay, the on-promotion walkthrough to add a personal key, a rank-aware setup prompt) is a deliberate Phase 2.
14
+
15
+ This ADR is that Phase 2. Two problems remained:
16
+
17
+ 1. **Nothing told the builder anything.** A newcomer never learned we were covering their art spend; a builder who graduated to Thetes (when the shared key is withdrawn) was never told they now need their own key — their next art task just failed. The owner framed the real need broadly: *we want one consistent way to flag to a builder that the system needs a specific input from them to run* — not a one-off banner bolted onto the Gemini case.
18
+ 2. **The own key was CLI-only and local-only.** A builder's own Gemini key could only be entered during `/builder-setup` and lived only in `~/.config/otb/gds-session.json#gemini_api_key`. A browser-first / non-technical builder had no way to set it and was never told they needed one — and per the `feedback_auth_flows_ui_first` rule, a non-technical builder must be able to do credential setup with browser clicks alone.
19
+
20
+ ## Decision
21
+
22
+ Two coupled pieces: a **reusable signal** (the general mechanism the owner asked for) and **pragmatic BYOK** (the specific input it first carries).
23
+
24
+ ### 1. The `needs` signal — one consistent way to flag a required input
25
+
26
+ A new pure module, [`src/bongos/builder-needs.js`](../../src/bongos/builder-needs.js), is a small **registry**. Each thing the system needs from a builder to run a capability — today the Gemini image key; tomorrow a Stripe key, a first-party Anthropic link, … — is one `(ctx) => need|null` entry. The server computes the live list on `GET /api/gds/me` (`needs: { items, action_needed_count, has_action_needed }`); every surface renders the **same** shape. Adding a future input is one registry entry — the renderers don't change.
27
+
28
+ A need is always in exactly one of three states:
29
+
30
+ | State | Meaning | How it surfaces |
31
+ |---|---|---|
32
+ | `covered` | The system is handling it for them right now — nothing to do. | Calm note (the "we cover it" line for newcomers). |
33
+ | `action_needed` | The system needs the input **now** or a capability won't run. | Loud: amber banner + action button (hall), one line at session start (CLI), and a friendly stop at point-of-use. |
34
+ | `satisfied` | They've provided it. | Quiet (✓) or nothing. |
35
+
36
+ Three renderers consume the one data shape:
37
+
38
+ - **Hall Standing card** ([`public-builders/builders.js`](../../public-builders/builders.js)) — an "Action needed" / "we cover it" banner, same grid slot + warm/amber tones as the budget banner ([ADR 0054]/C3).
39
+ - **CLI session nudge** (`printNeedsNudge` in [`scripts/gds/cli-lib.js`](../../scripts/gds/cli-lib.js), called by `/builder-start`) — one line per `action_needed` item, on the builder's private surface (mirrors `printCostWarning`).
40
+ - **Point-of-use stop** — the art pipeline's "no key" error ([`art/pipeline/gen_api.py`](../../art/pipeline/gen_api.py)) now points at the web Settings page first.
41
+
42
+ The owner picked "visible **and** block-at-use" (the builder can't miss it or hit a confusing failure), with newcomer coverage copy that **foreshadows the hand-off** so the later `action_needed` is never a surprise.
43
+
44
+ ### 2. Pragmatic BYOK — the own Gemini key, server-stored and synced
45
+
46
+ The own key moves from local-file-only to **encrypted server storage that becomes the source of truth**, managed in the hall Settings page, synced down to the builder's own machine at session start — the same rail [ADR 0068](<redacted>.md) built for the shared key.
47
+
48
+ - **Encrypted at rest** ([`src/bongos/secret-box.js`](../../src/bongos/secret-box.js)): AES-256-GCM, master key (`BUILDER_SECRET_KEY`) in **server env only** — never the DB, never the repo — so a DB dump alone can't decrypt. Migration 122 adds `gemini_key_enc` / `gemini_key_last4` / `gemini_key_set_at` to `builders`. Fails **closed**: no/invalid master key → set-key 503s, the feature stays dark (exactly the [ADR 0068] rollout shape).
49
+ - **Write-only Settings UI** (`GET/PUT/DELETE /api/gds/me/art-key/own`): set / replace / remove; masked (last-4) after save, like GitHub/Stripe; a get-one link; "needed only if you generate art." Own-scoped — a builder reads/writes only their own key.
50
+ - **Validate on save**: one cheap, non-billable call to Google (list models) catches a typo. A *network* failure on our side does not block the save (`validated:false`).
51
+ - **Box sync** (`scripts/gds/fetch-art-key.js`, already wired into SessionStart): the own key lands in the local `gemini_api_key` slot — which already wins over the shared key in the pipeline cascade — tagged `_managed` so removing it on the server withdraws *our* copy without clobbering a legacy hand-entered local key.
52
+
53
+ ### Why server-stored (not local-only, not a server-side proxy)
54
+
55
+ - A web form can't write a file on the builder's box, and the box runs the pipeline — so for UI-first entry the server must hold and deliver the key.
56
+ - A server-side proxy would mean moving art generation onto the droplet (cost + latency on us) and would break per-builder cost attribution (the C3 property: each pays their own Google bill). Rejected.
57
+ - The one new risk — the server holds N builder keys so it can sync them — is contained by encryption-at-rest with an env-only master key.
58
+
59
+ ## Consequences
60
+
61
+ - **One pattern for "we need input from you."** Future credentials/links register one `needs` entry and inherit all three surfaces. This is the durable win; the Gemini key is just its first consumer.
62
+ - **A new server secret.** `BUILDER_SECRET_KEY` (32 bytes, hex or base64) must be set in `/etc/example/web-source.env` on the droplet before the own-key feature works — see the linked blocker. Until then: newcomers stay covered, the Settings card shows a "being set up" notice, no plaintext is ever stored.
63
+ - **Legacy local-only keys keep working.** A builder who only ever set a key via the CLI (server has none) is untouched by the sync; they'll see one mild "add your key" nudge until they re-enter it in Settings (one-time), at which point the server becomes the source of truth.
64
+ - **The `satisfied` state is server-knowable only for server-stored keys.** A Thetes+ builder with a working *local-only* legacy key shows as `action_needed` until they re-save it in Settings. Accepted: the population is tiny and the nudge is mild.
@@ -0,0 +1,37 @@
1
+ # ADR 0073 — The secrets scan excludes TruffleHog's generic URI detector
2
+
3
+ **Date:** 2026-06-20
4
+ **Context:** Secrets-scanning gate (`.github/workflows/secrets-scan.yml` + the `.husky/pre-commit` early-catch). Tasks [#1318](https://example.com/builders#/task/1318) and [#1320](https://example.com/builders#/task/1320). Relates to [ADR 0022](0022-secrets-policy.md) (secrets policy) and [ADR 0071](<redacted>.md) (dev-box teardown — the trigger).
5
+ **Status:** Accepted.
6
+ **Track:** `internal` (development system / CI gates).
7
+
8
+ ## Problem — a noisy detector turned a green gate red repo-wide
9
+
10
+ The CI gate runs `trufflehog git` over the branch's **full history** with `--results=verified,unknown --fail`. TruffleHog's generic **URI** detector flags any `scheme://<userinfo>@host` string as an embedded credential. Two things in this repo match that shape and are **not** secrets:
11
+
12
+ 1. **A rejection-test fixture** — `tests/box_terminal_ssrf.mjs` asserts the SSRF guard *rejects* terminal URLs that carry userinfo credentials, so the fixtures contain exactly that shape on purpose.
13
+ 2. **Per-builder tunnel hostnames** that no longer resolve. The detector "verifies" a URI by DNS/connection; an unresolvable host yields an `unknown` (unverifiable) result, which `--results=verified,unknown` reports.
14
+
15
+ This was latent until 2026-06-20: when a builder's dev box was torn down ([ADR 0071](<redacted>.md)) its tunnel host stopped resolving, flipping the fixture's result to a gating failure — reddening **every** PR built off `main` (caught while landing Bongos `R01`, task [#1296](https://example.com/builders#/task/1296)).
16
+
17
+ The first attempt (task [#1318](https://example.com/builders#/task/1318)) added the fixture file to `--exclude-paths`. That failed for two compounding reasons, and is the load-bearing lesson here:
18
+
19
+ - **TruffleHog scans commit messages, not just file contents.** `--exclude-paths` filters by file path; it has no effect on a finding that lives in a commit message.
20
+ - The [#1318](https://example.com/builders#/task/1318) fix **quoted the offending URL in its own commit message** (and in an allowlist comment). That commit is now permanent in `main`'s history, so a path exclude can never suppress it.
21
+
22
+ ## Decision
23
+
24
+ Exclude the **URI** detector from both scan surfaces: add `--exclude-detectors=URI` to the CI `trufflehog git` invocation and to the `.husky/pre-commit` `trufflehog filesystem` invocation. Remove the [#1318](https://example.com/builders#/task/1318) path-allowlist entry (superseded; its comment also carried the offending shape).
25
+
26
+ **This loses no meaningful coverage.** The high-value credentials-in-URL case — database connection strings (`postgres://`, `mysql://`, `redis://`, `mongodb://`, JDBC, …) — is caught by TruffleHog's **dedicated** connection-string detectors, which remain enabled. Verified locally (TruffleHog 3.95.6): a Postgres connection string with a password is still detected with the URI detector excluded. The generic URI detector adds only <redacted> matching, whose signal here is dominated by test fixtures and documentation.
27
+
28
+ **Operational rules that fall out of this:**
29
+
30
+ - **Keep commit messages free of credential-shaped URLs.** The scan reads them; history is immutable. Describe such strings in prose, never paste them.
31
+ - **A noisy detector is excluded at the detector level, not by path-allowlisting individual files** — path excludes cannot reach commit-message or cross-file recurrences of the same shape.
32
+
33
+ ## Consequences
34
+
35
+ - The gate is green repo-wide again; the permanent commit-message false positive in the [#1318](https://example.com/builders#/task/1318) fix commit is neutralized without rewriting `main`'s history.
36
+ - A real credential embedded in a *non-database* URL (e.g. `<redacted>) would no longer be flagged by the URI detector. Judged acceptable: that pattern is rare in this codebase, the dedicated detectors cover the common high-value cases, and the alternative (per-host regex allowlists that every new dev-box hostname must be added to) is more fragile.
37
+ - Revisit if TruffleHog gains a way to scope a detector by path/ref, or a finding-level (not path-level) allowlist — that would let us re-enable URI with the fixtures suppressed surgically.
@@ -0,0 +1,32 @@
1
+ # ADR 0074 — The memory map stays light (budget guard + auto-tidy + drawer)
2
+
3
+ **Status:** Accepted (2026-06-20) · task [#1362](https://example.com/builders#/task/1362)
4
+
5
+ ## Context
6
+
7
+ A builder's durable memory is two layers:
8
+
9
+ - **The map** — `MEMORY.md` (`~/.claude/projects/<proj>/memory/`). The Claude Code harness loads it **in full at the start of every session**. By design it's an *index*: one line per memory — title + pointer + a one-line hook, just enough to judge relevance.
10
+ - **The drawer** — the per-topic `*.md` files holding the full facts. They sync to the GDS server (`builder_memory`, via `ship.js`/`pull-memory.js`) and are indexed by `/recall` (ADR 0060). They cost **zero** session tokens until something fetches them.
11
+
12
+ Only the map is paid for every session, so it must stay small. But nothing kept it small: every session that wrote a memory appended a line, and the "≤200-char, one-line" rule was unenforced. The map re-bloated (entries ballooned into full paragraphs) until the harness's ~24.4 KB hard limit silently **truncated** it — i.e. it started dropping information, undetected. The token-cost audit (tasks 1283/1285/1286) compressed it once by hand, but a one-time fix doesn't hold.
13
+
14
+ The relevance-fetch half of "load only what's relevant" already exists — `/recall` searches the server memory, and `recall-hints.js` surfaces task-relevant memories at session start for an active claim. The missing piece was keeping the always-loaded map itself light, automatically.
15
+
16
+ ## Decision
17
+
18
+ Make the map self-maintaining, in `scripts/gds/memory-map.js` (pure, tested) driven from the session-start hook `.claude/hooks/pull-memory.js`:
19
+
20
+ 1. **Guard** — measure `MEMORY.md` each session start; emit one warning line when it's over a soft byte budget *or* has over-long index lines. Silent when healthy.
21
+ 2. **Auto-tidy** — when it crosses a higher threshold, **demote** the oldest non-rule entries until back under target. *Demote = remove the entry's line from `MEMORY.md` only.* The topic file is untouched — still on disk, on the server, and in `/recall`. Nothing is deleted; cold memories are one query away.
22
+ 3. **Keep-always** — standing rules (`feedback_*` / `type: user`) and any entry with `pin: true` in its frontmatter are never demoted, regardless of age. Pinning is how the live-version pointer and standing security alerts stay on the map even when they aren't the newest.
23
+ 4. **Parallel-safe write** — the builder runs many concurrent sessions, so the rewrite is optimistic: re-read just before writing and skip if the file changed since (another session's edit is never clobbered; it tidies next session).
24
+
25
+ Budgets are tunable constants in `memory-map.js` (`WARN_BYTES`, `TIDY_BYTES`, `TARGET_BYTES`, `MAX_LINE_CHARS`, `KEEP_NEWEST`).
26
+
27
+ ## Consequences
28
+
29
+ - The always-loaded cost stays bounded automatically; truncation can't sneak up.
30
+ - "Newest + rules + pinned" is a deliberately simple relevance proxy. It can demote a still-useful old note — acceptable because demotion is lossless and `/recall` resurfaces it on demand. Pinning is the escape hatch for evergreen entries.
31
+ - `.claude/hooks/` is a gate hard-floor, so changes here ship via an owner-approved Gate PR (ADR 0043) — the heavy logic lives in `scripts/gds/memory-map.js` (not a hard floor) to keep the hook diff minimal.
32
+ - Future refinement (not built here): a `/memory-compact` skill + a BFG hygiene pass (ADR 0026) that scores relevance richer than recency.
@@ -0,0 +1,37 @@
1
+ # ADR 0075 — Per-system cost attribution + the savings counterfactual ledger
2
+
3
+ **Status:** Accepted (2026-06-20) · tasks [#1343](https://example.com/builders#/task/1343) [#1344](https://example.com/builders#/task/1344) [#1345](https://example.com/builders#/task/1345) [#1346](https://example.com/builders#/task/1346) · System 1 of the Cloud Bongos LLM-reduction redesign (spike [#1326](https://example.com/builders#/task/1326))
4
+
5
+ ## Context
6
+
7
+ The 2026-06-20 efficiency audit ([`docs/audits/gds-efficiency-2026-06-20.md`](../audits/gds-efficiency-2026-06-20.md)) found real spend ~2× the annual budget, with **~82% concentrated in a few dozen Opus "marathon" sessions** whose cost is overwhelmingly `cache_read` (a growing context re-billed every turn for hours). But that finding was an **inference**: the ledger could not prove it, because `cost_log` lumped every LLM call into one untagged `amount_usd` row with no tier breakdown, and the price table had drifted to Opus 4.1 rates (3× too high). You cannot greenlight, tune, or defend a cut you cannot see — so the redesign's first system makes the spend *queryable per call-site and per tier*, and gives every later system a dollar-denominated place to prove its savings.
8
+
9
+ ## Decision
10
+
11
+ Four shipped changes turn the inference into instrumentation:
12
+
13
+ 1. **1M-pricing correction (task 1343).** `llm-pricing.js` is corrected to the live Anthropic list rates — opus (4.8/4.7) **$5 in / $25 out**, sonnet (4.6) $3/$15, haiku (4.5) $1/$5 — **flat across the full 1M window with no long-context premium** (verified against the platform models/pricing page). There is deliberately **no `>200K` tier table**: do not add one unless Anthropic introduces a long-context surcharge. `priceUsage()` now also returns a per-tier `components` split (fresh input / cache-read / cache-write 5m+1h / output) that it previously computed and discarded.
14
+
15
+ 2. **Source taxonomy (task 1344).** The single legacy `source='session'` `cost_log` row is split into **two call-site-tagged rows per session**, distinct on the `(source, source_ref)` idempotency index:
16
+ - `session:<redacted> — the builder's own transcript (`source_ref = <session-id>`).
17
+ - `session:<redacted> — that session's ad-hoc Agent/Task subagents (`source_ref = <session-id>:sub`); grader-signature transcripts stay excluded (already captured via the [#486](https://example.com/builders#/task/486) worker envelope — the ADR 0028 non-double-count invariant).
18
+ - A **cron-launched** session sets `OTB_COST_CRON_ROUTINE=<name>`, so its rows are tagged `cron:<routine>:interactive` / `cron:<routine>:subagent`. Wiring each routine to export this var is follow-on (System 4); until then cron sessions fall back to `session:*`.
19
+
20
+ Each row carries a four-tier USD split persisted in new **nullable** `cost_log` columns (migration 123): `fresh_input_usd`, `cache_read_usd`, `cache_write_usd` (5m+1h summed), `output_usd`. For session/cron rows the four sum to `amount_usd` by construction; legacy and non-LLM rows (manual/infra/`box-lifecycle` compute) stay NULL.
21
+
22
+ 3. **The savings counterfactual ledger (task 1345).** A tiny new table `cost_baseline` (migration 124) is where each later system records what a run cost (`amount_usd`) versus what it *would* have cost had the system not acted (`baseline_usd`), tagged by `system`. **Contract: `baseline_usd` is ALWAYS computed server-side from real token counts via `priceUsage()` — never a client-supplied dollar figure** (the same trust rule as the cost-plus reward, ADR 0054). The saving is `SUM(baseline_usd − amount_usd)` grouped by system. `db.costSummary()` gains three **additive** blocks — `by_source`, `by_tier` (with the headline `cache_read_pct`), and `savings` — shaped by a pure, unit-tested module (`cost-summary-shape.js`).
23
+
24
+ 4. **Additive endpoint contract.** All of the above surfaces through the **unchanged** `GET /api/gds/public/cost-summary` passthrough: every pre-existing key keeps its exact shape; the new keys are added alongside. The `savings` query is guarded against a missing `cost_baseline` table (`42P01`) so a pre-migration window degrades to empty savings rather than 500ing the public status dashboard. The audit (`cost.js auditCostAttribution` / `formatAuditReport`, task 1346) folds in `by_source`, the `cache_read` share of LLM-priced spend, and per-system `eliminated_usd`, plus a **tripwire** (`savings_without_baseline`) that warns when a system appears in the savings ledger with no `priceUsage` baseline behind it — a saving that cannot be verified.
25
+
26
+ ## Consequences
27
+
28
+ - The 82%-cache_read claim is now a column (`cost_log.cache_read_usd`) and a headline (`by_tier.cache_read_pct`), not an inference — the baseline System 2 reads and must move.
29
+ - Every later system (2–5) reports its savings into one comparable, server-priced ledger; "we saved X" becomes a query, not a slide.
30
+ - **Migrations 123 + 124 are additive only** (nullable columns / a new table / indexes) and must deploy *before or with* the code (the morning `~/deploy.sh` runs migrations then restarts, so co-deploy is safe; the guard covers any gap).
31
+ - The historical `cost_log` is still ~3× overstated on the pre-correction opus rows, and the drachma reward over-paid ~3× for opus work before task 1343. **Recomputing/backfilling that history is an owner decision** (clawing back reward history is explicitly out of scope for the overnight build) — the correction fixes spend and rewards going forward only.
32
+ - The cron-source tags are inert until the cron routines export `OTB_COST_CRON_ROUTINE` (System 4 wires them); session-cost.js reading the var is the mechanism, not the wiring.
33
+
34
+ ## Reproduce / verify
35
+
36
+ - Live: `node scripts/gds/api.js GET /api/gds/public/cost-summary` → now carries `by_source`, `by_tier`, `savings`.
37
+ - Pure tests (DB-free): `tests/llm-pricing.mjs`, `tests/session_cost.mjs`, `tests/cost_summary_shape.mjs`, `tests/cost.mjs`.
@@ -0,0 +1,58 @@
1
+ # ADR 0076 — In-session deterministic compaction (retrieval-first context)
2
+
3
+ **Status:** Accepted (2026-06-20) · tasks [#1347](https://example.com/builders#/task/1347) [#1348](https://example.com/builders#/task/1348) [#1349](https://example.com/builders#/task/1349) [#1350](https://example.com/builders#/task/1350) · hardened [#1364](https://example.com/builders#/task/1364) · System 2 of the Cloud Bongos LLM-reduction redesign (spike [#1326](https://example.com/builders#/task/1326)) · builds on [ADR 0075](<redacted>.md) (the ledger that measures it) and [ADR 0060](0060-gds-retrieval-layer.md) (the recall layer it recovers through)
4
+
5
+ ## Context
6
+
7
+ The efficiency audit's central finding ([ADR 0075](<redacted>.md)): **~82% of token spend is a few dozen Opus "marathon" sessions**, and their cost is overwhelmingly `cache_read` — a context prefix that grows monotonically and is **re-billed on every assistant turn for hours**. Marathon cost is therefore the *integral of a growing prefix over hundreds of turns*, and the prefix is dominated by stale tool output: file reads later edited, the same file read repeatedly, large `Grep`/`Glob`/`ls`/`Bash` dumps acted on once and never referenced again. **This is the only pool large enough to matter — no cache, model-router, or cron-gate can touch it. Only bounding the live context can.**
8
+
9
+ Spike [#1347](https://example.com/builders#/task/1347) measured the realized headroom on 7 real OTB Opus transcripts: **~24% of tool-output tokens are provably stale** by three conservative deterministic rules (superseded reads 7.3%, stale dumps 7.9%, duplicate reads 0.2%; per-session range 4–73%). That is the *floor* — the classifier deliberately counts only what it can prove — so System 2's 20–40% estimate is validated as plausible-to-conservative.
10
+
11
+ ## Decision
12
+
13
+ A **deterministic eviction pass batched at the PreCompact boundary** drops stale tool output so the re-billed prefix stops growing; recovery is **retrieval-first** through the existing `/recall` layer.
14
+
15
+ ### Why the PreCompact boundary, not per-turn
16
+
17
+ Rewriting the prefix mid-session invalidates the prompt cache: the next turn re-pays a full **cache-write** ($6.25/Mtok opus) instead of a cache-read ($0.50/Mtok). Doing that every turn costs far more than it saves. But compaction **already** resets the cache and pays one cache-write — so an eviction batched *there* is free of marginal cache cost, and every later turn reads the smaller, longer-lived working set. So: **evict only at PreCompact, never per-turn.**
18
+
19
+ ### Always-live vs retrieve-on-demand
20
+
21
+ The classifier (`.claude/hooks/eviction-policy.js`, pure + hermetically tested) only ever targets `tool_result` blocks, and only these three classes:
22
+
23
+ | Reason | Rule | Why safe to drop |
24
+ |---|---|---|
25
+ | `superseded` | a **whole-file** `Read` whose file was later `Edit`/`Write`-n | a definitive newer source of truth exists (the edit); the old read is stale |
26
+ | `duplicate` | an older `Read` whose line range is later **covered** by another `Read` of the same file | the later read fully contains it; it is the current truth |
27
+ | `stale_dump` | a `Grep`/`Glob`/`LS`/**reproducible** `Bash` result ≥ dumpMin tokens, older than the recency floor, **not cited** by a later turn | bulk output acted on once; re-derivable by re-running the tool |
28
+
29
+ **Never-evict (always-live):** user turns, assistant text + reasoning, the claim **context-pack**, **worktree-path guidance**, harness `system-reminder`s, the **last N turns** (the live working set), the **newest read of any file**, and any **non-reproducible/side-effectful `Bash` output** (a generated secret, a timestamp, a migration result — re-running yields a different value, so it is irrecoverable). A **backward-reference liveness scan** is the final safety: a dump whose distinct line is quoted *or* whose distinctive identifiers/paths are reused by a *later* assistant turn (a paraphrase) is kept (it is still being cited). When in doubt, keep — the system must never break a session to save tokens.
30
+
31
+ ### Retrieval-first recovery (the evict-stub → /recall loop)
32
+
33
+ Each evicted block is replaced by a **one-line stub** naming what is gone and a **one-step recovery**: a file `re-Read`, or — for a dump — a concrete `` /recall "<pattern>" `` query (which routes through `src/bongos/search.js` `searchChunks` / RRF, the same rank-scoped layer [ADR 0060](0060-gds-retrieval-layer.md) and the session-start `recall-hints.js` precedent use) **or** a re-run of the same tool. The PreCompact hook emits a **one-time** directive stating the recovery rule once — *recover on demand, do NOT pre-fetch* — which is what prevents a retrieval loop (the agent re-fetching everything it just evicted and undoing the compaction). `search_chunks` already dedups by `content_hash`, so re-ingested/duplicate content costs nothing extra.
34
+
35
+ ### Wire, don't arm
36
+
37
+ The PreCompact hook (`.claude/hooks/pre-compact.js`, task 1349) is gated behind the per-builder **`OTB_INSESSION_COMPACT`** flag, **OFF by default** — an instant no-op for every builder until explicitly enabled. On a harness build without a PreCompact event the hook degrades to a Stop-hook *advisory* (stderr only, never blocks, never per-turn-rewrites). The directive is emitted as `hookSpecificOutput.additionalContext`; an older harness that ignores it simply compacts as usual.
38
+
39
+ ## Consequences
40
+
41
+ - The single largest lever in the redesign (20–40% of total spend) is built and inert, ready for the owner to arm per-builder.
42
+ - Savings are **measurable**: once armed, each compaction can record its counterfactual into `cost_baseline` (ADR 0075) — the priced size of what was evicted vs. what re-reading it would have cost — so the system proves itself in dollars rather than asserting.
43
+ - Recovery never silently loses data: every evicted block is on disk (re-Read), in `/recall` (file content), or re-derivable (re-run the tool); the stub says which.
44
+ - **Risk owned:** the directive is *guidance* to the compaction step, which is itself an LLM — eviction is advisory, not a hard transcript edit. The conservative classifier + never-evict list bound the blast radius; arming should start on one builder and watch `by_tier.cache_read_pct` (ADR 0075) before rollout.
45
+
46
+ ### Hardening before arming (task [#1364](https://example.com/builders#/task/1364))
47
+
48
+ Three soundness gaps in the original classifier were closed before the flag is armed — each tightens a rule toward *keep* (the safety direction), so none can newly evict something that was previously kept:
49
+
50
+ 1. **Non-reproducible/side-effectful `Bash` is never a `stale_dump`.** The recovery stub said "re-run `Bash`", but re-running `openssl rand`, a `date`, a one-time generated value, or an `apply migration` yields a *different* value or has already mutated state — the affordance was actively wrong. A volatile-command detector (randomness, timestamps, mutations, file-writing redirects) excludes these from eviction; pure read commands (`cat`/`grep`/`ls`/`find`/…) stay evictable.
51
+ 2. **`duplicate`/`superseded` respect `Read` `offset`/`limit`.** They keyed on `file_path` alone, so a later read of a *different slice* marked the earlier slice `duplicate`, and a 1-line `Edit` marked an *entire* prior read `superseded` — dropping content never actually superseded. Now a read is `duplicate` only when a later read's line range **covers** it, and `superseded` fires only on a **whole-file** read (a partial read can't be located against a line-range-less `Edit`).
52
+ 3. **Liveness catches paraphrase.** The backward-reference scan matched only verbatim ≥40-char line quotes; an agent that re-stated a still-needed dump in its own words lost it. A distinctive-identifier/path overlap heuristic now keeps a dump when a later turn reuses several of its salient tokens.
53
+
54
+ ## Reproduce / verify
55
+
56
+ - Pure tests (DB-free): `tests/eviction_policy.mjs` (classifier, 22 cases incl. the task 1364 hardening), `tests/pre_compact.mjs` (gate + directive).
57
+ - Dry-run against a real transcript: `OTB_INSESSION_COMPACT=1` piped a `{hook_event_name:'PreCompact', transcript_path}` payload to `pre-compact.js` → emits the directive; unset → no-op.
58
+ - Spike methodology + numbers: task [#1347](https://example.com/builders#/task/1347).
@@ -0,0 +1,32 @@
1
+ # ADR 0077 — Content-addressed LLM cache
2
+
3
+ **Status:** Accepted (2026-06-20) · tasks [#1358](https://example.com/builders#/task/1358) [#1359](https://example.com/builders#/task/1359) [#1360](https://example.com/builders#/task/1360) · System 5 of the Cloud Bongos LLM-reduction redesign (spike [#1326](https://example.com/builders#/task/1326)) · reports savings into [ADR 0075](<redacted>.md); reuses the content-hash convention of [ADR 0060](0060-gds-retrieval-layer.md)
4
+
5
+ ## Context
6
+
7
+ Several GDS-internal model calls are **idempotent**: they re-process inputs that haven't changed. The nightly `architect-audit` re-audits a `main` that is often unchanged since the last run; `onboarding-analyze` re-runs over **immutable** session transcripts. Each is a full Opus call billed in full every time, for an answer byte-identical to one already produced. This is the residual after Systems 3 (autonomy gate) and 4 (deterministic-first cron) — the lowest-magnitude lever (est 2–5%), and the safety net that catches what slips through them.
8
+
9
+ Every GDS-internal model call already funnels through **one** spawn primitive — `grader.runSubagent` — which makes a single wrap point the whole surface.
10
+
11
+ ## Decision
12
+
13
+ Memoize idempotent model runs at `runSubagent`, keyed on the **content** of the request, with validity bound to the **git SHA of the inputs**.
14
+
15
+ - **Cache key** = `sha256(normalized-prompt | model | task_type | scope_sha)` (`src/bongos/llm-cache.js`, table `llm_cache`, migration 125). `scope_sha` is the git tree/blob SHA of the embedded inputs (`git rev-parse HEAD:<path>`), so **a stale answer is only ever returned when the inputs are provably unchanged** — the moment the tree changes, the key changes and the cache misses. This is the correctness backbone.
16
+ - **The normalizer registry is the other correctness surface.** A per-`task_type` normalizer strips only **provably-volatile** lines (timestamps, run-ids, the architect's `version=` echo) so two logically-identical prompts hash the same — *without* ever collapsing two genuinely-different requests. Adding a task type means adding a normalizer; that is where a reviewer looks to verify a cache can't return a wrong answer.
17
+ - **Store only on a clean run.** A result is cached only when `exit_code === 0` and stdout is present — **never a timeout or a non-zero exit**. A cache must never pin a failure.
18
+ - **The wrap is opt-in and behavior-preserving.** `grader.runSubagentCached({prompt, opts, cache})` checks the cache then falls through to the **untouched** `runSubagent`; with no `cache` spec it is exactly today's call. A hit returns `{stdout, cost_usd: 0, cached: true}`, so the $0 flows automatically through the existing `extractCostUsd → session-cost` ledger, and the saving is recorded into `cost_baseline` (`system5:llm-cache`, [ADR 0075](<redacted>.md)) — `baseline_usd` = what the run *would* have cost, `amount_usd` = 0 — so the system proves its savings in dollars.
19
+ - **First plug-ins (highest rerun value):** `architect-audit` (key scoped to the git tree-hash of `--paths`) and `onboarding-analyze` (key on the immutable session id). Both are best-effort: any `llm_cache` error degrades to an ordinary uncached run — the cache can never take down the thing it accelerates.
20
+ - **v1 is exact-match.** Semantic / near-match caching is deferred; a v1 key either matches exactly (after normalization) or misses. That keeps correctness obvious.
21
+
22
+ ## Consequences
23
+
24
+ - An unchanged-`main` `architect-audit` re-run, or a re-`onboarding-analyze` of a session, returns at **zero new tokens**, with `hit_count` incremented and the saving in `cost_baseline`.
25
+ - Because validity is git-SHA-scoped, the cache is **self-invalidating** — no manual purges; a real code change always re-runs.
26
+ - The blast radius of a wrong normalizer is bounded to its one `task_type`; the default normalizer only trims.
27
+ - **Runtime verification is deferred to a deployed run.** These caches sit on Opus subagent calls that this overnight build does not execute (and `architect-audit.js` is independently known to mis-parse its Opus output — a pre-existing defect, see the efficiency audit's meta-note). The pure key/normalizer/scope-sha logic is unit-tested DB-free; the lookup/store/hit-count/$0 path is verified on first real post-deploy run.
28
+
29
+ ## Reproduce / verify
30
+
31
+ - Pure tests (DB-free): `tests/llm-cache.mjs` (sha256, normalizers, key composition, scope-sha invalidation).
32
+ - Post-deploy: run `architect-audit --paths <p>` twice over an unchanged tree → the 2nd logs `cost_usd=0`, `cached:true`, `llm_cache.hit_count` increments, and a `cost_baseline` `system5:llm-cache` row appears.
@@ -0,0 +1,48 @@
1
+ # ADR 0078 — Deterministic-first cron harness
2
+
3
+ **Status:** Accepted (2026-06-20) · tasks [#1355](https://example.com/builders#/task/1355) [#1356](https://example.com/builders#/task/1356) [#1357](https://example.com/builders#/task/1357) · System 4 of the Cloud Bongos LLM-reduction redesign (spike [#1326](https://example.com/builders#/task/1326)) · cost visibility via [ADR 0075](<redacted>.md)
4
+
5
+ ## Context
6
+
7
+ Several of the ~17 scheduled routines are an **Opus session wrapping a single committed deterministic script**. `peer-vote-tally` literally instructs the model "do NOT compute anything by hand — run `tally.js`"; `diagram-drift` runs `check.js --file-idea`; `dep-audit-nightly` and `main-audit` run a scan script. Booting a model, loading CLAUDE.md, and paying per-turn `cache_read` just to shell one `node` command is pure waste — the model adds nothing a cron line couldn't do. (Est 3–6% of total token spend.)
8
+
9
+ ## Decision
10
+
11
+ A routine **declares its run mode** in SKILL.md frontmatter, and a dispatcher runs it at the cheapest sufficient tier — for deterministic routines, **no model is launched at all**.
12
+
13
+ - **`scripts/gds/run-routine.js <name>`** (task 1355) reads `mode:` + a `steps:` list (`command` + `sink: discord|gds|none`) from the routine's SKILL.md frontmatter:
14
+ - **`deterministic`** — `execFileSync` each step as plain node; route stdout by sink; non-zero exit → best-effort `#ops` alert + non-zero exit. **This is the whole execution — no `claude -p`.**
15
+ - **`hybrid`** — run the deterministic prefix as code; spawn `claude -p` *only* when a step emits a non-empty `{"needs_judgment": …}` payload, feeding the model only that payload.
16
+ - **`judgment`** — the status quo: a wrapped session over the SKILL body.
17
+ - Steps run with `OTB_COST_CRON_ROUTINE=<name>` so System 1 ([ADR 0075](<redacted>.md)) tags any (hybrid) spend `cron:<routine>:*` — making "did demoting this to deterministic actually cost ~$0?" a queryable fact.
18
+ - **Convert only the provably-deterministic wrappers (task 1356).** `peer-vote-tally` and `diagram-drift` already do their whole job in one self-contained, self-filing script — converted to `mode: deterministic`. **`main-audit` and `dep-audit-nightly` were NOT converted:** `main-audit.js` is trust-boundary core (SEC [#863](https://example.com/builders#/task/863) / [ADR 0043](<redacted>.md)) and neither script self-files its findings (the model currently does the per-finding `idea_inbox` / `vulnerability_report` filing), so demoting them blindly would silently drop alerting. They need a self-filing flag added to their (security) scripts first — a separate, security-reviewed task.
19
+ - **A fitness check stops the boundary from rotting (task 1357).** `fitness.checkDeterministicRoutines` fails CI if a `mode: deterministic` SKILL body contains a judgment/mutation instruction (`git push`/`commit`, `deploy.sh`, an `Edit`/`Write` tool instruction, free-text synthesis) — *negated* mentions ("never pushes", "does NOT edit") are allowed as descriptive boundaries — or if a fenced `node …` command diverges from the declared `steps:`. The pure core (`scanDeterministicBody`) is unit-tested both ways (clean passes, each violation class is caught). This is the structural cure for the markdown-graveyard pattern: a deterministic routine can never quietly become a wrapped session again.
20
+
21
+ ## Consequences
22
+
23
+ - Two nightly/weekly Opus sessions become zero-model cron lines; the pattern is now declared, enforced, and ready for more routines to adopt as their scripts gain self-sufficiency.
24
+ - **Operator action required (not in-repo):** the cron entries for `peer-vote-tally` + `diagram-drift` must be repointed from `claude -p <skill>` to `node scripts/gds/run-routine.js <name>`. The schedules live in the operator/MCP layer (`~/.claude/scheduled-tasks/` is symlinked to the repo), so the repo holds the SKILL definitions but not the launch command.
25
+ - The fitness check means the SKILL *body* of a deterministic routine is now documentation only — it must describe, not instruct. Remediation steps move to a separate claimed task (the routine *detects*; a human *fixes*).
26
+ - Composes with the rest of the redesign: System 3 (autonomy gate) decides whether a *judgment* routine fires; this decides a *deterministic* routine needs no model at all; System 5 (cache) catches a same-model-run-twice.
27
+
28
+ ## Reproduce / verify
29
+
30
+ - Pure tests (DB-free): `tests/run_routine.mjs` (frontmatter parser + tokenizer), `tests/fitness.mjs` (the deterministic-boundary check, clean + catches).
31
+ - `node scripts/gds/run-routine.js peer-vote-tally --dry-run` → prints the one command it would run, no model.
32
+ - Post-deploy: System 1's `by_source` shows `cron:peer-vote-tally:*` / `cron:diagram-drift:*` at ~$0.
33
+
34
+ ## Amendment (2026-06-21) — server-internal-timer realization for server-call routines
35
+
36
+ **Status:** Accepted · task [#1382](https://example.com/builders#/task/1382) · supersedes the "operator wires cron" consequence above for `peer-vote-tally`.
37
+
38
+ **What we found.** The original decision built an external dispatcher (`scripts/gds/run-routine.js`) and left the *scheduling* to the operator/MCP layer. Nothing was ever durably scheduled — **every scheduler layer was empty** (the local app tasks, the in-session cron, and the claude.ai cloud routines all returned nothing; the "overnight build" was a manually-pasted brief). So both routines' realized run count was **zero**, and a deterministic routine that never fires saves no tokens because it does no work. (Confirmed in the System 4 effectiveness eval, task [#1371](https://example.com/builders#/task/1371).)
39
+
40
+ **What changed.** `peer-vote-tally`'s real work is server-side and needs no model, so the durable realization is an **in-process timer** inside the always-on Node process — the same pattern as `src/bongos/publish-reconciler.js` and `src/bongos/uptime-poller.js`. `src/bongos/routine-timers.js` runs **peer-vote-tally weekly**, calling `db.tallyPeerVotes()` directly (the exact transaction the Archon-gated `POST /tasks/peer-votes/tally` route runs, now extracted to `db.js` so route + timer share one path). The route's Archon gate is an HTTP-auth concern; an in-process call has no requester and the SQL writes `karma_log` with `granted_by = NULL`. Idempotent (only matured, untallied votes) and protected by a `FOR UPDATE OF pv` row lock — the real multi-instance guard.
41
+
42
+ The timer is **unref'd**, **best-effort** (a throw logs `[routine-timers]` and waits for the next tick — never crashes the game/API), kill-switched by `ROUTINE_TIMERS_DISABLED=1`, and a **no-op anywhere the DB is unreachable** (builder laptops/boxes), so it is safe to start unconditionally on the game boot. Started/stopped in `server.js` beside `publishReconciler` — and **only** in `server.js` (the game/droplet entrypoint), not `src/platform-server.js`, so a future second always-on instance can't double-run; if one ever shares the `example` DB, set `ROUTINE_TIMERS_DISABLED=1` on the secondary.
43
+
44
+ **`diagram-drift` was intentionally NOT made a timer.** All five onboarding diagrams already auto-regenerate from live facts on every deploy (`gen-diagrams.js`), so a daily drift check is near-redundant, and an in-process loopback read would add a needless request surface. The manual `node scripts/gds/run-routine.js diagram-drift` remains for on-demand use.
45
+
46
+ **What we KEPT.** `run-routine.js`, the SKILLs' `mode: deterministic` declarations, `tally.js`, `check.js`, and the `checkDeterministicRoutines` fitness guard are all unchanged. `run-routine.js` remains the manual/on-demand front door (and keeps `tests/run_routine.mjs` meaningful); the timer is the always-on front door. Both reach the same deterministic work. The amendment is documented HERE and in `docs/recipes/ops-gotchas.md`, **never** in a deterministic SKILL body (a stray `node …` line there would fail the prose↔steps divergence check).
47
+
48
+ **Operator action retired.** The original "repoint the cron entries from `claude -p` to `node run-routine.js`" step is no longer required for `peer-vote-tally` — the server schedules it itself.
@@ -0,0 +1,39 @@
1
+ # ADR 0079 — Value-gated autonomous engagement (BUILT DISABLED)
2
+
3
+ **Status:** Accepted, **shipped inert** (2026-06-20) · tasks [#1351](https://example.com/builders#/task/1351) [#1352](https://example.com/builders#/task/1352) [#1353](https://example.com/builders#/task/1353) [#1354](https://example.com/builders#/task/1354) · System 3 of the Cloud Bongos LLM-reduction redesign (spike [#1326](https://example.com/builders#/task/1326)) · cost visibility via [ADR 0075](<redacted>.md); reuses [ADR 0043](<redacted>.md) protected-path matcher
4
+
5
+ ## Context
6
+
7
+ The largest lever in the ~18% non-marathon remainder is *autonomous* model spend: nightly routines that boot a full Opus session even when there's nothing to do, default every spawn to the dearest model, and split a single code-review finding across three Opus sessions (review → triage → rebuild). Three eliminations sit here, and they're really two decisions about every spawn — **whether** to fire, and **which** model — plus collapsing the triple-spend. (Est 8–14%.)
8
+
9
+ ## Decision
10
+
11
+ Three mechanisms, merged so each spawn decision lives in exactly one place — **all built behind a single off-by-default flag.**
12
+
13
+ 1. **Whether to fire — the autonomy precheck** ([#1351](https://example.com/builders#/task/1351)). A $0 deterministic `decide()` (`scripts/gds/autonomy-gate.js`) runs as a routine's Step 0: NO-GO (and nothing boots) when there's no claimable autonomous work *and* `origin/main` is unchanged since the last run, or no open ideas to triage, or the autonomous (`cron:%`) month-to-date spend has hit a **hard spend-brake** ceiling. Exposed at `GET /autonomy/precheck` (archon) and audited in `autonomy_runs` (migration 126) so every skip is a queryable fact.
14
+
15
+ 2. **Which model — the cascade router** ([#1352](https://example.com/builders#/task/1352)). `src/bongos/cascade-dispatch.js` `dispatch()` drafts a spawn on the cheapest sufficient model (mechanical→haiku, bug/refactor/feature→sonnet via the shared `task-classifier`) and **escalates a rung only on an objective signal** — a schema-validate fail or a self-reported `CONFIDENCE: low` / `ESCALATE: yes` trailer — capped at 2 escalations and **never above the builder's configured model ceiling** (`skill-prefs.getForBuilder`). Wired into the routines' spawns + a fail-open `cascade-route.js` PreToolUse hook for in-session subagent spawns ([#1353](https://example.com/builders#/task/1353)).
16
+
17
+ 3. **Collapse the triple-spend — the safe_autofix lane** ([#1354](https://example.com/builders#/task/1354)). A code-review finding may be fixed-and-shipped in ONE run instead of review→triage→rebuild, but `autofixAllowed()` permits it **only** when ALL hold: the gate is armed, the grader is **LIVE** (never auto-fix while `GRADER_BYPASS_ENABLED` is on), the change is **not** a protected path (`permission-path-check.matchProtected`), and the finding is **high-confidence + single-file**. Anything failing one check stays on the inbox→promote, human-in-the-loop path. Untrusted finding text is fenced per SR-12 (data, never instructions). Plus a **batched-context dispatch**: the overnight builder, when armed, claims `optimizeSession`'s touches-**disjoint** set and fans its workers from one supervisor that loads orientation once (the merge/ship leg stays serialized).
18
+
19
+ ## BUILT DISABLED — wire, don't arm (owner directive, 2026-06-20)
20
+
21
+ Per the owner directive, System 3 ships **inert**, gated OFF together with the grader; turn it on only when the owner enables it alongside the grader rework. The master switch is **`OTB_AUTONOMY_ENABLED`** (unset by default):
22
+
23
+ - `decide()` returns **GO** when the flag is off → a routine's Step 0 is a no-op; the routine runs exactly as before.
24
+ - `cascade-route.js` emits nothing when off; `cascade-dispatch` is a library nothing calls until armed.
25
+ - `autofixAllowed()` returns **false** by default (its defaults are the refusing values), and is **double-gated**: even when the flag is armed, it stays off while `GRADER_BYPASS_ENABLED` is on — which it currently is. So the auto-ship lane cannot fire until BOTH the autonomy flag is armed AND the grader is live.
26
+
27
+ The pure decision cores (`decide`, `autofixAllowed`, `cascade-dispatch.dispatch`) are unit-tested DB-free, including the inert-by-default and ceiling-never-exceeded properties.
28
+
29
+ ## Consequences
30
+
31
+ - The system is fully built and reviewable, but changes nothing in production until the owner arms it — no autonomous behavior shifts on deploy.
32
+ - When armed, the spend-brake protects against a runaway autonomous fleet; **security routines (dep-audit) should be exempted from the brake at arming time** — a skipped vuln scan is a security hole, not a saved dollar (noted in the routine).
33
+ - This system does **NOT** address marathon (interactive `cache_read`) spend — that is System 2 ([ADR 0076](<redacted>.md)), the only lever on the 82% pool. System 3 attacks the autonomous remainder.
34
+ - Arming guidance: enable `OTB_AUTONOMY_ENABLED` first with the grader live, watch `autonomy_runs` (skips) + System 1's `by_source` `cron:%` spend, then let the safe_autofix lane follow once the cascade + gate behavior is trusted.
35
+
36
+ ## Reproduce / verify
37
+
38
+ - Pure tests (DB-free): `tests/autonomy_gate.mjs` (decide + autofixAllowed, inert-by-default), `tests/cascade-dispatch.mjs` (ceiling clamp + escalation).
39
+ - `node scripts/gds/autonomy-gate.js overnight-builder` → with the flag unset, prints `GO — autonomy gate disabled … (inert)`.
@@ -0,0 +1,46 @@
1
+ # ADR 0080 — LLM-cache API transport + trust model
2
+
3
+ **Status:** Accepted (2026-06-21) · task [#1381](https://example.com/builders#/task/1381) · transport for the content-addressed cache of [ADR 0077](<redacted>.md); savings ledger contract per [ADR 0075](<redacted>.md) / `migrations/124_cost_baseline.sql`; reuses the rank trust boundary of [ADR 0016](<redacted>.md)
4
+
5
+ ## Context
6
+
7
+ System 5 ([ADR 0077](<redacted>.md)) memoizes idempotent model runs in the `llm_cache` Postgres table via `src/bongos/llm-cache.js` (`lookup`/`store`/`recordSaving`), all of which use a **direct `pg` pool**. But its two consumers — `architect-audit.js` and `onboarding-analyze.js` — run as CLI/cron on **builder machines**, where the pool is unreachable (peer-socket only; TCP is scram-only). So every cache op silently degraded to miss/no-store and the cache **could never hit organically** (verified empirically in the System-5 effectiveness eval, task [#1372](https://example.com/builders#/task/1372): 0 rows, 0 hits, despite correct logic — proven only when the DB was reached via a forwarded socket).
8
+
9
+ The fix is a transport: reach the cache DB from any consumer machine. The hard part is **trust** — a cache *store* writes a `result_stdout` that a later run **replays at $0 and trusts** (for `architect-audit` it becomes `audit_md` written to `docs/audits/` and `seed_ideas` filed to `idea_inbox`). An open store endpoint is a content-injection vector into the planning pipeline and a metrics-integrity vector into the public savings number.
10
+
11
+ ## Decision
12
+
13
+ **Expose the cache over the GDS API; keep the in-process pool as the server fast path; inject the API transport into the consumers — never statically couple the core to the CLI layer.**
14
+
15
+ - **`src/bongos/routes/llm-cache.js`** exposes `POST /api/gds/llm-cache/lookup` and `POST /api/gds/llm-cache/store`, each mapping 1:1 onto the existing `llm-cache.js` DB helper (the route never reimplements SQL). `/store` mounts its own 512 KB `express.json` (a full subagent stdout exceeds the global 64 KB cap; `routes.js` skips the global parser for that path).
16
+ - **`llm-cache.js` self-routes.** `lookup`/`store` try the pool first (`poolReachable()` — a memoized `SELECT 1`; `true` is sticky, `false` is **never** memoized so a transient boot blip can't permanently disable the server cache), then fall back to an **injected** `apiCall` (`setApiFallback(fn)`). The consumers — which already import `cli-lib` — inject `apiCall`; the core never statically requires the CLI layer (that would drag session/fetch plumbing into the always-on server and cross the core↔host boundary the fitness gate guards). Best-effort is preserved end-to-end: any pool/network/auth error degrades to miss/no-store and **never throws** (the fallback passes `allowUnauthenticated:true` so an expired session can't `process.exit` the audit it rides on).
17
+
18
+ ### Trust model (the load-bearing part)
19
+
20
+ | Control | What it stops |
21
+ |---|---|
22
+ | **Metic+ gate** on both routes (`requireRank('metic','archon')`, read live per-request — [ADR 0016](<redacted>.md)) | Xenos/Thetes seeding a result a high-value audit later replays. There is no legitimate sub-Metic consumer. |
23
+ | **`cache_key` must be `/^[0-9a-f]{64}$/`** | malformed / SQL-shaped keys; a key is a sha256 by construction. |
24
+ | **`task_type` ∈ the registered `NORMALIZERS`** | caching arbitrary (non-idempotent) producers; bounds stores to the known idempotent ones. |
25
+ | **`owner_builder_id` pinned to `req.builder.id`** (client value ignored) | a caller falsifying write-attribution. (The cache is **shared-on-read by content address** — `lookup` keys on `cache_key` only, not on owner. Isolation comes from the key itself: an entry is only readable by someone who can reconstruct its exact `prompt+model+task_type+scope_sha`, and only at Metic+ — not from an owner filter.) |
26
+ | **`scope_sha` in the key** (pre-existing) | blast radius: a poisoned entry is only ever replayed for the exact `(prompt, model, task_type, git-tree)` it was stored under — a changed tree misses. |
27
+ | **No `/record-saving` route — `recordSaving` stays pool-only** | the migration-124 contract: the saving lands in the **public** `cost_baseline` → `/public/cost-summary`, so it must be a server-side-priced figure, never a client dollar amount. |
28
+ | audit middleware + rate limiter (automatic) | a forensic record of every store; poisoning velocity capped at 30 writes/min/IP. |
29
+
30
+ ### The savings-booking gap (deliberate, interim)
31
+
32
+ `result_cost_usd` on `/store` is **clamped** (`[0, OTB_LLM_CACHE_MAX_COST_USD]`, default $10) and stored **only as informational metadata** on the internal `llm_cache` row — it is **never booked to the public ledger**. Because there is no API path for `recordSaving`, an off-server hit **records the hit** (`hit_count` bumped in `lookup`) but **does not book a dollar saving**. This honors the migration-124 contract ("`baseline_usd` is ALWAYS computed server-side from token counts via `priceUsage()` — NEVER a client-supplied dollar figure") by booking *nothing* rather than an unverified client figure.
33
+
34
+ **Follow-up (filed):** have the consumers forward the subagent envelope's token `usage` so `/store` can re-price the saving server-side via `priceUsage`, then book *that* into `cost_baseline`. Until then, System 5's realized savings show as **hit counts, not dollars** — which is the honest state.
35
+
36
+ ## Consequences
37
+
38
+ - The cache becomes functional from any builder machine: an unchanged-input re-run replays at $0 with `hit_count++`, from the laptop/box where the audit actually runs.
39
+ - The public savings number stays at $0 for off-server hits until the re-pricing follow-up lands — by design, so the first real numbers are trustworthy.
40
+ - A poisoned store is bounded to Metic+ actors, one immutable tree-snapshot of one scope, audit-logged, and rate-limited. The grader being bypassed (`GRADER_BYPASS_ENABLED=1`) is irrelevant here — the cache rides `runSubagent`, the spawn primitive, not the grading panel.
41
+ - Organic hit rate is expected to be **low** (an audit must re-run over an unchanged tree before a relevant commit lands), so this is a correctness/enablement fix, not a large dollar lever — consistent with the System-5 eval's "low end of 2–5% latent."
42
+
43
+ ## Reproduce / verify
44
+
45
+ - Pure tests (DB-free): `tests/llm-cache.mjs` (transport fallback: pool-unreachable → injected apiCall; `recordSaving` never calls the API), `tests/llm-cache-route.mjs` (hex-key + task_type validation, cost clamp, owner pinning, never-500).
46
+ - `node tests/fitness.mjs` → "no route bypasses server-side rank checks (ADR 0016)" passes with the new route's inline `requireRank`.
@@ -0,0 +1,62 @@
1
+ # ADR 0081 — Tool-agnostic design layer: repo-canonical, Claude Design + Figma as adapters
2
+
3
+ **Status:** Accepted (2026-06-21) · this ADR [#1375](https://example.com/builders#/task/1375) · implementation cluster [#1376](https://example.com/builders#/task/1376) [#1377](https://example.com/builders#/task/1377) [#1378](https://example.com/builders#/task/1378) [#1379](https://example.com/builders#/task/1379) [#1380](https://example.com/builders#/task/1380) · applies the core↔host pattern of [ADR 0062](<redacted>.md) to design; grader/ship changes ride the gate-review hard floor of [ADR 0043](<redacted>.md)
4
+
5
+ ## Context
6
+
7
+ Developers collaborate through Git because code is text: it diffs line-by-line and 3-way-merges automatically. Design has no equivalent — a Figma `.fig` is a proprietary vector scene-graph and a PNG is a binary blob; neither line-diffs or auto-merges. Designers never adopted the merge model: they co-edit live (Figma's multiplayer), snapshot versions, and publish component libraries. So "how does a designer's work reach GitHub?" has never had a clean answer here.
8
+
9
+ Three forces made this worth deciding now:
10
+
11
+ 1. **UI is becoming real work.** Today the GDS has three disciplines — `engineer | artist | ideator` — and "design/figma/UI" tasks fall into `artist`, the pixel-art lane. UI (HUD, menus, the builders' hall, status dashboard, landing pages) is a different problem from world tiles and deserves its own lane.
12
+ 2. **The grader is secretly two systems.** The GDS ship pipeline (`confirm → grade → merge → deploy → credits`) does **not** branch by discipline — every task rides the same rails. But the *grade* step is the code panel [`grader.js`](../../src/bongos/grader.js) (reads a git diff; scores code quality), while pixel art is really gated by a *separate* Gemini vision pipeline ([`art/pipeline/review.py`](../../art/pipeline/review.py)) that runs **upstream** in `/paint`, not at ship. Art passes the ship-time grader as a near-rubber-stamp because a text-only panel can't see pixels. Two grader codebases is a maintenance trap.
13
+ 3. **Claude Design changed the calculus.** [Claude Design](https://www.anthropic.com/news/claude-design-anthropic-labs) (Anthropic Labs, beta, 2026) **writes code and renders it** — it has no vector canvas. Its output is HTML/CSS/JS, and its June 2026 update added tight Claude Code sync (`/design-sync` imports a repo's design system in; a finished design hands off to Claude Code "where the designer left off"). So for Claude Design, *design is code* — it merges like any other code.
14
+
15
+ Owner (Lars) requirements, reached in the 2026-06-21 design conversation:
16
+
17
+ - **No vendor lock-in.** A competitor may ship a rival design tool; the system must not depend on Claude Design specifically.
18
+ - **Human escape hatch.** A talented designer must be able to make manual changes directly in Figma.
19
+ - **One grader, one regen flow for every task type.** Type-dependent criteria are fine; two grader *systems* are not.
20
+
21
+ ## Decision
22
+
23
+ **The repo is the single source of truth; every design tool is a swappable adapter against a neutral contract.** This is the [ADR 0062](<redacted>.md) core↔host decoupling applied to design: the system depends on the *contract*, not on any tool.
24
+
25
+ 1. **Neutral design contract = the repo.** The canonical representation is design tokens (extending [`config/branding.json`](../../config/branding.json)) + component code + exported assets, plus a per-surface "design source pointer" (which tool authored it, where its editable source lives). Tools read from and write to this contract; nothing else is canonical. ([#1377](https://example.com/builders#/task/1377))
26
+
27
+ 2. **Tools are adapters, not integrations.** Claude Design and Figma are the first two adapters; a future tool is just a third. Each adapter does two things: import the repo design system *into* the tool, and emit a tool change back as a *committed diff*.
28
+ - **Claude Design adapter** ([#1378](https://example.com/builders#/task/1378)): `/design-sync` exports our design system in; the Claude Code handoff lands generated UI code under a claimed GDS task. No translation layer — the output is already code.
29
+ - **Figma adapter** ([#1379](https://example.com/builders#/task/1379)): a human edit → generate component code/tokens (Code Connect / Figma MCP) → commit; and the repo syncs *back* to Figma (the code→Figma bridge) so the designer never edits a stale file. This is the human escape hatch.
30
+
31
+ 3. **`ui` becomes its own discipline** ([#1376](https://example.com/builders#/task/1376)), split out of `artist`. `ui` = design-as-code (graded by diff + rendered screenshot); `artist`/graphics = pixel art (graded by vision). Each routes to its own work-mode (a new `/design`, mirroring `/paint`).
32
+
33
+ 4. **Code-canonical round-trip.** Structured UI (components, layout, tokens — the design-system vocabulary) round-trips as code. Freeform visual work that doesn't translate cleanly is exported as a committed *asset* (the graphics path), not round-tripped. A surface a human truly wants to own canvas-first can be flagged "Figma-canonical" as an explicit exception; code-canonical is the default.
34
+
35
+ 5. **One grader, one regen flow — parameterized by type, not forked** ([#1380](https://example.com/builders#/task/1380)). Collapse the code panel and the Gemini pipeline into a single engine: a rubric registry keyed by task type (code-quality / visual / UI+a11y), evidence chosen by type (git diff for code+UI; render→screenshot for visual), one **multimodal** Claude grade call that subsumes the separate vision pass, and one shared regen loop — `spec → generate → grade → fail? regenerate → pass? commit` — identical across types. Because Claude Design emits code, UI rides the *same* git-diff grader as engineer code; only pixel art needs the vision modality, which the multimodal grader already covers.
36
+
37
+ ## Consequences
38
+
39
+ - **No lock-in.** Tools plug into the repo contract; adding or dropping one (Claude Design, Figma, a future rival) doesn't touch the core. That is the explicit insurance the owner asked for.
40
+ - **Designers keep Figma.** Manual Figma edits are first-class for structured/design-system changes and round-trip into the repo via a normal GDS task + the same grader. The honest limit: the Figma→code round-trip is lossy for arbitrary canvas art — that work becomes a committed asset, not round-tripped code.
41
+ - **One grader to maintain, not two.** The standalone Gemini review path is retired into the unified engine. Code doesn't auto-regen today (a failed grade = human fixes + re-ships); unifying gives every type the same generate→grade→regenerate loop.
42
+ - **Graphics is unchanged.** World pixel art stays on the Claude Code + Gemini pipeline; Figma stays its viewer ([`otb-figma-sync`](../../.claude/skills/otb-figma-sync/SKILL.md)). This ADR adds the `ui` lane beside it, it does not disturb the art pipeline.
43
+ - **Gate-review floor applies.** [#1380](https://example.com/builders#/task/1380) touches [`grader.js`](../../src/bongos/grader.js) + [`ship.js`](../../scripts/gds/ship.js) — the gate-review **hard floor** ([ADR 0043](<redacted>.md)). It needs owner Gate approval even for Archon, and the multimodal call path wants a security review.
44
+
45
+ ## Rejected alternatives
46
+
47
+ - **Fork the GDS / keep two grader sets** (an earlier draft of this design). Rejected by the owner: separate grader systems per discipline is a maintenance trap. One engine + type-parameterized rubric/evidence achieves the same ends with one codebase.
48
+ - **Claude Design only.** Cleanest GitHub path (code-native), but bets the system on one beta — the lock-in the owner explicitly wants to avoid.
49
+ - **Figma only.** Mature and multiplayer, but its source is a vector file, so every change needs a code-generation translation step with an imperfect round-trip. Kept as an adapter, not as the single tool.
50
+ - **Figma-canonical (or per-tool source of truth) by default.** Two masters and lossy reconciliation. Code-canonical with Figma round-tripping *in* keeps one master; per-surface Figma-canonical remains available as an explicit exception.
51
+
52
+ ## Implementation
53
+
54
+ The cluster is seeded and dependency-wired in the GDS (this ADR is [#1375](https://example.com/builders#/task/1375)):
55
+
56
+ - [#1376](https://example.com/builders#/task/1376) — `ui` discipline + work-mode (→ [#1375](https://example.com/builders#/task/1375))
57
+ - [#1377](https://example.com/builders#/task/1377) — neutral design contract + adapter interface (→ [#1375](https://example.com/builders#/task/1375))
58
+ - [#1378](https://example.com/builders#/task/1378) — Claude Design adapter (→ [#1377](https://example.com/builders#/task/1377))
59
+ - [#1379](https://example.com/builders#/task/1379) — Figma round-trip adapter (→ [#1377](https://example.com/builders#/task/1377))
60
+ - [#1380](https://example.com/builders#/task/1380) — unify the grader (→ [#1376](https://example.com/builders#/task/1376), [#1377](https://example.com/builders#/task/1377))
61
+
62
+ Acceptance, when built: a UI surface authored in Claude Design *and* one hand-edited in Figma both reach prod through one GDS task and the one grader; the standalone Gemini review path is gone; editing Figma always opens a design synced from current `main`.
@@ -0,0 +1,32 @@
1
+ # ADR 0082 — Productized key-storage provisioning (server-generated master key, zero SSH)
2
+
3
+ **Status:** Accepted (2026-06-21) · task [#1398](https://example.com/builders#/task/1398) · resolves blocker 41 · extends the per-builder secret-box (task 1013; `src/bongos/secret-box.js`) · sibling of the UI-first intake work (task [#1391](https://example.com/builders#/task/1391))
4
+
5
+ > Note: `secret-box.js`'s header cites "ADR 0071" for the original design, but 0071 on disk is a different (dev-box) decision — that reference is stale. This ADR is the authoritative record for the master-key *provisioning* path; the encryption scheme itself shipped under task 1013.
6
+
7
+ ## Context
8
+
9
+ The per-builder Gemini key feature (task 1013) encrypts each builder's key at rest with an AES-256-GCM **master key** that, by design, lives ONLY in server env (`BUILDER_SECRET_KEY`) or a local `~/.config/otb/builder-secret.key` (0600) operator file — never in the DB, repo, or chat. The feature shipped its endpoints + settings UI, but the master key was **never provisioned in prod**, so `secretBox.isConfigured()` is false → `GET /me/art-key/own` returns `storage_configured:false` → the settings card is a dead-end ("Key storage is being set up by an Archon — check back shortly") with no input. The result: **no builder can store a key at all**, blocking the art pipeline for everyone past the shared-newcomer tier (surfaced live when an Archon hit it on task 587).
10
+
11
+ The only documented fix was a manual one: SSH to the droplet and hand-add `BUILDER_SECRET_KEY` to the systemd EnvironmentFile. The owner declined that — provisioning should be a **product action**, not a terminal ritual.
12
+
13
+ ## Decision
14
+
15
+ An **Archon initializes key storage from the UI** — the server generates and persists the master key; no human touches a secret.
16
+
17
+ - **`secretBox.provisionMasterKey({ file?, env? })`** generates 32 crypto-random bytes (`crypto.randomBytes`) and writes them (64-hex) to the operator file (`~/.config/otb/builder-secret.key`) as **0600** — the path the loader already honors as its file-fallback source, so it survives restarts. It is **idempotent and never overwrites**: if a valid key already resolves (env or file) it's a no-op (`created:false`); if a file is present but *doesn't* decode, it writes with the `wx` (exclusive-create) flag and **refuses on EEXIST** rather than clobber — overwriting the master key would make every already-stored builder key permanently undecryptable. `opts` exist only for the hermetic unit test.
18
+ - **`POST /api/gds/me/art-key/storage-init`** (in `routes/me.js`), gated `requireRank('archon')` — a server-wide admin action that happens to live under `/me/art-key/*` for client locality. It calls `provisionMasterKey()` and returns `{ ok, created, storage_configured }`; a refusal (present-but-invalid file) is a `409` that tells the operator to look, never a silent overwrite.
19
+ - **The settings card** (`public-builders/settings.js`), in the `storage_configured:false` state, now shows an Archon a **"Set up key storage"** button (the server enforces the rank regardless — the client check only decides what to render; divine tiers above archon also pass). Non-Archons keep the wait-for-an-Archon message. On success the card drops straight into the key-entry state.
20
+
21
+ ## Consequences
22
+
23
+ - Turning on key storage is now one click by any Archon — **zero SSH, zero hand-edited prod secrets**. Re-clicking after it's up is a safe no-op.
24
+ - **Durability trade-off (accepted):** the master key lives in a 0600 file beside the encrypted blobs on the prod droplet. A `DB dump alone still cannot decrypt` (the key isn't in the DB). If the *droplet's disk* is lost without the file, stored keys become undecryptable — but this is BYOK: builders simply re-add their own keys. Crypto-RNG-to-file also beats a human-chosen secret (no weak/reused values, never pasted anywhere). Backing up the file with the other droplet secrets is recommended but not required for correctness.
25
+ - **Idempotency is load-bearing.** The never-overwrite guard is the one property that must never regress — a unit test asserts a second call leaves the key bytes unchanged and that a present-but-invalid file is refused, not clobbered.
26
+ - Security surface: this touches secret-box + an auth-gated route, so it runs the hacker/security review and gate-review will flag it. The provisioning endpoint exposes no secret material in any response (only `{ ok, created, storage_configured }`).
27
+
28
+ ## Reproduce / verify
29
+
30
+ - Pure tests (DB-free): `tests/secret_box.mjs` — `provisionMasterKey` creates a 0600 64-hex file, is idempotent (no overwrite / no brick), short-circuits on a valid env key, and refuses a present-but-invalid file.
31
+ - Route gate: `tests/route_rank_check.mjs` confirms the new privileged route classifies to its rank.
32
+ - End-to-end: on a server with no master key, an Archon clicks "Set up key storage" → `storage_configured` flips true → a key can be added via Settings and syncs to the box (`fetch-art-key.js`).