@bongos/core 1.21.175 → 1.21.176

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 (1739) hide show
  1. package/.bongos-core.json +3551 -1516
  2. package/.claude/skills/ask-for-help/SKILL.md +4 -4
  3. package/.claude/skills/backlog-review/SKILL.md +1 -1
  4. package/.claude/skills/blocker-review/SKILL.md +2 -2
  5. package/.claude/skills/blocker-solve/SKILL.md +4 -4
  6. package/.claude/skills/bongos-feedback/SKILL.md +1 -1
  7. package/.claude/skills/bug-triage/SKILL.md +8 -8
  8. package/.claude/skills/builder-backup/SKILL.md +3 -3
  9. package/.claude/skills/builder-claim/SKILL.md +5 -5
  10. package/.claude/skills/builder-cost/SKILL.md +5 -5
  11. package/.claude/skills/builder-end/SKILL.md +6 -6
  12. package/.claude/skills/builder-exit/SKILL.md +2 -2
  13. package/.claude/skills/builder-key/SKILL.md +6 -6
  14. package/.claude/skills/builder-reauth/SKILL.md +4 -4
  15. package/.claude/skills/builder-redteam/SKILL.md +3 -3
  16. package/.claude/skills/builder-release/SKILL.md +3 -3
  17. package/.claude/skills/builder-sequence/SKILL.md +8 -8
  18. package/.claude/skills/builder-setup/SKILL.md +4 -4
  19. package/.claude/skills/builder-ship/SKILL.md +7 -7
  20. package/.claude/skills/builder-stage/SKILL.md +8 -8
  21. package/.claude/skills/builder-start/SKILL.md +4 -4
  22. package/.claude/skills/collab-review/SKILL.md +5 -5
  23. package/.claude/skills/design/SKILL.md +6 -4
  24. package/.claude/skills/design-sync/SKILL.md +3 -3
  25. package/.claude/skills/figma-design-sync/SKILL.md +4 -4
  26. package/.claude/skills/fix-task/SKILL.md +8 -8
  27. package/.claude/skills/goal-close/SKILL.md +9 -9
  28. package/.claude/skills/goal-create/SKILL.md +18 -18
  29. package/.claude/skills/grade-recover/SKILL.md +8 -8
  30. package/.claude/skills/grade-sweep/SKILL.md +15 -15
  31. package/.claude/skills/idea-triage/SKILL.md +15 -15
  32. package/.claude/skills/merge-mode/SKILL.md +14 -14
  33. package/.claude/skills/new-project/SKILL.md +5 -5
  34. package/.claude/skills/owner-review/SKILL.md +1 -1
  35. package/.claude/skills/planning-session/SKILL.md +14 -14
  36. package/.claude/skills/priority-session/SKILL.md +6 -6
  37. package/.claude/skills/read-session-export/SKILL.md +3 -3
  38. package/.claude/skills/recall/SKILL.md +7 -7
  39. package/.claude/skills/scan-before-install/SKILL.md +3 -3
  40. package/.claude/skills/session-handoff/SKILL.md +1 -1
  41. package/.claude/skills/ship-check/SKILL.md +3 -3
  42. package/.claude/skills/status/SKILL.md +3 -3
  43. package/.claude/skills/strand-fix/SKILL.md +6 -6
  44. package/.claude/skills/worktree-clean/SKILL.md +4 -4
  45. package/.gitattributes +12 -32
  46. package/GOVERNMENT.md +1 -1
  47. package/README.md +8 -8
  48. package/bin/bongos.js +23 -23
  49. package/clients/bongos-client/README.md +2 -2
  50. package/clients/bongos-client/bongos-client.global.js +22 -4
  51. package/clients/bongos-client/index.cjs +22 -4
  52. package/clients/bongos-client/index.d.ts +33 -4
  53. package/clients/bongos-client/index.mjs +21 -3
  54. package/config/branding.neutral.json +1 -1
  55. package/config/design-tokens.schema.json +1 -1
  56. package/config/modules.neutral.json +1 -3
  57. package/docs/adr/0029-status-page-outage-resilience.md +6 -6
  58. package/docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md +1 -1
  59. package/docs/adr/0294-cli-sessions-do-not-expire.md +1 -1
  60. package/docs/adr/0383-sessions-end-after-ten-idle-days.md +35 -0
  61. package/docs/adr/0384-the-raise-page-is-a-hub-module-builders-edit-in-place.md +31 -0
  62. package/docs/adr/README.md +2 -0
  63. package/docs/api/openapi.json +606 -44
  64. package/docs/api-reference.md +25 -12
  65. package/docs/architecture.md +8 -7
  66. package/docs/canonical-permissions.md +3 -3
  67. package/docs/copy-inventory.md +1370 -1411
  68. package/docs/copy-registry.json +2136 -2536
  69. package/docs/design/demonolith-plan.md +6 -6
  70. package/docs/design/modular-architecture/00-research-report.md +1 -1
  71. package/docs/design/project-startup-direction.md +2 -2
  72. package/docs/design/projects-hub-direction-v2.md +1 -1
  73. package/docs/design/reviews/hall-v2/README.md +2 -2
  74. package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
  75. package/docs/file-map.md +89 -88
  76. package/docs/handoff-template.md +4 -4
  77. package/docs/module-api-changelog.md +5 -3
  78. package/docs/modules-contract.md +8 -7
  79. package/docs/onboarding/diagrams/01-task-lifecycle.mmd +1 -1
  80. package/docs/onboarding/diagrams/02-rank-ladder.mmd +1 -1
  81. package/docs/onboarding/diagrams/03-drachmae-karma.mmd +1 -1
  82. package/docs/onboarding/diagrams/04-architecture.mmd +1 -1
  83. package/docs/onboarding/diagrams/05-versioning.mmd +1 -1
  84. package/docs/onboarding/diagrams/README.md +2 -2
  85. package/docs/onboarding/diagrams/assertions.json +2 -2
  86. package/docs/onboarding/slash-commands.md +2 -2
  87. package/docs/packs/artist.md +4 -4
  88. package/docs/packs/engineer.md +11 -10
  89. package/docs/packs/ideator.md +7 -7
  90. package/docs/page-inventory.json +20 -1
  91. package/docs/page-readings.json +4387 -4603
  92. package/docs/recipes/README.md +1 -1
  93. package/docs/recipes/audit-replay.md +4 -4
  94. package/docs/recipes/autobongos-windows-host.md +6 -6
  95. package/docs/recipes/bongos-cli-release.md +2 -2
  96. package/docs/recipes/claude-design-loop.md +7 -7
  97. package/docs/recipes/core-release-pipeline.md +19 -19
  98. package/docs/recipes/failed-ship-recovery-proof.md +2 -2
  99. package/docs/recipes/figma-design-loop.md +6 -6
  100. package/docs/recipes/gds-db-backup.md +9 -9
  101. package/docs/recipes/instance-deploy.md +3 -3
  102. package/docs/recipes/instance-first-run.md +1 -1
  103. package/docs/recipes/multi-builder-merge.md +2 -2
  104. package/docs/recipes/ops-gotchas.md +10 -9
  105. package/docs/recipes/packaging-the-core.md +6 -6
  106. package/docs/recipes/parallel-goal-waves.md +4 -4
  107. package/docs/recipes/private-npm-distribution.md +9 -9
  108. package/docs/recipes/redteam-patrol.md +5 -5
  109. package/docs/recipes/render-pilot.md +2 -2
  110. package/docs/recipes/reranking-a-goals-board.md +2 -2
  111. package/docs/recipes/search-index-ingestion.md +5 -5
  112. package/docs/recipes/self-host.md +1 -1
  113. package/docs/recipes/ship-and-regrade.md +4 -4
  114. package/docs/recipes/staging-environment.md +1 -1
  115. package/docs/recipes/standalone-live-docs.md +1 -1
  116. package/docs/recipes/ui-look-before-you-ship.md +2 -2
  117. package/docs/recipes/upgrading-the-core.md +11 -11
  118. package/docs/recipes/windows-builders.md +18 -18
  119. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +6 -6
  120. package/docs/research/task-network-map-readability.md +3 -3
  121. package/migrations/core_278_builder_tester_tag.sql +18 -0
  122. package/migrations/core_279_bongos_shipper_new_scripts_path.sql +13 -0
  123. package/modules/agents/lib/answer-hold.js +1 -1
  124. package/modules/agents/lib/gate.js +1 -1
  125. package/modules/agents/lib/validate.js +1 -1
  126. package/modules/autonomy/gauge.js +1 -1
  127. package/modules/autonomy/governor-docket.js +2 -2
  128. package/modules/autonomy/pollers/routine-timers.js +3 -3
  129. package/modules/autonomy/routes/autonomy.js +3 -3
  130. package/modules/builder-settings/interaction-prefs.js +1 -1
  131. package/modules/builder-settings/render-prefs.js +1 -1
  132. package/modules/builder-settings/routes/settings.js +1 -1
  133. package/modules/builder-settings/skill-prefs.js +2 -2
  134. package/modules/builder-settings/wandering-prefs.js +2 -2
  135. package/modules/copy-desk/module.json +2 -2
  136. package/modules/copy-desk/page-data.js +5 -5
  137. package/modules/copy-desk/page-decisions.js +13 -1
  138. package/modules/copy-desk/proposals.js +4 -4
  139. package/modules/copy-desk/registry.js +2 -2
  140. package/modules/copy-desk/routes/copy-desk-release.js +119 -0
  141. package/modules/copy-desk/routes/copy-desk.js +3 -12
  142. package/modules/copy-desk/skills/tweak/SKILL.md +12 -12
  143. package/modules/copy-desk/tests/copy_flags.mjs +1 -1
  144. package/modules/copy-desk/tests/copy_no_cms.mjs +7 -3
  145. package/modules/copy-desk/tests/copy_proposals.mjs +2 -2
  146. package/modules/copy-desk/tests/copy_queue.mjs +1 -1
  147. package/modules/design-styles/skills/README.md +4 -4
  148. package/modules/design-styles/skills/imagegen-frontend-mobile/SKILL.md +1 -1
  149. package/modules/design-styles/skills/imagegen-frontend-web/SKILL.md +1 -1
  150. package/modules/discord/bug-attachments.js +1 -1
  151. package/modules/discord/ship-broadcast.js +1 -1
  152. package/modules/economy/achievements.js +49 -7
  153. package/modules/economy/cost-classify.js +6 -6
  154. package/modules/economy/cost-report.js +1 -1
  155. package/modules/economy/cost.js +1 -1
  156. package/modules/economy/credits.js +2 -1
  157. package/modules/economy/idea-size.js +2 -2
  158. package/modules/economy/reward.js +2 -0
  159. package/modules/economy/routes/cost.js +1 -1
  160. package/modules/economy/streak.js +43 -4
  161. package/modules/government/asks.js +1 -1
  162. package/modules/government/board.js +19 -2
  163. package/modules/government/catalog.js +3 -0
  164. package/modules/government/migrations/government_033_idea_vote.sql +46 -0
  165. package/modules/government/protected-surfaces.json +48 -47
  166. package/modules/government/recommendations.js +6 -2
  167. package/modules/government/routes/government.js +1 -1
  168. package/modules/grading/generated-provenance.js +13 -5
  169. package/modules/grading/grade-engine.js +1 -1
  170. package/modules/grading/grader-rubric.json +1 -1
  171. package/modules/grading/grader-score.js +1 -1
  172. package/modules/grading/grader-workers/index.js +1 -1
  173. package/modules/grading/grader.js +1 -1
  174. package/modules/grading/routes/grade.js +1 -1
  175. package/modules/hall-ui/public/atlas.html +5 -7
  176. package/modules/hall-ui/public/atlas.js +1 -1
  177. package/modules/hall-ui/public/atlas.states.json +1 -1
  178. package/modules/hall-ui/public/blockers.css +9 -0
  179. package/modules/hall-ui/public/blockers.html +4 -4
  180. package/modules/hall-ui/public/blockers.js +29 -30
  181. package/modules/hall-ui/public/board-room.css +5 -17
  182. package/modules/hall-ui/public/board-room.html +5 -6
  183. package/modules/hall-ui/public/board-room.js +41 -23
  184. package/modules/hall-ui/public/board-room.states.json +1 -1
  185. package/modules/hall-ui/public/brand-apply.js +1 -1
  186. package/modules/hall-ui/public/brand-holes.js +1 -1
  187. package/modules/hall-ui/public/builders.js +40 -86
  188. package/modules/hall-ui/public/city-decide.js +18 -4
  189. package/modules/hall-ui/public/city.html +1 -1
  190. package/modules/hall-ui/public/collab.html +1 -1
  191. package/modules/hall-ui/public/commands.html +6 -9
  192. package/modules/hall-ui/public/copy-desk.html +1 -1
  193. package/modules/hall-ui/public/copy-desk.js +2 -2
  194. package/modules/hall-ui/public/craft-mode.js +4 -0
  195. package/modules/hall-ui/public/deploy.html +6 -2
  196. package/modules/hall-ui/public/deploy.js +21 -13
  197. package/modules/hall-ui/public/diagrams.css +1 -1
  198. package/modules/hall-ui/public/diagrams.html +5 -8
  199. package/modules/hall-ui/public/diagrams.states.json +1 -1
  200. package/modules/hall-ui/public/drachmae.html +3 -7
  201. package/modules/hall-ui/public/fleet.html +3 -2
  202. package/modules/hall-ui/public/fleet.js +0 -4
  203. package/modules/hall-ui/public/gate.html +7 -7
  204. package/modules/hall-ui/public/gate.js +58 -77
  205. package/modules/hall-ui/public/goal-map.html +1 -1
  206. package/modules/hall-ui/public/goals-page.js +5 -5
  207. package/modules/hall-ui/public/goals-render.js +10 -11
  208. package/modules/hall-ui/public/goals.css +10 -0
  209. package/modules/hall-ui/public/goals.html +14 -7
  210. package/modules/hall-ui/public/government.html +3 -5
  211. package/modules/hall-ui/public/government.js +1 -5
  212. package/modules/hall-ui/public/hall-render.js +117 -57
  213. package/modules/hall-ui/public/hall-widgets.js +11 -11
  214. package/modules/hall-ui/public/idea.html +1 -1
  215. package/modules/hall-ui/public/ideas.html +3 -1
  216. package/modules/hall-ui/public/ideas.js +1 -0
  217. package/modules/hall-ui/public/index.html +12 -6
  218. package/modules/hall-ui/public/index.states.json +1 -1
  219. package/modules/hall-ui/public/mine-lens.js +1 -1
  220. package/modules/hall-ui/public/modules.html +7 -10
  221. package/modules/hall-ui/public/modules.js +0 -2
  222. package/modules/hall-ui/public/my-agents.html +1 -1
  223. package/modules/hall-ui/public/palette.js +5 -5
  224. package/modules/hall-ui/public/primer.html +4 -9
  225. package/modules/hall-ui/public/profile-connections.js +10 -2
  226. package/modules/hall-ui/public/profile-roles.js +3 -10
  227. package/modules/hall-ui/public/profile.html +12 -10
  228. package/modules/hall-ui/public/profile.js +13 -17
  229. package/modules/hall-ui/public/project-settings.html +3 -4
  230. package/modules/hall-ui/public/project-settings.js +0 -3
  231. package/modules/hall-ui/public/ranks.html +5 -11
  232. package/modules/hall-ui/public/ranks.js +6 -8
  233. package/modules/hall-ui/public/roadmap.css +0 -2
  234. package/modules/hall-ui/public/roadmap.html +1 -1
  235. package/modules/hall-ui/public/roadmap.js +16 -51
  236. package/modules/hall-ui/public/roster.html +1 -1
  237. package/modules/hall-ui/public/sessions.html +6 -8
  238. package/modules/hall-ui/public/sessions.js +7 -7
  239. package/modules/hall-ui/public/settings.html +1 -1
  240. package/modules/hall-ui/public/shell-trail.js +1 -1
  241. package/modules/hall-ui/public/shell.js +17 -17
  242. package/modules/hall-ui/public/street-deck.css +2 -1
  243. package/modules/hall-ui/public/street-deck.js +10 -2
  244. package/modules/hall-ui/public/street-desk.js +16 -5
  245. package/modules/hall-ui/public/street.html +1 -1
  246. package/modules/hall-ui/public/studio-lib.js +4 -0
  247. package/modules/hall-ui/public/studio.css +2 -0
  248. package/modules/hall-ui/public/studio.html +1 -1
  249. package/modules/hall-ui/public/studio.js +27 -1
  250. package/modules/hall-ui/public/style.css +43 -26
  251. package/modules/hall-ui/public/task-detail.js +10 -7
  252. package/modules/hall-ui/public/task.css +2 -0
  253. package/modules/hall-ui/public/task.html +3 -1
  254. package/modules/hall-ui/public/task.js +23 -7
  255. package/modules/hall-ui/public/thinking.html +1 -1
  256. package/modules/hall-ui/public/tweak-editor.html +1 -1
  257. package/modules/hall-ui/public/vote-control.js +208 -0
  258. package/modules/hall-ui/public/watch.html +3 -5
  259. package/modules/hall-ui/public/watch.js +5 -4
  260. package/modules/hall-ui/public/welcome-boot.css +130 -0
  261. package/modules/hall-ui/public/welcome-boot.js +334 -0
  262. package/modules/hall-ui/public/welcome-day.webp +0 -0
  263. package/modules/hall-ui/public/welcome-night.webp +0 -0
  264. package/modules/hall-ui/public/work-summary.js +1 -1
  265. package/modules/hall-ui/public/work.css +1 -0
  266. package/modules/hall-ui/public/work.html +3 -1
  267. package/modules/hall-ui/public/work.js +2 -1
  268. package/modules/hall-ui/records/accomplishments.md +16 -0
  269. package/modules/hall-ui/records/hall-ask-card.md +9 -0
  270. package/modules/hall-ui/records/karma-vote-control.md +13 -0
  271. package/modules/hall-ui/records/oversight-family.md +1 -1
  272. package/modules/hall-ui/records/profile-connections.md +2 -0
  273. package/modules/hall-ui/records/profile-roles.md +1 -1
  274. package/modules/hall-ui/records/reading-rooms.md +1 -1
  275. package/modules/hall-ui/records/welcome-tower.md +50 -0
  276. package/modules/ideas/migrations/ideas_011_idea_votes.sql +31 -0
  277. package/modules/ideas/projection.js +1 -1
  278. package/modules/ideas/routes/blockers.js +3 -3
  279. package/modules/ideas/routes/inbox.js +29 -1
  280. package/modules/ideas/routes/ratify-goal.js +1 -1
  281. package/modules/ideas/routing.js +1 -1
  282. package/modules/ideas/templates.js +1 -1
  283. package/modules/ideas/trail-descent.js +1 -1
  284. package/modules/ideas/trail-size.js +1 -1
  285. package/modules/ideas/votes.js +93 -0
  286. package/modules/lifecycle/abandon-leftovers.js +1 -1
  287. package/modules/lifecycle/cascade.js +1 -1
  288. package/modules/lifecycle/conflict-resolve.js +13 -21
  289. package/modules/lifecycle/criterion-ref.js +1 -1
  290. package/modules/lifecycle/db-analytics.js +57 -4
  291. package/modules/lifecycle/db-deps-criteria.js +1 -1
  292. package/modules/lifecycle/db-ship.js +2 -2
  293. package/modules/lifecycle/db-tasks.js +2 -2
  294. package/modules/lifecycle/db-versions.js +1 -1
  295. package/modules/lifecycle/db.js +2 -0
  296. package/modules/lifecycle/dead-deps.js +3 -3
  297. package/modules/lifecycle/dependency-advisory.js +3 -3
  298. package/modules/lifecycle/goal-category.js +1 -1
  299. package/modules/lifecycle/goal-forest.js +1 -1
  300. package/modules/lifecycle/goal-task-relevance-advisory.js +1 -1
  301. package/modules/lifecycle/kickoff-checklist.js +1 -1
  302. package/modules/lifecycle/kickoff-seed.js +1 -1
  303. package/modules/lifecycle/lifecycle.js +2 -0
  304. package/modules/lifecycle/merge-reach.js +29 -15
  305. package/modules/lifecycle/missing-dep-classify.js +3 -3
  306. package/modules/lifecycle/module.json +2 -1
  307. package/modules/lifecycle/page-tweak-approve.js +85 -1
  308. package/modules/lifecycle/page-tweak-hold.js +1 -1
  309. package/modules/lifecycle/publish-reconciler.js +1 -2
  310. package/modules/lifecycle/rot.js +1 -1
  311. package/modules/lifecycle/routes/artist-gate.js +1 -1
  312. package/modules/lifecycle/routes/gate-approvals.js +22 -1
  313. package/modules/lifecycle/routes/goals.js +1 -1
  314. package/modules/lifecycle/routes/task-route-helpers.js +1 -1
  315. package/modules/lifecycle/routes/task-votes.js +54 -0
  316. package/modules/lifecycle/routes/task-write-routes.js +1 -1
  317. package/modules/lifecycle/routes/tasks.js +2 -2
  318. package/modules/lifecycle/routes/versions.js +2 -2
  319. package/modules/lifecycle/ship-card.js +4 -4
  320. package/modules/lifecycle/ship-preflight.js +1 -1
  321. package/modules/lifecycle/task-classifier.js +1 -1
  322. package/modules/lifecycle/task-status.js +1 -1
  323. package/modules/lifecycle/task-visual-db.js +1 -1
  324. package/modules/memory/learnings.js +1 -1
  325. package/modules/memory/pollers/search-index.js +2 -2
  326. package/modules/memory/routes/learnings.js +1 -1
  327. package/modules/memory/routes/memory.js +1 -1
  328. package/modules/memory/search.js +2 -2
  329. package/modules/npm-release/release.js +1 -1
  330. package/modules/onboarding/howto-moments.js +1 -1
  331. package/modules/onboarding/newcomer-restock.js +3 -3
  332. package/modules/onboarding/onboarding.js +1 -1
  333. package/modules/pixel-art/skills/otb-tile-generate/SKILL.md +1 -1
  334. package/modules/platform-identity/origin-containment.js +1 -1
  335. package/modules/platform-identity/publish-gate.js +1 -1
  336. package/modules/platform-identity/tests/platform-identity.mjs +1 -1
  337. package/modules/provisioning/capacity.js +1 -1
  338. package/modules/provisioning/core-upgrade.js +15 -9
  339. package/modules/provisioning/credential-preflight.js +3 -3
  340. package/modules/provisioning/disconnect.js +1 -1
  341. package/modules/provisioning/dns-resolves.js +1 -1
  342. package/modules/provisioning/module.json +1 -1
  343. package/modules/provisioning/onboard-plan.js +1 -1
  344. package/modules/provisioning/paid-shape-gate.js +2 -2
  345. package/modules/provisioning/planet-physics.js +11 -2
  346. package/modules/provisioning/pollers/liveness-sweep.js +1 -1
  347. package/modules/provisioning/pollers/runner-drift-notify.js +5 -5
  348. package/modules/provisioning/provisioning.js +2 -2
  349. package/modules/provisioning/render-lookup.js +1 -1
  350. package/modules/provisioning/render-standup.js +3 -3
  351. package/modules/provisioning/repo-private.js +1 -1
  352. package/modules/provisioning/routes/callback-page.js +1 -1
  353. package/modules/provisioning/routes/core-upgrade.js +23 -3
  354. package/modules/provisioning/routes/provisioning.js +2 -2
  355. package/modules/provisioning/routes/render-standup.js +1 -1
  356. package/modules/provisioning/routes/repo-private.js +1 -1
  357. package/modules/provisioning/soft-limits.js +1 -1
  358. package/modules/provisioning/starter-bundles.js +4 -2
  359. package/modules/provisioning/tests/provisioning.mjs +1 -1
  360. package/modules/public-landing/public/account.html +4 -6
  361. package/modules/public-landing/public/assets/cosmos.css +13 -6
  362. package/modules/public-landing/public/connections.html +4 -6
  363. package/modules/public-landing/public/contact.html +4 -6
  364. package/modules/public-landing/public/guild.html +4 -6
  365. package/modules/public-landing/public/index.html +11 -9
  366. package/modules/public-landing/public/invitations.html +4 -6
  367. package/modules/public-landing/public/privacy.html +4 -6
  368. package/modules/public-landing/public/projects.html +168 -46
  369. package/modules/public-landing/public/terms.html +4 -6
  370. package/modules/raise/content/copy.json +40 -0
  371. package/modules/raise/content/nda.html +39 -0
  372. package/modules/raise/content/settings.json +49 -0
  373. package/modules/raise/db.js +95 -0
  374. package/modules/raise/migrations/raise_001_tables.sql +71 -0
  375. package/modules/raise/module.json +28 -0
  376. package/modules/raise/page.js +194 -0
  377. package/modules/raise/public/edit.js +152 -0
  378. package/modules/raise/public/favicon.svg +1 -0
  379. package/modules/raise/public/logo-ink.svg +1 -0
  380. package/modules/raise/public/logo-night.svg +1 -0
  381. package/modules/raise/public/mode.js +8 -0
  382. package/modules/raise/public/raise.css +234 -0
  383. package/modules/raise/public/raise.js +91 -0
  384. package/modules/raise/raise.js +174 -0
  385. package/modules/raise/routes/raise.js +152 -0
  386. package/modules/raise/views/gate.html +39 -0
  387. package/modules/raise/views/nda.html +21 -0
  388. package/modules/raise/views/page.html +133 -0
  389. package/modules/raise/web.js +72 -0
  390. package/modules/render-deploy/deploys.js +1 -1
  391. package/modules/render-deploy/render.js +2 -2
  392. package/modules/security/secret-scrub.js +3 -3
  393. package/modules/security/security.js +1 -1
  394. package/modules/security/tests/artifact_scan.mjs +1 -1
  395. package/modules/security/tests/mirror.mjs +1 -1
  396. package/modules/security/tests/scan_store.mjs +1 -1
  397. package/modules/sessions/db.js +2 -2
  398. package/modules/sessions/pulse.js +2 -2
  399. package/modules/sessions/routes/sessions.js +1 -1
  400. package/modules/specialities/specialities.js +1 -1
  401. package/modules/status-ui/public/README.md +3 -4
  402. package/modules/status-ui/public/index.html +5 -31
  403. package/modules/status-ui/public/status.js +6 -174
  404. package/modules/status-ui/public/style.css +4 -133
  405. package/modules/ui-design/docs/design-contract.md +3 -3
  406. package/modules/ui-design/kit/README.md +1 -1
  407. package/modules/ui-design/kit/serve.js +13 -4
  408. package/modules/ui-design/scripts/design-sync.js +1 -1
  409. package/modules/ui-design/scripts/figma-design-sync.js +1 -1
  410. package/modules/ui-design/scripts/validate-design.js +1 -1
  411. package/package-lock.json +27 -11
  412. package/package.json +2 -3
  413. package/release-notes.json +172 -0
  414. package/scripts/bongos/CLAUDE.md +15 -0
  415. package/scripts/bongos/abandon.js +137 -0
  416. package/scripts/bongos/accessibility-replay.js +195 -0
  417. package/scripts/bongos/address-park-sweep.sh +91 -0
  418. package/scripts/bongos/adopt-detect.js +123 -0
  419. package/scripts/bongos/adopt-import.js +111 -0
  420. package/scripts/bongos/adopt-preflight.js +187 -0
  421. package/scripts/bongos/adr-namespace.js +273 -0
  422. package/scripts/bongos/agent-invoke.js +689 -0
  423. package/scripts/bongos/agents-sync.js +502 -0
  424. package/scripts/bongos/api-alias-caller-scan.js +256 -0
  425. package/scripts/bongos/api-artifacts.js +91 -0
  426. package/scripts/bongos/api.js +86 -0
  427. package/scripts/bongos/api.ps1 +26 -0
  428. package/scripts/bongos/architect-audit.js +294 -0
  429. package/scripts/bongos/artifact-audit.js +326 -0
  430. package/scripts/bongos/artifact-format.js +203 -0
  431. package/scripts/bongos/artifact-staleness.js +267 -0
  432. package/scripts/bongos/ask.js +231 -0
  433. package/scripts/bongos/audit-authorship.sh +329 -0
  434. package/scripts/bongos/audit-deps.js +189 -0
  435. package/scripts/bongos/audit-gate.js +121 -0
  436. package/scripts/bongos/audit-rank-roles.js +172 -0
  437. package/scripts/bongos/audit-replay.sh +205 -0
  438. package/scripts/bongos/autobongos-digest.js +123 -0
  439. package/scripts/bongos/autobongos-grade-cap.js +187 -0
  440. package/scripts/bongos/autobongos-loop.js +210 -0
  441. package/scripts/bongos/autobongos-run.js +1361 -0
  442. package/scripts/bongos/autobongos-service.cmd +50 -0
  443. package/scripts/bongos/autobongos-service.ps1 +270 -0
  444. package/scripts/bongos/autobongos-tweak-lane.js +262 -0
  445. package/scripts/bongos/autobongos-verify.js +618 -0
  446. package/scripts/bongos/autonomy-gate.js +135 -0
  447. package/scripts/bongos/autonomy-gauge-statusline.js +124 -0
  448. package/scripts/bongos/autonomy-gauge.js +84 -0
  449. package/scripts/bongos/backfill-cost.js +176 -0
  450. package/scripts/bongos/backfill-disciplines.js +144 -0
  451. package/scripts/bongos/backfill-session-earnings.js +123 -0
  452. package/scripts/bongos/backfill-session-types.js +87 -0
  453. package/scripts/bongos/backfill-sessions.js +411 -0
  454. package/scripts/bongos/backfill-subagent-rewards.js +485 -0
  455. package/scripts/bongos/backfill-task-rewards.js +413 -0
  456. package/scripts/bongos/backlog-review.js +399 -0
  457. package/scripts/bongos/backup-dropin-sweep.sh +95 -0
  458. package/scripts/bongos/backup.js +116 -0
  459. package/scripts/bongos/baseline-staleness.js +217 -0
  460. package/scripts/bongos/bfg-principal-token.js +65 -0
  461. package/scripts/bongos/bug-attachment-audit.js +149 -0
  462. package/scripts/bongos/bug-attachment-recover.js +198 -0
  463. package/scripts/bongos/bug-triage.js +292 -0
  464. package/scripts/bongos/build-bongos.js +94 -0
  465. package/scripts/bongos/bump-version.js +221 -0
  466. package/scripts/bongos/capture.js +481 -0
  467. package/scripts/bongos/category-advisory-guard.js +206 -0
  468. package/scripts/bongos/ci-grade.js +82 -0
  469. package/scripts/bongos/claim-recall.js +112 -0
  470. package/scripts/bongos/claim.js +789 -0
  471. package/scripts/bongos/classify-discipline.js +153 -0
  472. package/scripts/bongos/claude-materialize.js +1200 -0
  473. package/scripts/bongos/claude-md-template.js +142 -0
  474. package/scripts/bongos/cleanup-orphans.js +74 -0
  475. package/scripts/bongos/cli-lib.js +1226 -0
  476. package/scripts/bongos/client-baseurl-guard.js +116 -0
  477. package/scripts/bongos/codemod-rename-scripts-gds.js +381 -0
  478. package/scripts/bongos/codemod-rename-src-gds.js +145 -0
  479. package/scripts/bongos/conductor-dispatch.js +535 -0
  480. package/scripts/bongos/context-pack.js +326 -0
  481. package/scripts/bongos/control-manifest.js +199 -0
  482. package/scripts/bongos/copy-apply.js +758 -0
  483. package/scripts/bongos/copy-inventory.js +571 -0
  484. package/scripts/bongos/core-origin-follow.js +185 -0
  485. package/scripts/bongos/core-pin-sync.js +260 -0
  486. package/scripts/bongos/coreB-carve-proof.sh +725 -0
  487. package/scripts/bongos/cost-report.js +63 -0
  488. package/scripts/bongos/cost.js +47 -0
  489. package/scripts/bongos/credential-presence.js +296 -0
  490. package/scripts/bongos/cutover-codemod.js +240 -0
  491. package/scripts/bongos/db-backup-nightly.sh +232 -0
  492. package/scripts/bongos/db-backup-offsite.sh +267 -0
  493. package/scripts/bongos/demote.js +45 -0
  494. package/scripts/bongos/deploy-divergence.js +454 -0
  495. package/scripts/bongos/deploy-main-audit-gate.sh +97 -0
  496. package/scripts/bongos/design-sync.js +12 -0
  497. package/scripts/bongos/dev-box-guard.js +166 -0
  498. package/scripts/bongos/dev-lib.js +722 -0
  499. package/scripts/bongos/dev.js +645 -0
  500. package/scripts/bongos/device-flow-help.js +72 -0
  501. package/scripts/bongos/diagnose-achievements.js +118 -0
  502. package/scripts/bongos/diagram-facts.js +355 -0
  503. package/scripts/bongos/discord-channels.js +77 -0
  504. package/scripts/bongos/do-api.js +109 -0
  505. package/scripts/bongos/doc-cli-guard.js +274 -0
  506. package/scripts/bongos/doc-comment-coverage.js +139 -0
  507. package/scripts/bongos/doc-control-claims.js +170 -0
  508. package/scripts/bongos/docs-entropy.js +453 -0
  509. package/scripts/bongos/doctor.js +493 -0
  510. package/scripts/bongos/enroll-control-plane.js +101 -0
  511. package/scripts/bongos/exec-path-guard.js +564 -0
  512. package/scripts/bongos/feedback-send.js +249 -0
  513. package/scripts/bongos/fetch-art-key.js +106 -0
  514. package/scripts/bongos/fetch-sound-prefs.js +126 -0
  515. package/scripts/bongos/figma-design-sync.js +11 -0
  516. package/scripts/bongos/find-untested.js +371 -0
  517. package/scripts/bongos/fitness-checks-error-envelope.js +134 -0
  518. package/scripts/bongos/fitness-checks-identity.js +343 -0
  519. package/scripts/bongos/fitness-checks-packaging.js +132 -0
  520. package/scripts/bongos/fitness-checks-route-pins.js +76 -0
  521. package/scripts/bongos/fitness-checks-vocabulary.js +392 -0
  522. package/scripts/bongos/fitness-checks-write-validation.js +157 -0
  523. package/scripts/bongos/fitness-lib.js +127 -0
  524. package/scripts/bongos/fitness-migration-contraction.js +50 -0
  525. package/scripts/bongos/fitness-ratchets.js +594 -0
  526. package/scripts/bongos/fitness.js +1498 -0
  527. package/scripts/bongos/forwarder.js +80 -0
  528. package/scripts/bongos/gate-review.js +330 -0
  529. package/scripts/bongos/gating.js +348 -0
  530. package/scripts/{gds → bongos}/gds-db-backup.service +6 -6
  531. package/scripts/{gds → bongos}/gds-db-backup.timer +4 -4
  532. package/scripts/{gds → bongos}/gds-db-offsite.service +4 -4
  533. package/scripts/{gds → bongos}/gds-db-offsite.timer +4 -4
  534. package/scripts/bongos/gds-literal-scan.js +196 -0
  535. package/scripts/bongos/gen-api-client.js +576 -0
  536. package/scripts/bongos/gen-api-docs.js +1111 -0
  537. package/scripts/bongos/gen-atlas.js +366 -0
  538. package/scripts/bongos/gen-diagrams.js +608 -0
  539. package/scripts/bongos/gen-file-map.js +337 -0
  540. package/scripts/bongos/gen-freshness.js +32 -0
  541. package/scripts/bongos/gen-interaction-posture.js +122 -0
  542. package/scripts/bongos/gen-repo-map.js +540 -0
  543. package/scripts/bongos/gen-role-responsibilities.js +134 -0
  544. package/scripts/bongos/gen-session-index.js +243 -0
  545. package/scripts/bongos/gen-sounds.js +176 -0
  546. package/scripts/bongos/git-merge-regen.js +254 -0
  547. package/scripts/bongos/go-live.js +1071 -0
  548. package/scripts/bongos/goal-names.js +102 -0
  549. package/scripts/bongos/goal.js +272 -0
  550. package/scripts/bongos/government-walk.js +1477 -0
  551. package/scripts/bongos/grade-correlation-audit.js +310 -0
  552. package/scripts/bongos/grade-replay.js +237 -0
  553. package/scripts/bongos/grade-smoke.js +205 -0
  554. package/scripts/bongos/home-isolation-guard.js +126 -0
  555. package/scripts/bongos/hooks/pre-push.js +211 -0
  556. package/scripts/bongos/howto.js +145 -0
  557. package/scripts/bongos/http-api-client.js +81 -0
  558. package/scripts/bongos/identity-strip.js +75 -0
  559. package/scripts/bongos/init.js +1159 -0
  560. package/scripts/bongos/install-git-hooks.js +200 -0
  561. package/scripts/bongos/instance-apex.js +38 -0
  562. package/scripts/bongos/intent-retry.js +52 -0
  563. package/scripts/bongos/key-card.js +222 -0
  564. package/scripts/bongos/key-status.js +126 -0
  565. package/scripts/bongos/land-watch.js +201 -0
  566. package/scripts/bongos/leak-scan-allowlist.js +293 -0
  567. package/scripts/bongos/learning-capture.js +145 -0
  568. package/scripts/bongos/lib.sh +74 -0
  569. package/scripts/bongos/linkify-refs.js +655 -0
  570. package/scripts/bongos/lint-infra-exec.js +70 -0
  571. package/scripts/bongos/lint-migrations.js +102 -0
  572. package/scripts/bongos/lint-workflow-exec.js +63 -0
  573. package/scripts/bongos/local-preview-lib.js +128 -0
  574. package/scripts/bongos/local-preview.js +82 -0
  575. package/scripts/bongos/login.js +360 -0
  576. package/scripts/bongos/main-audit.js +625 -0
  577. package/scripts/bongos/me.js +97 -0
  578. package/scripts/bongos/memory-map.js +176 -0
  579. package/scripts/bongos/merge-lock.js +71 -0
  580. package/scripts/bongos/migration-namespace.js +313 -0
  581. package/scripts/bongos/mirror-lineage-check.js +343 -0
  582. package/scripts/bongos/mirror-redact.js +350 -0
  583. package/scripts/bongos/module-artifact.js +289 -0
  584. package/scripts/bongos/module-assess-docs.js +238 -0
  585. package/scripts/bongos/module-assess-installs.js +228 -0
  586. package/scripts/bongos/module-assess-score.js +111 -0
  587. package/scripts/bongos/module-assess-security.js +252 -0
  588. package/scripts/bongos/module-assess-tests.js +278 -0
  589. package/scripts/bongos/module-assess-version.js +92 -0
  590. package/scripts/bongos/module-error-report.js +148 -0
  591. package/scripts/{gds → bongos}/module-test-runner/README.md +3 -3
  592. package/scripts/{gds → bongos}/module-test-runner/module-tests.yml +2 -2
  593. package/scripts/bongos/module-test-runner.js +414 -0
  594. package/scripts/bongos/module.js +1376 -0
  595. package/scripts/bongos/move-escalation.js +141 -0
  596. package/scripts/{gds → bongos}/newcomer-floor.config.json +1 -1
  597. package/scripts/bongos/newcomer-floor.js +421 -0
  598. package/scripts/{gds → bongos}/newcomer-floor.templates.json +13 -13
  599. package/scripts/bongos/newcomer-floor.test.js +235 -0
  600. package/scripts/bongos/next-number.js +163 -0
  601. package/scripts/bongos/oauth-secret.js +202 -0
  602. package/scripts/bongos/onboard.js +267 -0
  603. package/scripts/bongos/onboarding-analyze.js +226 -0
  604. package/scripts/bongos/onboarding-config.js +179 -0
  605. package/scripts/bongos/onboarding-ship.js +92 -0
  606. package/scripts/bongos/pack-env-prefix.js +73 -0
  607. package/scripts/bongos/package-core.js +1200 -0
  608. package/scripts/bongos/page-inventory.js +348 -0
  609. package/scripts/bongos/page-reader.js +722 -0
  610. package/scripts/bongos/paste-token.js +212 -0
  611. package/scripts/bongos/plain-cards.js +351 -0
  612. package/scripts/bongos/portability-smoke-art.sh +85 -0
  613. package/scripts/bongos/portability-smoke-memory.sh +176 -0
  614. package/scripts/bongos/preflight.js +214 -0
  615. package/scripts/bongos/probe-cache.js +246 -0
  616. package/scripts/bongos/prove-strict-versioning.js +284 -0
  617. package/scripts/bongos/provision-auto-upgrade.js +162 -0
  618. package/scripts/bongos/provision-byo-host.js +68 -0
  619. package/scripts/bongos/provision-capacity.js +79 -0
  620. package/scripts/bongos/provision-caps.js +63 -0
  621. package/scripts/bongos/provision-config.js +233 -0
  622. package/scripts/bongos/provision-core-upgrade.js +1166 -0
  623. package/scripts/bongos/provision-disconnect.js +88 -0
  624. package/scripts/bongos/provision-github-setup.js +168 -0
  625. package/scripts/bongos/provision-net.js +357 -0
  626. package/scripts/bongos/provision-pin-key.js +176 -0
  627. package/scripts/bongos/provision-pin-replay.js +126 -0
  628. package/scripts/bongos/provision-process.js +170 -0
  629. package/scripts/bongos/provision-render.js +201 -0
  630. package/scripts/bongos/provision-repo-auth.js +164 -0
  631. package/scripts/bongos/provision-repo-private.js +98 -0
  632. package/scripts/bongos/provision-repo.js +1337 -0
  633. package/scripts/bongos/provision-teardown.js +106 -0
  634. package/scripts/bongos/provision-units.js +469 -0
  635. package/scripts/bongos/provision.js +1479 -0
  636. package/scripts/bongos/publish-credential-check.js +66 -0
  637. package/scripts/bongos/publish-integration-gate.js +142 -0
  638. package/scripts/bongos/publish-manifest.js +440 -0
  639. package/scripts/bongos/publish-watch.js +268 -0
  640. package/scripts/bongos/pulse.js +336 -0
  641. package/scripts/bongos/push-main.js +56 -0
  642. package/scripts/bongos/push-path-brief.js +100 -0
  643. package/scripts/bongos/read-session-export.js +359 -0
  644. package/scripts/bongos/reauth.js +155 -0
  645. package/scripts/bongos/recall.js +183 -0
  646. package/scripts/bongos/redteam-patrol.js +437 -0
  647. package/scripts/bongos/regen-instance-docs.js +47 -0
  648. package/scripts/bongos/release-core.js +80 -0
  649. package/scripts/bongos/release-notes.js +271 -0
  650. package/scripts/bongos/release.js +139 -0
  651. package/scripts/bongos/rename-goals.js +109 -0
  652. package/scripts/bongos/rename-history-check.js +369 -0
  653. package/scripts/bongos/rename-ledger-prose.js +482 -0
  654. package/scripts/bongos/render-api.js +197 -0
  655. package/scripts/bongos/render-check.js +206 -0
  656. package/scripts/bongos/render-ideas.js +226 -0
  657. package/scripts/bongos/render-payload.js +85 -0
  658. package/scripts/bongos/repo-metrics.js +363 -0
  659. package/scripts/bongos/review-sheet.js +108 -0
  660. package/scripts/bongos/role-pack-guard.js +142 -0
  661. package/scripts/bongos/route-shadow-guard.js +175 -0
  662. package/scripts/bongos/routine-schedule.js +283 -0
  663. package/scripts/bongos/run-routine.js +257 -0
  664. package/scripts/bongos/run-unit-tests.js +654 -0
  665. package/scripts/bongos/runner-drift.js +151 -0
  666. package/scripts/bongos/sandbox-stage.js +459 -0
  667. package/scripts/bongos/scope-map-guard.js +300 -0
  668. package/scripts/bongos/scope-roster-guard.js +118 -0
  669. package/scripts/bongos/seam-wiring-guard.js +275 -0
  670. package/scripts/bongos/search-ingest-db.js +288 -0
  671. package/scripts/bongos/search-ingest-md.js +269 -0
  672. package/scripts/bongos/seed-adopt-tasks.js +75 -0
  673. package/scripts/bongos/seed-api-contract-goal-tasks.js +141 -0
  674. package/scripts/bongos/seed-board-room-tasks.js +196 -0
  675. package/scripts/bongos/seed-bongos-app-tasks.js +294 -0
  676. package/scripts/bongos/seed-bongos-coreB-tranche1-tasks.js +81 -0
  677. package/scripts/bongos/seed-bongos-coreB-tranche2-tasks.js +100 -0
  678. package/scripts/bongos/seed-bongos-goal-hierarchy-tasks.js +307 -0
  679. package/scripts/bongos/seed-bongos-module-system-tasks.js +346 -0
  680. package/scripts/bongos/seed-bongos-tasks.js +214 -0
  681. package/scripts/bongos/seed-bongos-v1-idea-routing-tasks.js +152 -0
  682. package/scripts/bongos/seed-bongos-v1-seo-tasks.js +104 -0
  683. package/scripts/bongos/seed-bv1-community-tasks.js +131 -0
  684. package/scripts/bongos/seed-bv1-privacy-invites-tasks.js +133 -0
  685. package/scripts/bongos/seed-bv1-profile-page-tasks.js +161 -0
  686. package/scripts/bongos/seed-bv1-profiles-tasks.js +135 -0
  687. package/scripts/bongos/seed-bv1-r01-delta-tasks.js +154 -0
  688. package/scripts/bongos/seed-bv2-ideator-surface-tasks.js +390 -0
  689. package/scripts/bongos/seed-bv2-tweak-mode-tasks.js +277 -0
  690. package/scripts/bongos/seed-gds-v4-tasks.js +624 -0
  691. package/scripts/bongos/seed-governance-tasks.js +340 -0
  692. package/scripts/bongos/seed-medusa-tasks.js +440 -0
  693. package/scripts/bongos/seed-module-upstreaming.js +219 -0
  694. package/scripts/bongos/seed-productization-tasks.js +235 -0
  695. package/scripts/bongos/seed-project-admin-console-tasks.js +88 -0
  696. package/scripts/bongos/seed-provisioning-tasks.js +83 -0
  697. package/scripts/bongos/seed-staging.sh +117 -0
  698. package/scripts/bongos/seed-strict-versioning-tasks.js +275 -0
  699. package/scripts/bongos/seed-v2-world-tasks.js +283 -0
  700. package/scripts/bongos/seed-verify-criteria.js +124 -0
  701. package/scripts/bongos/sequence.js +597 -0
  702. package/scripts/bongos/session-cost.js +430 -0
  703. package/scripts/bongos/session-digest-build.js +293 -0
  704. package/scripts/bongos/session-digest.js +200 -0
  705. package/scripts/bongos/session-eval.js +631 -0
  706. package/scripts/bongos/session-transcript-build.js +155 -0
  707. package/scripts/bongos/session-transcript-upload.js +29 -0
  708. package/scripts/bongos/session.js +404 -0
  709. package/scripts/bongos/setup.js +646 -0
  710. package/scripts/bongos/ship-check.js +89 -0
  711. package/scripts/bongos/ship-deploy-target.js +393 -0
  712. package/scripts/bongos/ship-escalation.js +167 -0
  713. package/scripts/bongos/ship-finish.js +420 -0
  714. package/scripts/bongos/ship-flow.js +1217 -0
  715. package/scripts/bongos/ship-git.js +100 -0
  716. package/scripts/bongos/ship-grade-steps.js +547 -0
  717. package/scripts/bongos/ship-grade.js +426 -0
  718. package/scripts/bongos/ship-honesty.js +314 -0
  719. package/scripts/bongos/ship-io.js +139 -0
  720. package/scripts/bongos/ship-land.js +1130 -0
  721. package/scripts/bongos/ship-memory-sync.js +249 -0
  722. package/scripts/bongos/ship-merge-gate.js +225 -0
  723. package/scripts/bongos/ship-merge.js +466 -0
  724. package/scripts/bongos/ship-mode-ask.js +138 -0
  725. package/scripts/bongos/ship-mode-manual.js +54 -0
  726. package/scripts/bongos/ship-preflight-steps.js +399 -0
  727. package/scripts/bongos/ship-regen.js +292 -0
  728. package/scripts/bongos/ship-resume.js +201 -0
  729. package/scripts/bongos/ship-session-upload.js +313 -0
  730. package/scripts/bongos/ship-state.js +110 -0
  731. package/scripts/bongos/ship-surprise.js +84 -0
  732. package/scripts/bongos/ship-visual.js +75 -0
  733. package/scripts/bongos/ship.js +382 -0
  734. package/scripts/bongos/shipping-mode.js +71 -0
  735. package/scripts/bongos/skill-lint.js +250 -0
  736. package/scripts/bongos/skill-preflight.js +361 -0
  737. package/scripts/bongos/smoke-batch-claim.sh +238 -0
  738. package/scripts/bongos/smoke-batch-release.sh +316 -0
  739. package/scripts/bongos/smoke-claim-consistency.sh +222 -0
  740. package/scripts/bongos/smoke-dependencies.sh +143 -0
  741. package/scripts/bongos/smoke-gds.js +256 -0
  742. package/scripts/bongos/smoke-write.sh +275 -0
  743. package/scripts/bongos/source-text-test-scan.js +106 -0
  744. package/scripts/bongos/spark.js +294 -0
  745. package/scripts/bongos/stale-worktrees.js +212 -0
  746. package/scripts/bongos/start-goals.js +102 -0
  747. package/scripts/bongos/start.js +1090 -0
  748. package/scripts/bongos/status.js +545 -0
  749. package/scripts/bongos/strand-watch.js +315 -0
  750. package/scripts/bongos/stranded-rows.js +200 -0
  751. package/scripts/bongos/stray-unit-sweep.sh +71 -0
  752. package/scripts/bongos/surface.js +101 -0
  753. package/scripts/bongos/task.js +273 -0
  754. package/scripts/bongos/test-path-guard.js +99 -0
  755. package/scripts/bongos/triage.js +742 -0
  756. package/scripts/bongos/turn-end-sound.js +74 -0
  757. package/scripts/bongos/tweak-halt.js +70 -0
  758. package/scripts/bongos/tweak-renders.js +200 -0
  759. package/scripts/bongos/uat.js +120 -0
  760. package/scripts/bongos/ui-kit-transform.js +43 -0
  761. package/scripts/bongos/update-channel.js +512 -0
  762. package/scripts/bongos/update-sweep.js +829 -0
  763. package/scripts/bongos/upgrade-artist-gate.js +46 -0
  764. package/scripts/bongos/upgrade-commit-identity.js +32 -0
  765. package/scripts/bongos/upgrade-migrate.js +224 -0
  766. package/scripts/bongos/upgrade-operator.js +73 -0
  767. package/scripts/bongos/upgrade-outcome.js +174 -0
  768. package/scripts/bongos/upgrade.js +1499 -0
  769. package/scripts/bongos/validate-design.js +12 -0
  770. package/scripts/bongos/version-close.js +621 -0
  771. package/scripts/bongos/version-literal-guard.js +140 -0
  772. package/scripts/bongos/version-select.js +79 -0
  773. package/scripts/bongos/visual-review-nudge.js +39 -0
  774. package/scripts/bongos/wedge-remedy.js +174 -0
  775. package/scripts/bongos/worktree-claim-guard.js +130 -0
  776. package/scripts/bongos/worktree.js +449 -0
  777. package/scripts/discord/post.js +1 -1
  778. package/scripts/gds/README.md +9 -0
  779. package/scripts/gds/abandon.js +6 -136
  780. package/scripts/gds/accessibility-replay.js +5 -194
  781. package/scripts/gds/address-park-sweep.sh +7 -90
  782. package/scripts/gds/adopt-detect.js +5 -121
  783. package/scripts/gds/adopt-import.js +5 -109
  784. package/scripts/gds/adopt-preflight.js +5 -185
  785. package/scripts/gds/adr-namespace.js +5 -271
  786. package/scripts/gds/agent-invoke.js +5 -687
  787. package/scripts/gds/agents-sync.js +5 -500
  788. package/scripts/gds/api-alias-caller-scan.js +5 -255
  789. package/scripts/gds/api-artifacts.js +6 -0
  790. package/scripts/gds/api.js +6 -85
  791. package/scripts/gds/api.ps1 +8 -26
  792. package/scripts/gds/architect-audit.js +6 -293
  793. package/scripts/gds/artifact-audit.js +5 -324
  794. package/scripts/gds/artifact-format.js +6 -203
  795. package/scripts/gds/artifact-staleness.js +5 -265
  796. package/scripts/gds/ask.js +5 -229
  797. package/scripts/gds/audit-authorship.sh +7 -328
  798. package/scripts/gds/audit-deps.js +6 -188
  799. package/scripts/gds/audit-gate.js +5 -119
  800. package/scripts/gds/audit-rank-roles.js +6 -171
  801. package/scripts/gds/audit-replay.sh +7 -204
  802. package/scripts/gds/autobongos-digest.js +5 -121
  803. package/scripts/gds/autobongos-grade-cap.js +5 -186
  804. package/scripts/gds/autobongos-loop.js +5 -208
  805. package/scripts/gds/autobongos-run.js +5 -1359
  806. package/scripts/gds/autobongos-service.cmd +8 -49
  807. package/scripts/gds/autobongos-service.ps1 +8 -270
  808. package/scripts/gds/autobongos-tweak-lane.js +5 -261
  809. package/scripts/gds/autobongos-verify.js +5 -616
  810. package/scripts/gds/autonomy-gate.js +5 -133
  811. package/scripts/gds/autonomy-gauge-statusline.js +5 -122
  812. package/scripts/gds/autonomy-gauge.js +5 -82
  813. package/scripts/gds/backfill-cost.js +6 -175
  814. package/scripts/gds/backfill-disciplines.js +5 -142
  815. package/scripts/gds/backfill-session-earnings.js +5 -121
  816. package/scripts/gds/backfill-session-types.js +5 -85
  817. package/scripts/gds/backfill-sessions.js +5 -409
  818. package/scripts/gds/backfill-subagent-rewards.js +5 -483
  819. package/scripts/gds/backfill-task-rewards.js +5 -411
  820. package/scripts/gds/backlog-review.js +6 -398
  821. package/scripts/gds/backup-dropin-sweep.sh +7 -94
  822. package/scripts/gds/backup.js +6 -115
  823. package/scripts/gds/baseline-staleness.js +5 -215
  824. package/scripts/gds/bfg-principal-token.js +6 -64
  825. package/scripts/gds/bug-attachment-audit.js +5 -147
  826. package/scripts/gds/bug-attachment-recover.js +5 -196
  827. package/scripts/gds/bug-triage.js +6 -291
  828. package/scripts/gds/build-bongos.js +5 -92
  829. package/scripts/gds/bump-version.js +5 -219
  830. package/scripts/gds/capture.js +6 -480
  831. package/scripts/gds/category-advisory-guard.js +5 -205
  832. package/scripts/gds/ci-grade.js +6 -81
  833. package/scripts/gds/claim-recall.js +6 -111
  834. package/scripts/gds/claim.js +6 -788
  835. package/scripts/gds/classify-discipline.js +6 -152
  836. package/scripts/gds/claude-materialize.js +5 -1198
  837. package/scripts/gds/claude-md-template.js +5 -140
  838. package/scripts/gds/cleanup-orphans.js +6 -73
  839. package/scripts/gds/cli-lib.js +6 -1204
  840. package/scripts/gds/client-baseurl-guard.js +5 -114
  841. package/scripts/gds/codemod-rename-src-gds.js +6 -144
  842. package/scripts/gds/conductor-dispatch.js +6 -534
  843. package/scripts/gds/context-pack.js +6 -325
  844. package/scripts/gds/control-manifest.js +5 -197
  845. package/scripts/gds/copy-apply.js +5 -756
  846. package/scripts/gds/copy-inventory.js +5 -569
  847. package/scripts/gds/core-origin-follow.js +5 -184
  848. package/scripts/gds/core-pin-sync.js +5 -258
  849. package/scripts/gds/coreB-carve-proof.sh +7 -724
  850. package/scripts/gds/cost-report.js +6 -62
  851. package/scripts/gds/cost.js +6 -46
  852. package/scripts/gds/credential-presence.js +5 -294
  853. package/scripts/gds/cutover-codemod.js +5 -239
  854. package/scripts/gds/db-backup-nightly.sh +7 -231
  855. package/scripts/gds/db-backup-offsite.sh +7 -266
  856. package/scripts/gds/demote.js +6 -44
  857. package/scripts/gds/deploy-divergence.js +6 -445
  858. package/scripts/gds/deploy-main-audit-gate.sh +7 -96
  859. package/scripts/gds/design-sync.js +5 -10
  860. package/scripts/gds/dev-box-guard.js +5 -164
  861. package/scripts/gds/dev-lib.js +5 -721
  862. package/scripts/gds/dev.js +5 -643
  863. package/scripts/gds/device-flow-help.js +5 -70
  864. package/scripts/gds/diagnose-achievements.js +5 -116
  865. package/scripts/gds/diagram-facts.js +6 -355
  866. package/scripts/gds/discord-channels.js +5 -75
  867. package/scripts/gds/do-api.js +6 -109
  868. package/scripts/gds/doc-cli-guard.js +5 -266
  869. package/scripts/gds/doc-comment-coverage.js +5 -137
  870. package/scripts/gds/doc-control-claims.js +5 -166
  871. package/scripts/gds/docs-entropy.js +5 -443
  872. package/scripts/gds/doctor.js +6 -492
  873. package/scripts/gds/enroll-control-plane.js +5 -99
  874. package/scripts/gds/exec-path-guard.js +5 -562
  875. package/scripts/gds/feedback-send.js +5 -247
  876. package/scripts/gds/fetch-art-key.js +5 -104
  877. package/scripts/gds/fetch-sound-prefs.js +5 -124
  878. package/scripts/gds/figma-design-sync.js +5 -9
  879. package/scripts/gds/find-untested.js +5 -369
  880. package/scripts/gds/fitness-checks-error-envelope.js +5 -133
  881. package/scripts/gds/fitness-checks-identity.js +5 -342
  882. package/scripts/gds/fitness-checks-packaging.js +5 -131
  883. package/scripts/gds/fitness-checks-route-pins.js +5 -75
  884. package/scripts/gds/fitness-checks-vocabulary.js +5 -391
  885. package/scripts/gds/fitness-checks-write-validation.js +5 -156
  886. package/scripts/gds/fitness-lib.js +5 -126
  887. package/scripts/gds/fitness-migration-contraction.js +5 -49
  888. package/scripts/gds/fitness-ratchets.js +5 -563
  889. package/scripts/gds/fitness.js +5 -1493
  890. package/scripts/gds/gate-review.js +5 -328
  891. package/scripts/gds/gating.js +5 -346
  892. package/scripts/gds/gds-literal-scan.js +5 -194
  893. package/scripts/gds/gen-api-client.js +5 -555
  894. package/scripts/gds/gen-api-docs.js +5 -1100
  895. package/scripts/gds/gen-atlas.js +5 -364
  896. package/scripts/gds/gen-diagrams.js +6 -607
  897. package/scripts/gds/gen-file-map.js +5 -335
  898. package/scripts/gds/gen-freshness.js +5 -31
  899. package/scripts/gds/gen-interaction-posture.js +5 -120
  900. package/scripts/gds/gen-repo-map.js +5 -538
  901. package/scripts/gds/gen-role-responsibilities.js +5 -133
  902. package/scripts/gds/gen-session-index.js +5 -241
  903. package/scripts/gds/gen-sounds.js +5 -174
  904. package/scripts/gds/git-merge-regen.js +6 -291
  905. package/scripts/gds/go-live.js +5 -1069
  906. package/scripts/gds/goal-names.js +5 -100
  907. package/scripts/gds/goal.js +6 -271
  908. package/scripts/gds/government-walk.js +5 -1475
  909. package/scripts/gds/grade-correlation-audit.js +5 -308
  910. package/scripts/gds/grade-replay.js +5 -235
  911. package/scripts/gds/grade-smoke.js +6 -204
  912. package/scripts/gds/home-isolation-guard.js +5 -125
  913. package/scripts/gds/hooks/pre-push.js +5 -209
  914. package/scripts/gds/howto.js +5 -143
  915. package/scripts/gds/http-api-client.js +6 -81
  916. package/scripts/gds/identity-strip.js +5 -74
  917. package/scripts/gds/init.js +5 -1157
  918. package/scripts/gds/install-git-hooks.js +5 -198
  919. package/scripts/gds/instance-apex.js +5 -37
  920. package/scripts/gds/intent-retry.js +5 -51
  921. package/scripts/gds/key-card.js +6 -221
  922. package/scripts/gds/key-status.js +5 -124
  923. package/scripts/gds/land-watch.js +5 -199
  924. package/scripts/gds/leak-scan-allowlist.js +5 -291
  925. package/scripts/gds/learning-capture.js +6 -144
  926. package/scripts/gds/lib.sh +7 -73
  927. package/scripts/gds/linkify-refs.js +6 -654
  928. package/scripts/gds/lint-infra-exec.js +5 -68
  929. package/scripts/gds/lint-migrations.js +5 -100
  930. package/scripts/gds/lint-workflow-exec.js +5 -61
  931. package/scripts/gds/local-preview-lib.js +6 -128
  932. package/scripts/gds/local-preview.js +6 -81
  933. package/scripts/gds/login.js +5 -358
  934. package/scripts/gds/main-audit.js +5 -623
  935. package/scripts/gds/me.js +6 -96
  936. package/scripts/gds/memory-map.js +5 -174
  937. package/scripts/gds/merge-lock.js +6 -70
  938. package/scripts/gds/migration-namespace.js +5 -311
  939. package/scripts/gds/mirror-lineage-check.js +5 -341
  940. package/scripts/gds/mirror-redact.js +5 -348
  941. package/scripts/gds/module-artifact.js +6 -289
  942. package/scripts/gds/module-assess-docs.js +6 -237
  943. package/scripts/gds/module-assess-installs.js +6 -227
  944. package/scripts/gds/module-assess-score.js +6 -110
  945. package/scripts/gds/module-assess-security.js +6 -251
  946. package/scripts/gds/module-assess-tests.js +6 -277
  947. package/scripts/gds/module-assess-version.js +6 -91
  948. package/scripts/gds/module-error-report.js +5 -146
  949. package/scripts/gds/module-test-runner.js +6 -413
  950. package/scripts/gds/module.js +5 -1374
  951. package/scripts/gds/move-escalation.js +5 -140
  952. package/scripts/gds/newcomer-floor.js +6 -420
  953. package/scripts/gds/newcomer-floor.test.js +6 -234
  954. package/scripts/gds/next-number.js +6 -162
  955. package/scripts/gds/oauth-secret.js +5 -200
  956. package/scripts/gds/onboard.js +5 -265
  957. package/scripts/gds/onboarding-analyze.js +6 -225
  958. package/scripts/gds/onboarding-config.js +6 -179
  959. package/scripts/gds/onboarding-ship.js +6 -91
  960. package/scripts/gds/pack-env-prefix.js +5 -72
  961. package/scripts/gds/package-core.js +5 -1102
  962. package/scripts/gds/page-inventory.js +5 -346
  963. package/scripts/gds/page-reader.js +5 -720
  964. package/scripts/gds/paste-token.js +6 -211
  965. package/scripts/gds/plain-cards.js +5 -350
  966. package/scripts/gds/portability-smoke-art.sh +7 -84
  967. package/scripts/gds/portability-smoke-memory.sh +7 -175
  968. package/scripts/gds/preflight.js +5 -212
  969. package/scripts/gds/probe-cache.js +5 -244
  970. package/scripts/gds/prove-strict-versioning.js +6 -283
  971. package/scripts/gds/provision-auto-upgrade.js +5 -161
  972. package/scripts/gds/provision-byo-host.js +5 -67
  973. package/scripts/gds/provision-capacity.js +5 -78
  974. package/scripts/gds/provision-caps.js +5 -62
  975. package/scripts/gds/provision-config.js +5 -232
  976. package/scripts/gds/provision-core-upgrade.js +5 -1165
  977. package/scripts/gds/provision-disconnect.js +5 -87
  978. package/scripts/gds/provision-github-setup.js +5 -167
  979. package/scripts/gds/provision-net.js +5 -356
  980. package/scripts/gds/provision-pin-key.js +5 -175
  981. package/scripts/gds/provision-pin-replay.js +5 -125
  982. package/scripts/gds/provision-process.js +5 -169
  983. package/scripts/gds/provision-render.js +5 -200
  984. package/scripts/gds/provision-repo-auth.js +5 -163
  985. package/scripts/gds/provision-repo-private.js +5 -97
  986. package/scripts/gds/provision-repo.js +5 -1336
  987. package/scripts/gds/provision-teardown.js +5 -105
  988. package/scripts/gds/provision-units.js +5 -468
  989. package/scripts/gds/provision.js +5 -1477
  990. package/scripts/gds/publish-credential-check.js +6 -65
  991. package/scripts/gds/publish-integration-gate.js +5 -140
  992. package/scripts/gds/publish-manifest.js +5 -437
  993. package/scripts/gds/publish-watch.js +5 -266
  994. package/scripts/gds/pulse.js +6 -335
  995. package/scripts/gds/push-main.js +5 -54
  996. package/scripts/gds/push-path-brief.js +5 -98
  997. package/scripts/gds/read-session-export.js +5 -357
  998. package/scripts/gds/reauth.js +6 -154
  999. package/scripts/gds/recall.js +6 -182
  1000. package/scripts/gds/redteam-patrol.js +5 -435
  1001. package/scripts/gds/regen-instance-docs.js +5 -45
  1002. package/scripts/gds/release-core.js +5 -78
  1003. package/scripts/gds/release-notes.js +5 -270
  1004. package/scripts/gds/release.js +6 -138
  1005. package/scripts/gds/rename-goals.js +5 -107
  1006. package/scripts/gds/rename-history-check.js +5 -367
  1007. package/scripts/gds/rename-ledger-prose.js +5 -480
  1008. package/scripts/gds/render-api.js +5 -196
  1009. package/scripts/gds/render-check.js +5 -204
  1010. package/scripts/gds/render-ideas.js +6 -225
  1011. package/scripts/gds/render-payload.js +5 -84
  1012. package/scripts/gds/repo-metrics.js +6 -362
  1013. package/scripts/gds/review-sheet.js +5 -106
  1014. package/scripts/gds/role-pack-guard.js +5 -141
  1015. package/scripts/gds/route-shadow-guard.js +5 -173
  1016. package/scripts/gds/routine-schedule.js +5 -281
  1017. package/scripts/gds/run-routine.js +5 -255
  1018. package/scripts/gds/run-unit-tests.js +6 -659
  1019. package/scripts/gds/runner-drift.js +5 -149
  1020. package/scripts/gds/sandbox-stage.js +6 -458
  1021. package/scripts/gds/scope-map-guard.js +5 -299
  1022. package/scripts/gds/scope-roster-guard.js +5 -117
  1023. package/scripts/gds/seam-wiring-guard.js +5 -274
  1024. package/scripts/gds/search-ingest-db.js +6 -287
  1025. package/scripts/gds/search-ingest-md.js +6 -268
  1026. package/scripts/gds/seed-adopt-tasks.js +6 -74
  1027. package/scripts/gds/seed-api-contract-goal-tasks.js +6 -140
  1028. package/scripts/gds/seed-board-room-tasks.js +6 -196
  1029. package/scripts/gds/seed-bongos-app-tasks.js +6 -293
  1030. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +6 -80
  1031. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +6 -99
  1032. package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +6 -306
  1033. package/scripts/gds/seed-bongos-module-system-tasks.js +6 -345
  1034. package/scripts/gds/seed-bongos-tasks.js +6 -213
  1035. package/scripts/gds/seed-bongos-v1-idea-routing-tasks.js +6 -152
  1036. package/scripts/gds/seed-bongos-v1-seo-tasks.js +6 -104
  1037. package/scripts/gds/seed-bv1-community-tasks.js +6 -131
  1038. package/scripts/gds/seed-bv1-privacy-invites-tasks.js +6 -133
  1039. package/scripts/gds/seed-bv1-profile-page-tasks.js +6 -161
  1040. package/scripts/gds/seed-bv1-profiles-tasks.js +6 -135
  1041. package/scripts/gds/seed-bv1-r01-delta-tasks.js +6 -154
  1042. package/scripts/gds/seed-bv2-ideator-surface-tasks.js +6 -390
  1043. package/scripts/gds/seed-bv2-tweak-mode-tasks.js +6 -277
  1044. package/scripts/gds/seed-gds-v4-tasks.js +6 -623
  1045. package/scripts/gds/seed-governance-tasks.js +6 -339
  1046. package/scripts/gds/seed-medusa-tasks.js +6 -439
  1047. package/scripts/gds/seed-module-upstreaming.js +5 -217
  1048. package/scripts/gds/seed-productization-tasks.js +6 -234
  1049. package/scripts/gds/seed-project-admin-console-tasks.js +6 -88
  1050. package/scripts/gds/seed-provisioning-tasks.js +6 -82
  1051. package/scripts/gds/seed-staging.sh +7 -116
  1052. package/scripts/gds/seed-strict-versioning-tasks.js +6 -274
  1053. package/scripts/gds/seed-v2-world-tasks.js +6 -282
  1054. package/scripts/gds/seed-verify-criteria.js +6 -124
  1055. package/scripts/gds/sequence.js +6 -596
  1056. package/scripts/gds/session-cost.js +6 -429
  1057. package/scripts/gds/session-digest-build.js +6 -293
  1058. package/scripts/gds/session-digest.js +6 -199
  1059. package/scripts/gds/session-eval.js +6 -630
  1060. package/scripts/gds/session-transcript-build.js +6 -155
  1061. package/scripts/gds/session-transcript-upload.js +6 -29
  1062. package/scripts/gds/session.js +6 -403
  1063. package/scripts/gds/setup.js +6 -645
  1064. package/scripts/gds/ship-check.js +5 -85
  1065. package/scripts/gds/ship-deploy-target.js +5 -392
  1066. package/scripts/gds/ship-escalation.js +5 -166
  1067. package/scripts/gds/ship-finish.js +5 -419
  1068. package/scripts/gds/ship-flow.js +5 -1216
  1069. package/scripts/gds/ship-git.js +5 -99
  1070. package/scripts/gds/ship-grade-steps.js +5 -546
  1071. package/scripts/gds/ship-grade.js +5 -425
  1072. package/scripts/gds/ship-honesty.js +5 -312
  1073. package/scripts/gds/ship-io.js +5 -138
  1074. package/scripts/gds/ship-land.js +5 -1129
  1075. package/scripts/gds/ship-memory-sync.js +5 -248
  1076. package/scripts/gds/ship-merge-gate.js +5 -224
  1077. package/scripts/gds/ship-merge.js +5 -465
  1078. package/scripts/gds/ship-mode-ask.js +5 -137
  1079. package/scripts/gds/ship-mode-manual.js +5 -53
  1080. package/scripts/gds/ship-preflight-steps.js +5 -398
  1081. package/scripts/gds/ship-regen.js +5 -313
  1082. package/scripts/gds/ship-resume.js +5 -200
  1083. package/scripts/gds/ship-session-upload.js +5 -312
  1084. package/scripts/gds/ship-state.js +5 -109
  1085. package/scripts/gds/ship-surprise.js +5 -83
  1086. package/scripts/gds/ship-visual.js +5 -74
  1087. package/scripts/gds/ship.js +5 -380
  1088. package/scripts/gds/shipping-mode.js +5 -69
  1089. package/scripts/gds/skill-lint.js +5 -248
  1090. package/scripts/gds/skill-preflight.js +5 -359
  1091. package/scripts/gds/smoke-batch-claim.sh +7 -237
  1092. package/scripts/gds/smoke-batch-release.sh +7 -315
  1093. package/scripts/gds/smoke-claim-consistency.sh +7 -221
  1094. package/scripts/gds/smoke-dependencies.sh +7 -142
  1095. package/scripts/gds/smoke-gds.js +6 -255
  1096. package/scripts/gds/smoke-write.sh +7 -274
  1097. package/scripts/gds/source-text-test-scan.js +7 -0
  1098. package/scripts/gds/spark.js +6 -293
  1099. package/scripts/gds/stale-worktrees.js +5 -210
  1100. package/scripts/gds/start-goals.js +5 -101
  1101. package/scripts/gds/start.js +6 -1089
  1102. package/scripts/gds/status.js +6 -544
  1103. package/scripts/gds/strand-watch.js +5 -313
  1104. package/scripts/gds/stranded-rows.js +5 -198
  1105. package/scripts/gds/stray-unit-sweep.sh +7 -70
  1106. package/scripts/gds/surface.js +5 -100
  1107. package/scripts/gds/task.js +6 -272
  1108. package/scripts/gds/test-path-guard.js +5 -97
  1109. package/scripts/gds/triage.js +6 -741
  1110. package/scripts/gds/turn-end-sound.js +5 -72
  1111. package/scripts/gds/tweak-halt.js +5 -68
  1112. package/scripts/gds/tweak-renders.js +5 -198
  1113. package/scripts/gds/uat.js +6 -119
  1114. package/scripts/gds/ui-kit-transform.js +5 -41
  1115. package/scripts/gds/update-channel.js +5 -510
  1116. package/scripts/gds/update-sweep.js +5 -827
  1117. package/scripts/gds/upgrade-artist-gate.js +5 -45
  1118. package/scripts/gds/upgrade-commit-identity.js +5 -31
  1119. package/scripts/gds/upgrade-migrate.js +5 -223
  1120. package/scripts/gds/upgrade-operator.js +6 -73
  1121. package/scripts/gds/upgrade-outcome.js +5 -173
  1122. package/scripts/gds/upgrade.js +5 -1497
  1123. package/scripts/gds/validate-design.js +5 -10
  1124. package/scripts/gds/version-close.js +6 -620
  1125. package/scripts/gds/version-literal-guard.js +5 -138
  1126. package/scripts/gds/version-select.js +5 -77
  1127. package/scripts/gds/visual-review-nudge.js +5 -38
  1128. package/scripts/gds/wedge-remedy.js +5 -173
  1129. package/scripts/gds/worktree-claim-guard.js +5 -129
  1130. package/scripts/gds/worktree.js +6 -448
  1131. package/scripts/hall-preview/refresh-fixtures.js +1 -1
  1132. package/scripts/hall-preview/server.js +2 -2
  1133. package/scripts/migrate.sh +3 -3
  1134. package/scripts/public-mirror-export.js +3 -3
  1135. package/scripts/setup-builder.js +7 -7
  1136. package/src/bongos/api-errors.js +1 -0
  1137. package/src/bongos/api-prefix.js +1 -1
  1138. package/src/bongos/auth-github.js +19 -3
  1139. package/src/bongos/auth-idp.js +7 -0
  1140. package/src/bongos/claim-attribution.js +2 -2
  1141. package/src/bongos/core-moves.js +1 -1
  1142. package/src/bongos/core-update.js +3 -3
  1143. package/src/bongos/craft-mode.js +2 -2
  1144. package/src/bongos/db-kernel.js +15 -3
  1145. package/src/bongos/db.js +30 -4
  1146. package/src/bongos/github-repos.js +1 -1
  1147. package/src/bongos/llm-cache.js +1 -1
  1148. package/src/bongos/llm-pricing.js +1 -1
  1149. package/src/bongos/metrics.js +1 -1
  1150. package/src/bongos/middleware/rate-limit.js +2 -2
  1151. package/src/bongos/module-listing.js +93 -1
  1152. package/src/bongos/module-scope-map.js +90 -85
  1153. package/src/bongos/module-store.js +1 -1
  1154. package/src/bongos/module-submissions.js +1 -1
  1155. package/src/bongos/optimizer.js +1 -1
  1156. package/src/bongos/package-registry.js +1 -1
  1157. package/src/bongos/path-match.js +1 -1
  1158. package/src/bongos/permission-path-check.js +3 -3
  1159. package/src/bongos/platform-visibility-gate.js +3 -5
  1160. package/src/bongos/prelaunch-gate.js +7 -6
  1161. package/src/bongos/route-rank-check.js +2 -2
  1162. package/src/bongos/routes/auth.js +15 -2
  1163. package/src/bongos/routes/backup.js +1 -1
  1164. package/src/bongos/routes/builders.js +29 -1
  1165. package/src/bongos/routes/me.js +49 -18
  1166. package/src/bongos/routes/modules.js +29 -9
  1167. package/src/bongos/routes/public.js +3 -72
  1168. package/src/bongos/schema-lag.js +1 -1
  1169. package/src/bongos/sensitive-surfaces.js +1 -1
  1170. package/src/bongos/serve-internal.js +65 -16
  1171. package/src/bongos/software-update.js +2 -2
  1172. package/src/bongos/upgrade-hold.js +3 -3
  1173. package/src/hall-look.js +6 -5
  1174. package/src/module-api.js +3 -3
  1175. package/src/module-loader/catalog.js +1 -1
  1176. package/src/module-loader/error-tally.js +3 -3
  1177. package/src/module-loader/manifest-schema.js +3 -3
  1178. package/src/platform-server.js +10 -0
  1179. package/src/role-responsibilities.js +1 -1
  1180. package/src/stale-timer.js +2 -2
  1181. package/tests/accessibility_replay.mjs +1 -1
  1182. package/tests/activity_rollup_order_db.mjs +1 -1
  1183. package/tests/activity_snapshots_db.mjs +1 -1
  1184. package/tests/adopt_detect.mjs +1 -1
  1185. package/tests/adopt_import.mjs +1 -1
  1186. package/tests/adopt_preflight.mjs +1 -1
  1187. package/tests/adr_0089_scope.mjs +10 -7
  1188. package/tests/adr_0162_citation.mjs +1 -1
  1189. package/tests/adr_0162_gate_citation.mjs +1 -1
  1190. package/tests/agent_invoke.mjs +1 -1
  1191. package/tests/agent_invoke_live.mjs +3 -3
  1192. package/tests/agents_cron_trigger.mjs +2 -2
  1193. package/tests/agents_roster.mjs +1 -1
  1194. package/tests/agents_sync.mjs +4 -4
  1195. package/tests/allow_rule_guard.mjs +20 -20
  1196. package/tests/api_alias_caller_ratchet.mjs +9 -10
  1197. package/tests/api_alias_exceptions.mjs +7 -6
  1198. package/tests/api_artifacts.mjs +214 -0
  1199. package/tests/api_cli_flags.mjs +3 -3
  1200. package/tests/api_client.mjs +56 -54
  1201. package/tests/api_docs.mjs +30 -9
  1202. package/tests/api_error_envelope_buildcheck.mjs +1 -1
  1203. package/tests/api_msys_path_repair.mjs +2 -2
  1204. package/tests/architect.mjs +1 -1
  1205. package/tests/art_stage.mjs +2 -2
  1206. package/tests/artifact_audit.mjs +2 -2
  1207. package/tests/artifact_staleness.mjs +9 -9
  1208. package/tests/atlas.mjs +1 -1
  1209. package/tests/audit_deps.mjs +1 -1
  1210. package/tests/audit_gate.mjs +1 -1
  1211. package/tests/auth_flow_slice1.mjs +3 -3
  1212. package/tests/auth_inactive_builder.mjs +43 -5
  1213. package/tests/auth_session_expiry_db.mjs +16 -4
  1214. package/tests/auth_session_ttl.mjs +23 -0
  1215. package/tests/authorship_audit.mjs +2 -2
  1216. package/tests/autobongos_cadence.mjs +1 -1
  1217. package/tests/autobongos_fence.mjs +1 -1
  1218. package/tests/autobongos_grade_cap.mjs +2 -2
  1219. package/tests/autobongos_heartbeat_head.mjs +1 -1
  1220. package/tests/autobongos_host_access.mjs +3 -3
  1221. package/tests/autobongos_loop.mjs +17 -17
  1222. package/tests/autobongos_service_ps1.mjs +3 -3
  1223. package/tests/autobongos_tweak_lane.mjs +2 -2
  1224. package/tests/autobongos_verify.mjs +2 -2
  1225. package/tests/autonomous_fit_protected_paths.mjs +3 -3
  1226. package/tests/autonomy_config_idle.mjs +1 -1
  1227. package/tests/autonomy_digest.mjs +1 -1
  1228. package/tests/autonomy_gate.mjs +1 -1
  1229. package/tests/autonomy_gauge.mjs +2 -2
  1230. package/tests/autonomy_runner_identity.mjs +1 -1
  1231. package/tests/backfill_sessions.mjs +8 -8
  1232. package/tests/backfill_subagent_rewards.mjs +1 -1
  1233. package/tests/backfill_task_rewards.mjs +2 -2
  1234. package/tests/backlog_review.mjs +3 -3
  1235. package/tests/baseline_staleness.mjs +2 -2
  1236. package/tests/bfg.mjs +11 -5
  1237. package/tests/bfg_write.mjs +20 -11
  1238. package/tests/blockers_hall.mjs +14 -4
  1239. package/tests/blockers_page_ui.mjs +56 -12
  1240. package/tests/bongos_dispatch.mjs +5 -5
  1241. package/tests/bongos_login.mjs +2 -2
  1242. package/tests/bug_attachment_audit.mjs +1 -1
  1243. package/tests/bug_attachment_recover.mjs +2 -2
  1244. package/tests/bug_triage.mjs +3 -3
  1245. package/tests/build_info.mjs +1 -1
  1246. package/tests/builder_tester_tag.mjs +184 -0
  1247. package/tests/bump_version.mjs +3 -3
  1248. package/tests/canonical_profile_url.mjs +1 -1
  1249. package/tests/capture_error_format.mjs +1 -1
  1250. package/tests/capture_goal_routing.mjs +2 -2
  1251. package/tests/category_advisory_guard.mjs +3 -3
  1252. package/tests/claim_error_surface.mjs +2 -2
  1253. package/tests/claim_from_task_and_home.mjs +1 -1
  1254. package/tests/claim_gate_open_blocker.mjs +7 -4
  1255. package/tests/claim_gate_rebase.mjs +12 -8
  1256. package/tests/claim_recall.mjs +4 -4
  1257. package/tests/claim_resolve_worktree_lock.mjs +1 -1
  1258. package/tests/claude_materialize.mjs +58 -58
  1259. package/tests/clawback_confirmed_backlog.mjs +8 -5
  1260. package/tests/cli_allowlist_permissions.mjs +11 -11
  1261. package/tests/cli_dispatcher.mjs +2 -2
  1262. package/tests/cli_err_code.mjs +6 -6
  1263. package/tests/cli_exit_no_abort.mjs +7 -7
  1264. package/tests/cli_lib_formatters.mjs +2 -2
  1265. package/tests/cli_sessions.mjs +5 -5
  1266. package/tests/cli_surface.mjs +15 -15
  1267. package/tests/cli_token_reissue.mjs +2 -2
  1268. package/tests/client_baseurl_guard.mjs +1 -1
  1269. package/tests/client_bundle_route.mjs +35 -4
  1270. package/tests/cloud_bongos_pack.mjs +1 -1
  1271. package/tests/community_leaderboard_db.mjs +1 -1
  1272. package/tests/conductor.mjs +18 -18
  1273. package/tests/conflict_resolve.mjs +14 -16
  1274. package/tests/consumer_layout_boot.mjs +12 -12
  1275. package/tests/context_pack.mjs +6 -6
  1276. package/tests/control_manifest.mjs +4 -4
  1277. package/tests/copy_desk_page_reads.mjs +1 -1
  1278. package/tests/copy_desk_page_release.mjs +192 -0
  1279. package/tests/copy_inventory.mjs +2 -2
  1280. package/tests/core_auto_upgrade.mjs +1 -1
  1281. package/tests/core_move_notice.mjs +2 -2
  1282. package/tests/core_origin_follow.mjs +7 -7
  1283. package/tests/core_pin_sync.mjs +3 -3
  1284. package/tests/core_upgrade_door.mjs +2 -2
  1285. package/tests/core_upgrade_owner_door.mjs +34 -1
  1286. package/tests/core_upgrade_runner.mjs +19 -19
  1287. package/tests/credential_presence.mjs +2 -2
  1288. package/tests/credit_grant.mjs +3 -3
  1289. package/tests/credit_log_single_writer.mjs +5 -5
  1290. package/tests/criterion_ref_status.mjs +2 -2
  1291. package/tests/cross_discipline_priority_direction.mjs +3 -3
  1292. package/tests/cutover_codemod.mjs +2 -4
  1293. package/tests/db_backup_nightly.mjs +1 -1
  1294. package/tests/db_backup_offsite.mjs +1 -1
  1295. package/tests/db_ownership_handover.mjs +2 -2
  1296. package/tests/dead_deps.mjs +3 -3
  1297. package/tests/dependency_advisory.mjs +1 -1
  1298. package/tests/deploy_audit_gate.mjs +4 -4
  1299. package/tests/deploy_divergence_line.mjs +36 -16
  1300. package/tests/deploy_page_projects.mjs +35 -4
  1301. package/tests/dev_lib.mjs +2 -2
  1302. package/tests/dev_windows.mjs +2 -2
  1303. package/tests/diagram_facts_offset.mjs +1 -1
  1304. package/tests/diagram_repo_slug.mjs +1 -1
  1305. package/tests/diff_derived_signals.mjs +2 -2
  1306. package/tests/dns_preflight.mjs +2 -2
  1307. package/tests/do_api.mjs +3 -3
  1308. package/tests/doc_cli_guard.mjs +28 -28
  1309. package/tests/doc_comment_coverage.mjs +1 -1
  1310. package/tests/doc_control_claims.mjs +11 -11
  1311. package/tests/docs_entropy.mjs +2 -2
  1312. package/tests/docs_openapi_route.mjs +8 -6
  1313. package/tests/doctor_hooks.mjs +1 -1
  1314. package/tests/edit_hints.mjs +3 -2
  1315. package/tests/effective_visibility_predicate.mjs +3 -3
  1316. package/tests/env_knobs_neutral_prefix.mjs +13 -13
  1317. package/tests/exec_path_guard.mjs +4 -4
  1318. package/tests/executed_closure.mjs +18 -12
  1319. package/tests/file_map.mjs +1 -1
  1320. package/tests/find_untested.mjs +13 -13
  1321. package/tests/first_admin_bootstrap.mjs +1 -1
  1322. package/tests/fitness.mjs +16 -16
  1323. package/tests/fitness_gds_ratchet.mjs +2 -2
  1324. package/tests/fitness_installed_core.mjs +3 -3
  1325. package/tests/fitness_no_raw_nul.mjs +1 -1
  1326. package/tests/fitness_ratchets.mjs +3 -3
  1327. package/tests/fitness_scope_roster.mjs +2 -2
  1328. package/tests/fitness_two_root.mjs +8 -8
  1329. package/tests/fixtures/accessibility-replay.json +5 -5
  1330. package/tests/fixtures/grade-replay/recorded-panel-grades.json +1 -1
  1331. package/tests/fixtures/ideator-prefold/README.md +1 -1
  1332. package/tests/fixtures/page-ledger.mjs +22 -0
  1333. package/tests/fixtures/session-506-digest.json +5 -5
  1334. package/tests/gate_approvals.mjs +50 -0
  1335. package/tests/gate_review.mjs +8 -8
  1336. package/tests/gating_review_retired.mjs +2 -2
  1337. package/tests/gen_freshness.mjs +3 -3
  1338. package/tests/git_guard.mjs +3 -3
  1339. package/tests/git_merge_regen.mjs +41 -65
  1340. package/tests/github_one_trip.mjs +4 -4
  1341. package/tests/github_pick_up.mjs +2 -2
  1342. package/tests/github_push_merge_driver.mjs +1 -1
  1343. package/tests/go_live.mjs +3 -2
  1344. package/tests/goal_category.mjs +1 -1
  1345. package/tests/goal_cli.mjs +2 -2
  1346. package/tests/goal_create_spec_entry.mjs +1 -1
  1347. package/tests/goal_invite_consent.mjs +3 -1
  1348. package/tests/goal_move.mjs +1 -1
  1349. package/tests/goal_names.mjs +2 -2
  1350. package/tests/goal_working_area.mjs +1 -1
  1351. package/tests/government_agent_asks.mjs +7 -7
  1352. package/tests/government_board_room_copy.mjs +6 -1
  1353. package/tests/government_board_view.mjs +39 -0
  1354. package/tests/government_board_vote_ui.mjs +39 -1
  1355. package/tests/government_config.mjs +2 -2
  1356. package/tests/government_live_proof_shape.mjs +1 -1
  1357. package/tests/government_protected_surfaces.mjs +54 -53
  1358. package/tests/government_require_permission.mjs +9 -1
  1359. package/tests/government_vanilla_boot.mjs +1 -1
  1360. package/tests/government_vocabulary.mjs +2 -2
  1361. package/tests/government_walk.mjs +2 -2
  1362. package/tests/grade_body_limit.mjs +6 -4
  1363. package/tests/grade_correlation_audit.mjs +3 -3
  1364. package/tests/grade_diff_hash.mjs +1 -1
  1365. package/tests/grade_engine_replay.mjs +2 -2
  1366. package/tests/grade_server_authoritative.mjs +1 -1
  1367. package/tests/grade_unavailable_display.mjs +1 -1
  1368. package/tests/grader.mjs +8 -24
  1369. package/tests/grader_generated_provenance.mjs +14 -14
  1370. package/tests/grader_no_artifact.mjs +1 -1
  1371. package/tests/grader_prompt_fencing.mjs +1 -1
  1372. package/tests/grader_quality_window_overflow.mjs +1 -1
  1373. package/tests/grader_reader_lens.mjs +3 -3
  1374. package/tests/grader_regrade_delta.mjs +1 -1
  1375. package/tests/grader_unbacked_score.mjs +2 -2
  1376. package/tests/hall_acclaim_vote_control.mjs +113 -0
  1377. package/tests/hall_asset_cache.mjs +127 -0
  1378. package/tests/hall_audit.mjs +63 -0
  1379. package/tests/hall_board_world.mjs +20 -0
  1380. package/tests/hall_city_card_words.mjs +61 -0
  1381. package/tests/hall_client_request_shape.mjs +5 -1
  1382. package/tests/hall_home_ships_bounded.mjs +160 -0
  1383. package/tests/hall_landing_boot.mjs +15 -2
  1384. package/tests/hall_nav.mjs +33 -0
  1385. package/tests/hall_onboarding_bongos_setup.mjs +1 -1
  1386. package/tests/hall_oversight_world.mjs +44 -4
  1387. package/tests/hall_palette.mjs +12 -9
  1388. package/tests/hall_preview_security.mjs +1 -1
  1389. package/tests/hall_profile_world.mjs +17 -0
  1390. package/tests/hall_reading_world.mjs +16 -1
  1391. package/tests/hall_roster_world.mjs +2 -1
  1392. package/tests/hall_studio_world.mjs +4 -1
  1393. package/tests/hall_work_history_id.mjs +39 -0
  1394. package/tests/held_tweak_reporting.mjs +4 -4
  1395. package/tests/helpers.mjs +3 -3
  1396. package/tests/home_bounded_reads.mjs +1 -1
  1397. package/tests/home_isolation_guard.mjs +1 -1
  1398. package/tests/hook_core_resolve.mjs +7 -7
  1399. package/tests/hook_user_agents.mjs +1 -1
  1400. package/tests/hooks_drain.mjs +2 -2
  1401. package/tests/host_topology_skips.mjs +1 -1
  1402. package/tests/howto_guide.mjs +1 -1
  1403. package/tests/howto_moments.mjs +3 -3
  1404. package/tests/hub_account_page.mjs +1 -1
  1405. package/tests/idea_capture_grades.mjs +2 -2
  1406. package/tests/idea_develop_spark.mjs +1 -1
  1407. package/tests/idea_filed_via.mjs +2 -2
  1408. package/tests/idea_ideate_full.mjs +1 -1
  1409. package/tests/idea_spark_mark.mjs +1 -1
  1410. package/tests/idea_spark_queue.mjs +1 -1
  1411. package/tests/idea_triage.mjs +1 -1
  1412. package/tests/idea_triage_grade.mjs +3 -3
  1413. package/tests/idea_vote_permission.mjs +113 -0
  1414. package/tests/idea_votes_fold_db.mjs +123 -0
  1415. package/tests/infra_exec_paths.mjs +12 -12
  1416. package/tests/init.mjs +2 -2
  1417. package/tests/instance_db_migrated_on_code_move.mjs +5 -5
  1418. package/tests/instance_feedback.mjs +9 -9
  1419. package/tests/instance_mismatch_guard.mjs +2 -2
  1420. package/tests/integration_parked_ratchet.mjs +24 -2
  1421. package/tests/intent_retry.mjs +1 -1
  1422. package/tests/interaction_posture.mjs +3 -3
  1423. package/tests/invite_expiry_db.mjs +1 -1
  1424. package/tests/joinability_invite_only.mjs +1 -1
  1425. package/tests/karma_vote_lists.mjs +270 -0
  1426. package/tests/key-card.mjs +2 -2
  1427. package/tests/key-status.mjs +2 -2
  1428. package/tests/knip_ratchet_ambient.mjs +2 -2
  1429. package/tests/known_failing_ratchet.mjs +1 -1
  1430. package/tests/land_watch.mjs +2 -2
  1431. package/tests/landing_legal_pages.mjs +1 -1
  1432. package/tests/landing_page.mjs +2 -2
  1433. package/tests/leaderboard_roles.mjs +4 -1
  1434. package/tests/leak_scan_allowlist.mjs +8 -8
  1435. package/tests/leak_scan_fail_closed.mjs +1 -1
  1436. package/tests/lib_sh_resolution.mjs +9 -9
  1437. package/tests/lifecycle-card.mjs +7 -7
  1438. package/tests/linkify_check.mjs +2 -2
  1439. package/tests/linkify_refs.mjs +1 -1
  1440. package/tests/llm-cache-route.mjs +1 -1
  1441. package/tests/local_preview.mjs +2 -2
  1442. package/tests/main_audit.mjs +3 -3
  1443. package/tests/main_audit_attestation.mjs +1 -1
  1444. package/tests/main_audit_db_roster.mjs +2 -2
  1445. package/tests/main_worktree_busy_reason.mjs +3 -3
  1446. package/tests/markdown_line_endings.mjs +2 -2
  1447. package/tests/me_streak_leaderboard_queries.mjs +193 -0
  1448. package/tests/membership_kind_lockstep.mjs +1 -1
  1449. package/tests/memory_isolation.mjs +16 -8
  1450. package/tests/memory_map.mjs +2 -2
  1451. package/tests/memory_pull.mjs +33 -25
  1452. package/tests/merge_driver_register.mjs +3 -3
  1453. package/tests/migration_allocation.mjs +2 -2
  1454. package/tests/migration_namespace.mjs +1 -1
  1455. package/tests/migrations_forward_safe.mjs +1 -1
  1456. package/tests/mingle.mjs +1 -1
  1457. package/tests/mirror_lineage_fulltree.mjs +3 -3
  1458. package/tests/mirror_lineage_proof.mjs +2 -2
  1459. package/tests/mirror_redact.mjs +4 -4
  1460. package/tests/missing_dep_classify.mjs +3 -3
  1461. package/tests/module-scope-map.mjs +22 -22
  1462. package/tests/module_api_lazy.mjs +1 -1
  1463. package/tests/module_assess_docs.mjs +2 -2
  1464. package/tests/module_assess_installs.mjs +3 -3
  1465. package/tests/module_assess_price_parity.mjs +5 -5
  1466. package/tests/module_assess_score.mjs +5 -5
  1467. package/tests/module_assess_security.mjs +4 -4
  1468. package/tests/module_assess_tests.mjs +3 -3
  1469. package/tests/module_assessments_migration.mjs +1 -1
  1470. package/tests/module_catalog.mjs +2 -2
  1471. package/tests/module_cli.mjs +3 -3
  1472. package/tests/module_entitlements.mjs +1 -1
  1473. package/tests/module_error_counts.mjs +1 -1
  1474. package/tests/module_install.mjs +4 -4
  1475. package/tests/module_loader.mjs +3 -1
  1476. package/tests/module_owned_tests.mjs +1 -1
  1477. package/tests/module_release_channels.mjs +1 -1
  1478. package/tests/module_store_howto.mjs +3 -3
  1479. package/tests/module_store_listing.mjs +139 -2
  1480. package/tests/module_store_publish.mjs +4 -4
  1481. package/tests/module_store_publish_route.mjs +1 -1
  1482. package/tests/module_store_reassess.mjs +1 -1
  1483. package/tests/module_store_registry_migration.mjs +1 -1
  1484. package/tests/module_test_runner.mjs +3 -3
  1485. package/tests/module_update.mjs +4 -4
  1486. package/tests/module_upgrade_updates.mjs +1 -1
  1487. package/tests/move_escalation.mjs +2 -2
  1488. package/tests/nav_permission_atoms.mjs +3 -2
  1489. package/tests/needs_rebase.mjs +7 -3
  1490. package/tests/newcomer_floor.mjs +1 -1
  1491. package/tests/newcomer_generator.mjs +48 -0
  1492. package/tests/next_number.mjs +1 -1
  1493. package/tests/no_artifact_escalation.mjs +3 -3
  1494. package/tests/npm_release_where.mjs +1 -1
  1495. package/tests/oauth_secret.mjs +2 -2
  1496. package/tests/onboard.mjs +6 -6
  1497. package/tests/onboarding_gate.mjs +2 -2
  1498. package/tests/opt_in_skill_modules.mjs +3 -3
  1499. package/tests/own_scope_guard.mjs +1 -1
  1500. package/tests/own_session_revoke.mjs +4 -1
  1501. package/tests/package_core.mjs +10 -11
  1502. package/tests/page_inventory.mjs +5 -5
  1503. package/tests/page_reader.mjs +7 -7
  1504. package/tests/page_tweak_hold.mjs +6 -6
  1505. package/tests/parallel-load.mjs +1 -1
  1506. package/tests/paste_token_api_base.mjs +1 -1
  1507. package/tests/paste_token_session_store.mjs +2 -2
  1508. package/tests/pending_invite_purge_db.mjs +1 -1
  1509. package/tests/permission_path.mjs +1 -1
  1510. package/tests/pin_replay.mjs +1 -1
  1511. package/tests/pin_write_key.mjs +7 -7
  1512. package/tests/plain_cards.mjs +15 -15
  1513. package/tests/pr_assign.mjs +1 -1
  1514. package/tests/pre_push_hook.mjs +3 -3
  1515. package/tests/preflight_checks.mjs +2 -2
  1516. package/tests/prelaunch_gate.mjs +1 -1
  1517. package/tests/privacy_matrix.mjs +1 -1
  1518. package/tests/probe_cache.mjs +6 -6
  1519. package/tests/profile_connections_ui.mjs +4 -3
  1520. package/tests/profile_fields.mjs +11 -1
  1521. package/tests/profile_privacy_owner_view.mjs +1 -1
  1522. package/tests/profile_role_headline.mjs +10 -9
  1523. package/tests/project_admin_console_model.mjs +1 -1
  1524. package/tests/projects_hub.mjs +1 -1
  1525. package/tests/projects_hub_cloud_hop.mjs +1 -1
  1526. package/tests/promote_goal_id.mjs +6 -6
  1527. package/tests/promotion_sweep.mjs +1 -1
  1528. package/tests/provision.mjs +24 -24
  1529. package/tests/provision_account_identity.mjs +2 -2
  1530. package/tests/provision_byo_host.mjs +1 -1
  1531. package/tests/provision_caddy_wiring.mjs +2 -2
  1532. package/tests/provision_disconnect.mjs +2 -2
  1533. package/tests/provision_dns_first.mjs +1 -1
  1534. package/tests/provision_render.mjs +9 -9
  1535. package/tests/provision_repo_private.mjs +3 -3
  1536. package/tests/provision_resource_caps.mjs +5 -5
  1537. package/tests/provision_restart.mjs +3 -3
  1538. package/tests/provision_settings_apply.mjs +7 -7
  1539. package/tests/provision_teardown_address.mjs +2 -2
  1540. package/tests/provisioning_capacity.mjs +5 -5
  1541. package/tests/provisioning_credential_preflight.mjs +1 -1
  1542. package/tests/provisioning_disconnect.mjs +1 -1
  1543. package/tests/provisioning_error_note_scope.mjs +4 -4
  1544. package/tests/provisioning_paid_shape_gate.mjs +2 -2
  1545. package/tests/provisioning_planet_physics.mjs +16 -0
  1546. package/tests/provisioning_runner_drift_notice.mjs +2 -2
  1547. package/tests/provisioning_settings_env.mjs +1 -1
  1548. package/tests/pruned_lockfile_integrity.mjs +1 -1
  1549. package/tests/public_mirror_export.mjs +1 -1
  1550. package/tests/publish_integration_gate.mjs +2 -2
  1551. package/tests/publish_manifest.mjs +6 -6
  1552. package/tests/publish_watch.mjs +1 -1
  1553. package/tests/push_path_brief.mjs +2 -2
  1554. package/tests/raise.mjs +248 -0
  1555. package/tests/rank_roles_audit.mjs +1 -1
  1556. package/tests/rank_tier_single_source.mjs +2 -2
  1557. package/tests/rate_limit_public.mjs +1 -1
  1558. package/tests/read_default_meter.mjs +2 -2
  1559. package/tests/read_session_export.mjs +1 -1
  1560. package/tests/rebase_gate_set_aside.mjs +1 -1
  1561. package/tests/recall_cli.mjs +1 -1
  1562. package/tests/recall_corpus_health.mjs +3 -2
  1563. package/tests/recall_hints.mjs +1 -1
  1564. package/tests/recruiter_sliver_boundary.mjs +1 -1
  1565. package/tests/redteam_patrol.mjs +2 -2
  1566. package/tests/regrade_actual_minutes.mjs +2 -2
  1567. package/tests/regrade_eligibility.mjs +2 -2
  1568. package/tests/release_core.mjs +2 -2
  1569. package/tests/release_notes.mjs +4 -4
  1570. package/tests/rename_history_restraint.mjs +3 -3
  1571. package/tests/rename_ledger_prose.mjs +6 -6
  1572. package/tests/render_api.mjs +1 -1
  1573. package/tests/render_check.mjs +4 -4
  1574. package/tests/render_deploy.mjs +1 -1
  1575. package/tests/repo_info_binding.mjs +1 -1
  1576. package/tests/repo_map.mjs +5 -5
  1577. package/tests/reward_mode_cost_plus_only.mjs +7 -3
  1578. package/tests/reward_mode_surfacing.mjs +1 -1
  1579. package/tests/role_responsibilities.mjs +1 -1
  1580. package/tests/route_permission_check.mjs +1 -1
  1581. package/tests/route_shadow_guard.mjs +1 -1
  1582. package/tests/route_validation.mjs +1 -1
  1583. package/tests/routine_capture_kind.mjs +6 -6
  1584. package/tests/routine_schedule.mjs +9 -9
  1585. package/tests/run_routine.mjs +5 -5
  1586. package/tests/run_routine_two_root.mjs +5 -5
  1587. package/tests/runner_drift.mjs +17 -17
  1588. package/tests/sandbox_stage.mjs +5 -5
  1589. package/tests/scope_map_guard.mjs +7 -7
  1590. package/tests/scouting_owner_access_and_reach.mjs +1 -1
  1591. package/tests/scripts_gds_forwarders.mjs +224 -0
  1592. package/tests/scrubber_corpus.mjs +2 -2
  1593. package/tests/seam_wiring_guard.mjs +1 -1
  1594. package/tests/search_ingest.mjs +2 -2
  1595. package/tests/search_ingest_db.mjs +1 -1
  1596. package/tests/search_ingest_nul.mjs +6 -6
  1597. package/tests/seed_verify_criteria.mjs +3 -3
  1598. package/tests/sequence.mjs +3 -3
  1599. package/tests/served_paths_shipped.mjs +3 -3
  1600. package/tests/session_506_regression.mjs +1 -1
  1601. package/tests/session_accessibility.mjs +1 -1
  1602. package/tests/session_caps.mjs +1 -1
  1603. package/tests/session_cost.mjs +1 -1
  1604. package/tests/session_digest.mjs +2 -2
  1605. package/tests/session_eval.mjs +6 -6
  1606. package/tests/session_index.mjs +1 -1
  1607. package/tests/session_records.mjs +4 -4
  1608. package/tests/session_rename_fallback.mjs +2 -2
  1609. package/tests/session_reward_on_land.mjs +7 -149
  1610. package/tests/session_reward_on_land_db.mjs +191 -0
  1611. package/tests/session_reward_reconcile.mjs +6 -88
  1612. package/tests/session_reward_reconcile_db.mjs +132 -0
  1613. package/tests/session_transcript.mjs +1 -1
  1614. package/tests/sessions_kit_pager.mjs +2 -1
  1615. package/tests/setup_device_flow_fallback.mjs +2 -2
  1616. package/tests/setup_smoke.mjs +12 -5
  1617. package/tests/setup_status_facts.mjs +54 -12
  1618. package/tests/ship_autolinkify.mjs +2 -2
  1619. package/tests/ship_automerge_injection.mjs +1 -1
  1620. package/tests/ship_base_flag.mjs +1 -1
  1621. package/tests/ship_broadcast_routing.mjs +1 -1
  1622. package/tests/ship_broadcast_server.mjs +2 -2
  1623. package/tests/ship_builder_model.mjs +1 -1
  1624. package/tests/ship_cannot_lie.mjs +9 -9
  1625. package/tests/ship_card.mjs +2 -2
  1626. package/tests/ship_ci_deploy.mjs +7 -7
  1627. package/tests/ship_error_shape.mjs +1 -1
  1628. package/tests/ship_land_ci_not_started.mjs +3 -3
  1629. package/tests/ship_land_conflict.mjs +3 -3
  1630. package/tests/ship_land_proof.mjs +3 -3
  1631. package/tests/ship_land_red_pr.mjs +5 -5
  1632. package/tests/ship_merge_gate.mjs +14 -14
  1633. package/tests/ship_mode.mjs +1 -1
  1634. package/tests/ship_mode_first_ship.mjs +4 -4
  1635. package/tests/ship_mode_hands_off.mjs +8 -8
  1636. package/tests/ship_post_land_verify.mjs +1 -1
  1637. package/tests/ship_preflight.mjs +19 -19
  1638. package/tests/ship_premerge.mjs +1 -1
  1639. package/tests/ship_publish_error.mjs +2 -2
  1640. package/tests/ship_push_diagnosis.mjs +1 -1
  1641. package/tests/ship_regen_copy_inventory.mjs +3 -3
  1642. package/tests/ship_resume.mjs +4 -4
  1643. package/tests/ship_smoke_gate.mjs +1 -1
  1644. package/tests/ship_upload_skip.mjs +1 -1
  1645. package/tests/ship_upstream_deletion.mjs +1 -1
  1646. package/tests/ship_vendored_instance.mjs +8 -8
  1647. package/tests/ship_visual_regrade.mjs +3 -3
  1648. package/tests/ship_zero_commit.mjs +1 -1
  1649. package/tests/skill_docs_unavailable_regrade.mjs +3 -3
  1650. package/tests/skill_friction_kind.mjs +1 -1
  1651. package/tests/skill_grade_recover.mjs +1 -1
  1652. package/tests/skill_grader_health.mjs +1 -1
  1653. package/tests/skill_lint.mjs +1 -1
  1654. package/tests/skill_menu_ruling.mjs +1 -1
  1655. package/tests/skill_preflight.mjs +7 -7
  1656. package/tests/skip_is_not_pass.mjs +22 -1
  1657. package/tests/smoke_dependencies_witness.mjs +2 -2
  1658. package/tests/smoke_preflight.mjs +1 -1
  1659. package/tests/smoke_target.mjs +2 -2
  1660. package/tests/smoke_write_contract.mjs +2 -2
  1661. package/tests/sound_player.mjs +8 -8
  1662. package/tests/source_text_test_ratchet.mjs +97 -0
  1663. package/tests/speciality_corpus_scope.mjs +1 -1
  1664. package/tests/speciality_session_skills.mjs +1 -1
  1665. package/tests/sso_checkin_legacy_field_gone.mjs +4 -2
  1666. package/tests/stale_timer.mjs +3 -3
  1667. package/tests/stale_worktrees.mjs +1 -1
  1668. package/tests/start_env_guard.mjs +1 -1
  1669. package/tests/start_goal_first.mjs +3 -3
  1670. package/tests/start_inbox_count.mjs +1 -1
  1671. package/tests/start_rebase_warning.mjs +1 -1
  1672. package/tests/status_default_version.mjs +3 -3
  1673. package/tests/status_mirror_sync.mjs +1 -1
  1674. package/tests/status_page_no_dead_uptime.mjs +80 -0
  1675. package/tests/stop_refcheck.mjs +1 -1
  1676. package/tests/strand_watch.mjs +1 -1
  1677. package/tests/stranded_rows.mjs +1 -1
  1678. package/tests/stuck_detector.mjs +14 -14
  1679. package/tests/sweep_app_account.mjs +3 -3
  1680. package/tests/task_cli.mjs +2 -2
  1681. package/tests/task_detail_ui.mjs +11 -1
  1682. package/tests/task_discipline_required.mjs +2 -2
  1683. package/tests/task_list_paging.mjs +1 -1
  1684. package/tests/task_visual_slots.mjs +2 -2
  1685. package/tests/terms_acceptance.mjs +1 -1
  1686. package/tests/terms_grandfather_db.mjs +1 -1
  1687. package/tests/test_path_guard.mjs +1 -1
  1688. package/tests/triage_development.mjs +1 -1
  1689. package/tests/tweak_batch_apply.mjs +2 -2
  1690. package/tests/tweak_land_heal.mjs +3 -3
  1691. package/tests/tweak_unattended.mjs +3 -3
  1692. package/tests/ui_design_skills.mjs +2 -2
  1693. package/tests/unit_report_status.mjs +2 -2
  1694. package/tests/unit_runner_serial.mjs +2 -2
  1695. package/tests/unit_runner_teardown_abort.mjs +1 -1
  1696. package/tests/update_channel.mjs +2 -2
  1697. package/tests/update_channel_db.mjs +4 -4
  1698. package/tests/update_subscription_engine.mjs +26 -26
  1699. package/tests/update_sweep_home.mjs +14 -14
  1700. package/tests/upgrade.mjs +11 -11
  1701. package/tests/upgrade_artist_gate.mjs +4 -4
  1702. package/tests/upgrade_commit_identity.mjs +2 -2
  1703. package/tests/upgrade_migrate.mjs +7 -7
  1704. package/tests/upgrade_operator.mjs +2 -2
  1705. package/tests/upgrade_outcome.mjs +2 -2
  1706. package/tests/upgrade_persist_pin.mjs +5 -5
  1707. package/tests/upkeep_home.mjs +1 -1
  1708. package/tests/version_close.mjs +2 -2
  1709. package/tests/version_close_cli.mjs +2 -2
  1710. package/tests/version_close_route.mjs +1 -1
  1711. package/tests/version_literals.mjs +23 -23
  1712. package/tests/visual_review.mjs +5 -5
  1713. package/tests/wedge_remedy.mjs +5 -5
  1714. package/tests/welcome_boot.mjs +116 -0
  1715. package/tests/welcome_boot_browser.mjs +271 -0
  1716. package/tests/wizard_born_first_board.mjs +3 -3
  1717. package/tests/wizard_demo.mjs +1 -1
  1718. package/tests/wizard_one_page.mjs +4 -3
  1719. package/tests/wizard_physics.mjs +3 -1
  1720. package/tests/wizard_physics_more.mjs +42 -3
  1721. package/tests/work_title_wrap.mjs +1 -1
  1722. package/tests/workflow_exec_paths.mjs +6 -6
  1723. package/tests/worktree_claim_guard.mjs +1 -1
  1724. package/tests/worktree_helper.mjs +2 -2
  1725. package/tests/write_validation_gaps.mjs +3 -3
  1726. package/scripts/gds/api.sh +0 -6
  1727. package/scripts/gds/audit-exports.js +0 -128
  1728. package/scripts/gds/resolve-skill-model.js +0 -57
  1729. package/scripts/gds/security-baseline-check.sh +0 -180
  1730. package/scripts/gds/spike-task-map.js +0 -899
  1731. package/scripts/status-probe.mjs +0 -213
  1732. package/src/bongos/uptime-poller.js +0 -93
  1733. package/tests/government_fold_bench.mjs +0 -50
  1734. package/tests/spike_task_map.mjs +0 -422
  1735. package/tests/status-probe.mjs +0 -89
  1736. /package/{scripts/gds → modules/raise}/CLAUDE.md +0 -0
  1737. /package/scripts/{gds → bongos}/cloudbongos-token-isolation.conf +0 -0
  1738. /package/scripts/{gds → bongos}/discipline-modes.json +0 -0
  1739. /package/scripts/{gds → bongos}/retired-core-skills.json +0 -0
