@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,257 @@
1
+ // tests/scrubber_corpus.mjs
2
+ //
3
+ // Transcript-grade secret-scrubber corpus (task 1003). This is the HARD gate
4
+ // the full-transcript capture task depends on: a planted-secret corpus where
5
+ // every secret MUST be fully redacted, plus a benign corpus that must survive
6
+ // (recall-first, but not so blunt it nukes ordinary prose/paths/identifiers).
7
+ //
8
+ // Covers scrubSecrets (ship.js) end-to-end + its exported internals
9
+ // (shannonEntropy, looksHighEntropySecret, collectEnvSecrets). Pure + DB-free +
10
+ // network-free, so it runs in the run-unit-tests gate (ADR 0042) and standalone.
11
+ //
12
+ // NOTE on fixtures: every secret-SHAPED string is assembled at RUNTIME
13
+ // (concatenation / a deterministic PRNG), so no literal secret pattern ever
14
+ // appears in this file's source. That keeps the pre-commit guard (.husky/
15
+ // pre-commit) and the CI TruffleHog scan clean WITHOUT allowlisting the file —
16
+ // full scan coverage is retained; only the scrubber's behavior is exercised.
17
+ // No Math.random / Date — the PRNG is a fixed-seed LCG so the corpus is
18
+ // deterministic across runs.
19
+ //
20
+ // Run: node tests/scrubber_corpus.mjs
21
+
22
+ import { strict as assert } from 'node:assert';
23
+ import { createRequire } from 'node:module';
24
+
25
+ const require = createRequire(import.meta.url);
26
+ const { scrubSecrets, shannonEntropy, looksHighEntropySecret, collectEnvSecrets } =
27
+ require('../scripts/gds/ship.js');
28
+
29
+ let passed = 0;
30
+ let failed = 0;
31
+ function test(name, fn) {
32
+ try {
33
+ fn();
34
+ passed++;
35
+ console.log(` ok ${name}`);
36
+ } catch (err) {
37
+ failed++;
38
+ console.log(` FAIL ${name}`);
39
+ console.log(` ${err.message}`);
40
+ }
41
+ }
42
+
43
+ const REDACTED = '<redacted>';
44
+
45
+ // ---- deterministic high-entropy generators (no Math.random / Date) ----
46
+ // A tiny LCG over a chosen alphabet → reproducible, clearly-random tokens.
47
+ function lcg(seed) {
48
+ let s = seed >>> 0;
49
+ return () => {
50
+ s = (Math.imul(s, 1664525) + 1013904223) >>> 0;
51
+ return s;
52
+ };
53
+ }
54
+ function randStr(seed, len, alphabet) {
55
+ const next = lcg(seed);
56
+ let out = '';
57
+ for (let i = 0; i < len; i++) out += alphabet[next() % alphabet.length];
58
+ return out;
59
+ }
60
+ const B64URL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
61
+ const HEX = '0123456789abcdef';
62
+ const UPPERNUM = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
63
+
64
+ // ============================================================
65
+ // POSITIVES — planted secrets. After scrub, the secret VALUE must be gone.
66
+ // Each entry: { name, secret, context } — context embeds the secret in
67
+ // realistic transcript text (a command, a file dump, a header line).
68
+ // ============================================================
69
+ function positives() {
70
+ const anthropic = 'sk-' + 'ant-api03-' + randStr(11, 40, B64URL);
71
+ const ghpat = 'gh' + 'p_' + randStr(22, 36, UPPERNUM);
72
+ const ghfine = 'github' + '_pat_' + randStr(33, 50, B64URL.replace(/-/g, ''));
73
+ const slack = 'xo' + 'xb-' + '2488' + randStr(44, 20, UPPERNUM);
74
+ const stripeLive = 'sk' + '_live_' + randStr(55, 24, UPPERNUM);
75
+ const stripeRk = 'rk' + '_test_' + randStr(66, 24, UPPERNUM);
76
+ const stripeWh = 'wh' + 'sec_' + randStr(77, 32, B64URL.replace(/[-_]/g, ''));
77
+ const aws = 'AK' + 'IA' + randStr(88, 16, UPPERNUM);
78
+ const google = 'AI' + 'za' + randStr(99, 35, B64URL);
79
+ const gds = 'gds' + '_' + randStr(101, 40, HEX);
80
+ const pms = 'pms' + '_' + randStr(102, 40, HEX);
81
+ const apple = 'wxyz' + '-' + 'mnop' + '-' + 'qrst' + '-' + 'uvwa'; // app-specific pw shape
82
+ const bearer = randStr(103, 36, B64URL.replace(/-/g, '.'));
83
+ const jwt =
84
+ 'eyJ' + randStr(104, 20, B64URL) + '.' + randStr(105, 30, B64URL) + '.' + randStr(106, 30, B64URL);
85
+ const pgPass = 'sup3r' + randStr(107, 14, B64URL.replace(/[-_]/g, ''));
86
+ const pgDsn = 'postgres' + 'ql://' + 'appuser:' + pgPass + '@db.internal:5432/otb';
87
+ const pemBody = randStr(108, 120, B64URL.replace(/-/g, '+'));
88
+ const pem =
89
+ '-'.repeat(5) + 'BEGIN OPENSSH PRIVATE KEY' + '-'.repeat(5) + '\n' +
90
+ pemBody.match(/.{1,64}/g).join('\n') + '\n' +
91
+ '-'.repeat(5) + 'END OPENSSH PRIVATE KEY' + '-'.repeat(5);
92
+ // gds-session.json full file contents (a `cat` of the credential file). The
93
+ // REAL token shape is crypto.randomBytes(32).toString('hex') — a bare 64-hex
94
+ // string with NO recognizable prefix (auth.js). This fixture uses that real
95
+ // shape on purpose, so the corpus proves the unkeyed token is still caught —
96
+ // by the "token": assignment + the hex entropy rule, not by any prefix match.
97
+ const sessTok = randStr(110, 64, HEX);
98
+ const sessionJson =
99
+ '{\n "token": "' + sessTok + '",\n "builder": "lars589",\n "rank": "archon"\n}';
100
+ // The same real token as it appears on the wire: a bare-64-hex cookie value +
101
+ // an Authorization: Bearer header (the two ways it leaves a CLI session).
102
+ const wireTok = randStr(115, 64, HEX);
103
+ // env / assignment shapes
104
+ const envGithub = 'GITHUB_TOKEN=' + 'gh' + 'o_' + randStr(111, 36, UPPERNUM);
105
+ const envAccess = 'access_token=' + randStr(112, 30, B64URL);
106
+ const envClient = '"client_secret": "' + randStr(113, 40, HEX) + '"';
107
+ const envApiKey = 'MY_API_KEY = ' + randStr(114, 28, B64URL);
108
+ // UNKNOWN shapes — the entropy catch-all is the only thing that can catch these.
109
+ const unknownB64 = randStr(120, 44, B64URL); // base64url, no known prefix
110
+ const unknownHex64 = randStr(121, 64, HEX); // sha256-shaped
111
+ const oauthHex40 = randStr(122, 40, HEX); // GitHub OAuth client secret shape (== a git SHA shape)
112
+
113
+ return [
114
+ { name: 'Anthropic API key', secret: anthropic, context: `claude --api-key ${anthropic} run` },
115
+ { name: 'GitHub classic PAT', secret: ghpat, context: `git remote set-url origin https://${ghpat}@github.com/x/y` },
116
+ { name: 'GitHub fine-grained PAT', secret: ghfine, context: `export GH_TOKEN=${ghfine}` },
117
+ { name: 'Slack bot token', secret: slack, context: `curl -H "token: ${slack}" slack` },
118
+ { name: 'Stripe live secret key', secret: stripeLive, context: `STRIPE_KEY=${stripeLive}` },
119
+ { name: 'Stripe restricted key', secret: stripeRk, context: `using ${stripeRk} for tests` },
120
+ { name: 'Stripe webhook secret', secret: stripeWh, context: `whsec configured: ${stripeWh}` },
121
+ { name: 'AWS access key id', secret: aws, context: `aws_access_key_id = ${aws}` },
122
+ { name: 'Google API key', secret: google, context: `&key=${google}` },
123
+ { name: 'GDS session token (shape)', secret: gds, context: `Authorization: Bearer ${gds}` },
124
+ { name: 'PMS session token (shape)', secret: pms, context: `cookie pms_session=${pms}` },
125
+ { name: 'Apple app-specific password', secret: apple, context: `xcrun notarytool --password ${apple}` },
126
+ { name: 'Bearer auth header', secret: bearer, context: `Authorization: Bearer ${bearer}` },
127
+ { name: 'JWT', secret: jwt, context: `set-cookie: jwt=${jwt}; HttpOnly` },
128
+ { name: 'Postgres DSN password', secret: pgPass, context: `DATABASE_URL=${pgDsn}` },
129
+ { name: 'PEM private key body', secret: pemBody, context: `key:\n${pem}\n(end)` },
130
+ { name: 'gds-session.json token (real bare-64-hex shape)', secret: sessTok, context: `$ cat ~/.config/otb/gds-session.json\n${sessionJson}` },
131
+ { name: 'real GDS token on the wire (cookie)', secret: wireTok, context: `Cookie: gds_session=${wireTok}; Path=/` },
132
+ { name: 'real GDS token on the wire (Bearer header)', secret: wireTok, context: `curl -H "Authorization: Bearer ${wireTok}" https://amazonprimea.com/api/gds/me` },
133
+ { name: 'env GITHUB_TOKEN value', secret: envGithub.split('=')[1], context: envGithub },
134
+ { name: 'env access_token value', secret: envAccess.split('=')[1], context: envAccess },
135
+ { name: 'JSON client_secret value', secret: envClient.match(/"client_secret": "([^"]+)"/)[1], context: envClient },
136
+ { name: 'env API_KEY value', secret: envApiKey.split('= ')[1], context: envApiKey },
137
+ { name: 'UNKNOWN base64url token (entropy)', secret: unknownB64, context: `weird = ${unknownB64} done` },
138
+ { name: 'UNKNOWN 64-hex token (entropy)', secret: unknownHex64, context: `digest ${unknownHex64} computed` },
139
+ { name: 'UNKNOWN 40-hex (OAuth secret / SHA shape)', secret: oauthHex40, context: `value ${oauthHex40} here` },
140
+ ];
141
+ }
142
+
143
+ test('every planted secret is fully redacted from its context', () => {
144
+ for (const { name, secret, context } of positives()) {
145
+ const out = scrubSecrets(context, collectEnvSecrets({})); // empty env: pattern+entropy must carry it
146
+ assert.ok(
147
+ !out.includes(secret),
148
+ `LEAK: "${name}" survived the scrubber.\n in : ${context}\n out: ${out}`
149
+ );
150
+ assert.ok(out.includes(REDACTED), `"${name}" produced no redaction marker: ${out}`);
151
+ }
152
+ });
153
+
154
+ test('planted secrets are also redacted when handed in as literal extraSecrets', () => {
155
+ // The defense-in-depth path: even a value the patterns somehow miss is removed
156
+ // because the live token / env value is passed as a literal.
157
+ for (const { name, secret, context } of positives()) {
158
+ if (secret.length < 8) continue;
159
+ const out = scrubSecrets(context, [secret]);
160
+ assert.ok(!out.includes(secret), `LEAK via literal path: "${name}" survived: ${out}`);
161
+ }
162
+ });
163
+
164
+ // ============================================================
165
+ // NEGATIVES — benign text that must survive untouched (no over-redaction of
166
+ // ordinary prose / short identifiers / numbers). High-entropy random-looking
167
+ // non-secrets (SHAs, UUIDs, worktree names) are intentionally NOT here: per the
168
+ // recall-first decision they are redacted, and the BFG metrics that matter
169
+ // (token/turn counts, tool names) are structured fields, not free-text.
170
+ // ============================================================
171
+ function negatives() {
172
+ return [
173
+ 'claimed task 540 and shipped the fix',
174
+ 'the cat sat on the mat today',
175
+ 'ran 57 tasks across 4 criteria in 2 days',
176
+ 'node scripts/gds/session-digest.js --transcript path',
177
+ 'internationalization is a long english word',
178
+ 'see docs/adr/0022-secrets-policy.md for the policy',
179
+ 'merge-mode swept the confirmed queue and deployed',
180
+ 'the vendor sells physical and digital goods in Amazonprimea',
181
+ 'P0: kill the grader bypass and rotate the token soon', // "token" but no value after a separator
182
+ 'git log shows acf3f3c bcb0794 282a155 fc8f4a5', // short SHAs (< 20)
183
+ ];
184
+ }
185
+
186
+ test('benign prose and short identifiers survive untouched', () => {
187
+ for (const s of negatives()) {
188
+ const out = scrubSecrets(s);
189
+ assert.equal(out, s, `over-redacted benign text:\n in : ${s}\n out: ${out}`);
190
+ }
191
+ });
192
+
193
+ test('empty / non-string / short-literal inputs are safe', () => {
194
+ assert.equal(scrubSecrets(''), '');
195
+ assert.equal(scrubSecrets(null), null);
196
+ assert.equal(scrubSecrets(undefined), undefined);
197
+ assert.equal(scrubSecrets('the cat sat', ['cat']), 'the cat sat'); // <8-char literal ignored
198
+ });
199
+
200
+ // ============================================================
201
+ // Unit-level: the entropy primitives.
202
+ // ============================================================
203
+ test('shannonEntropy: zero for uniform, high for random', () => {
204
+ assert.equal(shannonEntropy(''), 0);
205
+ assert.equal(shannonEntropy('aaaaaaaa'), 0);
206
+ assert.ok(shannonEntropy(randStr(7, 40, B64URL)) > 4.5, 'random base64 is high-entropy');
207
+ });
208
+
209
+ test('looksHighEntropySecret: catches random tokens, spares words & short strings', () => {
210
+ assert.ok(looksHighEntropySecret(randStr(1, 40, B64URL)), 'random base64url → secret');
211
+ assert.ok(looksHighEntropySecret(randStr(2, 64, HEX)), 'random 64-hex → secret');
212
+ assert.ok(looksHighEntropySecret(randStr(3, 40, HEX)), '40-hex (OAuth/SHA shape) → secret');
213
+ assert.equal(looksHighEntropySecret('internationalization'), false, 'plain word → not secret');
214
+ assert.equal(looksHighEntropySecret('shortlowentropy'), false, '< 20 chars → not secret');
215
+ assert.equal(looksHighEntropySecret('aaaaaaaaaaaaaaaaaaaaaaaa'), false, 'repetitive → not secret');
216
+ });
217
+
218
+ test('collectEnvSecrets: gathers secret-shaped env VALUES, skips benign & short', () => {
219
+ const env = {
220
+ GDS_TOKEN: 'gds' + '_' + randStr(9, 40, B64URL),
221
+ MAC_INSTALLER_CERT_P12: randStr(10, 60, B64URL),
222
+ APPLE_API_ISSUER_ID: randStr(11, 36, B64URL),
223
+ GITHUB_TOKEN: 'gh' + 'o_' + randStr(12, 36, UPPERNUM),
224
+ ANTHROPIC_API_KEY: 'sk-' + 'ant-' + randStr(13, 30, B64URL),
225
+ CLIENT_SECRET: randStr(14, 40, HEX),
226
+ DO_TOKEN: randStr(15, 64, HEX),
227
+ PATH: '/usr/local/bin:/usr/bin', // benign key, must be skipped
228
+ HOME: '/root', // benign + short
229
+ SHORT_TOKEN: 'abc', // secret-ish key but < 8 chars → skipped
230
+ };
231
+ const got = collectEnvSecrets(env);
232
+ for (const k of ['GDS_TOKEN', 'MAC_INSTALLER_CERT_P12', 'APPLE_API_ISSUER_ID', 'GITHUB_TOKEN', 'ANTHROPIC_API_KEY', 'CLIENT_SECRET', 'DO_TOKEN']) {
233
+ assert.ok(got.includes(env[k]), `expected ${k} value collected`);
234
+ }
235
+ assert.ok(!got.includes(env.PATH), 'PATH value must not be collected');
236
+ assert.ok(!got.includes(env.HOME), 'HOME value must not be collected');
237
+ assert.ok(!got.includes('abc'), 'short secret-ish value must be skipped');
238
+
239
+ // And the collected literals actually scrub their values out of a transcript.
240
+ const text = `the build used ${env.MAC_INSTALLER_CERT_P12} and ${env.APPLE_API_ISSUER_ID}`;
241
+ const out = scrubSecrets(text, got);
242
+ assert.ok(!out.includes(env.MAC_INSTALLER_CERT_P12) && !out.includes(env.APPLE_API_ISSUER_ID), 'env literals scrubbed');
243
+ });
244
+
245
+ test('self-reference `key = key` (SQL SET col = col) survives — zero recall loss', () => {
246
+ // task 1688: the core packager redacts live SQL, so a `_token` COLUMN self-increment
247
+ // must NOT be corrupted — while a real `key = <secret>` assignment is STILL redacted.
248
+ const selfRef = 'SET tokens_saved_est = tokens_saved_est + $2';
249
+ assert.equal(scrubSecrets(selfRef), selfRef, 'a _token column self-increment must survive intact');
250
+ const secret = 'ghp' + '_' + randStr(101, 36, B64URL); // github-PAT shape, built at runtime
251
+ const out = scrubSecrets(`access_token = ${secret}`);
252
+ assert.ok(!out.includes(secret), 'a real key=<secret> assignment must still be redacted');
253
+ assert.ok(out.startsWith('access_token = '), 'only the value is redacted; the key survives');
254
+ });
255
+
256
+ console.log(`\nscrubber_corpus: ${passed} passed, ${failed} failed`);
257
+ process.exit(failed ? 1 : 0);
@@ -0,0 +1,209 @@
1
+ // tests/search_chunker.mjs
2
+ //
3
+ // Hermetic unit tests for src/bongos/search-chunker.js (task 945, V4.R07 / ADR 0060
4
+ // §3). Pure transform — literal markdown strings in, chunks out. No fs, no
5
+ // network, no DB. Covers: front-matter strip+capture, heading-stack breadcrumbs
6
+ // (nesting + level pop), code-fence safety (a `#` inside ``` is NOT a heading),
7
+ // over-long section sub-splitting (breadcrumb preserved), the no-heading and
8
+ // empty-doc edges, and the document shapes the chunker must handle (CLAUDE.md,
9
+ // ADRs, recipes, session logs).
10
+ //
11
+ // Run: node tests/search_chunker.mjs
12
+
13
+ import { strict as assert } from 'node:assert';
14
+ import { createRequire } from 'node:module';
15
+
16
+ const require = createRequire(import.meta.url);
17
+ const { chunkMarkdown, parseFrontMatter, estTokens, stripPrivate } = require('../modules/memory/search-chunker.js');
18
+
19
+ let passed = 0;
20
+ let failed = 0;
21
+ function test(name, fn) {
22
+ try { fn(); passed++; console.log(` ok ${name}`); }
23
+ catch (err) { failed++; console.log(` FAIL ${name}`); console.log(` ${err.message}`); }
24
+ }
25
+
26
+ test('estTokens ~ chars/4, integer, zero for empty', () => {
27
+ assert.equal(estTokens(''), 0);
28
+ assert.equal(estTokens('abcd'), 1);
29
+ assert.equal(estTokens('abcde'), 2);
30
+ });
31
+
32
+ test('parseFrontMatter: leading --- block is captured + stripped from body', () => {
33
+ const md = '---\nname: my-note\ndescription: a thing\n---\n\n# Title\n\nbody text';
34
+ const { frontmatter, body } = parseFrontMatter(md);
35
+ assert.equal(frontmatter.name, 'my-note');
36
+ assert.equal(frontmatter.description, 'a thing');
37
+ assert.ok(!body.includes('name: my-note'), 'front-matter must not leak into body');
38
+ assert.ok(body.startsWith('# Title'), 'body starts after the closing fence');
39
+ });
40
+
41
+ test('parseFrontMatter: a --- that is NOT first line is a horizontal rule, kept in body', () => {
42
+ const md = '# Title\n\nintro\n\n---\n\nmore';
43
+ const { frontmatter, body } = parseFrontMatter(md);
44
+ assert.equal(frontmatter, null);
45
+ assert.ok(body.includes('---'), 'a mid-document hr stays in the body');
46
+ });
47
+
48
+ test('heading breadcrumbs: nested H1>H2>H3 reflected in heading_path', () => {
49
+ const md = [
50
+ '# Alpha', 'a-body',
51
+ '## Beta', 'b-body',
52
+ '### Gamma', 'g-body',
53
+ ].join('\n');
54
+ const { chunks } = chunkMarkdown({ path: 'docs/x.md', content: md });
55
+ const paths = chunks.map((c) => c.heading_path);
56
+ assert.ok(paths.includes('x.md > Alpha'), `got: ${paths.join(' | ')}`);
57
+ assert.ok(paths.includes('x.md > Alpha > Beta'));
58
+ assert.ok(paths.includes('x.md > Alpha > Beta > Gamma'));
59
+ });
60
+
61
+ test('heading level pop: H2 after H3 returns to the H1 ancestry (no stale H3)', () => {
62
+ const md = [
63
+ '# Top', 't',
64
+ '## One', '1',
65
+ '### Deep', 'd',
66
+ '## Two', '2', // pops 'Deep' AND 'One' → ancestry is just Top > Two
67
+ ].join('\n');
68
+ const { chunks } = chunkMarkdown({ path: 'f.md', content: md });
69
+ const two = chunks.find((c) => c.body === '2');
70
+ assert.equal(two.heading_path, 'f.md > Top > Two', `got ${two.heading_path}`);
71
+ });
72
+
73
+ test('code fence safety: a # line inside ``` is NOT treated as a heading', () => {
74
+ const md = [
75
+ '# Real Heading',
76
+ 'intro',
77
+ '```sh',
78
+ '# this is a shell comment, not a heading',
79
+ 'echo hi',
80
+ '```',
81
+ 'after',
82
+ ].join('\n');
83
+ const { chunks } = chunkMarkdown({ path: 'r.md', content: md });
84
+ // Exactly one heading section; the fenced '# comment' must not split it.
85
+ assert.equal(chunks.length, 1, `expected 1 chunk, got ${chunks.length}`);
86
+ assert.equal(chunks[0].heading_path, 'r.md > Real Heading');
87
+ assert.ok(chunks[0].body.includes('shell comment'), 'fenced content is retained in the body');
88
+ });
89
+
90
+ test('no headings: whole doc is one section under the file label', () => {
91
+ const md = 'just some prose\n\nwith two paragraphs';
92
+ const { chunks, title } = chunkMarkdown({ path: 'notes.md', content: md });
93
+ assert.equal(chunks.length, 1);
94
+ assert.equal(chunks[0].heading_path, 'notes.md');
95
+ assert.equal(title, 'notes.md', 'title falls back to the file label when no H1/front-matter');
96
+ });
97
+
98
+ test('title resolution: front-matter title wins, then first H1, then file label', () => {
99
+ assert.equal(chunkMarkdown({ path: 'a.md', content: '---\ntitle: FM Title\n---\n# H1\nx' }).title, 'FM Title');
100
+ assert.equal(chunkMarkdown({ path: 'a.md', content: '# H1 Title\nx' }).title, 'H1 Title');
101
+ assert.equal(chunkMarkdown({ path: 'a.md', content: 'no heading at all' }).title, 'a.md');
102
+ });
103
+
104
+ test('over-long section sub-splits, preserves the breadcrumb, stays under max', () => {
105
+ const para = 'word '.repeat(400); // ~2000 chars ≈ 500 tokens per paragraph
106
+ const md = `# Big\n\n${para}\n\n${para}\n\n${para}`;
107
+ const { chunks } = chunkMarkdown({ path: 'big.md', content: md, maxTokens: 200 });
108
+ assert.ok(chunks.length >= 3, `expected several sub-chunks, got ${chunks.length}`);
109
+ for (const c of chunks) {
110
+ assert.equal(c.heading_path, 'big.md > Big', 'every sub-chunk keeps the section breadcrumb');
111
+ assert.ok(c.est_tokens <= 200 + 5, `sub-chunk over cap: ${c.est_tokens}`);
112
+ }
113
+ });
114
+
115
+ test('chunk_index is sequential and 0-based across the document', () => {
116
+ const md = '# A\nx\n## B\ny\n## C\nz';
117
+ const { chunks } = chunkMarkdown({ path: 'i.md', content: md });
118
+ chunks.forEach((c, i) => assert.equal(c.chunk_index, i));
119
+ });
120
+
121
+ test('empty / front-matter-only doc → zero chunks (nothing to index)', () => {
122
+ assert.equal(chunkMarkdown({ path: 'e.md', content: '' }).chunks.length, 0);
123
+ assert.equal(chunkMarkdown({ path: 'e.md', content: ' \n\n ' }).chunks.length, 0);
124
+ assert.equal(chunkMarkdown({ path: 'e.md', content: '---\nname: x\n---\n' }).chunks.length, 0);
125
+ });
126
+
127
+ test('real shapes: an ADR-style doc chunks into its sections with breadcrumbs', () => {
128
+ const adr = [
129
+ '# ADR 0060 — Retrieval layer',
130
+ '- **Status:** Accepted',
131
+ '## Context',
132
+ 'Some context about why.',
133
+ '## Decision',
134
+ '### Schema',
135
+ 'A table.',
136
+ '### Query',
137
+ 'RRF fusion.',
138
+ ].join('\n');
139
+ const { chunks, title } = chunkMarkdown({ path: 'docs/adr/0060-x.md', content: adr });
140
+ assert.equal(title, 'ADR 0060 — Retrieval layer');
141
+ const paths = chunks.map((c) => c.heading_path);
142
+ assert.ok(paths.some((p) => p === '0060-x.md > ADR 0060 — Retrieval layer > Decision > Schema'), paths.join(' | '));
143
+ assert.ok(paths.some((p) => p === '0060-x.md > ADR 0060 — Retrieval layer > Context'));
144
+ });
145
+
146
+ test('typed DB ref label (task:431) is used verbatim as the breadcrumb root', () => {
147
+ const { chunks } = chunkMarkdown({ path: 'task:431', content: '# Fix the thing\nbody' });
148
+ assert.equal(chunks[0].heading_path, 'task:431 > Fix the thing');
149
+ });
150
+
151
+ // -------------------------------------------------------------------------
152
+ // <private> content-exclusion marker (ADR 0095 C4, task 1661)
153
+ // -------------------------------------------------------------------------
154
+
155
+ test('stripPrivate: no marker → text returned unchanged', () => {
156
+ const s = '# Title\n\nplain public body';
157
+ assert.equal(stripPrivate(s), s);
158
+ });
159
+
160
+ test('stripPrivate: a balanced <private>…</private> region is removed', () => {
161
+ const out = stripPrivate('keep <private>SECRET token=abc</private> keep');
162
+ assert.ok(!out.includes('SECRET'), out);
163
+ assert.ok(!out.includes('token=abc'), out);
164
+ assert.ok(out.includes('keep'), out);
165
+ });
166
+
167
+ test('stripPrivate: multi-line fence spanning many lines is removed whole', () => {
168
+ const md = ['public line', '<private>', 'API_KEY=sk-123', 'more secret', '</private>', 'tail'].join('\n');
169
+ const out = stripPrivate(md);
170
+ assert.ok(!out.includes('API_KEY'), out);
171
+ assert.ok(!out.includes('more secret'), out);
172
+ assert.ok(out.includes('public line') && out.includes('tail'), out);
173
+ });
174
+
175
+ test('stripPrivate: multiple independent fences each strip', () => {
176
+ const out = stripPrivate('a <private>x</private> b <private>y</private> c');
177
+ assert.ok(!out.includes('x') && !out.includes('y'), out);
178
+ assert.ok(out.includes('a') && out.includes('b') && out.includes('c'), out);
179
+ });
180
+
181
+ test('stripPrivate: case-insensitive + whitespace-tolerant tags', () => {
182
+ assert.ok(!stripPrivate('p <PRIVATE>nope</PRIVATE> q').includes('nope'));
183
+ assert.ok(!stripPrivate('p < private >nope< / private > q').includes('nope'));
184
+ });
185
+
186
+ test('stripPrivate: fail-closed — an unbalanced open strips to end of content', () => {
187
+ const out = stripPrivate('public head\n<private>dangling secret with no close\nstill secret');
188
+ assert.ok(!out.includes('secret'), out);
189
+ assert.ok(out.includes('public head'), out);
190
+ });
191
+
192
+ test('chunkMarkdown: <private> content never reaches the index chunks', () => {
193
+ const md = [
194
+ '# Notes',
195
+ 'public intro',
196
+ '<private>',
197
+ 'GITHUB_TOKEN=ghp_secret',
198
+ '</private>',
199
+ 'public outro',
200
+ ].join('\n');
201
+ const { chunks } = chunkMarkdown({ path: 'memory/note.md', content: md });
202
+ const blob = chunks.map((c) => c.body).join('\n');
203
+ assert.ok(!blob.includes('GITHUB_TOKEN'), blob);
204
+ assert.ok(!blob.includes('ghp_secret'), blob);
205
+ assert.ok(blob.includes('public intro') && blob.includes('public outro'), blob);
206
+ });
207
+
208
+ console.log(`\n${passed} passed, ${failed} failed`);
209
+ process.exit(failed === 0 ? 0 : 1);
@@ -0,0 +1,96 @@
1
+ // tests/search_ingest.mjs
2
+ //
3
+ // Unit tests for the PURE pieces of the repo-markdown ingester (task 947,
4
+ // V4.R09): the rank-tagging rule (metic for read-sensitive doc surfaces, xenos
5
+ // otherwise — incl. the CLAUDE.md read-public carve-out) and the corpus walk's
6
+ // exclusions. The DB delta/upsert (ingestFile) is exercised against a live
7
+ // Postgres on the droplet (the deploy hook + the initial backfill); here we pin
8
+ // the no-DB decisions that govern WHAT gets indexed and at what rank.
9
+ //
10
+ // Run: node tests/search_ingest.mjs
11
+
12
+ import { strict as assert } from 'node:assert';
13
+ import { createRequire } from 'node:module';
14
+
15
+ const require = createRequire(import.meta.url);
16
+ const ingest = require('../scripts/gds/search-ingest-md.js');
17
+ const { minRankForDoc, collectMarkdown, chunkFile, SENSITIVE_DOC_GLOBS } = ingest;
18
+
19
+ let passed = 0;
20
+ let failed = 0;
21
+ function test(name, fn) {
22
+ try { fn(); passed++; console.log(` ok ${name}`); }
23
+ catch (err) { failed++; console.log(` FAIL ${name}`); console.log(` ${err.message}`); }
24
+ }
25
+
26
+ test('metic-tagging: read-sensitive doc surfaces → metic', () => {
27
+ assert.equal(minRankForDoc('docs/canonical-permissions.md'), 'metic');
28
+ assert.equal(minRankForDoc('docs/security/threat-model.md'), 'metic');
29
+ assert.equal(minRankForDoc('docs/security/2026-06-12-newbuilder-redteam.md'), 'metic');
30
+ assert.equal(minRankForDoc('docs/audits/2026-06-08-server-security-audit.md'), 'metic');
31
+ assert.equal(minRankForDoc('docs/adr/0016-trust-boundary-server-enforced-permissions.md'), 'metic');
32
+ assert.equal(minRankForDoc('docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md'), 'metic');
33
+ });
34
+
35
+ test('metic-tagging: ordinary docs → xenos (read-public)', () => {
36
+ assert.equal(minRankForDoc('docs/architecture.md'), 'xenos');
37
+ assert.equal(minRankForDoc('docs/file-map.md'), 'xenos');
38
+ assert.equal(minRankForDoc('docs/adr/0060-gds-retrieval-layer.md'), 'xenos');
39
+ assert.equal(minRankForDoc('limitations/v1-shipped.md'), 'xenos');
40
+ assert.equal(minRankForDoc('art/README.md'), 'xenos');
41
+ });
42
+
43
+ test('CLAUDE.md is xenos (write-protected but READ-PUBLIC — the carve-out)', () => {
44
+ // CLAUDE.md is in permission-path-check PROTECTED_GLOBS (write protection), but
45
+ // it's the universal onboarding index — a Xenos recall MUST surface it.
46
+ assert.equal(minRankForDoc('CLAUDE.md'), 'xenos');
47
+ });
48
+
49
+ test('SENSITIVE_DOC_GLOBS is the curated source of truth (subtrees end with /)', () => {
50
+ assert.ok(SENSITIVE_DOC_GLOBS.includes('docs/security/'));
51
+ assert.ok(SENSITIVE_DOC_GLOBS.includes('docs/audits/'));
52
+ assert.ok(SENSITIVE_DOC_GLOBS.includes('docs/canonical-permissions.md'));
53
+ });
54
+
55
+ test('collectMarkdown finds the repo corpus but excludes node_modules/.git/worktrees/public', () => {
56
+ const path = require('node:path');
57
+ const repoRoot = path.resolve(new URL('..', import.meta.url).pathname);
58
+ const real = collectMarkdown(repoRoot, repoRoot);
59
+ // Assert on paths RELATIVE to the repo root — the suite may run from inside a
60
+ // git worktree (…/.claude/worktrees/<name>/…), so the ABSOLUTE paths would all
61
+ // contain '.claude/worktrees'; the exclusion is about NESTED such dirs.
62
+ const rel = real.map((f) => path.relative(repoRoot, f).split(path.sep).join('/'));
63
+ assert.ok(rel.length > 50, `expected a sizable md corpus, got ${rel.length}`);
64
+ assert.ok(rel.includes('CLAUDE.md'), 'CLAUDE.md must be in the corpus');
65
+ assert.ok(!rel.some((r) => r.startsWith('node_modules/')), 'node_modules excluded');
66
+ assert.ok(!rel.some((r) => r.startsWith('.git/')), '.git excluded');
67
+ assert.ok(!rel.some((r) => r.startsWith('.claude/worktrees/')), 'nested worktrees excluded');
68
+ assert.ok(!rel.some((r) => r.startsWith('public/')), 'public/ web assets excluded');
69
+ });
70
+
71
+ test('chunkFile yields well-formed rows (source_kind doc, hash, rank, sequential index)', () => {
72
+ const path = require('node:path');
73
+ const repoRoot = path.resolve(new URL('..', import.meta.url).pathname);
74
+ const rows = chunkFile(path.join(repoRoot, 'docs', 'adr', '0016-trust-boundary-server-enforced-permissions.md'));
75
+ assert.ok(rows.length > 0);
76
+ rows.forEach((r, i) => {
77
+ assert.equal(r.source_kind, 'doc');
78
+ assert.equal(r.source_ref, 'docs/adr/0016-trust-boundary-server-enforced-permissions.md');
79
+ assert.equal(r.chunk_index, i);
80
+ assert.equal(r.min_rank, 'metic', 'a trust-boundary ADR must be metic');
81
+ assert.equal(r.owner_builder_id ?? null, null, 'docs are never owner-scoped');
82
+ assert.match(r.content_hash, /^[0-9a-f]{64}$/, 'content_hash is a sha256 hex');
83
+ });
84
+ });
85
+
86
+ test('requirePool() resolves the real pg Pool with a .connect (task 1156 regression guard)', () => {
87
+ // The bug: the ingester required src/bongos/db (no `pool` export) → the DB path
88
+ // crashed with "Cannot read properties of undefined (reading connect)". Pin
89
+ // that requirePool() yields a usable pool so a wrong path is caught here, not
90
+ // only when the ingest actually runs against Postgres.
91
+ const pool = ingest.requirePool();
92
+ assert.ok(pool && typeof pool.connect === 'function', 'requirePool() must return a pg Pool with .connect()');
93
+ });
94
+
95
+ console.log(`\n${passed} passed, ${failed} failed`);
96
+ process.exit(failed === 0 ? 0 : 1);
@@ -0,0 +1,88 @@
1
+ // tests/search_ingest_db.mjs
2
+ //
3
+ // Unit tests for the PURE pieces of the DB-prose ingester (task 948, V4.R10):
4
+ // the row builder's scrubbing + rank/owner scoping, the excluded-sources
5
+ // invariant, and the git-commit parser. The DB queries + upsert run nightly on
6
+ // the droplet against live Postgres; here we pin the no-DB decisions that govern
7
+ // what gets indexed, at what rank, for whom, and with secrets removed.
8
+ //
9
+ // Run: node tests/search_ingest_db.mjs
10
+
11
+ import { strict as assert } from 'node:assert';
12
+ import { createRequire } from 'node:module';
13
+
14
+ const require = createRequire(import.meta.url);
15
+ const ingest = require('../scripts/gds/search-ingest-db.js');
16
+ const { buildRows, recentCommitRows, SOURCES } = ingest;
17
+
18
+ let passed = 0;
19
+ let failed = 0;
20
+ function test(name, fn) {
21
+ try { fn(); passed++; console.log(` ok ${name}`); }
22
+ catch (err) { failed++; console.log(` FAIL ${name}`); console.log(` ${err.message}`); }
23
+ }
24
+
25
+ test('buildRows: source_kind db rows carry source_ref, sequential index, content_hash', () => {
26
+ const rows = buildRows({ sourceRef: 'task:431', title: 'Fix the thing', body: 'A real description with enough words to chunk.' });
27
+ assert.ok(rows.length >= 1);
28
+ rows.forEach((r, i) => {
29
+ assert.equal(r.source_ref, 'task:431');
30
+ assert.equal(r.chunk_index, i);
31
+ assert.match(r.content_hash, /^[0-9a-f]{64}$/);
32
+ assert.equal(r.min_rank, 'xenos');
33
+ assert.equal(r.owner_builder_id, null);
34
+ });
35
+ });
36
+
37
+ test('buildRows: a security_sensitive task is tagged metic (caller passes minRank)', () => {
38
+ const rows = buildRows({ sourceRef: 'task:9', title: 'sec', body: 'sensitive body text here', minRank: 'metic' });
39
+ assert.ok(rows.every((r) => r.min_rank === 'metic'));
40
+ });
41
+
42
+ test('buildRows: builder_memory is OWNER-SCOPED (owner_builder_id on every chunk)', () => {
43
+ const rows = buildRows({ sourceRef: 'memory:7:MEMORY.md', title: 'MEMORY.md', body: 'my private notes about the project', ownerBuilderId: 7 });
44
+ assert.ok(rows.length >= 1);
45
+ assert.ok(rows.every((r) => r.owner_builder_id === 7), 'every memory chunk must carry the owner id');
46
+ });
47
+
48
+ test('buildRows: scrub=true redacts a planted secret before storage', () => {
49
+ const secret = 'ghp_' + 'A'.repeat(36); // GitHub-token shape
50
+ const rows = buildRows({ sourceRef: 'session_log:1', title: 'sess', body: `ran a deploy, token was ${secret} oops`, scrub: true });
51
+ const joined = rows.map((r) => r.body).join('\n');
52
+ assert.ok(!joined.includes(secret), 'the secret must NOT survive into a stored chunk');
53
+ assert.match(joined, /<redacted>/, 'scrubSecrets replaces it with the redaction marker');
54
+ });
55
+
56
+ test('buildRows: scrub=false leaves ordinary prose intact', () => {
57
+ const rows = buildRows({ sourceRef: 'learning:1', title: 'L', body: 'a perfectly ordinary learning about postgres indexes' });
58
+ assert.match(rows.map((r) => r.body).join(' '), /ordinary learning about postgres/);
59
+ });
60
+
61
+ test('buildRows: empty / whitespace body → no rows', () => {
62
+ assert.equal(buildRows({ sourceRef: 'idea:1', title: 'x', body: '' }).length, 0);
63
+ assert.equal(buildRows({ sourceRef: 'idea:1', title: 'x', body: ' ' }).length, 0);
64
+ assert.equal(buildRows({ sourceRef: 'idea:1', title: 'x', body: null }).length, 0);
65
+ });
66
+
67
+ test('SECURITY: vulnerability_reports + security_reports are NOT ingested', () => {
68
+ const names = SOURCES.map((s) => s.name);
69
+ assert.ok(!names.includes('vulnerability_reports'), 'vulnerability_reports must be excluded');
70
+ assert.ok(!names.includes('security_reports'), 'security_reports must be excluded');
71
+ // The sources we DO index include the documented prose surfaces.
72
+ for (const expected of ['tasks', 'learnings', 'session_logs', 'idea_inbox', 'task_grades', 'done_when_criteria', 'blockers', 'builder_memory']) {
73
+ assert.ok(names.includes(expected), `expected source ${expected}`);
74
+ }
75
+ });
76
+
77
+ test('recentCommitRows: parses git log into commit: chunks (best-effort)', () => {
78
+ // Runs against this repo's git; in a real checkout it returns rows, in a
79
+ // shallow/–git env it returns [] (best-effort). Assert the SHAPE when present.
80
+ const rows = recentCommitRows(5);
81
+ for (const r of rows) {
82
+ assert.match(r.source_ref, /^commit:[0-9a-f]{7,12}$/);
83
+ assert.ok(r.body && r.body.length > 0);
84
+ }
85
+ });
86
+
87
+ console.log(`\n${passed} passed, ${failed} failed`);
88
+ process.exit(failed === 0 ? 0 : 1);