@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,322 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // scripts/gds/gate-review.js — the automatic gate-surface gatekeeper (ADR 0058).
5
+ //
6
+ // WHY. In deploy mode 'ci' (config/deploy.json) PRs auto-merge on green checks and
7
+ // main auto-deploys to prod. CODEOWNERS (owner review on gate surfaces) was the ONLY
8
+ // human in that loop — and the bottleneck. The owner chose a RANK-BASED trust model
9
+ // (2026-06-15): trust senior builders to auto-merge routine sensitive work, but keep a
10
+ // HARD, rank-independent floor for the gate's own machinery + deploy switch.
11
+ //
12
+ // WHAT. This is a PURE, deterministic classifier over the PR diff-as-DATA. It runs in
13
+ // CI (.github/workflows/gate-review.yml) from the TRUSTED BASE copy (the workflow
14
+ // overlays scripts/+src/ from origin/main before running, so a PR cannot edit the
15
+ // analyzer to pass itself). It emits one of three verdicts:
16
+ //
17
+ // PASS — no gate surface touched, OR only AUTO pure-removal surfaces
18
+ // (un-mute a test, narrow the secret-scanner allowlist). Auto-merge.
19
+ // NEEDS_TRUST — a sensitive-but-routine gate surface (migrations, deps, routes,
20
+ // server, ship plumbing, boxes, auth-adjacent, doctrine docs). The
21
+ // workflow auto-merges this IFF the author is Metic+ (rank trust) or
22
+ // the owner approved; otherwise it escalates.
23
+ // ESCALATE — the HARD FLOOR: the gate's own machinery, the deploy switch, branch
24
+ // protection, CI workflows, the rank/permission enforcement, the
25
+ // grader, the deploy-time audit, or the hooks the gate ships through.
26
+ // Rank-trust does NOT apply — this ALWAYS pings the owner. Also any
27
+ // pre-flight rejection (symlink / non-ASCII path / oversize / analyzer
28
+ // error) → ESCALATE, fail-closed.
29
+ //
30
+ // The gate-surface SET is the authoritative src/bongos/permission-path-check.PROTECTED_GLOBS
31
+ // (imported, NEVER hand-retyped — the red-team's #1 finding). The classifier only
32
+ // decides, per touched surface, whether it is HARD-FLOOR, NEEDS_TRUST, or AUTO. Anything
33
+ // matched-protected-but-unclassified defaults to ESCALATE (no allow-by-omission).
34
+ //
35
+ // The pure core (classifyChanges) takes diff data as arguments and is exhaustively
36
+ // unit-tested (tests/gate_review.mjs) with the red-team evasion matrix. The CLI wrapper
37
+ // (main) gathers the real diff via git and applies GATE_REPORT_ONLY / exit codes.
38
+
39
+ const { execFileSync } = require('node:child_process');
40
+ const fs = require('node:fs');
41
+ const permPath = require('../../src/bongos/permission-path-check');
42
+ const { PROTECTED_GLOBS, globToRegExp } = permPath;
43
+
44
+ // --- HARD FLOOR (rank-independent ESCALATE) -------------------------------------------
45
+ // A subset of PROTECTED_GLOBS: the surfaces that, if a compromised/injected senior
46
+ // session auto-merged them, would DISABLE the safety system itself or the deploy gate.
47
+ // Kept as globs so the matcher is identical to permission-path-check (trailing '/' =
48
+ // subtree). The owner can promote a NEEDS_TRUST surface here with a one-line edit (which
49
+ // is itself a hard-floor change to this file → escalates — correct).
50
+ const HARD_FLOOR_GLOBS = [
51
+ 'scripts/gds/gate-review.js', // self
52
+ 'src/bongos/permission-path-check.js', // defines the protected set this gate reads
53
+ 'src/bongos/route-rank-check.js', // the route-gate auditor
54
+ 'src/bongos/auth.js', // requireRank / requireBuilder — the enforcement point
55
+ 'modules/grading/grader.js', // BV1.R73: grading carved to modules/grading/
56
+ 'modules/grading/grader-workers/',
57
+ 'modules/grading/grader-rubric.json',
58
+ 'scripts/gds/ci-grade.js', // CI grade-gate driver (task 1143 — red-team #3)
59
+ 'scripts/gds/grade-smoke.js', // grade-smoke driver
60
+ 'scripts/gds/conductor-dispatch.js', // mid-flight grader dispatch
61
+ 'scripts/gds/main-audit.js', // the authoritative deploy-time audit (the backstop)
62
+ 'scripts/gds/push-main.js', // the sanctioned main-push carrying the override
63
+ 'scripts/gds/run-unit-tests.js', // the test selector (AUTO pure-removal handled first)
64
+ 'scripts/gds/install-git-hooks.js',
65
+ 'scripts/gds/hooks/',
66
+ 'scripts/migrate.sh',
67
+ 'scripts/deploy/',
68
+ 'config/deploy.json', // the laptop/ci/bypass deploy switch
69
+ 'infra/', // branch-protection.json + deploy substrate
70
+ '.github/', // CI gates: gate-review.yml, deploy-prod.yml, secret scan, grade gate
71
+ 'CODEOWNERS',
72
+ '.husky/', // pre-push/pre-commit gate delivery (secrets-allowlist.txt is AUTO, checked first)
73
+ '.claude/hooks/',
74
+ '.claude/settings.json',
75
+ ];
76
+
77
+ // db.js is HARD-FLOOR only for the rank-tier brain (REQUIRES_RANK_TIER); every other
78
+ // db.js change is NEEDS_TRUST (it is a huge, routinely-edited module — file-level
79
+ // hard-flooring it would ping the owner for ordinary query work). This is the one
80
+ // content-level rule; everything else is path-level.
81
+ const DB_JS = 'src/bongos/db.js';
82
+ const RANK_TIER_RE = /REQUIRES_RANK_TIER\s*=\s*\{[\s\S]*?\}/;
83
+
84
+ // AUTO pure-removal surfaces — a NARROWING-only edit can only STRENGTHEN the gate, so
85
+ // it may auto-pass for ANY author. Any non-narrowing edit falls through to its glob
86
+ // classification (run-unit-tests.js → HARD FLOOR; secrets-allowlist.txt → .husky/ HARD FLOOR).
87
+ const AUTO_NARROWING = {
88
+ 'scripts/gds/run-unit-tests.js': certifyRunUnitTestsNarrowing,
89
+ '.husky/secrets-allowlist.txt': certifyAllowlistNarrowing,
90
+ };
91
+
92
+ const COMPILED_HARD = HARD_FLOOR_GLOBS.map((g) => ({ glob: g, re: globToRegExp(g) }));
93
+ const matchesHardFloor = (f) => COMPILED_HARD.some((c) => c.re.test(f));
94
+
95
+ // A path is "protected" per the authoritative module.
96
+ const protectedRe = PROTECTED_GLOBS.map((g) => ({ glob: g, re: globToRegExp(g) }));
97
+ const matchesProtected = (f) => protectedRe.some((c) => c.re.test(f));
98
+
99
+ // Only [\x20-\x7e] path chars, NFC-stable, no leading/trailing whitespace. Defeats the
100
+ // unicode-homoglyph + whitespace-alias evasions (red-team Holes 6/8).
101
+ function isCanonicalPath(p) {
102
+ return typeof p === 'string' && p.length > 0 && /^[\x20-\x7e]+$/.test(p)
103
+ && p === p.normalize('NFC') && p === p.trim();
104
+ }
105
+
106
+ // AUTO certifier: run-unit-tests.js may auto-pass ONLY if its sole semantic change is
107
+ // REMOVING entries from INTEGRATION/KNOWN_FAILING (un-muting tests) — never adding, and
108
+ // the rest of the file byte-identical modulo those two set literals.
109
+ function certifyRunUnitTestsNarrowing(base, head) {
110
+ if (base == null || head == null) return { pass: false, reason: 'added/removed wholesale — not a narrowing edit' };
111
+ const setOf = (t, name) => {
112
+ const m = new RegExp(`const ${name} = new Set\\(\\[([\\s\\S]*?)\\]\\)`).exec(t);
113
+ if (!m) return null;
114
+ return new Set([...m[1].matchAll(/['"]([^'"]+)['"]/g)].map((x) => x[1]));
115
+ };
116
+ const strip = (t) => t.replace(/const (INTEGRATION|KNOWN_FAILING) = new Set\(\[[\s\S]*?\]\)/g, 'SET');
117
+ if (strip(base) !== strip(head)) return { pass: false, reason: 'non-set code changed in run-unit-tests.js' };
118
+ for (const name of ['INTEGRATION', 'KNOWN_FAILING']) {
119
+ const b = setOf(base, name), h = setOf(head, name);
120
+ if (!b || !h) return { pass: false, reason: `cannot parse ${name} set — fail-closed` };
121
+ for (const x of h) if (!b.has(x)) return { pass: false, reason: `${name} ADDED '${x}' (muting a test)` };
122
+ }
123
+ return { pass: true };
124
+ }
125
+
126
+ // AUTO certifier: secrets-allowlist.txt may auto-pass ONLY if its head line set is a
127
+ // subset of the base (removing/narrowing allowlist entries) — never adding a new exclude.
128
+ function certifyAllowlistNarrowing(base, head) {
129
+ if (base == null || head == null) return { pass: false, reason: 'added/removed wholesale — not a narrowing edit' };
130
+ const norm = (t) => new Set(t.split('\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('#')));
131
+ const b = norm(base), h = norm(head);
132
+ for (const line of h) if (!b.has(line)) return { pass: false, reason: `allowlist ADDED/BROADENED: ${line}` };
133
+ return { pass: true };
134
+ }
135
+
136
+ // ----------------------------------------------------------------------------------------
137
+ // PURE CORE. Inputs are diff DATA (no git, no fs) so the whole policy is unit-tested:
138
+ // files: [{ path, mode, deleted }] — changed paths + git new-mode + delete flag
139
+ // blobAt: (which:'base'|'head', path) => string|null — file content at base/head
140
+ // diffBytes: number — total textual diff size
141
+ // Returns { verdict:'pass'|'needs_trust'|'escalate', escalations:[{path,reason}],
142
+ // needsTrust:[{path,reason}], autoPassed:[path], surfaces:[path] }.
143
+ // ----------------------------------------------------------------------------------------
144
+ const MAX_DIFF_BYTES = Number(process.env.GATE_MAX_DIFF_BYTES || 2 * 1024 * 1024);
145
+
146
+ function classifyChanges({ files, blobAt, diffBytes = 0 } = {}) {
147
+ const escalations = [];
148
+ const needsTrust = [];
149
+ const autoPassed = [];
150
+ const surfaces = [];
151
+
152
+ // --- Pre-flight, fail-closed (whole changed set) ---
153
+ for (const f of files || []) {
154
+ if (f.mode === '120000') escalations.push({ path: f.path, reason: 'symlink in diff — refused (alias evasion)' });
155
+ if (!isCanonicalPath(f.path)) escalations.push({ path: String(f.path), reason: 'non-ASCII/whitespace path — refused' });
156
+ }
157
+ if (diffBytes > MAX_DIFF_BYTES) {
158
+ escalations.push({ path: '<diff>', reason: `diff ${diffBytes}B exceeds ${MAX_DIFF_BYTES}B — too large to certify` });
159
+ }
160
+
161
+ for (const f of files || []) {
162
+ const p = f.path;
163
+ if (!isCanonicalPath(p)) continue; // already escalated above
164
+ // A gate surface = the authoritative PROTECTED_GLOBS, OR a hard-floor glob (some
165
+ // floor paths — gate-review.js itself, config/deploy.json, CODEOWNERS — are also
166
+ // added to PROTECTED_GLOBS, but OR-ing keeps the gatekeeper correct even if a
167
+ // future hard-floor entry isn't yet in the shared list), OR a tests/*.mjs file.
168
+ const isProtected = matchesProtected(p) || matchesHardFloor(p);
169
+ const isTest = /^tests\/.+\.mjs$/.test(p);
170
+ if (!isProtected && !isTest) continue; // not a gate surface
171
+
172
+ surfaces.push(p);
173
+
174
+ // tests/*.mjs: deleting or shrinking a test silently weakens the suite → NEEDS_TRUST
175
+ // (rank-trustable per the owner's model); adding/expanding is fine → PASS.
176
+ if (isTest && !isProtected) {
177
+ if (f.deleted) { needsTrust.push({ path: p, reason: 'test file DELETED — suite shrink' }); continue; }
178
+ const base = blobAt('base', p), head = blobAt('head', p);
179
+ if (base != null && head != null && head.length < base.length) {
180
+ needsTrust.push({ path: p, reason: 'test file SHRANK — possible muting' });
181
+ }
182
+ continue;
183
+ }
184
+
185
+ // AUTO pure-removal surfaces: certify a narrowing-only edit (any author).
186
+ if (Object.prototype.hasOwnProperty.call(AUTO_NARROWING, p)) {
187
+ const cert = AUTO_NARROWING[p](blobAt('base', p), blobAt('head', p));
188
+ if (cert.pass) { autoPassed.push(p); continue; }
189
+ // not a narrowing edit → fall through to HARD FLOOR (both AUTO files are floor globs)
190
+ escalations.push({ path: p, reason: `AUTO surface failed narrowing cert (${cert.reason}) — root-of-trust` });
191
+ continue;
192
+ }
193
+
194
+ // db.js: HARD FLOOR only when the rank-tier brain changed; else NEEDS_TRUST.
195
+ if (p === DB_JS) {
196
+ const base = blobAt('base', p), head = blobAt('head', p);
197
+ const region = (t) => { const m = t == null ? null : RANK_TIER_RE.exec(t); return m ? m[0] : (t == null ? '<absent>' : '<no-region>'); };
198
+ if (base == null || head == null) { needsTrust.push({ path: p, reason: 'db.js added/removed' }); continue; }
199
+ if (region(base) !== region(head)) {
200
+ escalations.push({ path: p, reason: 'db.js REQUIRES_RANK_TIER (rank brain) changed — root-of-trust' });
201
+ } else {
202
+ needsTrust.push({ path: p, reason: 'db.js change outside the rank-tier region' });
203
+ }
204
+ continue;
205
+ }
206
+
207
+ // HARD FLOOR globs → ESCALATE regardless of rank.
208
+ if (matchesHardFloor(p)) { escalations.push({ path: p, reason: 'gate machinery / deploy switch (hard floor) — owner review required' }); continue; }
209
+
210
+ // Any other protected surface → NEEDS_TRUST (rank-trustable).
211
+ needsTrust.push({ path: p, reason: 'sensitive gate surface — auto-merges for Metic+ (rank trust)' });
212
+ }
213
+
214
+ const verdict = escalations.length ? 'escalate' : (needsTrust.length ? 'needs_trust' : 'pass');
215
+ return { verdict, escalations, needsTrust, autoPassed, surfaces };
216
+ }
217
+
218
+ // Resolve the merge action from the verdict + the two trust signals (both injected by
219
+ // the workflow, never read by the pure classifier). RANK trust (server-attested Metic+)
220
+ // clears NEEDS_TRUST only; the HARD FLOOR (escalate) is cleared ONLY by an explicit
221
+ // owner review — rank never bypasses it. An owner approval clears anything.
222
+ // pass → 'pass'
223
+ // needs_trust → 'pass' iff (rank-trusted OR owner-approved)
224
+ // escalate → 'pass' iff owner-approved
225
+ function resolveAction({ verdict, trusted, ownerApproved }) {
226
+ if (verdict === 'pass') return 'pass';
227
+ if (verdict === 'escalate') return ownerApproved ? 'pass' : 'block';
228
+ return trusted || ownerApproved ? 'pass' : 'block';
229
+ }
230
+
231
+ // ----------------------------------------------------------------------------------------
232
+ // CLI wrapper — gather the real diff and apply report-only / exit codes. Never returns 0
233
+ // on an analyzer error (fail-closed). The rank/owner-approval resolution for NEEDS_TRUST
234
+ // is provided by the workflow via GATE_AUTHOR_TRUSTED (set from the server-resolved rank /
235
+ // owner approval); the pure core never reads rank.
236
+ // ----------------------------------------------------------------------------------------
237
+ function git(args) { return execFileSync('git', args, { encoding: 'utf8', maxBuffer: 128 * 1024 * 1024 }); }
238
+
239
+ function gatherDiff(baseRef) {
240
+ const mb = git(['merge-base', baseRef, 'HEAD']).trim();
241
+ const raw = git(['diff', '--raw', `${mb}...HEAD`]).split('\n').filter(Boolean);
242
+ const files = [];
243
+ for (const line of raw) {
244
+ // ":100644 100644 sha sha M\tpath" (status D = delete; mode 120000 = symlink)
245
+ const m = /^:(\d{6}) (\d{6}) \S+ \S+ (\S+)\t(.+)$/.exec(line);
246
+ if (!m) { files.push({ path: '<unparseable>', mode: '000000', deleted: false, parseError: true }); continue; }
247
+ const [, , newMode, status, rawPath] = m;
248
+ files.push({ path: rawPath, mode: newMode, deleted: status.startsWith('D') });
249
+ }
250
+ const diffBytes = Buffer.byteLength(git(['diff', `${mb}...HEAD`]), 'utf8');
251
+ const blobAt = (which, p) => {
252
+ const ref = which === 'base' ? mb : 'HEAD';
253
+ try { return git(['show', `${ref}:${p}`]); } catch { return null; }
254
+ };
255
+ return { files, blobAt, diffBytes };
256
+ }
257
+
258
+ async function main() {
259
+ const baseRef = process.env.GATE_BASE_REF || 'origin/main';
260
+ const reportOnly = process.env.GATE_REPORT_ONLY === '1';
261
+ const trusted = process.env.GATE_AUTHOR_TRUSTED === '1'; // set by the workflow from server-resolved rank / owner approval
262
+
263
+ let result;
264
+ try {
265
+ if ((process.env.GATE_FILES_JSON || '').trim()) {
266
+ // test/dry-run injection: {files, blobs:{ 'base:path':..., 'head:path':... }, diffBytes}
267
+ const inj = JSON.parse(process.env.GATE_FILES_JSON);
268
+ const blobAt = (which, p) => (inj.blobs && Object.prototype.hasOwnProperty.call(inj.blobs, `${which}:${p}`)) ? inj.blobs[`${which}:${p}`] : null;
269
+ result = classifyChanges({ files: inj.files, blobAt, diffBytes: inj.diffBytes || 0 });
270
+ } else {
271
+ const { files, blobAt, diffBytes } = gatherDiff(baseRef);
272
+ if (files.some((f) => f.parseError)) throw new Error('unparseable --raw diff line (fail-closed)');
273
+ result = classifyChanges({ files, blobAt, diffBytes });
274
+ }
275
+ } catch (e) {
276
+ console.error(`gate-review: analyzer error (fail-closed): ${e && e.stack ? e.stack : e}`);
277
+ process.exit(reportOnly ? 0 : 1);
278
+ return;
279
+ }
280
+
281
+ // Resolve the final action.
282
+ const ownerApproved = process.env.GATE_OWNER_APPROVED === '1';
283
+ const action = resolveAction({ verdict: result.verdict, trusted, ownerApproved });
284
+
285
+ const lines = [`## gate-review: ${result.verdict.toUpperCase()}${reportOnly ? ' (report-only)' : ''} → would ${action === 'pass' ? 'PASS' : 'BLOCK + ping owner'}`, ''];
286
+ if (result.surfaces.length) lines.push(`Gate surfaces touched: ${result.surfaces.length}`);
287
+ for (const e of result.escalations) lines.push(`- ESCALATE \`${e.path}\` — ${e.reason}`);
288
+ for (const n of result.needsTrust) lines.push(`- NEEDS-TRUST \`${n.path}\` — ${n.reason} → ${action === 'pass' ? 'PASS' : 'BLOCK (needs Metic+ attestation or owner approval)'}`);
289
+ for (const a of result.autoPassed) lines.push(`- AUTO-PASS \`${a}\` — pure narrowing (strengthens the gate)`);
290
+ if (!result.surfaces.length) lines.push('No gate surface touched — auto-merge.');
291
+
292
+ const out = lines.join('\n');
293
+ console.log(out);
294
+ if (process.env.GITHUB_STEP_SUMMARY) { try { fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, out + '\n'); } catch (_) { /* best-effort */ } }
295
+
296
+ if (action === 'block' && !reportOnly) {
297
+ await pingOwner(result).catch(() => {});
298
+ process.exit(1);
299
+ }
300
+ process.exit(0);
301
+ }
302
+
303
+ async function pingOwner(result) {
304
+ const url = process.env.DISCORD_GATE_APPROVALS_WEBHOOK;
305
+ const pr = process.env.GATE_PR_NUMBER;
306
+ if (!url || !pr) return;
307
+ const surfaces = [...new Set([...result.escalations, ...result.needsTrust].map((x) => x.path))].slice(0, 10).join(', ');
308
+ const body = { content: `gate-pr #${pr} — gate-surface change needs your review: ${surfaces}\nReview + approve the PR to land it.`, allowed_mentions: { parse: [] } };
309
+ await fetch(url, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) });
310
+ }
311
+
312
+ module.exports = {
313
+ classifyChanges,
314
+ resolveAction,
315
+ certifyRunUnitTestsNarrowing,
316
+ certifyAllowlistNarrowing,
317
+ isCanonicalPath,
318
+ matchesHardFloor,
319
+ HARD_FLOOR_GLOBS,
320
+ };
321
+
322
+ if (require.main === module) main();
@@ -0,0 +1,325 @@
1
+ #!/usr/bin/env node
2
+ // scripts/gds/gating.js — owner kill-switch for main-branch merge gating.
3
+ //
4
+ // What "gating" means here — TWO independent levers, both toggled together:
5
+ // 1. GitHub branch protection on `main`: required status checks (unit,
6
+ // trufflehog, gate-review) + required code-owner review (CODEOWNERS).
7
+ // 2. The application-layer trust gates that run on every PR — the gate-review
8
+ // and grade-gate CI workflows. These post their own status checks and the
9
+ // ship / auto-merge pipeline refuses to land a PR while gate-review is red
10
+ // (it escalates gate-surface changes — infra/, migrations/, CODEOWNERS,
11
+ // scripts/gds plumbing — to owner approval). Branch protection alone does
12
+ // NOT neutralize these, which is why `off` also `gh workflow disable`s them.
13
+ // With gating ON, a gate-surface PR needs owner approval / --admin to merge.
14
+ // With gating OFF, ordinary `gh pr merge N` (and every builder / autonomous
15
+ // session) merges with no checks and no approval. `unit` + `trufflehog` keep
16
+ // running either way — real safety nets that force no approval.
17
+ //
18
+ // It is REVERSIBLE by construction: `off` snapshots the live protection to a
19
+ // replay-ready file, then deletes protection; `on` PUTs the snapshot back,
20
+ // byte-for-byte. If the snapshot is missing, `on` falls back to a baked-in
21
+ // known-good config (printed loudly) so you can never get permanently stuck.
22
+ //
23
+ // ⚠ While OFF, ANY merge to `main` reaches prod with no checks and no review —
24
+ // yours, any builder's, any autonomous session's. This is a deliberate,
25
+ // owner-only, temporary posture. Flip it back with `on` when done.
26
+ //
27
+ // Usage:
28
+ // node scripts/gds/gating.js status # show current protection + snapshot state
29
+ // node scripts/gds/gating.js off # snapshot, then remove all protection
30
+ // node scripts/gds/gating.js on # restore protection from the snapshot
31
+ //
32
+ // Auth: uses the `gh` CLI, which must be authenticated as a repo admin (the
33
+ // owner). This is a trust-boundary surface (ADR 0016/0043) — owner-gated in
34
+ // CODEOWNERS so a builder cannot weaken the gate by editing this file.
35
+
36
+ 'use strict';
37
+
38
+ const { execFileSync } = require('node:child_process');
39
+ const fs = require('node:fs');
40
+ const os = require('node:os');
41
+ const path = require('node:path');
42
+
43
+ const BRANCH = 'main';
44
+ const SNAPSHOT = require('../../src/instance-config').configPath('gating-snapshot.json');
45
+
46
+ // The application-layer trust gates that run on every PR and force owner
47
+ // approval / --admin on gate-surface changes. Branch protection alone does NOT
48
+ // neutralize these — they post their own status checks and the auto-merge /
49
+ // ship pipeline refuses to land a PR while gate-review is red. So the kill-switch
50
+ // also disables/enables these workflows. `unit` + `trufflehog` (secret scan) are
51
+ // deliberately left running — they are real safety nets and force no approval.
52
+ const GATE_WORKFLOWS = ['gate-review.yml', 'grade-gate.yml'];
53
+
54
+ // Baked-in known-good config (the live state captured 2026-06-19). Used only as
55
+ // a restore fallback when no snapshot exists, so `on` can never be stuck.
56
+ const DEFAULT_PROTECTION = {
57
+ required_status_checks: {
58
+ strict: false,
59
+ checks: [
60
+ { context: 'unit', app_id: 15368 },
61
+ { context: 'trufflehog', app_id: 15368 },
62
+ { context: 'gate-review', app_id: 15368 },
63
+ ],
64
+ },
65
+ enforce_admins: false,
66
+ required_pull_request_reviews: {
67
+ dismiss_stale_reviews: false,
68
+ require_code_owner_reviews: true,
69
+ required_approving_review_count: 0,
70
+ require_last_push_approval: false,
71
+ },
72
+ restrictions: null,
73
+ };
74
+
75
+ function gh(args, opts = {}) {
76
+ return execFileSync('gh', args, {
77
+ encoding: 'utf8',
78
+ stdio: ['pipe', 'pipe', 'pipe'],
79
+ ...opts,
80
+ });
81
+ }
82
+
83
+ function repoSlug() {
84
+ try {
85
+ return gh(['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner']).trim();
86
+ } catch (e) {
87
+ fail('could not resolve the repo via `gh repo view` — is gh installed and run inside the repo?', e);
88
+ }
89
+ }
90
+
91
+ // GET protection. Returns the parsed object, or null if protection is OFF
92
+ // (GitHub returns 404 "Branch not protected").
93
+ function getProtection(repo) {
94
+ try {
95
+ const out = gh(['api', `repos/${repo}/branches/${BRANCH}/protection`]);
96
+ return JSON.parse(out);
97
+ } catch (e) {
98
+ const msg = `${e.stderr || ''}${e.stdout || ''}`;
99
+ if (/Branch not protected|Not Found|HTTP 404/i.test(msg)) return null;
100
+ fail('failed to read branch protection', e);
101
+ }
102
+ }
103
+
104
+ // Transform a GET-protection response into a valid PUT body (the two shapes
105
+ // differ — GET nests booleans under {enabled}, PUT wants flat values).
106
+ function toPutBody(p) {
107
+ const body = {
108
+ required_status_checks: null,
109
+ enforce_admins: !!(p.enforce_admins && p.enforce_admins.enabled),
110
+ required_pull_request_reviews: null,
111
+ restrictions: null,
112
+ };
113
+ if (p.required_status_checks) {
114
+ const rsc = p.required_status_checks;
115
+ body.required_status_checks = { strict: !!rsc.strict };
116
+ if (Array.isArray(rsc.checks) && rsc.checks.length) {
117
+ body.required_status_checks.checks = rsc.checks.map((c) => ({
118
+ context: c.context,
119
+ app_id: c.app_id ?? null,
120
+ }));
121
+ } else {
122
+ body.required_status_checks.contexts = rsc.contexts || [];
123
+ }
124
+ }
125
+ if (p.required_pull_request_reviews) {
126
+ const r = p.required_pull_request_reviews;
127
+ const rb = {
128
+ dismiss_stale_reviews: !!r.dismiss_stale_reviews,
129
+ require_code_owner_reviews: !!r.require_code_owner_reviews,
130
+ required_approving_review_count: r.required_approving_review_count ?? 0,
131
+ };
132
+ if (typeof r.require_last_push_approval === 'boolean') {
133
+ rb.require_last_push_approval = r.require_last_push_approval;
134
+ }
135
+ body.required_pull_request_reviews = rb;
136
+ }
137
+ if (p.restrictions) {
138
+ body.restrictions = {
139
+ users: (p.restrictions.users || []).map((u) => u.login),
140
+ teams: (p.restrictions.teams || []).map((t) => t.slug),
141
+ apps: (p.restrictions.apps || []).map((a) => a.slug),
142
+ };
143
+ }
144
+ for (const key of [
145
+ 'required_linear_history',
146
+ 'allow_force_pushes',
147
+ 'allow_deletions',
148
+ 'block_creations',
149
+ 'required_conversation_resolution',
150
+ 'lock_branch',
151
+ 'allow_fork_syncing',
152
+ ]) {
153
+ if (p[key] && typeof p[key].enabled === 'boolean') body[key] = p[key].enabled;
154
+ }
155
+ return body;
156
+ }
157
+
158
+ function putProtection(repo, putBody) {
159
+ gh(['api', '-X', 'PUT', `repos/${repo}/branches/${BRANCH}/protection`, '--input', '-'], {
160
+ input: JSON.stringify(putBody),
161
+ });
162
+ }
163
+
164
+ function deleteProtection(repo) {
165
+ gh(['api', '-X', 'DELETE', `repos/${repo}/branches/${BRANCH}/protection`]);
166
+ }
167
+
168
+ // --- gate CI workflows ('active' | 'disabled_manually' | 'disabled_inactivity') ---
169
+ function workflowState(repo, wf) {
170
+ try {
171
+ return gh(['api', `repos/${repo}/actions/workflows/${wf}`, '-q', '.state']).trim();
172
+ } catch {
173
+ return 'absent'; // not on the default branch / never registered
174
+ }
175
+ }
176
+
177
+ function setWorkflow(repo, wf, enable) {
178
+ // `gh workflow enable/disable` resolves the workflow from the repo context.
179
+ gh(['workflow', enable ? 'enable' : 'disable', wf]);
180
+ }
181
+
182
+ function readSnapshot() {
183
+ try {
184
+ return JSON.parse(fs.readFileSync(SNAPSHOT, 'utf8'));
185
+ } catch {
186
+ return null;
187
+ }
188
+ }
189
+
190
+ function writeSnapshot(obj) {
191
+ fs.mkdirSync(path.dirname(SNAPSHOT), { recursive: true });
192
+ fs.writeFileSync(SNAPSHOT, JSON.stringify(obj, null, 2));
193
+ }
194
+
195
+ function fail(msg, err) {
196
+ console.error(`\nāœ— gating: ${msg}`);
197
+ if (err && (err.stderr || err.message)) console.error(` ${(err.stderr || err.message).trim()}`);
198
+ process.exit(1);
199
+ }
200
+
201
+ function summarize(putBody) {
202
+ const checks =
203
+ putBody.required_status_checks
204
+ ? (putBody.required_status_checks.checks || putBody.required_status_checks.contexts || [])
205
+ .map((c) => c.context || c)
206
+ .join(', ') || '(none)'
207
+ : '(none)';
208
+ const review =
209
+ putBody.required_pull_request_reviews?.require_code_owner_reviews
210
+ ? 'code-owner review required'
211
+ : putBody.required_pull_request_reviews
212
+ ? `${putBody.required_pull_request_reviews.required_approving_review_count || 0} approving review(s)`
213
+ : 'no PR review required';
214
+ return { checks, review };
215
+ }
216
+
217
+ function cmdStatus(repo) {
218
+ const live = getProtection(repo);
219
+ const snap = readSnapshot();
220
+ const wf = GATE_WORKFLOWS.map((w) => ({ w, state: workflowState(repo, w) }));
221
+ const wfActive = wf.filter((x) => x.state === 'active');
222
+ console.log(`repo: ${repo} branch: ${BRANCH}\n`);
223
+
224
+ // Lever 1 — branch protection.
225
+ if (live) {
226
+ const { checks, review } = summarize(toPutBody(live));
227
+ console.log('branch protection : 🟢 ON');
228
+ console.log(` required checks : ${checks}`);
229
+ console.log(` pr review : ${review}`);
230
+ console.log(` enforce_admins : ${!!(live.enforce_admins && live.enforce_admins.enabled)} (owner can --admin merge when false)`);
231
+ } else {
232
+ console.log('branch protection : šŸ”“ OFF — `main` is UNPROTECTED.');
233
+ }
234
+
235
+ // Lever 2 — gate CI workflows.
236
+ console.log(`\ngate CI workflows : ${wfActive.length ? '🟢 ON' : 'šŸ”“ OFF'}`);
237
+ for (const x of wf) console.log(` ${x.w.padEnd(16)}: ${x.state}`);
238
+
239
+ const fullyOff = !live && wfActive.length === 0;
240
+ const fullyOn = !!live && wfActive.length === GATE_WORKFLOWS.length;
241
+ console.log(`\ngating: ${fullyOff ? 'šŸ”“ fully OFF — merges sail through, no checks/approval' : fullyOn ? '🟢 fully ON' : '🟔 PARTIAL — run `off` or `on` to make it consistent'}`);
242
+ console.log(`snapshot: ${snap ? SNAPSHOT : '(none yet — `off` will create it; `on` would use the baked-in default)'}`);
243
+ }
244
+
245
+ function cmdOff(repo) {
246
+ // Lever 1 — branch protection (idempotent).
247
+ const live = getProtection(repo);
248
+ if (live) {
249
+ const putBody = toPutBody(live);
250
+ writeSnapshot({ saved_at_branch: BRANCH, repo, raw: live, put_body: putBody });
251
+ const { checks, review } = summarize(putBody);
252
+ console.log('branch protection: removing.');
253
+ console.log(` was: checks [${checks}] + ${review}`);
254
+ console.log(` snapshot saved: ${SNAPSHOT}`);
255
+ deleteProtection(repo);
256
+ } else {
257
+ console.log('branch protection: already off.');
258
+ }
259
+
260
+ // Lever 2 — gate CI workflows (idempotent).
261
+ for (const w of GATE_WORKFLOWS) {
262
+ const state = workflowState(repo, w);
263
+ if (state === 'active') {
264
+ setWorkflow(repo, w, false);
265
+ console.log(`gate workflow ${w}: disabled.`);
266
+ } else {
267
+ console.log(`gate workflow ${w}: already ${state}.`);
268
+ }
269
+ }
270
+
271
+ console.log('\nšŸ”“ gating OFF. `main` is UNPROTECTED and the gate-review/grade CI gates no longer');
272
+ console.log(' run — ordinary `gh pr merge N` (and every builder / autonomous session) merges');
273
+ console.log(' with no checks and no approval. (unit + secret-scan still run.)');
274
+ console.log(' ↩ restore everything: node scripts/gds/gating.js on');
275
+ }
276
+
277
+ function cmdOn(repo) {
278
+ // Lever 1 — branch protection (idempotent).
279
+ const live = getProtection(repo);
280
+ if (!live) {
281
+ const snap = readSnapshot();
282
+ let putBody;
283
+ if (snap?.put_body) {
284
+ putBody = snap.put_body;
285
+ console.log(`branch protection: restoring from snapshot ${SNAPSHOT}`);
286
+ } else {
287
+ putBody = DEFAULT_PROTECTION;
288
+ console.log('⚠ branch protection: no snapshot — restoring the baked-in known-good default.');
289
+ }
290
+ putProtection(repo, putBody);
291
+ const after = getProtection(repo);
292
+ if (!after) fail('PUT returned but protection still reads as OFF — check `gh` auth / admin rights');
293
+ const { checks, review } = summarize(toPutBody(after));
294
+ console.log(` restored: checks [${checks}] + ${review}`);
295
+ } else {
296
+ console.log('branch protection: already on.');
297
+ }
298
+
299
+ // Lever 2 — gate CI workflows (idempotent).
300
+ for (const w of GATE_WORKFLOWS) {
301
+ const state = workflowState(repo, w);
302
+ if (state !== 'active' && state !== 'absent') {
303
+ setWorkflow(repo, w, true);
304
+ console.log(`gate workflow ${w}: re-enabled.`);
305
+ } else {
306
+ console.log(`gate workflow ${w}: already ${state}.`);
307
+ }
308
+ }
309
+
310
+ console.log('\n🟢 gating ON. Branch protection + the gate-review/grade CI gates are back.');
311
+ }
312
+
313
+ function main() {
314
+ const cmd = (process.argv[2] || 'status').toLowerCase();
315
+ if (!['status', 'off', 'on'].includes(cmd)) {
316
+ console.error('usage: node scripts/gds/gating.js <status|off|on>');
317
+ process.exit(2);
318
+ }
319
+ const repo = repoSlug();
320
+ if (cmd === 'status') cmdStatus(repo);
321
+ else if (cmd === 'off') cmdOff(repo);
322
+ else if (cmd === 'on') cmdOn(repo);
323
+ }
324
+
325
+ main();
@@ -0,0 +1,24 @@
1
+ [Unit]
2
+ Description=Nightly pg_dump of GDS Postgres DB (filed by #412)
3
+ Documentation=file:///home/lars/amazonprimea/docs/recipes/gds-db-backup.md
4
+ After=postgresql.service
5
+ Requires=postgresql.service
6
+
7
+ [Service]
8
+ Type=oneshot
9
+ User=lars
10
+ Group=lars
11
+ # Run the canonical script from the deployed repo. Keep this path stable;
12
+ # the recipe doc points at it for restore + manual-one-shot use cases.
13
+ ExecStart=/home/lars/amazonprimea/scripts/gds/db-backup-nightly.sh
14
+ # Modest hardening — the script only needs read on the socket + write on
15
+ # /var/backups/gds. Anything else is gravy for forensics.
16
+ NoNewPrivileges=true
17
+ ProtectSystem=strict
18
+ ReadWritePaths=/var/backups/gds
19
+ ProtectHome=read-only
20
+ PrivateTmp=true
21
+
22
+ [Install]
23
+ # Not socket-activated; timer drives this. No [Install] WantedBy needed —
24
+ # the timer's WantedBy is what gets enabled.