@@ -1,1495 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ // scripts/gds/fitness.js — @bongos-forwarder (task 1004848). Generated by
3
+ // scripts/bongos/codemod-rename-scripts-gds.js; do not edit.
4
+ // The real script is scripts/bongos/fitness.js. This forwarder keeps callers that still name
5
+ // the old path working, and warns once so they get repointed. Task 1003706 removes it.
2
6
  'use strict';
3
- // fitness.js — architecture fitness functions (Path C / ADR 0062 §9, task 1225).
4
- //
5
- // The ENFORCEMENT layer for the Cloud Bongos decoupling. A dependency-cruiser/ArchUnit-style gate that
6
- // keeps the architecture from silently rotting back together. Each check is a pure function over
7
- // the repo on disk returning { name, ok, hardFail, violations[], warnings[], note }. The CLI runs
8
- // them all, prints a report, and exits non-zero on any hard failure. tests/fitness.mjs asserts
9
- // each check passes, so the DB-free unit gate (run-unit-tests.js → the `unit` required check)
10
- // enforces them on every PR — no new workflow needed.
11
- //
12
- // RATCHET, not big-bang. The structural epics that physically separate the core (R51 entrypoint
13
- // #1190, R52 DB carve-out #1191, R54 module system #1193) are not built yet, so the codebase is
14
- // still fused (every src/bongos/*.js shares the game's pg Pool via require('../db')). These checks
15
- // therefore lock in the boundary DIRECTION now and fail only on NEW violations beyond a documented
16
- // grandfather list; as the epics land they SHRINK the grandfather list. Module-level boundary
17
- // enforcement (§4) tightens once R54 (#1193) gives us a module manifest to check against.
18
- //
19
- // Usage:
20
- // node scripts/gds/fitness.js # run all checks, print report, exit 1 on any hard failure
21
- // node scripts/gds/fitness.js --json # machine-readable report
22
-
23
- const fs = require('node:fs');
24
- const path = require('node:path');
25
- const { execFileSync } = require('node:child_process');
26
- const { checkRankGuards, checkModulePinKeysResolve } = require('./fitness-checks-route-pins.js'); // Checks 4 + 4b — carved out by task 1003192 (the 1,500-line ratchet)
27
- const genApiDocs = require('./gen-api-docs'); // R12 (#1999): reuse the route model (readsBody/validated) that drives the OpenAPI spec
28
- const { parseRoutineFrontmatter } = require('./run-routine'); // System 4 (ADR 0078): deterministic-routine boundary
29
- const { filenameViolation, stemCollisions, numberCollisions, CORE_NS, INSTANCE_NS } = require('./migration-namespace'); // ADR 0108 §5: cross-repo migration namespacing
30
- const { resolveCoreRoot, resolveInstanceRoot } = require('../../src/instance-config'); // ADR 0108 §1: configurable-root
31
-
32
- // task 1003206 (goal 1000079): fitness.js was 2,004 lines. Four cohesive pieces now
33
- // live beside it — the shared roots/walkers and three check clusters. They are
34
- // IMPORTED (not registered by path) so the CHECKS array and module.exports below
35
- // stay byte-identical to the single-file version every test was written against.
36
- const { CORE_ROOT, INSTANCE_ROOT, MODULE_ROOTS, REPO_ROOT, keyTokenRe, rel, runChecks, walkJs, walkJsAllRoots } = require('./fitness-lib.js');
37
- const { IDENTITY_SCAN_ALLOWED, IDENTITY_SCAN_EXCLUDE, IDENTITY_SCAN_EXTRA_FILES, IDENTITY_SCAN_EXTS, IDENTITY_SCAN_ROOTS, IDENTITY_SCAN_SKIP_DIRS, PROMPT_IDENTITY_LITERALS, checkDesignContract, checkKernelPromptsNoHardcodedIdentity, checkNeutralConfigsNoHostIdentity, collectIdentityFiles, scanPromptIdentity, stripCommentsForIdentity } = require('./fitness-checks-identity.js');
38
- const { WRITE_VALIDATION_BASELINE, WRITE_VALIDATION_EXEMPT, checkWriteRoutesValidated, scanUnvalidatedWriteRoutes } = require('./fitness-checks-write-validation.js');
39
- const { GOAL_VOCAB_CITATION, GOAL_VOCAB_LINE_SCOPED, GOAL_VOCAB_SURFACE, LIFECYCLE_DB_FILES, PRELAUNCH_SURFACE, RENAME_IDENTITY_RE, VOCAB_ALLOW, VOCAB_BANNED, VOCAB_CITATION, VOCAB_EXTS, VOCAB_HISTORICAL_REF, VOCAB_SURFACE, checkGoalMembershipVocabulary, checkGovernmentRenameIdentity, checkPrelaunchVocabulary, checkVocabularyWall, vocabFilesToScan } = require('./fitness-checks-vocabulary.js');
40
- const { checkCoreRequiresExcludedConfig, checkCoreRequiresExcludedModule } = require('./fitness-checks-packaging.js'); // Checks 16 + 16b — carved out by task 1003825 (the 1,500-line ratchet)
41
- const { FLAT_ERROR_BASELINE, checkErrorEnvelope, countFlatErrors, scanFlatErrorSites } = require('./fitness-checks-error-envelope.js'); // Check 17 — carved out by task 1003825
42
- // ============================================================================
43
- // Check 1 — core ↔ host/game import boundary (ADR 0062 §1 cut-line)
44
- // ============================================================================
45
- //
46
- // The portable core (src/bongos/) must not import the HOST GAME runtime. After BV1.R49 the game
47
- // module lives in modules/game/ (rooms, world, db, seats, public, migrations). The only game-
48
- // related file that stays in src/ is src/preview-server.js (the game-only sandbox entrypoint).
49
- // Imports into scripts/ (build tooling / engine) are NOT host-game coupling.
50
- const HOST_GAME = [
51
- /^modules\/game\//, // everything in the game module (moved from src/ by BV1.R49)
52
- /^src\/preview-server\.js$/, // game-only sandbox entrypoint (stays in src/)
53
- ];
54
- // Empty as of R52/#1191 — the core owns its pool (src/bongos/pool.js) and no longer imports the
55
- // game's db helper. The boundary now enforces with ZERO grandfathered exceptions.
56
- const GRANDFATHERED = new Set([]);
57
- const REQUIRE_RE = /require\(\s*['"](\.\.?\/[^'"]+)['"]\s*\)/g;
58
-
59
- function resolvesToHostGame(fromAbsFile, spec) {
60
- const abs = path.resolve(path.dirname(fromAbsFile), spec);
61
- const r = rel(abs);
62
- for (const cand of [r, r + '.js', r.replace(/\/$/, '') + '/index.js']) {
63
- if (GRANDFATHERED.has(cand)) return null; // allowed (and not a violation)
64
- if (HOST_GAME.some((re) => re.test(cand))) return cand;
65
- }
66
- return null;
67
- }
68
-
69
- function checkCoreHostBoundary() {
70
- const coreDir = path.join(REPO_ROOT, 'src', 'bongos');
71
- const violations = [];
72
- for (const abs of walkJs(coreDir)) {
73
- // scan line-by-line, skipping comment lines so a require(...) quoted in a doc comment
74
- // (e.g. explaining the boundary) is never mistaken for a real import.
75
- for (const raw of fs.readFileSync(abs, 'utf8').split('\n')) {
76
- const trimmed = raw.trim();
77
- if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) continue;
78
- let m;
79
- REQUIRE_RE.lastIndex = 0;
80
- while ((m = REQUIRE_RE.exec(raw))) {
81
- const target = resolvesToHostGame(abs, m[1]);
82
- if (target) violations.push(`${rel(abs)} → require('${m[1]}') reaches host-game code (${target}) — the core must not import the game runtime (ADR 0062 §1).`);
83
- }
84
- }
85
- }
86
- return {
87
- name: 'core↔host import boundary',
88
- ok: violations.length === 0,
89
- hardFail: violations.length > 0,
90
- violations,
91
- warnings: [],
92
- note: `src/bongos/ must not import the host game runtime (grandfathered: ${[...GRANDFATHERED].join(', ') || 'none'} — severed by R52/#1191).`,
93
- };
94
- }
95
-
96
- // ============================================================================
97
- // Check 2 — root CLAUDE.md size budget + charter presence (ADR 0061)
98
- // ============================================================================
99
- const ROOT_HARD_MAX = 300; // ceiling: the always-loaded file must never balloon past this. Ratcheted
100
- // 360→310 when task 1226 generated the §13 session-log index (was a ~58-line
101
- // hand-maintained list), then 310→300 when task 1283 trimmed the quick-nav
102
- // table + §2/§8/§9/§10/§12 verbose prose down to ~294 lines. Lower further as
103
- // more detail relocates to nested docs / ADRs (ADR 0061).
104
- const ROOT_TARGET = 200; // the charter's stated aim; keep ratcheting toward it.
105
-
106
- // The line count is a structure/readability proxy; the cost paid EVERY session is
107
- // characters/tokens. A 600-char quick-nav row is one line but ~150 tokens, so
108
- // within-line bloat slips past ROOT_HARD_MAX entirely (exactly what task 1283
109
- // trimmed). Guard the real cost too (task 1286). Ratcheted just above the
110
- // post-1283 size (~39.5K chars / ~9.9K tok); lower alongside ROOT_HARD_MAX as
111
- // detail relocates to nested docs / ADRs.
112
- const ROOT_CHAR_HARD_MAX = 42000; // ~10.5K tokens — the always-loaded file must never balloon past this.
113
- const ROOT_CHAR_TARGET = 32000; // ~8K tokens — aspirational, mirrors the ~200-line aim.
114
- const estTokens = (n) => Math.round(n / 4); // ~4 chars/token for markdown prose.
115
-
116
- // Where the charter BODY lives since task 1003687. It is guidance for EDITING a
117
- // CLAUDE.md, so it is paths-scoped (`paths:` frontmatter, same mechanism as
118
- // .claude/rules/hook-authoring.md) and costs nothing in the sessions — the large
119
- // majority — that never open one. The kernel keeps the heading and a pointer.
120
- const CHARTER_RULE_REL = '.claude/rules/claudemd-authoring.md';
121
-
122
- function checkClaudeMdBudget(opts = {}) {
123
- const p = path.join(INSTANCE_ROOT, 'CLAUDE.md'); // the root CLAUDE.md is INSTANCE content (materialized per instance; ADR 0108)
124
- const text = opts.text != null ? opts.text : fs.readFileSync(p, 'utf8');
125
- const lines = text.split('\n').length;
126
- const violations = [];
127
- const warnings = [];
128
- if (lines > ROOT_HARD_MAX) {
129
- violations.push(`CLAUDE.md is ${lines} lines — over the ${ROOT_HARD_MAX}-line hard ceiling. It loads in full every session; relocate detail to a nested CLAUDE.md / ADR / recipe (ADR 0061).`);
130
- } else if (lines > ROOT_TARGET) {
131
- warnings.push(`CLAUDE.md is ${lines} lines — over the ~${ROOT_TARGET}-line target (still under the ${ROOT_HARD_MAX} ceiling). Relocate more detail to nested CLAUDE.md / ADRs / recipes (ADR 0061), then lower ROOT_HARD_MAX as it shrinks.`);
132
- }
133
- const chars = text.length;
134
- const tok = estTokens(chars);
135
- if (chars > ROOT_CHAR_HARD_MAX) {
136
- violations.push(`CLAUDE.md is ${chars} chars (~${tok} tokens) — over the ${ROOT_CHAR_HARD_MAX}-char (~${estTokens(ROOT_CHAR_HARD_MAX)}-token) hard ceiling. The line count may be fine, but the per-session token cost is not — trim verbose prose WITHIN lines (long quick-nav rows, restated rationale), not just whole lines (ADR 0061).`);
137
- } else if (chars > ROOT_CHAR_TARGET) {
138
- warnings.push(`CLAUDE.md is ${chars} chars (~${tok} tokens) — over the ~${ROOT_CHAR_TARGET}-char (~${estTokens(ROOT_CHAR_TARGET)}-token) target. This is the true per-session cost; within-line bloat (a 600-char table row is one line) escapes the line check. Trim prose, then lower ROOT_CHAR_HARD_MAX.`);
139
- }
140
- if (!text.includes('## Working with this file (content charter)')) {
141
- violations.push('CLAUDE.md is missing the content-charter section (ADR 0061) — the per-line test + "what goes where" table must stay.');
142
- } else {
143
- // Task 1003687 relocated the charter BODY to a paths-scoped rule, so the kernel
144
- // keeps the heading and a pointer. That makes the heading cheap to fake: a section
145
- // with nothing behind it satisfies a substring check while the rules it names are
146
- // gone. So the charter must resolve to something — either inline here, or through a
147
- // pointer whose target actually exists and still carries the two rules + the table.
148
- const namesRule = text.includes(CHARTER_RULE_REL);
149
- const inlineCharter = text.includes('Per-line test:');
150
- if (namesRule) {
151
- const rulePath = path.join(INSTANCE_ROOT, CHARTER_RULE_REL); // .claude/ is materialized INSTANCE content (ADR 0108 §3)
152
- if (!fs.existsSync(rulePath)) {
153
- violations.push(`CLAUDE.md points its content charter at ${CHARTER_RULE_REL}, but that file does not exist — a pointer to nothing is worse than no pointer (ADR 0061 / task 1003687).`);
154
- } else {
155
- const rule = fs.readFileSync(rulePath, 'utf8');
156
- const missing = [];
157
- if (!/^---\r?\n[\s\S]*?\bpaths:[\s\S]*?["']\*\*\/CLAUDE\.md["'][\s\S]*?^---$/m.test(rule)) {
158
- missing.push('`paths:` frontmatter matching `**/CLAUDE.md` (without it the rule never loads, and the charter is simply gone)');
159
- }
160
- if (!rule.includes('Per-line test:')) missing.push('the per-line test');
161
- if (!rule.includes('## What goes where')) missing.push('the "what goes where" table');
162
- if (missing.length) {
163
- violations.push(`${CHARTER_RULE_REL} is missing ${missing.join(', ')} — the kernel delegates the charter to it, so the charter is only as real as that file (ADR 0061 / task 1003687).`);
164
- }
165
- }
166
- } else if (!inlineCharter) {
167
- violations.push('The CLAUDE.md content-charter section is hollow — it has the heading but neither the per-line test inline nor a pointer to `' + CHARTER_RULE_REL + '`. The heading exists to make the rules findable; on its own it only satisfies this check (ADR 0061).');
168
- }
169
- }
170
- return { name: 'root CLAUDE.md budget + charter', ok: violations.length === 0, hardFail: violations.length > 0, violations, warnings, note: `≤ ${ROOT_HARD_MAX} lines / ${ROOT_CHAR_HARD_MAX} chars (~${estTokens(ROOT_CHAR_HARD_MAX)} tok); targets ~${ROOT_TARGET} lines / ~${estTokens(ROOT_CHAR_TARGET)} tok; charter resolves (inline or via ${CHARTER_RULE_REL}).` };
171
- }
172
-
173
- // ============================================================================
174
- // Check 3 — nested per-module CLAUDE.md presence for high-traffic dirs (ADR 0061)
175
- // ============================================================================
176
- const HIGH_TRAFFIC = ['src/bongos', 'src/bongos/routes', 'scripts/gds'];
177
-
178
- function checkNestedDocsPresent() {
179
- const violations = [];
180
- for (const dir of HIGH_TRAFFIC) {
181
- // HIGH_TRAFFIC dirs (src/bongos, src/bongos/routes, scripts/gds) are CORE-package dirs — resolve
182
- // against the core root, not the instance repo (ADR 0108 §Consequences #4).
183
- const doc = path.join(CORE_ROOT, dir, 'CLAUDE.md');
184
- if (!fs.existsSync(doc)) violations.push(`${dir}/CLAUDE.md is missing — high-traffic dirs must carry a nested altitude map (ADR 0061).`);
185
- }
186
- return { name: 'nested CLAUDE.md presence', ok: violations.length === 0, hardFail: violations.length > 0, violations, warnings: [], note: `present for: ${HIGH_TRAFFIC.join(', ')}.` };
187
- }
188
-
189
- // ============================================================================
190
- // Check 5 — generated artifacts are fresh (Path C enforces Path B; ADR 0063 + ADR 0062 §8)
191
- // ============================================================================
192
- // Deterministic file-reads with a `--check` mode (regenerate in-memory, diff, exit non-zero on
193
- // drift). This gate fails a PR that committed a stale artifact so the "generate, don't hand-maintain"
194
- // contract can't rot.
195
- // ADR 0110 (task 1926): docs/repo-map.md + docs/session-log-index.md are now GITIGNORED and
196
- // regenerated at deploy/box-fetch (the gen-atlas.js model), so parallel branches never collide on
197
- // them — and there is no committed copy to gate. Their generators are DUAL-DUTY, though: each also
198
- // refreshes a TRACKED embedded block (the nested CLAUDE.md symbol blocks; the CLAUDE.md §13 snippet).
199
- // Those blocks stay committed, so we gate the BLOCK bucket HARD via `--check-block`. A naive `--check`
200
- // here would false-fail every PR (the gitignored whole file is absent from a clean checkout, so it
201
- // always reads as "would change"); `--check-block` is the exact, non-noisy gate. (docs/file-map.md +
202
- // the OpenAPI docs are still fully committed and unchanged by ADR 0110 — they keep the plain --check.)
203
- function checkGeneratedArtifactsFresh() {
204
- const violations = [];
205
- try {
206
- execFileSync(process.execPath, [path.join(__dirname, 'gen-repo-map.js'), '--check-block'], { cwd: REPO_ROOT, stdio: 'pipe' });
207
- } catch {
208
- violations.push('The tracked nested-doc symbol blocks (src/bongos/CLAUDE.md, src/bongos/routes/CLAUDE.md) are STALE — run `node scripts/gds/gen-repo-map.js` and commit (ADR 0063 / ADR 0110). NB docs/repo-map.md itself is gitignored + deploy-regenerated, not gated here.');
209
- }
210
- try {
211
- execFileSync(process.execPath, [path.join(__dirname, 'gen-session-index.js'), '--check-block'], { cwd: REPO_ROOT, stdio: 'pipe' });
212
- } catch {
213
- violations.push('The tracked CLAUDE.md §13 recent-sessions snippet is STALE — run `node scripts/gds/gen-session-index.js` and commit (ADR 0062 §8 / ADR 0110). NB docs/session-log-index.md itself is gitignored + deploy-regenerated, not gated here.');
214
- }
215
- try {
216
- // task 1002515 (criterion `accessibility-fluency-profile`, clause 2): the CLAUDE.md §2
217
- // fallback posture is generated from the interaction knob's own defaults, so the kernel
218
- // and modules/builder-settings/interaction-prefs.js cannot drift into two copies of one
219
- // rule — which is what they were. Fully tracked (unlike the ADR 0110 pair above), so a
220
- // plain --check is the right gate.
221
- execFileSync(process.execPath, [path.join(__dirname, 'gen-interaction-posture.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
222
- } catch {
223
- violations.push('The CLAUDE.md §2 interaction-posture block is STALE — it is generated from modules/builder-settings/interaction-prefs.js. Run `node scripts/gds/gen-interaction-posture.js` and commit (task 1002515).');
224
- }
225
- try {
226
- execFileSync(process.execPath, [path.join(__dirname, 'gen-file-map.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
227
- } catch {
228
- violations.push('docs/file-map.md generated sections (.claude/skills/, .claude/scheduled-tasks/) are STALE, a skill/routine has no note in docs/file-map.notes.json, or a directory under modules/ has no file-map entry at all — run `node scripts/gds/gen-file-map.js --check` for the exact list, then fix and commit (ADR 0066; module coverage: task 1004066).');
229
- }
230
- try {
231
- // Also structurally validates the spec (exit 1 on invalid OpenAPI 3.1) beyond the drift check (exit 2). Task 1918.
232
- execFileSync(process.execPath, [path.join(__dirname, 'gen-api-docs.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
233
- } catch {
234
- violations.push('docs/api/openapi.json + docs/api-reference.md + docs/routes-permissions.md are STALE (or the spec is not valid OpenAPI 3.1) — run `node scripts/gds/gen-api-docs.js` and commit (task 1918).');
235
- }
236
- try {
237
- // task 1003556: the copy registry's rows carry LINE NUMBERS, so editing any scanned
238
- // UI file stales it. It was covered only by ship-check's OPTIONAL step, which a
239
- // builder has to remember to run — so the first signal was CI failing on the PR's
240
- // MERGE ref, where the shift is hardest to attribute. Gated here so a local fitness
241
- // run says so first.
242
- execFileSync(process.execPath, [path.join(__dirname, 'copy-inventory.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
243
- } catch {
244
- violations.push('docs/copy-registry.json + docs/copy-inventory.md are STALE — every row carries a line number, so editing any scanned UI file shifts them. Run `node scripts/gds/copy-inventory.js` and commit (task 1003556).');
245
- }
246
- try {
247
- // task 1004314 (BV2.TW02): the page inventory is the key Tweak Mode's page status,
248
- // claims and pay join on, so a page added, renamed or retitled without it would
249
- // be a page the chain cannot see. --check also fails on a duplicate or malformed id.
250
- execFileSync(process.execPath, [path.join(__dirname, 'page-inventory.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
251
- } catch {
252
- violations.push('docs/page-inventory.json + docs/page-inventory.md are STALE (or two pages claim one id) — a page was added, renamed, retitled or changed its scripts/states. Run `node scripts/gds/page-inventory.js` and commit (task 1004314).');
253
- }
254
- // NB the role packs' responsibility blocks are generated too, but their freshness
255
- // is asserted by role-pack-guard.js — one check owns "the packs are correct".
256
- return { name: 'generated artifacts fresh', ok: violations.length === 0, hardFail: violations.length > 0, violations, warnings: [], note: 'Tracked generated content matches source: nested CLAUDE.md symbol blocks (code) + the CLAUDE.md §13 snippet (sessions) via --check-block, plus the CLAUDE.md §2 interaction-posture block (the knob defaults), docs/file-map.md skills/scheduled-tasks sections, docs/api/openapi.json + api-reference.md (API), docs/copy-registry.json + copy-inventory.md (the reader-facing copy, task 1003556) and docs/page-inventory.json + page-inventory.md (every page and its stable id, task 1004314). The gitignored docs/repo-map.md + docs/session-log-index.md are deploy-regenerated (ADR 0110), not gated here.' };
257
- }
258
-
259
- // ---- deterministic cron routine boundary (System 4 / ADR 0078) -------------
260
- //
261
- // A `mode: deterministic` routine runs as plain node via run-routine.js — NO
262
- // model session reads its SKILL body. So that body must not rot back into a
263
- // wrapped session: it may not instruct a model to mutate (Edit/Write/git
264
- // push/commit/deploy) or synthesize free text, and its documented commands must
265
- // not diverge from its declared steps. Keeps the markdown-graveyard pattern out.
266
-
267
- const SCHEDULED_TASKS_DIR = path.join(INSTANCE_ROOT, '.claude', 'scheduled-tasks'); // .claude/ is materialized INSTANCE content (ADR 0108 §3)
268
-
269
- // Judgment/mutation instructions illegal in a deterministic body. Negated
270
- // mentions ("never pushes", "does NOT edit") are descriptive boundaries — allowed.
271
- const JUDGMENT_PATTERNS = [
272
- { re: /\bgit\s+(push|commit|add)\b/i, label: 'a git push/commit/add' },
273
- { re: /deploy\.sh\b/i, label: 'a deploy.sh invocation' },
274
- { re: /`(Edit|Write|MultiEdit|NotebookEdit)`/, label: 'an Edit/Write tool instruction' },
275
- { re: /\bsynthesi[sz]e\b/i, label: 'free-text synthesis' },
276
- { re: /\b(write|compose|draft)\s+(a|an|the)\s+(summary|report|analysis|narrative|note)\b/i, label: 'free-text synthesis' },
277
- ];
278
- const NEGATION_RE = /\b(never|not|no|without|cannot|can't|don'?t|doesn'?t|won'?t)\b/i;
279
-
280
- // Pure: scan one routine's parsed (mode, steps, body). Returns violation strings.
281
- // Only inspects deterministic routines; others return []. Exported for tests.
282
- function scanDeterministicBody(name, { mode, steps, body }) {
283
- if (mode !== 'deterministic') return [];
284
- const violations = [];
285
- if (!steps || steps.length === 0) {
286
- violations.push(`${name}: mode: deterministic but no steps: — run-routine.js would launch nothing (ADR 0078).`);
287
- }
288
- const text = String(body == null ? '' : body);
289
- for (const raw of text.split('\n')) {
290
- const line = raw.trim();
291
- if (!line || NEGATION_RE.test(line)) continue; // skip blank + negated (boundary) lines
292
- for (const p of JUDGMENT_PATTERNS) {
293
- if (p.re.test(line)) {
294
- violations.push(`${name}: deterministic SKILL body contains ${p.label} ("${line.slice(0, 70)}") — it runs as plain node with no model; move remediation/judgment to a separate claimed task (ADR 0078).`);
295
- }
296
- }
297
- }
298
- // Divergence: every `node …` command in a fenced code block must be a declared step.
299
- const stepCmds = (steps || []).map((s) => String(s.command).replace(/\s+/g, ' ').trim());
300
- for (const fence of text.match(/```[\s\S]*?```/g) || []) {
301
- for (const fl of fence.split('\n')) {
302
- const cmd = fl.trim().replace(/\s+/g, ' ');
303
- if (!cmd.startsWith('node ')) continue;
304
- if (!stepCmds.some((s) => cmd === s || cmd.startsWith(s) || s.startsWith(cmd))) {
305
- violations.push(`${name}: deterministic SKILL body documents \`${cmd.slice(0, 70)}\` which is not in its steps: — prose and steps must not diverge (ADR 0078).`);
306
- }
307
- }
308
- }
309
- return violations;
310
- }
311
-
312
- function checkDeterministicRoutines() {
313
- const violations = [];
314
- let detCount = 0;
315
- let dirs = [];
316
- try {
317
- dirs = fs.readdirSync(SCHEDULED_TASKS_DIR, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
318
- } catch (_) { /* no scheduled-tasks dir → nothing to check */ }
319
- for (const name of dirs) {
320
- let md;
321
- try { md = fs.readFileSync(path.join(SCHEDULED_TASKS_DIR, name, 'SKILL.md'), 'utf8'); } catch (_) { continue; }
322
- const { mode, steps } = parseRoutineFrontmatter(md);
323
- if (mode !== 'deterministic') continue;
324
- detCount += 1;
325
- const body = md.replace(/^---\n[\s\S]*?\n---\n?/, ''); // strip frontmatter
326
- violations.push(...scanDeterministicBody(name, { mode, steps, body }));
327
- }
328
- return {
329
- name: 'deterministic cron routines (ADR 0078)',
330
- ok: violations.length === 0,
331
- hardFail: violations.length > 0,
332
- violations,
333
- warnings: [],
334
- note: `${detCount} mode:deterministic routine(s): steps declared, no judgment instructions, prose↔steps aligned.`,
335
- };
336
- }
337
-
338
- // ============================================================================
339
- // Check 7/8 — module boundary (the one-way rule, ADR 0083 / design 04§3)
340
- // ============================================================================
341
- //
342
- // The module system's one-way rule: a module imports ONLY src/module-api.js (the
343
- // published doorway); the core NEVER imports a module; a module NEVER imports a
344
- // sibling module. These two checks enforce it.
345
- //
346
- // Both were GREEN through the strangler: the first two moved modules (M07/M08)
347
- // imported only the doorway, and the core imported neither. The boundary
348
- // shipped in WARN mode so a half-moved module mid-migration couldn't red the
349
- // build; BV1.R45 (task 1414) flips it to ENFORCING now that the first move
350
- // (M07) proved clean — the monotonic ratchet (ADR 0062 §9 / design
351
- // 04§3). A NEW cross-boundary import is now a red build; warn-mode is gone.
352
- let MODULE_BOUNDARY_ENFORCING = true;
353
- const MODULE_API_REL = 'src/module-api.js';
354
-
355
- // If `spec` (a relative require) from `fromAbsFile` resolves into modules/<key>/,
356
- // return <key>; else null. Pure path math — no fs.
357
- function resolvesToModule(fromAbsFile, spec) {
358
- const abs = path.resolve(path.dirname(fromAbsFile), spec);
359
- const r = rel(abs);
360
- const m = /^modules\/([^/]+)(\/|$)/.exec(r);
361
- return m ? m[1] : null;
362
- }
363
-
364
- // The module a core/module file belongs to, or null if it isn't under modules/.
365
- function moduleOwnerOf(absFile) {
366
- const m = /^modules\/([^/]+)\//.exec(rel(absFile));
367
- return m ? m[1] : null;
368
- }
369
-
370
- // For a require `spec` inside a MODULE file, return a violation string or null.
371
- // Allowed: src/module-api.js (the doorway), intra-module relatives, and bare
372
- // (npm/node) specs. Forbidden: deep core imports + sibling-module imports.
373
- function moduleImportViolation(fromAbsFile, spec) {
374
- const ownKey = moduleOwnerOf(fromAbsFile);
375
- if (!ownKey) return null; // not a module file
376
- const absTarget = path.resolve(path.dirname(fromAbsFile), spec);
377
- const r = rel(absTarget);
378
- // resolve possible file forms
379
- const forms = [r, r + '.js', r.replace(/\/$/, '') + '/index.js'];
380
- if (forms.includes(MODULE_API_REL)) return null; // the doorway — allowed
381
- const otherKey = (() => { const m = /^modules\/([^/]+)(\/|$)/.exec(r); return m ? m[1] : null; })();
382
- if (otherKey) {
383
- if (otherKey === ownKey) return null; // intra-module — allowed
384
- return `${rel(fromAbsFile)} → require('${spec}') reaches sibling module "${otherKey}" — modules must not import each other (use a kernel seam; ADR 0083).`;
385
- }
386
- if (/^src\//.test(r)) {
387
- return `${rel(fromAbsFile)} → require('${spec}') reaches core internals (${r}) — a module may import only the published doorway src/module-api.js (ADR 0083).`;
388
- }
389
- return null; // outside the repo (node/npm) — not our concern
390
- }
391
-
392
- function checkCoreNeverImportsModule() {
393
- const findings = [];
394
- const roots = [path.join(REPO_ROOT, 'src'), path.join(REPO_ROOT, 'server.js')];
395
- for (const root of roots) {
396
- for (const abs of walkJs(root)) {
397
- if (moduleOwnerOf(abs)) continue; // module files are scanned by the other check
398
- if (HOST_GAME.some((re) => re.test(rel(abs)))) continue; // game-owned files that live in src/ (e.g. preview-server.js) may import game module
399
- for (const raw of fs.readFileSync(abs, 'utf8').split('\n')) {
400
- const t = raw.trim();
401
- if (t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) continue;
402
- let m; REQUIRE_RE.lastIndex = 0;
403
- while ((m = REQUIRE_RE.exec(raw))) {
404
- const key = resolvesToModule(abs, m[1]);
405
- if (key) findings.push(`${rel(abs)} → require('${m[1]}') reaches module "${key}" — the core must never import a module (ADR 0083).`);
406
- }
407
- }
408
- }
409
- }
410
- const enforcing = MODULE_BOUNDARY_ENFORCING;
411
- return {
412
- name: 'core never imports a module',
413
- ok: findings.length === 0,
414
- hardFail: enforcing && findings.length > 0,
415
- violations: enforcing ? findings : [],
416
- warnings: enforcing ? [] : findings,
417
- note: `core (src/, server.js) must not require modules/* — ${enforcing ? 'ENFORCING' : 'warn-mode until BV1.R45'} (ADR 0083).`,
418
- };
419
- }
420
-
421
- function checkModulesImportOnlyApi() {
422
- const findings = [];
423
- for (const abs of walkJsAllRoots('modules')) { // modules ship from BOTH roots (ADR 0108 §Consequences #4)
424
- for (const raw of fs.readFileSync(abs, 'utf8').split('\n')) {
425
- const t = raw.trim();
426
- if (t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) continue;
427
- let m; REQUIRE_RE.lastIndex = 0;
428
- while ((m = REQUIRE_RE.exec(raw))) {
429
- const v = moduleImportViolation(abs, m[1]);
430
- if (v) findings.push(v);
431
- }
432
- }
433
- }
434
- const enforcing = MODULE_BOUNDARY_ENFORCING;
435
- return {
436
- name: 'modules import only the published API',
437
- ok: findings.length === 0,
438
- hardFail: enforcing && findings.length > 0,
439
- violations: enforcing ? findings : [],
440
- warnings: enforcing ? [] : findings,
441
- note: `modules/** may require only src/module-api.js (no deep core, no sibling) — ${enforcing ? 'ENFORCING' : 'warn-mode until BV1.R45'} (ADR 0083).`,
442
- };
443
- }
444
-
445
- // ============================================================================
446
- // Check 9 — the goal scope map imports PROTECTED_GLOBS, never re-declares it
447
- // (ADR 0086 §7; the SEC #863 "second list that drifts" failure mode)
448
- // ============================================================================
449
- //
450
- // src/bongos/module-scope-map.js (BV1.R54) derives each module's `protected` flag
451
- // from PROTECTED_GLOBS. That derivation is only trustworthy if it reads the ONE
452
- // source (permission-path-check.js) — a hand-copied second list would silently
453
- // drift from the real protected set and quietly de-protect a module. This check
454
- // reds the build if the scope map stops importing PROTECTED_GLOBS, or copies it.
455
- const SCOPE_MAP_REL = 'src/bongos/module-scope-map.js';
456
-
457
- // Pure: scan the scope-map source for the import contract. Exported for the
458
- // "actually catches a violation" test (mirrors scanDeterministicBody).
459
- function scanScopeMapSource(src) {
460
- const violations = [];
461
- const text = String(src || '');
462
- const importsFrom = /require\(\s*['"]\.\/permission-path-check['"]\s*\)/.test(text);
463
- const namesIt = /\bPROTECTED_GLOBS\b/.test(text);
464
- if (!importsFrom || !namesIt) {
465
- violations.push(`${SCOPE_MAP_REL} must IMPORT PROTECTED_GLOBS from ./permission-path-check and derive \`protected\` from it — never hand-maintain a second protected list (ADR 0086 §7).`);
466
- }
467
- if (/\b(?:const|let|var)\s+PROTECTED_GLOBS\s*=/.test(text)) {
468
- violations.push(`${SCOPE_MAP_REL} re-declares PROTECTED_GLOBS — it must import the single source from permission-path-check.js, not copy it (ADR 0086 §7; the SEC #863 second-list failure mode).`);
469
- }
470
- return violations;
471
- }
472
-
473
- function checkScopeMapImportsProtected() {
474
- const abs = path.join(REPO_ROOT, SCOPE_MAP_REL);
475
- let src = null;
476
- try { src = fs.readFileSync(abs, 'utf8'); } catch (_) { /* absent → skip */ }
477
- // Absent → clean pass: the scope map is a BV1.R54 deliverable; until it exists
478
- // there is no import contract to enforce (its own unit test asserts existence).
479
- const violations = src == null ? [] : scanScopeMapSource(src);
480
- return {
481
- name: 'scope map imports PROTECTED_GLOBS (ADR 0086)',
482
- ok: violations.length === 0,
483
- hardFail: violations.length > 0,
484
- violations,
485
- warnings: [],
486
- note: src == null
487
- ? `${SCOPE_MAP_REL} absent — skipped (created by BV1.R54).`
488
- : `${SCOPE_MAP_REL} derives \`protected\` from the imported PROTECTED_GLOBS (single source; no copied list).`,
489
- };
490
- }
491
-
492
- // ============================================================================
493
- // Check 10 — core carries no module-specific code (ADR 0083 §Decision #4 / design 04§3)
494
- // ============================================================================
495
- //
496
- // The module-system MACHINERY (the doorway + loader + seam registry) must stay
497
- // module-AGNOSTIC: it discovers, validates, and mounts modules uniformly and may
498
- // never special-case one by name. The import checks (Check 7/8) stop a module's
499
- // CODE from being reached by `require`; this stops a module's IDENTITY from being
500
- // hardcoded into the kernel (`if (key === 'art-pipeline') …`, a copied module helper,
501
- // a registry entry that should have moved out). "No module-specific code" is
502
- // operationalized as the one drift-free signal — the kernel names no discovered
503
- // module KEY (the canonical id from modules/<key>/module.json). Domain terms are
504
- // deliberately NOT pattern-matched: they're non-deterministic and the doorway
505
- // legitimately re-exports capability accessors (getBuilderGeminiKeyRow, …); the
506
- // KEY is the precise thing a generic kernel never needs to write.
507
- //
508
- // Scope (BV1.R70 / ADR 0091 §1): the real ~3.5k-LOC TRUST KERNEL — the module-
509
- // system machinery PLUS the trust primitives + data substrate + config/identity
510
- // the rest of core depends on. This replaces the original 6-file machinery-only
511
- // roster (the kernel was unbounded before — the audit's finding). Deliberately
512
- // EXCLUDED: the still-fused monolith remnants (src/bongos/db.js, routes/me.js,
513
- // routes.js, server.js) still carry un-stranglered module seams by design
514
- // (lifecycle + tranche-2 domains leave later) — scanning them would red the
515
- // build on intentional state. Comment lines are skipped (a key named in a
516
- // doc/example comment is documentation, not code), and the scope-map registry is
517
- // exempt from the no-module-keys scan (see KERNEL_NAMES_MODULES_OK).
518
- const KERNEL_FILES = [
519
- // module-system machinery (the original roster)
520
- 'src/module-api.js', // the published doorway
521
- 'src/modules.js', // the registry/resolver facade
522
- 'src/module-seams.js', // the seam registry (ports/events/contributions)
523
- 'src/role-responsibilities.js', // the owner's written role statements (task 1003732) — modules.js reads it; imports nothing
524
- 'src/module-loader/loader.js', // the disk loader (discover → validate → mount)
525
- 'src/module-loader/manifest-schema.js', // the manifest validator
526
- 'src/module-loader/semver.js', // coreVersion compatibility
527
- 'src/module-loader/error-tally.js', // per-module runtime-error counts the loader feeds (task 1004637)
528
- 'src/bongos/module-scope-map.js', // the module→path registry (it NAMES every module — exempt below)
529
- // trust primitives (ADR 0091 §1) — the authz boundary + data substrate
530
- 'src/bongos/auth.js', // authz gates (requireBuilder/requireRank, ADR 0016)
531
- // task 1003206 (goal 1000079) split auth.js's 1,867 lines into these five sign-in
532
- // flow modules. They are the SAME kernel machinery, not new domain — auth.js is a
533
- // kernel file, so if they were left off this roster the boundary check would read
534
- // its own carve as five kernel→non-kernel leaks. Being on the roster also means
535
- // each of them is itself held to the kernel import rule, which is the point.
536
- 'src/bongos/auth-config.js', // provider config + OAuth scope selection
537
- 'src/bongos/auth-admission.js', // membership kind, admission gate, first-admin seating
538
- 'src/bongos/auth-github.js', // GitHub device + web OAuth flows
539
- 'src/bongos/auth-idp.js', // hub federation, assertion + logout-token verification
540
- 'src/bongos/auth-discord.js', // Discord OAuth link + guild membership
541
- 'src/bongos/route-rank-check.js', // deterministic route→rank classification
542
- 'src/bongos/permission-path-check.js', // protected-path matcher (PROTECTED_GLOBS, ADR 0043)
543
- 'src/bongos/goal-scope-check.js', // goal create-gate scope wall (composes the 3 matchers above; ADR 0086 §3, BV1.R60)
544
- 'src/bongos/secret-box.js', // AES-256-GCM per-builder secret box
545
- 'src/bongos/pool.js', // the singleton Postgres pool accessor
546
- // task 1003208: the structured logger is kernel infrastructure in the same sense
547
- // the pool is — src/module-api.js hands every module a child of it, so it sits
548
- // BELOW the module boundary, not beside a domain. It imports only node built-ins
549
- // and pino, so joining the roster costs nothing and buys the import-direction
550
- // guarantee on the file every module now logs through.
551
- 'src/bongos/logger.js', // pino + request correlation + ADR 0022 redaction
552
- // task 1003339 (ADR 0209): the abuse ceiling is a trust primitive in the same
553
- // sense the authz gates are — authz says WHO may ask, this says HOW OFTEN, and
554
- // an unauthenticated read route has nothing else holding it. src/module-api.js
555
- // now hands modules the shared account-existence limiter (the onboarding
556
- // module's account-existence probe spends the same budget as core's), so it
557
- // sits BELOW the module boundary exactly as logger.js does. It requires NOTHING
558
- // — no relative imports at all — so joining the roster costs nothing and buys
559
- // the import-direction guarantee on a file two surfaces now trust.
560
- 'src/bongos/middleware/rate-limit.js', // the sliding-window abuse ceilings (write + per-surface read)
561
- 'src/bongos/db-kernel.js', // the kernel db slice — identity/audit/rank/withTx (BV1.R69)
562
- // task 1002969 (ADR 0356): when an invite's door closes is part of the admission
563
- // gate db-kernel.js runs, and the doorway hands the same definition to the
564
- // onboarding and hub modules. It requires NOTHING, so joining costs nothing.
565
- 'src/bongos/invite-expiry.js', // the read-time invite expiry (INVITE_EXPIRY_DAYS + its SQL)
566
- 'src/bongos/routes/_helpers.js', // shared request validators the doorway re-exports
567
- // config / identity (host context a module reads, never hardcodes)
568
- 'src/instance-config.js',
569
- 'src/branding.js',
570
- // task 1004421 (ADR 0358): branding.js lays the chosen look over the pack through this
571
- // file — the same identity/config category, requiring only instance-config and node
572
- // built-ins, so it joins the roster rather than reading as a kernel→domain leak.
573
- 'src/hall-look.js',
574
- 'src/build-info.js',
575
- // task 1003476 (goal 1000072): the project's stale-claim timer — host configuration
576
- // a module reads rather than hardcodes, exactly the category instance-config.js and
577
- // branding.js are in. The doorway (a KERNEL_FILE) re-exports it, so leaving it off
578
- // this roster would read as a kernel->non-kernel leak; it imports only
579
- // instance-config + node built-ins, so joining costs nothing.
580
- 'src/stale-timer.js',
581
- // task 1003279 (goal 1000072, ADR 0232): the project's live knob store and the ROT
582
- // timer resolver over it — the same category as stale-timer.js directly above (host
583
- // configuration a module reads rather than hardcodes), differing only in living in
584
- // the DB instead of the env, because task 1003280 requires that knob be changeable
585
- // from a page without a redeploy. The doorway re-exports it, so leaving it off this
586
- // roster reads as a kernel->non-kernel leak; it imports only pool.js (itself on this
587
- // roster) + node built-ins, so joining costs nothing and buys the import-direction
588
- // guarantee on the file every future project knob will be read through.
589
- 'src/bongos/project-settings.js',
590
- // BV1.R86: the git-remote/slug + publish-target identity the doorway exposes
591
- // (api.repoInfo) for the carved lifecycle github-push/conflict-resolve. It is
592
- // KERNEL (already in the module-scope-map kernel key) and imports only the
593
- // kernel (instance-config) + node built-ins, so it joins the roster cleanly.
594
- 'src/bongos/repo-info.js',
595
- // task 1002331 (ADR 0182 D6 / ADR 0247): the project's composed join/apply door — a
596
- // deterministic classifier over three policy values, the same category as
597
- // route-rank-check.js and goal-scope-check.js above (a trust decision the doorway
598
- // hands to modules so no module re-derives it). The doorway re-exports it, so
599
- // leaving it off this roster reads as a kernel->non-kernel leak; it imports only
600
- // branding.js, instance-config.js and logger.js — all on this roster — so joining
601
- // costs nothing and buys the import-direction guarantee on the file that decides
602
- // who may knock. (Task 1003579 moved joinabilityMode the other way: the gate reads
603
- // the composed door, so reader and composer had to sit together or the two would
604
- // cycle.) The ARTIST GATE joins for the same reason — task 1003575, ADR 0241.
605
- 'src/bongos/project-door.js', 'src/bongos/artist-gate.js',
606
- // task 1004296 (ADR 0340 D5): the npm registry reader — packument, the in-process
607
- // tarball stream and its small tar reader. It moved INTO the core because Settings →
608
- // Software update needs it in every hall, and the doorway re-exports it
609
- // (readPackageRegistry) for the module that publishes a package, so leaving it off
610
- // this roster reads as a kernel->non-kernel leak. It imports only node built-ins
611
- // (https, zlib), so joining costs nothing.
612
- 'src/bongos/package-registry.js',
613
- // task 1004657 (ADR 0363 D5): requireActAlone, the gate a building's own page mounts
614
- // after its permission gate — the same trust-gate category as auth.js, re-exported
615
- // by the doorway, so leaving it off reads as a kernel->non-kernel leak. It imports
616
- // only module-seams.js and logger.js (both on this roster) and reaches the
617
- // government module through its port, never by require.
618
- 'src/bongos/act-alone.js',
619
- ];
620
-
621
- // Kernel files exempt from the no-module-keys scan (Check 10) because naming a
622
- // module is, for them, the JOB — they stay in KERNEL_FILES for the import check
623
- // (Check 12), which guards dependency *direction* (a much stronger guarantee than
624
- // "never write the string 'art-pipeline'"). Two legitimate reasons a kernel file names
625
- // a module:
626
- // • the REGISTRY — module-scope-map.js IS the module→path map (and
627
- // checkScopeMapImportsProtected already guards how it derives `protected`).
628
- // • the TRUST BOUNDARY — auth.js carries the Discord OAuth account-LINK flow
629
- // (core by design — see modules/discord/CLAUDE.md "NOT in this module"); and
630
- // permission-path-check.js / route-rank-check.js MUST name module path
631
- // subtrees ('modules/grading/', …) to protect + rank-gate them. Forbidding
632
- // these the string would force the trust layer to stop protecting module
633
- // surfaces — exactly backwards. The generic machinery + data + config files
634
- // (module-api, the loader, db-kernel, secret-box, pool, _helpers, branding,
635
- // instance-config, build-info) are NOT exempt and must stay module-agnostic.
636
- const KERNEL_NAMES_MODULES_OK = new Set([
637
- 'src/bongos/module-scope-map.js', // the module→path registry
638
- // auth.js and the auth-*.js flow modules task 1003206 split out of it: the
639
- // sign-in path legitimately names modules — it resolves the 'onboarding' and
640
- // 'government' PORTS by key, and carries the Discord OAuth account-link flow
641
- // (core by design — see modules/discord/CLAUDE.md "NOT in this module"). The
642
- // exemption follows the code, exactly as the KERNEL_FILES roster above does;
643
- // Check 12 still guards these files' dependency DIRECTION, which is the
644
- // stronger guarantee.
645
- 'src/bongos/auth.js', // Discord OAuth account-link flow (core by design)
646
- 'src/bongos/auth-config.js',
647
- 'src/bongos/auth-admission.js', // resolves the 'government' rank-role port by key
648
- 'src/bongos/auth-github.js', // ticks the 'onboarding' port on first sign-in
649
- 'src/bongos/auth-idp.js', // same, on the federated path
650
- 'src/bongos/auth-discord.js', // the Discord account-link flow itself
651
- 'src/bongos/act-alone.js', // resolves the 'government' port by key for checkActAlone (task 1004657)
652
- 'src/bongos/permission-path-check.js', // names module path subtrees to PROTECT them
653
- 'src/bongos/route-rank-check.js', // names module route dirs to rank-gate them
654
- 'src/role-responsibilities.js', // the ideator's VERBATIM statement reads "Make good ideas" — the English word, colliding with the `ideas` key. Owner text; unparaphrasable.
655
- ]);
656
-
657
- // The discovered module keys = the directory names under modules/ (a manifest's
658
- // `key` must equal its dir name — manifest-schema). Empty before any move. With no explicit
659
- // `modulesDir` it UNIONS every module root (core package + instance repo, ADR 0108 §Consequences
660
- // #4); an explicit dir keeps the old single-dir behavior (tests). Deduped — a key resolves to
661
- // exactly one root (the loader errors on a cross-root collision), and today the roots coincide.
662
- function _moduleKeysIn(modulesDir) {
663
- try {
664
- return fs.readdirSync(modulesDir, { withFileTypes: true })
665
- .filter((d) => d.isDirectory())
666
- .map((d) => d.name);
667
- } catch { return []; }
668
- }
669
- function discoveredModuleKeys(modulesDir) {
670
- if (modulesDir) return _moduleKeysIn(modulesDir);
671
- const keys = new Set();
672
- for (const root of MODULE_ROOTS) for (const k of _moduleKeysIn(path.join(root, 'modules'))) keys.add(k);
673
- return [...keys];
674
- }
675
- // task 1002790: two questions, previously conflated and asserted EQUAL. BROAD
676
- // (every dir) stays broad — the migration checks need it, since a .sql in a
677
- // manifest-less dir must still be namespace/stem-checked (schema_migrations is
678
- // stem-keyed; a collision is silently SKIPPED). NARROW = carries module.json,
679
- // which is what makes a module a module (ADR 0083) and what kernel-naming means.
680
- function manifestModuleKeys(modulesDir) {
681
- const manifested = (dir) => _moduleKeysIn(dir).filter((k) => fs.existsSync(path.join(dir, k, 'module.json')));
682
- if (modulesDir) return manifested(modulesDir);
683
- return [...new Set(MODULE_ROOTS.flatMap((r) => manifested(path.join(r, 'modules'))))];
684
- }
685
- // The DIFFERENCE as an instruction, not a bare diff — and a WARNING, because a
686
- // dir without a manifest is the normal transient shape of scaffolding a module.
687
- function manifestlessModuleDirs(modulesDir) {
688
- const narrow = new Set(manifestModuleKeys(modulesDir));
689
- return discoveredModuleKeys(modulesDir).filter((k) => !narrow.has(k)).sort().map((k) =>
690
- `modules/${k}/ has no module.json — it is a directory, not a module. Add the manifest (ADR 0083) or remove the dir. Warning, not a failure: scaffolding a module dir before its manifest is normal and must not red CI.`);
691
- }
692
- // Absolute path to a discovered module's dir, resolving WHICH root holds it (core package or
693
- // instance repo). Today both roots coincide → the single checkout.
694
- function moduleDir(key) {
695
- for (const root of MODULE_ROOTS) {
696
- const d = path.join(root, 'modules', key);
697
- if (fs.existsSync(d)) return d;
698
- }
699
- return path.join(CORE_ROOT, 'modules', key);
700
- }
701
-
702
- // Pure: scan kernel source text for any hardcoded module key, skipping comment
703
- // lines. Returns violation strings (one per hit). Exported for the negative test
704
- // (mirrors scanScopeMapSource / scanDeterministicBody).
705
- function scanKernelForModuleKeys(text, keys) {
706
- const violations = [];
707
- if (!keys || keys.length === 0) return violations;
708
- const probes = keys.map((k) => ({ key: k, re: keyTokenRe(k) }));
709
- String(text == null ? '' : text).split('\n').forEach((raw, i) => {
710
- const t = raw.trim();
711
- if (!t || t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) return;
712
- for (const { key, re } of probes) {
713
- if (re.test(raw)) {
714
- violations.push(`names module "${key}" at line ${i + 1} — the kernel/module-system machinery must stay module-agnostic; no module key may be hardcoded in core (ADR 0083 §Decision #4).`);
715
- }
716
- }
717
- });
718
- return violations;
719
- }
720
-
721
- function checkCoreCarriesNoModuleCode() {
722
- const keys = manifestModuleKeys(); // task 1002790 — NARROW: a manifest-less dir is not a module
723
- const violations = [];
724
- for (const relFile of KERNEL_FILES) {
725
- if (KERNEL_NAMES_MODULES_OK.has(relFile)) continue; // the registry legitimately names every module
726
- let text;
727
- try { text = fs.readFileSync(path.join(REPO_ROOT, relFile), 'utf8'); } catch { continue; }
728
- for (const v of scanKernelForModuleKeys(text, keys)) violations.push(`${relFile} ${v}`);
729
- }
730
- return {
731
- name: 'core carries no module code',
732
- ok: violations.length === 0,
733
- hardFail: violations.length > 0,
734
- violations,
735
- warnings: manifestlessModuleDirs(), // task 1002790 — named, and never a hard fail
736
- note: `kernel machinery (${KERNEL_FILES.length} files) names no module key${keys.length ? ` (keys: ${keys.join(', ')})` : ' (none yet)'} (ADR 0083 §Decision #4). A key is a modules/ dir carrying module.json; the migration checks deliberately scan every dir (task 1002790).`,
737
- };
738
- }
739
-
740
- // ============================================================================
741
- // Check 12 — the kernel imports no domain (ADR 0091 §1 / BV1.R70)
742
- // ============================================================================
743
- //
744
- // A bounded kernel is only real if it DEPENDS on nothing but itself. This check
745
- // walks every KERNEL_FILE's relative requires and flags any that reach a
746
- // non-kernel core file (a soon-to-be-module domain). Kernel→kernel is fine;
747
- // kernel→grandfathered-infra (the raw base pg pool, the pure path-match util) is
748
- // fine; a bare npm/node spec is fine. Everything else is a tracked leak.
749
- //
750
- // ENFORCING (ADR 0102): the tranche-2 ratchet reached zero, so this is now a hard
751
- // gate — the kernel imports only itself + grandfathered infra, and any NEW
752
- // kernel→domain import fails the build (violations). The last leaks cleared were
753
- // auth.js→db (carved to db-kernel), the doorway's Gemini-key re-exports (→ the
754
- // art-pipeline 'art.getBuilderGeminiKeyRow' port) and builderRollingAvgGrade (→ the
755
- // grading 'grade.builderRollingAvgGrade' port), plus reclassifying llm-cache /
756
- // llm-pricing as kernel-adjacent infra. Adding a leak back reds the build.
757
-
758
- // Grandfathered kernel-adjacent targets a KERNEL_FILE may import without it
759
- // counting as a domain leak. The still-fused src/bongos/db.js monolith is NOT here:
760
- // a kernel file reaching into it IS a real (tracked) leak until the identity/
761
- // session slices finish carving into db-kernel.js.
762
- const KERNEL_IMPORT_ALLOWLIST = new Set([
763
- 'src/db.js', // the raw shared pg Pool (base infra; pool.js wraps it)
764
- 'src/bongos/path-match.js', // pure touches-overlap matcher (no domain logic)
765
- // Cross-cutting LLM-cost infra (ADR 0102): a stateless token→USD pricing table
766
- // (llm-pricing) + a best-effort content-addressed cache (llm-cache), consumed by
767
- // core, the grading module, and the CLI cost tooling ALIKE — no domain logic and
768
- // no domain state beyond a cache table. Same category as the pg pool / path-match,
769
- // not a domain module core would have to depend on anyway. The doorway may import
770
- // them; they never flip the kernel→domain leak.
771
- 'src/bongos/llm-cache.js',
772
- 'src/bongos/llm-pricing.js',
773
- // The cheapest-model-first cascade router (task 1001691 / ADR 0101 Part 1):
774
- // a pure ladder + an INJECTED runner (never a domain call itself — its own
775
- // header says so: "nothing calls it but its mock unit test" until this
776
- // task), holding no domain state of its own. Its first real caller is the
777
- // lifecycle module's relevance judge, which reaches it through the doorway
778
- // exactly as grading reaches llm-cache — same category as the pg pool /
779
- // path-match / llm-cache above, not a domain module core would otherwise
780
- // depend on.
781
- 'src/bongos/cascade-dispatch.js',
782
- ]);
783
-
784
- // Pure: for relative require `spec` from kernel file `fromRel` (repo-relative),
785
- // return the offending non-kernel target relpath, or null if the import is clean
786
- // (kernel→kernel, kernel→allowlisted-infra, or a bare npm/node spec). Exported
787
- // for the "actually catches a leak" negative test (mirrors scanScopeMapSource).
788
- function kernelDomainImport(fromRel, spec, kernelSet = new Set(KERNEL_FILES), allow = KERNEL_IMPORT_ALLOWLIST) {
789
- if (!/^\.\.?\//.test(spec)) return null; // bare npm/node spec — not our concern
790
- const absTarget = path.resolve(path.dirname(path.join(REPO_ROOT, fromRel)), spec);
791
- const r = rel(absTarget);
792
- const forms = [r, r + '.js', r.replace(/\/$/, '') + '/index.js'];
793
- if (forms.some((f) => kernelSet.has(f))) return null; // kernel → kernel
794
- if (forms.some((f) => allow.has(f))) return null; // grandfathered infra/util
795
- if (!/^src\//.test(r)) return null; // only flag app-source targets
796
- return r.endsWith('.js') || r.endsWith('.json') ? r : `${r}.js`; // name the real file
797
- }
798
-
799
- function checkKernelImportsNoDomain() {
800
- const kernelSet = new Set(KERNEL_FILES);
801
- const findings = [];
802
- for (const relFile of KERNEL_FILES) {
803
- let text;
804
- try { text = fs.readFileSync(path.join(REPO_ROOT, relFile), 'utf8'); } catch { continue; }
805
- for (const raw of text.split('\n')) {
806
- const t = raw.trim();
807
- if (t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) continue;
808
- let m; REQUIRE_RE.lastIndex = 0;
809
- while ((m = REQUIRE_RE.exec(raw))) {
810
- const target = kernelDomainImport(relFile, m[1], kernelSet);
811
- if (target) findings.push(`${relFile} → require('${m[1]}') reaches non-kernel core file ${target} — a kernel file must depend only on the kernel (ADR 0091 §1). Carve ${target}'s domain out (or promote it into the kernel) to clear this.`);
812
- }
813
- }
814
- }
815
- return {
816
- name: 'kernel imports no domain',
817
- ok: findings.length === 0,
818
- hardFail: findings.length > 0, // ENFORCING (ADR 0102): the ratchet reached zero — any new kernel→domain import now reds the build
819
- violations: findings,
820
- warnings: [],
821
- note: `every KERNEL_FILE (${KERNEL_FILES.length}) must import only the kernel + grandfathered infra — ENFORCING (ADR 0091 §1 / ADR 0102).${findings.length ? ` ${findings.length} leak(s).` : ' Boundary clean.'}`,
822
- };
823
- }
824
-
825
- // ============================================================================
826
- // Check 11 — module migrations are additive + namespaced (ADR 0083 §Decision #5 / design 04§3)
827
- // ============================================================================
828
- //
829
- // A module owns its DB slice through migrations under modules/<key>/migrations/.
830
- // Two invariants keep that slice from clobbering core or a sibling:
831
- // • ADDITIVE — no destructive DDL. "Disable a module" means "stop applying its
832
- // migrations," never "drop its tables" (ADR 0083 §Module-owned migrations);
833
- // there is no down path, so a DROP/TRUNCATE can only be an accident.
834
- // • NAMESPACED — every object it CREATEs lives under the <key>_ prefix
835
- // (art-pipeline → art_pipeline_), and it may only ALTER its own namespaced tables;
836
- // core/sibling state is reached through the doorway/seams, never raw DDL.
837
- //
838
- // LEGACY_NAMESPACED: tables that predate the <key>_-prefix convention (created before the module
839
- // system existed). Grandfathered per-module to avoid requiring a rename migration for legacy prod
840
- // data. The fitness rule applies in full to any NEW migration a module ships.
841
- const LEGACY_NAMESPACED = {
842
- // game module: world_events + players were created before the module system (V1 schema). The
843
- // schema_migrations table is a core tracking table that every migration may re-create idempotently.
844
- game: new Set(['world_events', 'players', 'schema_migrations']),
845
- // government module: the module KEY was renamed governance→government (ADR 0174, goal 1000068),
846
- // so its own historical migrations now read as "outside the namespace" purely because the key
847
- // moved underneath them. These three tables ARE this module's — under the name it used to have.
848
- // They are not renamed in place because schema_migrations is keyed by filename STEM: renaming an
849
- // already-applied migration file makes it look unapplied and re-runs it, and governance_002 is a
850
- // seed/backfill. government_001_rename_from_governance.sql renames the live tables forward; these
851
- // entries let the historical files that created them keep describing what actually happened.
852
- government: new Set([
853
- 'governance_roles', 'governance_builder_roles', 'governance_role_permissions',
854
- ]),
855
- };
856
- const DESTRUCTIVE_DDL = [
857
- { re: /\bdrop\s+table\b/i, label: 'DROP TABLE' },
858
- { re: /\balter\s+table\b[\s\S]*?\bdrop\s+(?:column|constraint)\b/i, label: 'ALTER TABLE … DROP COLUMN/CONSTRAINT' },
859
- { re: /\bdrop\s+(?:column|constraint)\b/i, label: 'DROP COLUMN/CONSTRAINT' },
860
- { re: /\bdrop\s+(?:index|type|view|sequence|schema|materialized\s+view)\b/i, label: 'DROP <object>' },
861
- { re: /\btruncate\b/i, label: 'TRUNCATE' },
862
- ];
863
- const CREATE_OBJ_RE = /\bcreate\s+(?:or\s+replace\s+)?(?:unique\s+)?(?:materialized\s+)?(table|view|sequence|type)\s+(?:if\s+not\s+exists\s+)?("?[\w.]+"?)/gi;
864
- const CREATE_INDEX_RE = /\bcreate\s+(?:unique\s+)?index\s+(?:concurrently\s+)?(?:if\s+not\s+exists\s+)?(?:"?[\w.]+"?)\s+on\s+(?:only\s+)?("?[\w.]+"?)/gi;
865
- const ALTER_TABLE_RE = /\balter\s+table\s+(?:if\s+exists\s+)?(?:only\s+)?("?[\w.]+"?)/gi;
866
-
867
- // SQL object-namespace prefix for a module key: art-pipeline → art_pipeline (SQL-safe).
868
- function moduleNamespace(key) { return key.replace(/-/g, '_'); }
869
-
870
- // strip SQL comments so a commented-out statement is never scanned
871
- function stripSqlComments(sql) {
872
- return String(sql == null ? '' : sql)
873
- .replace(/\/\*[\s\S]*?\*\//g, ' ')
874
- .replace(/--[^\n]*/g, ' ');
875
- }
876
-
877
- // is `rawName` (possibly quoted / schema-qualified) under the <ns>_ namespace?
878
- function inNamespace(rawName, ns, legacySet) {
879
- const name = String(rawName).replace(/"/g, '').replace(/^[A-Za-z_]\w*\./, '');
880
- return name.startsWith(ns + '_') || (legacySet && legacySet.has(name));
881
- }
882
-
883
- // A CHECK-enum WIDENING is additive-in-spirit: `DROP CONSTRAINT IF EXISTS <c>` PAIRED
884
- // with a re-`ADD CONSTRAINT <c>` (SAME name) in the SAME migration only PERMITS more
885
- // values — no existing row changes, no data is lost (task 1978: provisioning gains a
886
- // 'standalone' hosting_shape). Allow that exact pattern; a BARE `DROP CONSTRAINT` (no
887
- // re-add), or any DROP TABLE/COLUMN/TRUNCATE, stays destructive. PURE.
888
- function reAddedConstraintNames(sql) {
889
- const names = new Set();
890
- const re = /\badd\s+constraint\s+("?[\w.]+"?)/gi;
891
- let m;
892
- while ((m = re.exec(sql))) names.add(m[1].replace(/"/g, ''));
893
- return names;
894
- }
895
- function isConstraintWidening(stmt, reAdded) {
896
- const m = /\bdrop\s+constraint\s+(?:if\s+exists\s+)?("?[\w.]+"?)/i.exec(stmt);
897
- if (!m) return false; // not a DROP CONSTRAINT at all
898
- // never let a DROP CONSTRAINT statement smuggle a table/column drop past the gate
899
- if (/\bdrop\s+(?:table|column|index|type|view|sequence|schema|materialized\s+view)\b/i.test(stmt)) return false;
900
- if (/\btruncate\b/i.test(stmt)) return false;
901
- return reAdded.has(m[1].replace(/"/g, '')); // re-added same-named constraint → widening
902
- }
903
-
904
- // The ONE destructive shape a module may carry: an ACKNOWLEDGED contract-phase
905
- // `ALTER TABLE <own table> DROP COLUMN <c>` (task 1003092 — the expand-then-contract
906
- // rename of ADR 0177 has to finish; ADR 0083 §Module-owned migrations, amended). The
907
- // pragma is read off the RAW sql (it is a comment); everything else here still runs.
908
- const { acknowledgedContraction, isAcknowledgedColumnContraction } = require('./fitness-migration-contraction.js');
909
-
910
- // Pure: violations for ONE module's migration SQL. Exported for the negative test.
911
- function moduleMigrationViolations(key, sql) {
912
- const ns = moduleNamespace(key);
913
- const legacy = LEGACY_NAMESPACED[key] || null;
914
- const clean = stripSqlComments(sql);
915
- const violations = [];
916
- // additive — scan per statement so an ALTER…DROP never spans a `;`
917
- const reAdded = reAddedConstraintNames(clean);
918
- const acknowledged = acknowledgedContraction(sql);
919
- const ownTable = (t) => inNamespace(t, ns, legacy);
920
- for (const stmt of clean.split(';')) {
921
- if (isConstraintWidening(stmt, reAdded)) continue; // additive CHECK-enum widening (task 1978)
922
- if (isAcknowledgedColumnContraction(stmt, { acknowledged, inNamespace: ownTable })) continue; // contract phase (task 1003092)
923
- for (const d of DESTRUCTIVE_DDL) {
924
- if (d.re.test(stmt)) {
925
- violations.push(`module "${key}" migration uses destructive DDL (${d.label}) — module migrations must be ADDITIVE; disabling a module stops applying, it never drops (ADR 0083 §Decision #5).`);
926
- break; // one destructive flag per statement is enough
927
- }
928
- }
929
- }
930
- // namespaced — CREATEd objects + ALTER targets must live under <ns>_ (or be grandfathered)
931
- let m;
932
- CREATE_OBJ_RE.lastIndex = 0;
933
- while ((m = CREATE_OBJ_RE.exec(clean))) {
934
- if (!inNamespace(m[2], ns, legacy)) {
935
- violations.push(`module "${key}" migration creates ${m[1].toUpperCase()} ${m[2]} outside its namespace — module objects must be ${ns}_-prefixed (ADR 0083 §Decision #5).`);
936
- }
937
- }
938
- CREATE_INDEX_RE.lastIndex = 0;
939
- while ((m = CREATE_INDEX_RE.exec(clean))) {
940
- if (!inNamespace(m[1], ns, legacy)) {
941
- violations.push(`module "${key}" migration indexes a non-namespaced table ${m[1]} — a module migration may only touch its own ${ns}_ tables (ADR 0083 §Decision #5).`);
942
- }
943
- }
944
- ALTER_TABLE_RE.lastIndex = 0;
945
- while ((m = ALTER_TABLE_RE.exec(clean))) {
946
- if (!inNamespace(m[1], ns, legacy)) {
947
- violations.push(`module "${key}" migration alters a non-namespaced table ${m[1]} — a module migration may only touch its own ${ns}_ tables; reach core state through the doorway/seams, not DDL (ADR 0083 §Decision #5).`);
948
- }
949
- }
950
- return violations;
951
- }
952
-
953
- function checkModuleMigrationsAdditive() {
954
- const violations = [];
955
- let scanned = 0;
956
- for (const key of discoveredModuleKeys()) { // union across module roots (ADR 0108 §Consequences #4)
957
- const migDir = path.join(moduleDir(key), 'migrations');
958
- let files = [];
959
- try { files = fs.readdirSync(migDir).filter((f) => f.endsWith('.sql')); } catch { continue; }
960
- for (const f of files.sort()) {
961
- scanned += 1;
962
- const sql = fs.readFileSync(path.join(migDir, f), 'utf8');
963
- for (const v of moduleMigrationViolations(key, sql)) {
964
- violations.push(`modules/${key}/migrations/${f}: ${v}`);
965
- }
966
- }
967
- }
968
- return {
969
- name: 'module migrations additive + namespaced',
970
- ok: violations.length === 0,
971
- hardFail: violations.length > 0,
972
- violations,
973
- warnings: [],
974
- note: `${scanned} module migration file(s): additive (no destructive DDL) + <key>_-namespaced objects (ADR 0083 §Decision #5).`,
975
- };
976
- }
977
-
978
- // ============================================================================
979
- // Check 11b — migration FILENAMES are namespaced + no cross-root stem collision
980
- // (ADR 0108 §5; extends Check 11 to the cross-repo layer)
981
- // ============================================================================
982
- //
983
- // Check 11 (above) guards a module migration's OBJECTS (additive + <key>_-namespaced
984
- // tables). THIS check guards migration FILENAMES across all three roots — the
985
- // discipline that lets the core repo and the instance repo version independently
986
- // (ADR 0108) without their migrations colliding:
987
- // • migrations/*.sql (CORE) → NEW files must be core_-prefixed
988
- // • migrations/instance/*.sql (INSTANCE) → stay bare (or instance_-prefixed)
989
- // • modules/<key>/migrations/ (MODULE) → NEW files must be <key>_-prefixed
990
- // Existing bare files are grandfathered (migration-namespace.js LEGACY_BARE_*). The
991
- // second invariant is the real bug guard: migrate.sh keys schema_migrations by
992
- // filename STEM, so two migrations from different sources sharing a stem would apply
993
- // ONCE and the other be SILENTLY SKIPPED (never applied). Single-root today; W6/task
994
- // 1886 makes the root resolution two-root-aware once the core installs from node_modules.
995
- function sqlFilesIn(absDir) {
996
- try { return fs.readdirSync(absDir).filter((f) => f.endsWith('.sql')).sort(); }
997
- catch { return []; } // dir absent (e.g. no migrations/instance in a vanilla instance) → nothing to scan
998
- }
999
-
1000
- function checkMigrationNamespacing() {
1001
- const violations = [];
1002
- const files = []; // { source, moduleKey?, basename } — fed to the stem-collision scan
1003
-
1004
- const coreFiles = sqlFilesIn(path.join(CORE_ROOT, 'migrations')); // core migrations ship in the core package
1005
- for (const f of coreFiles) {
1006
- const v = filenameViolation(CORE_NS, f);
1007
- if (v) violations.push(`migrations/${f}: ${v}`);
1008
- files.push({ source: CORE_NS, basename: f });
1009
- }
1010
-
1011
- const instFiles = sqlFilesIn(path.join(INSTANCE_ROOT, 'migrations', 'instance')); // instance seeds live in the host repo
1012
- for (const f of instFiles) {
1013
- const v = filenameViolation(INSTANCE_NS, f);
1014
- if (v) violations.push(`migrations/instance/${f}: ${v}`);
1015
- files.push({ source: INSTANCE_NS, basename: f });
1016
- }
1017
-
1018
- let moduleCount = 0;
1019
- for (const key of discoveredModuleKeys()) {
1020
- for (const f of sqlFilesIn(path.join(moduleDir(key), 'migrations'))) {
1021
- moduleCount += 1;
1022
- const v = filenameViolation('module', f, { moduleKey: key });
1023
- if (v) violations.push(`modules/${key}/migrations/${f}: ${v}`);
1024
- files.push({ source: 'module', moduleKey: key, basename: f });
1025
- }
1026
- }
1027
-
1028
- for (const c of stemCollisions(files)) {
1029
- violations.push(`migration stem "${c.stem}" is produced by more than one source (${c.files.join(', ')}) — schema_migrations is stem-keyed, so one applies and the rest are SILENTLY SKIPPED; namespace them (ADR 0108 §5).`);
1030
- }
1031
-
1032
- // Two DIFFERENT stems at one number inside ONE series (task 1003646). Not the
1033
- // silent-skip above — all of them apply — but migrate.sh orders by basename, so
1034
- // their relative order is the alphabetical accident of the slug, and a from-scratch
1035
- // replay can order them differently from the merge order prod applied. Renumbering an
1036
- // APPLIED migration re-runs it, so the fix for a new one is to renumber BEFORE it
1037
- // lands; the single pre-existing case is grandfathered in migration-namespace.js.
1038
- for (const c of numberCollisions(files)) {
1039
- violations.push(`migration number ${String(c.number).padStart(3, '0')} is used by ${c.files.length} different migrations in one series (${c.series}): ${c.files.join(', ')} — each was allocated max+1 from its own branch point. migrate.sh applies in BASENAME order, so their order is decided by the slug alphabetically and a fresh replay can differ from the order prod applied. Renumber the one that has NOT landed yet (renaming an applied migration re-runs it) (task 1003646).`);
1040
- }
1041
-
1042
- return {
1043
- name: 'migration filenames namespaced + no stem/number collision (ADR 0108 §5)',
1044
- ok: violations.length === 0,
1045
- hardFail: violations.length > 0,
1046
- violations,
1047
- warnings: [],
1048
- note: `${coreFiles.length} core + ${instFiles.length} instance + ${moduleCount} module migration file(s): new core→core_, new module→<key>_, instance bare; no cross-root stem collision, and no two migrations share a number within one series.`,
1049
- };
1050
- }
1051
-
1052
- // ============================================================================
1053
- // Check — hall sections are registry-owned, not hardcoded (BV1.R75 / ADR 0062 §4)
1054
- // ============================================================================
1055
- // The builders'-hall widgets are now a REGISTRY (modules/hall-ui/public/dom-utils.js
1056
- // contributeHallWidget; the core set in modules/hall-ui/public/hall-widgets.js, modules
1057
- // via their own client script). The hall's <main> is filled by builders.js from that
1058
- // registry. So no widget may be hardcoded as a literal <section class="scroll"> inside
1059
- // <main> in index.html — that was the pre-R75 second copy this carve removed. This
1060
- // gate fails if one creeps back, keeping the registry the single source of truth (so a
1061
- // reskin/module-toggle reaches every widget). Self-contained: a pure scan of
1062
- // index.html's <main>, no module/registry state needed. Exported for the unit test.
1063
- // (The hall surface itself carved to modules/hall-ui/public/ in BV1.R85.)
1064
- //
1065
- // task 2177 — the check also asserts the HOME ZONE BUDGETS. builders.js caps how
1066
- // many widgets each Home zone mounts (ZONE_BUDGETS); past the cap a widget still
1067
- // mounts, but into a hidden overflow behind a "More" link. That graceful degrade
1068
- // is the runtime safety net — it is NOT a licence to keep adding cards, and
1069
- // because nothing goes red, a Home that has quietly outgrown its budget looks
1070
- // fine. So CI counts the registrations statically and fails on a breach: the
1071
- // budget becomes a decision someone has to make deliberately (raise the number
1072
- // in builders.js, with a reason) instead of one that erodes.
1073
- //
1074
- // NOT statically checkable, by design: the `home-banner` rule is "at most ONE
1075
- // VISIBLE", not "at most one registered" — both banner widgets (welcome,
1076
- // getting-started) are hiddenByDefault and reveal themselves from onboarding
1077
- // state, so only runtime knows the count. It is documented as a runtime
1078
- // invariant in modules/hall-ui/CLAUDE.md rather than faked with a static count
1079
- // that would either fail today or assert nothing.
1080
- const HALL_INDEX = path.join(moduleDir('hall-ui'), 'public', 'index.html'); // hall-ui is a module — resolve its root (ADR 0108)
1081
- const HALL_PUBLIC = path.join(moduleDir('hall-ui'), 'public');
1082
- // task 1003206 split the hall page script: builders.js keeps state/loading/wiring
1083
- // and hall-render.js holds the view painters — ZONE_BUDGETS travelled with the
1084
- // widget mounting. Read whichever of the pair actually declares it, so this
1085
- // check follows the code instead of a filename (it went vacuous on the move).
1086
- const HALL_BUILDERS_JS = path.join(HALL_PUBLIC, 'builders.js');
1087
- const HALL_RENDER_JS = path.join(HALL_PUBLIC, 'hall-render.js');
1088
- function hallWidgetSource() {
1089
- const parts = [];
1090
- for (const f of [HALL_BUILDERS_JS, HALL_RENDER_JS]) {
1091
- try { parts.push(fs.readFileSync(f, 'utf8')); } catch { /* absent → skip */ }
1092
- }
1093
- return parts.join('\n');
1094
- }
1095
-
1096
- // Parse builders.js's ZONE_BUDGETS object literal — the single source of truth
1097
- // for the caps (this check must never carry its own copy of the numbers).
1098
- function parseZoneBudgets(js) {
1099
- const block = js.match(/const\s+ZONE_BUDGETS\s*=\s*\{([^}]*)\}/);
1100
- if (!block) return null;
1101
- const budgets = {};
1102
- for (const [, zone, n] of block[1].matchAll(/['"]([\w-]+)['"]\s*:\s*(\d+)/g)) {
1103
- budgets[zone] = Number(n);
1104
- }
1105
- return Object.keys(budgets).length ? budgets : null;
1106
- }
1107
-
1108
- // Count registrations per Home zone across every hall client script that calls
1109
- // contributeHallWidget. The zones are static string literals in the registration
1110
- // object, so a literal scan is exact for the code we have (and a computed zone
1111
- // would be a placement smell in its own right — dom-utils' runtime validation
1112
- // still rejects an unknown one). Requiring the contributeHallWidget mention is
1113
- // what keeps an unrelated `zone:` key in some other object from eating budget.
1114
- function scanHallZoneCounts(dir = HALL_PUBLIC, fsImpl = fs) {
1115
- const counts = {};
1116
- let files = [];
1117
- try { files = fsImpl.readdirSync(dir).filter((f) => f.endsWith('.js')); } catch { return counts; }
1118
- for (const file of files) {
1119
- let src = '';
1120
- try { src = fsImpl.readFileSync(path.join(dir, file), 'utf8'); } catch { continue; }
1121
- if (!src.includes('contributeHallWidget')) continue;
1122
- for (const [, zone] of src.matchAll(/\bzone:\s*['"]([\w-]+)['"]/g)) {
1123
- counts[zone] = (counts[zone] || 0) + 1;
1124
- }
1125
- }
1126
- return counts;
1127
- }
1128
-
1129
- function checkHallZoneBudgets(fsImpl = fs) {
1130
- let js = '';
1131
- try {
1132
- js = [HALL_BUILDERS_JS, HALL_RENDER_JS]
1133
- .map((f) => { try { return fsImpl.readFileSync(f, 'utf8'); } catch { return ''; } })
1134
- .join('\n');
1135
- } catch { return []; }
1136
- const budgets = parseZoneBudgets(js);
1137
- if (!budgets) {
1138
- return ['modules/hall-ui/public/{builders,hall-render}.js no longer declares a parseable ZONE_BUDGETS literal — the Home zone budgets are unenforced (task 2177).'];
1139
- }
1140
- const counts = scanHallZoneCounts(HALL_PUBLIC, fsImpl);
1141
- const violations = [];
1142
- for (const [zone, budget] of Object.entries(budgets)) {
1143
- const n = counts[zone] || 0;
1144
- if (n > budget) {
1145
- violations.push(
1146
- `Home zone "${zone}" has ${n} registered hall widgets but its budget is ${budget} — the extras mount into the hidden overflow, so Home silently grew. Move it to its own page (see modules/hall-ui/CLAUDE.md §Placement), or raise ZONE_BUDGETS['${zone}'] in modules/hall-ui/public/builders.js deliberately (task 2177).`);
1147
- }
1148
- }
1149
- return violations;
1150
- }
1151
-
1152
- function hallMainSlice(html) {
1153
- // Strip HTML comments first so a comment that merely MENTIONS <main> or a
1154
- // <section class="scroll"> (e.g. the carve's own explanatory note) never trips
1155
- // the scan — only real, rendered markup counts.
1156
- const stripped = html.replace(/<!--[\s\S]*?-->/g, '');
1157
- const open = stripped.indexOf('<main');
1158
- if (open === -1) return '';
1159
- const start = stripped.indexOf('>', open);
1160
- const close = stripped.indexOf('</main>', start === -1 ? open : start);
1161
- if (start === -1 || close === -1) return '';
1162
- return stripped.slice(start + 1, close);
1163
- }
1164
-
1165
- function scanHallSectionRegistry(html) {
1166
- const main = hallMainSlice(html);
1167
- // A hall widget section carries class="scroll" (possibly with modifiers, e.g.
1168
- // "scroll scroll--welcome"). Catch any <section ... class="...scroll..."> in <main>.
1169
- const re = /<section\b[^>]*\bclass\s*=\s*"(?:[^"]*\b)?scroll\b[^"]*"/gi;
1170
- const hits = main.match(re) || [];
1171
- return hits.map((h) => h.replace(/\s+/g, ' ').trim());
1172
- }
1173
-
1174
- function checkHallSectionRegistry() {
1175
- let html = '';
1176
- try { html = fs.readFileSync(HALL_INDEX, 'utf8'); }
1177
- catch { return { name: 'hall widgets are registry-owned (ADR 0062 §4)', ok: true, hardFail: false, violations: [], warnings: ['modules/hall-ui/public/index.html not found — skipped'], note: 'index.html absent.' }; }
1178
- const hardcoded = scanHallSectionRegistry(html);
1179
- const violations = hardcoded.map((s) =>
1180
- `modules/hall-ui/public/index.html <main> hardcodes a hall section "${s}" — register it via window.OTB.contributeHallWidget (modules/hall-ui/public/hall-widgets.js for core, a module's client script otherwise), don't inline the markup (BV1.R75 / ADR 0062 §4).`);
1181
- violations.push(...checkHallZoneBudgets());
1182
- return {
1183
- name: 'hall widgets are registry-owned + within zone budget (ADR 0062 §4, task 2177)',
1184
- ok: violations.length === 0,
1185
- hardFail: violations.length > 0,
1186
- violations,
1187
- warnings: [],
1188
- note: 'modules/hall-ui/public/index.html <main> contains no hardcoded <section class="scroll">, and every Home zone is within the ZONE_BUDGETS cap builders.js declares — the registry is the single source of truth and Home cannot grow unnoticed.',
1189
- };
1190
- }
1191
-
1192
-
1193
- // ============================================================================
1194
- // Check 2c — every SKILL.md frontmatter parses the way Claude Code's YAML reader reads it (task 1003548)
1195
- // ============================================================================
1196
- // Ten of fifty skills shipped with an unquoted description holding ": " or " #": YAML dropped or
1197
- // truncated EVERY field, the skill matched on its body text, and nothing in CI noticed. A parse
1198
- // error is a hard fail; description length and the listing budget are advisory (the listing is
1199
- // resident in every session, ~1% of context, and gets truncated past ~8k chars). The check reads
1200
- // every skill Claude Code can load — the instance's .claude/skills/ AND the module-owned
1201
- // modules/*/skills/ that claude-materialize.js copies into it (task 1003587: scanning only the
1202
- // tracked root meant 14 ui-design skills went unlinted until the untracked copy existed, so four
1203
- // unparseable frontmatters shipped and fitness only went red on a checkout that had materialized).
1204
- // A quiet pass when a checkout carries none (published core).
1205
- function checkSkillFrontmatter() {
1206
- const violations = [];
1207
- const warnings = [];
1208
- let lint;
1209
- try { lint = require('./skill-lint'); } catch (e) {
1210
- return { name: 'skill frontmatter parses (task 1003548)', ok: true, hardFail: false, violations, warnings: [`skill-lint unavailable: ${e.message}`], note: 'linter missing — check skipped.' };
1211
- }
1212
- const files = lint.listSkillFiles(INSTANCE_ROOT);
1213
- // Lint every file; count the listing over the skills RESIDENT here (task 1004470).
1214
- const report = lint.lintSkills(files, { resident: lint.residentSkillFiles(INSTANCE_ROOT, { files }) });
1215
- const rel = (f) => path.relative(INSTANCE_ROOT, f).replace(/\\/g, '/');
1216
- const long = [];
1217
- for (const r of report.results) {
1218
- for (const e of r.errors) violations.push(`${rel(r.file)}: ${e}`);
1219
- if (r.description.length > lint.DESC_WARN_CHARS) long.push({ file: rel(r.file), n: r.description.length });
1220
- }
1221
- if (long.length) {
1222
- long.sort((a, b) => b.n - a.n);
1223
- // The skill's own name is its PARENT dir — a fixed path index would read "skills"
1224
- // for a module-owned path (modules/<key>/skills/<name>/SKILL.md).
1225
- const skillName = (f) => f.split('/').slice(-2, -1)[0] || f;
1226
- warnings.push(`${long.length} description(s) over ${lint.DESC_WARN_CHARS} chars (longest: ${long.slice(0, 4).map((l) => `${skillName(l.file)} ${l.n}`).join(', ')}) — every char is resident in every session; run node scripts/gds/skill-lint.js.`);
1227
- }
1228
- if (report.overBudget) warnings.push(`the skill listing is ${report.listingChars} chars (~${estTokens(report.listingChars)} tokens) against a ~${report.budgetChars}-char budget — Claude Code truncates entries past it and routing degrades.`);
1229
- return {
1230
- name: 'skill frontmatter parses (task 1003548)',
1231
- ok: violations.length === 0,
1232
- hardFail: violations.length > 0,
1233
- violations,
1234
- warnings,
1235
- note: `${report.results.length} SKILL.md file(s) under .claude/skills/ + modules/*/skills/ parse as YAML (name + description present, no ": " / " #" in a plain scalar); length + listing budget advisory.`,
1236
- };
1237
- }
1238
-
1239
- // ============================================================================
1240
- // Check 35 — no raw NUL byte in tracked publishable text (task 1002854)
1241
- // ============================================================================
1242
- //
1243
- // scripts/public-mirror-export.js decides binary-vs-text by sniffing for a NUL byte in
1244
- // the first 8 KiB (`isBinary`, ~line 86), and `redactBlob` skips `redactText` entirely
1245
- // for anything it classifies binary. So a TEXT source containing a raw NUL is published
1246
- // to the public AGPL mirror WITHOUT REDACTION.
1247
- //
1248
- // WHAT THIS IS AND IS NOT. The binary branch is not unguarded: it still leak-scans the
1249
- // blob's latin1 view, so an embedded instance literal trips the gate. But the gate uses
1250
- // `sensitiveLiterals` — raw substrings — while `redactText` applies the full `rules` set.
1251
- // The exposure is therefore the DELTA between them: anything redaction would have
1252
- // rewritten but the literal gate does not recognise ships verbatim. That is a latent
1253
- // unredacted-publish, not a live one, which is why this is a lint rather than a fix.
1254
- //
1255
- // THE CLASS RECURS, WHICH IS THE ARGUMENT FOR A LINT RATHER THAN ANOTHER FIX.
1256
- // Task 1703 found and fixed three instances, all the same mistake: a raw NUL used as a
1257
- // join delimiter instead of the `\u0000` escape. Task 1002507 fixed a fourth in session
1258
- // digests. Open idea 1000523 covers a fifth (search-ingest rollback). This check found
1259
- // four more — modules/copy-desk/proposals.js, scripts/gds/claim.js,
1260
- // scripts/gds/probe-cache.js and tests/copy_inventory.mjs — fixed in the same commit so
1261
- // the check lands green. Nothing prevented any of them; nothing would prevent the next.
1262
- //
1263
- // The fix is always the same and never changes behaviour: `\u0000` compiles to exactly
1264
- // the same string, so hashes, joins and regex ranges are byte-identical at runtime. Only
1265
- // the SOURCE stops carrying the byte.
1266
- //
1267
- // SCOPE. Tracked files only (git ls-files — an untracked scratch file is not published),
1268
- // with publishable text extensions. Binary formats are out of scope by definition: a PNG
1269
- // is *supposed* to contain NULs and the mirror is right to pass it through.
1270
- const NUL_TEXT_EXTS = ['.js', '.mjs', '.cjs', '.mts', '.md', '.sql', '.json'];
1271
-
1272
- // Exemptions must be justified, not just listed. There are none today, and that is the
1273
- // preferred state: the fix is a one-character escape with no behavioural cost, so
1274
- // "exempt it" should always lose to "escape it". Kept as a named, empty constant so a
1275
- // future addition is a visible, reviewable edit rather than a quiet change to a regex.
1276
- const NUL_EXEMPT_PATHS = [];
1277
-
1278
- function scanForRawNul(root, { listFiles, readFile } = {}) {
1279
- const list = listFiles || (() => execFileSync('git', ['ls-files', '-z'], {
1280
- cwd: root, encoding: 'latin1', maxBuffer: 1 << 26,
1281
- }).split('\u0000').filter(Boolean));
1282
- const read = readFile || ((f) => fs.readFileSync(path.join(root, f)));
1283
-
1284
- const hits = [];
1285
- for (const f of list()) {
1286
- if (!NUL_TEXT_EXTS.includes(path.extname(f))) continue;
1287
- if (NUL_EXEMPT_PATHS.some((e) => f === e || f.startsWith(e))) continue;
1288
- let buf;
1289
- try { buf = read(f); } catch (_) { continue; } // deleted-but-tracked, or unreadable
1290
- const at = buf.indexOf(0);
1291
- if (at === -1) continue;
1292
- // Report the LINE, not the byte offset — a byte offset is not actionable.
1293
- const line = buf.slice(0, at).toString('latin1').split('\n').length;
1294
- hits.push(`${f}:${line} — raw NUL byte; use the \\u0000 escape (same string at runtime, no NUL in source)`);
1295
- }
1296
- return hits;
1297
- }
1298
-
1299
- function checkNoRawNulInText() {
1300
- let violations = [];
1301
- let note = '';
1302
- try {
1303
- violations = scanForRawNul(REPO_ROOT);
1304
- note = `tracked ${NUL_TEXT_EXTS.join('/')} sources carry no raw NUL byte, so none can be misclassified `
1305
- + 'as binary and skip public-mirror redaction (task 1002854).';
1306
- } catch (e) {
1307
- // Never let the scan itself fail the build — a git failure is not a boundary breach.
1308
- return {
1309
- name: 'no raw NUL byte in tracked publishable text (task 1002854)',
1310
- ok: true, hardFail: false, violations: [], warnings: [`skipped: ${e.message}`],
1311
- note: 'could not list tracked files — check skipped.',
1312
- };
1313
- }
1314
- return {
1315
- name: 'no raw NUL byte in tracked publishable text (task 1002854)',
1316
- ok: violations.length === 0,
1317
- hardFail: violations.length > 0,
1318
- violations,
1319
- warnings: [],
1320
- note,
1321
- };
1322
- }
1323
-
1324
- const CHECKS = [
1325
- checkCoreHostBoundary,
1326
- checkNoRawNulInText, // Check 35 — task 1002854: a raw NUL makes the mirror skip redaction
1327
- checkClaudeMdBudget,
1328
- // Check 32 — task 1002990 / criterion wa6-kernel-and-packs: the root CLAUDE.md is
1329
- // now a role-neutral KERNEL and each craft's playbook lives in a pack under
1330
- // docs/packs/. claim.js resolves the pack through the role registry and fails
1331
- // OPEN, so a pack path that points at nothing is invisible at runtime — CI is the
1332
- // only place a hollowed-out role can be caught. Rationale in that file.
1333
- require('./role-pack-guard.js').checkRolePacks,
1334
- checkSkillFrontmatter,
1335
- checkNestedDocsPresent,
1336
- checkRankGuards,
1337
- checkModulePinKeysResolve,
1338
- checkGeneratedArtifactsFresh,
1339
- checkDeterministicRoutines,
1340
- checkCoreNeverImportsModule,
1341
- checkModulesImportOnlyApi,
1342
- checkScopeMapImportsProtected,
1343
- // Check 36 — task 1002900: a carved module with no roster key walls nothing. Extracted
1344
- // to its own file (the role-pack-guard.js precedent) to keep fitness.js under the size ratchet.
1345
- () => require('./scope-roster-guard.js').checkScopeRosterCoversModules({ repoRoot: REPO_ROOT, discoveredModuleKeys }),
1346
- checkCoreCarriesNoModuleCode,
1347
- checkKernelImportsNoDomain,
1348
- checkModuleMigrationsAdditive,
1349
- checkMigrationNamespacing, // Check 11b — ADR 0108 §5 cross-repo migration filenames + stem collision
1350
- checkDesignContract,
1351
- checkKernelPromptsNoHardcodedIdentity, // BV1.R76 — kernel prompts read identity from branding()
1352
- checkNeutralConfigsNoHostIdentity, // Check 15b — BV1.R102: .json is outside the scan above
1353
- checkHallSectionRegistry,
1354
- checkCoreRequiresExcludedConfig, // task 1824 — core→instance-config require guard
1355
- checkCoreRequiresExcludedModule, // Check 16b — task 2135: core→excluded-module require guard (R89 split)
1356
- checkErrorEnvelope, // Check 17 — BV1 R03 / task 1990: no route hand-rolls a flat error (ADR 0116)
1357
- checkVocabularyWall, // Check 19 — ADR 0174 / goal 1000068 R07: "role" is a craft, never a rank
1358
- checkGoalMembershipVocabulary, // Check 19b — ADR 0177 / task 1003013: the FOURTH "role" (goal membership)
1359
- checkGovernmentRenameIdentity, checkPrelaunchVocabulary, // 19c task 1003120 (`X`→`X` rename arrow) + 19d task 1003152 ("stealth" is the product's word) — sharing a line: this file is AT the 1,500 budget (Check 23/24 precedent below; task 1003825 buys it back)
1360
- checkWriteRoutesValidated, // Check 18 — BV1 R12 / task 1999: every body-reading write route validates (ADR 0118)
1361
- require('./fitness-ratchets.js').checkQualityRatchets, // Check 20 — task 1003129: quality budgets only tighten (mechanics + knip CI step live in fitness-ratchets.js)
1362
- require('./doc-control-claims.js').checkDocControlClaims, // Check 37 — task 1003418 / audit A14: a doc cannot describe an enforcement control that does not exist (derived from the docs, not a hand list)
1363
- require('./doc-cli-guard.js').checkDocNamesRealCli, // Check 22 — task 1003165 / G01: a doc that names a CLI invocation must match the real CLI
1364
- require('./skill-preflight.js').checkOpsSkillsDeclareMachine, // Check 23 — task 1003167 / G03: an ops skill declares the machine it needs
1365
- // Check 24 — task 1003166 / G02: no ops script hardcodes a version id. It landed
1366
- // sharing Check 23's line, deliberately, because fitness.js was ~500 lines over
1367
- // the excess-lines ratchet and a new check could not afford one (idea 1000810).
1368
- // Task 1003206 carved this file from 2,004 lines to ~1,350, so that toll is paid
1369
- // and the check gets its own line back.
1370
- require('./version-literal-guard.js').checkNoVersionLiterals,
1371
- require('./dev-box-guard.js').checkNoDevBox, // task 1003899 / ADR 0346: the retired dev box stays out (its exemption list lives in that file)
1372
- require('./control-manifest.js').checkControlsExist, // Check 21 — task 1003131: goal-1000076 controls assert their own existence (the ADR 0022 assurance-of-assurance)
1373
- require('./routine-schedule.js').checkRoutineCadencesScheduled, // Check 25 — task 1003209: a routine that declares a cadence must have a scheduler firing it AT that period (ADR 0188)
1374
- require('./baseline-staleness.js').checkBaselineFloors, // Check 26 — task 1003210: a shrink-only baseline that never shrinks is unmanaged debt; a floor exempting one must say why
1375
- require('./client-baseurl-guard.js').checkClientBaseUrl,
1376
- require('./route-shadow-guard.js').checkNoRouteShadowing, // Check 31 — task 1003747: a `:param` route must not swallow a literal route mounted after it (cross-module mount order; the rot feed shipped dead this way). Rationale in that file.
1377
- require('./test-path-guard.js').checkTestsUseFileUrlToPath, // Check 30 — task 1002889: a test builds its repo root with fileURLToPath, never URL.pathname (a %20 or a Windows drive slash makes require() throw at load; CI's spaceless checkout can't see it)
1378
- // Check 29 — task 1003275 / ADR 0189: a work category ORIENTS a human and steers
1379
- // Claude; it authorises nothing. The owner said so twice, and the goal's own prose
1380
- // predicts the failure: a second thing that looks like a hierarchy gets mistaken
1381
- // for one within a release. A comment cannot refuse the line that does it.
1382
- require('./category-advisory-guard.js').checkCategoryIsAdvisory, // Check 27 — task 1003263: a page must not combine baseUrl:'' with a generated namespaced call (that pairing 404s every request; three pages shipped it, two of them dead in prod)
1383
- // Check 28 — task 1001654 / ADR 0095: does each source file open with a module
1384
- // header saying what it does and why. ADVISORY ONLY (never hardFail) — a
1385
- // doc-comment gate that blocks a ship buys filler prose, not understanding.
1386
- // Making it blocking is an owner decision and needs its own ADR.
1387
- require('./doc-comment-coverage.js').checkDocCommentCoverage,
1388
- // Check 31 — task 1003164: two ADRs may not share a number, and docs/adr/README.md
1389
- // must agree with the tree. The ADR half of the guard Check 11b already gives
1390
- // migrations: same shared, monotonic, human-allocated number line, and until this
1391
- // landed only one of the two was enforced. An ADR number is a citation target, so a
1392
- // duplicate is wrong forever (ADR 0195).
1393
- // Check 33 — task 1003819: a module declares what it contributes, and nothing
1394
- // checked that a declared seam is actually WIRED. verifyPortsSatisfied asks the
1395
- // opposite question (every `consumes` has a provider) and validateManifest checks
1396
- // only the SHAPE, so a contributes entry whose artifact was never shipped — or was
1397
- // renamed out from under the manifest — boots silent: every consumer skips it the
1398
- // same way it correctly skips a real declarative-only entry. CI, not boot: nothing
1399
- // crashes later, so a start-up refusal would trade an outage risk for a cosmetic
1400
- // one (ADR 0289). Rationale + the seam→consumer table live in that file.
1401
- require('./seam-wiring-guard.js').checkSeamWiring,
1402
- require('./home-isolation-guard.js').checkHomeIsolation, // Check 34 — task 1003763: a test that sets HOME for a child without USERPROFILE isolates NOTHING on win32, so it silently stops testing what its comment says. Three tasks fixed this one site at a time. Rationale in that file.
1403
- ...['checkDevsecopsOwnsItsChecks', 'checkEveryModuleDirIsScoped', 'checkNoNewUnownedRoot'].map((k) => require('./scope-map-guard.js')[k]), // Check 35 — task 1003949: a check file no MODULE_SCOPE_MAP key owns cannot be authorized by the goal scoped to own it, and the list drifts once per new check. Check 36 — task 1004132: the same defect one level up, a carved module whose own directory no key claims (modules/specialities/ shipped that way). Sharing the line per the ratchet convention above. Rationale in that file.
1404
- require('./adr-namespace.js').checkAdrNumbering, require('./exec-path-guard.js').checkExecPathsStatic, // Check 32 — task 1003371 / B50: what the server EXECUTES, out of whose tree — the blind spot all three 2026-08-29 CRITICALs shared. Rationale + reviewed exemptions live in that file. Sharing Check 31's line (the 19c/19d + 23/24 precedent above): fitness.js is AT the 1,500 ratchet and a new check cannot afford a line until task 1003825 buys it back.
1405
- ];
1406
-
1407
- function runAll() {
1408
- return runChecks(CHECKS); // task 1004737: an installed core has no core source to measure — one skipped result, not a crash
1409
- }
1410
-
1411
- function main() {
1412
- const results = runAll();
1413
- if (process.argv.includes('--json')) {
1414
- process.stdout.write(JSON.stringify(results, null, 2) + '\n');
1415
- } else {
1416
- console.log('Architecture fitness functions (Path C / ADR 0062 §9)\n');
1417
- for (const r of results) {
1418
- const mark = r.hardFail ? '✗ FAIL' : (r.warnings.length ? '! WARN' : '✓ PASS');
1419
- console.log(`${mark} ${r.name}`);
1420
- console.log(` ${r.note}`);
1421
- for (const v of r.violations) console.log(` ✗ ${v}`);
1422
- for (const w of r.warnings) console.log(` ! ${w}`);
1423
- }
1424
- const failed = results.filter((r) => r.hardFail).length;
1425
- console.log(`\n${failed ? `${failed} check(s) FAILED` : 'all checks passed'}.`);
1426
- }
1427
- process.exit(results.some((r) => r.hardFail) ? 1 : 0);
1428
- }
1429
-
1430
- if (require.main === module) main();
1431
-
1432
- module.exports = {
1433
- scanForRawNul,
1434
- checkVocabularyWall, VOCAB_ALLOW, VOCAB_CITATION, VOCAB_EXTS, vocabFilesToScan,
1435
- checkGoalMembershipVocabulary, GOAL_VOCAB_SURFACE, checkGovernmentRenameIdentity, RENAME_IDENTITY_RE, checkPrelaunchVocabulary, PRELAUNCH_SURFACE, // 19c task 1003120, 19d task 1003152
1436
- runAll,
1437
- resolvesToHostGame,
1438
- checkCoreHostBoundary,
1439
- checkClaudeMdBudget,
1440
- checkNestedDocsPresent,
1441
- checkRankGuards,
1442
- checkModulePinKeysResolve,
1443
- checkGeneratedArtifactsFresh,
1444
- checkDeterministicRoutines,
1445
- checkCoreNeverImportsModule,
1446
- checkModulesImportOnlyApi,
1447
- checkScopeMapImportsProtected,
1448
- checkCoreCarriesNoModuleCode,
1449
- checkKernelImportsNoDomain,
1450
- checkModuleMigrationsAdditive,
1451
- checkMigrationNamespacing, // Check 11b — ADR 0108 §5 cross-repo migration filenames
1452
- checkAdrNumbering: require('./adr-namespace.js').checkAdrNumbering, // Check 31 — task 1003164 / ADR 0195: ADR numbers unique + index agrees with the tree
1453
- checkDesignContract,
1454
- checkKernelPromptsNoHardcodedIdentity, // BV1.R76 / task 1705
1455
- scanPromptIdentity, // BV1.R76 — negative-test hook
1456
- stripCommentsForIdentity, // task 1705 — comment-strip helper (tested)
1457
- checkNeutralConfigsNoHostIdentity, // Check 15b — BV1.R102 (tested)
1458
- checkHallSectionRegistry,
1459
- scanHallSectionRegistry,
1460
- hallMainSlice,
1461
- parseZoneBudgets, // task 2177 — hall Home zone budgets (tested)
1462
- scanHallZoneCounts,
1463
- checkHallZoneBudgets,
1464
- checkErrorEnvelope, // Check 17 — BV1 R03 / task 1990 (ADR 0116)
1465
- scanFlatErrorSites, // shared with the R04 sweep + its test
1466
- countFlatErrors, // per-text detector (tested)
1467
- FLAT_ERROR_BASELINE,
1468
- checkWriteRoutesValidated, // Check 18 — BV1 R12 / task 1999 (ADR 0118)
1469
- scanUnvalidatedWriteRoutes, // shared with its test
1470
- WRITE_VALIDATION_EXEMPT,
1471
- scanScopeMapSource,
1472
- scanKernelForModuleKeys,
1473
- kernelDomainImport,
1474
- KERNEL_FILES,
1475
- discoveredModuleKeys,
1476
- manifestModuleKeys, manifestlessModuleDirs, // task 1002790 — narrow defn + the difference
1477
- moduleMigrationViolations,
1478
- moduleNamespace,
1479
- resolvesToModule,
1480
- moduleImportViolation,
1481
- moduleOwnerOf,
1482
- // test/ratchet hook: toggle the module boundary enforce flag. Default is now
1483
- // ENFORCING (BV1.R45 / task 1414); tests that need warn-mode restore the
1484
- // default in a finally.
1485
- _setModuleBoundaryEnforcing: (v) => { MODULE_BOUNDARY_ENFORCING = !!v; },
1486
- scanDeterministicBody,
1487
- HOST_GAME,
1488
- GRANDFATHERED,
1489
- LEGACY_NAMESPACED,
1490
- ROOT_HARD_MAX,
1491
- ROOT_TARGET,
1492
- ROOT_CHAR_HARD_MAX,
1493
- ROOT_CHAR_TARGET,
1494
- HIGH_TRAFFIC,
1495
- };
7
+ require('../bongos/forwarder.js').forward(module, 'fitness.js');