@bongos/core 1.23.21 → 1.24.1

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 (457) hide show
  1. package/.bongos-core.json +983 -428
  2. package/.claude/skills/blocker-review/SKILL.md +9 -1
  3. package/.claude/skills/blocker-solve/SKILL.md +1 -1
  4. package/.claude/skills/builder-claim/SKILL.md +1 -1
  5. package/.claude/skills/builder-reauth/SKILL.md +1 -1
  6. package/.claude/skills/builder-redteam/SKILL.md +1 -1
  7. package/.claude/skills/builder-sequence/SKILL.md +1 -1
  8. package/.claude/skills/builder-setup/SKILL.md +1 -1
  9. package/.claude/skills/builder-ship/SKILL.md +1 -1
  10. package/.claude/skills/collab-review/SKILL.md +5 -2
  11. package/.claude/skills/design/SKILL.md +1 -1
  12. package/.claude/skills/goal-create/SKILL.md +6 -3
  13. package/.claude/skills/grade-recover/SKILL.md +1 -1
  14. package/.claude/skills/merge-mode/SKILL.md +1 -1
  15. package/.claude/skills/owner-review/SKILL.md +1 -1
  16. package/.claude/skills/planning-session/SKILL.md +11 -11
  17. package/.claude/skills/read-session-export/SKILL.md +1 -1
  18. package/.claude/skills/recall/SKILL.md +1 -1
  19. package/.claude/skills/scan-before-install/SKILL.md +1 -1
  20. package/.claude/skills/session-handoff/SKILL.md +1 -1
  21. package/.claude/skills/strand-fix/SKILL.md +13 -0
  22. package/.claude/skills/worktree-clean/SKILL.md +1 -1
  23. package/AGENTS.md +15 -0
  24. package/GEMINI.md +5 -0
  25. package/clients/bongos-client/README.md +1 -1
  26. package/clients/bongos-client/bongos-client.global.js +94 -0
  27. package/clients/bongos-client/index.cjs +94 -0
  28. package/clients/bongos-client/index.d.ts +154 -4
  29. package/clients/bongos-client/index.mjs +94 -0
  30. package/docs/adr/0054-session-token-reward-cost-plus.md +3 -1
  31. package/docs/adr/0055-server-mediated-branch-publish.md +1 -1
  32. package/docs/adr/0385-money-lives-with-a-processor-credits-stay-a-project-meter.md +87 -0
  33. package/docs/adr/0386-the-funding-wall-is-a-per-project-rule-claim-time-hold-by-default.md +37 -0
  34. package/docs/adr/0387-two-ledgers-credits-measure-work-money-stays-with-the-processor.md +39 -0
  35. package/docs/adr/0388-a-module-sale-is-split-by-the-project-the-buyer-pays-the-platform-fee.md +42 -0
  36. package/docs/adr/0392-ai-generation-runs-on-a-processor-held-balance-and-the-builders-own-keys.md +33 -0
  37. package/docs/adr/0393-a-platform-account-is-a-person-and-github-is-one-way-in.md +37 -0
  38. package/docs/adr/0394-market-watch-searches-through-the-messages-api-on-the-projects-key-and-runs-from-its-own-poller.md +102 -0
  39. package/docs/adr/0395-a-task-says-what-it-needs-and-lists-show-only-what-you-can-do.md +36 -0
  40. package/docs/adr/0396-google-sign-in-a-stand-in-login-and-a-browser-approved-cli-sign-in.md +41 -0
  41. package/docs/adr/README.md +10 -1
  42. package/docs/api/openapi.json +8619 -5885
  43. package/docs/api-reference.md +68 -9
  44. package/docs/architecture.md +37 -1
  45. package/docs/canonical-permissions.md +1 -1
  46. package/docs/copy-inventory.md +420 -337
  47. package/docs/copy-registry.json +1321 -500
  48. package/docs/file-map.md +4 -0
  49. package/docs/module-api-changelog.md +7 -0
  50. package/docs/onboarding/diagrams/03-drachmae-karma.mmd +3 -3
  51. package/docs/onboarding/diagrams/README.md +1 -1
  52. package/docs/onboarding/drachmae-and-karma.md +15 -15
  53. package/docs/onboarding/primer.md +2 -2
  54. package/docs/page-inventory.json +55 -6
  55. package/docs/page-readings.json +1185 -1011
  56. package/docs/recipes/google-sign-in.md +60 -0
  57. package/docs/recipes/ops-gotchas.md +1 -1
  58. package/migrations/core_282_builders_lower_login_idx.sql +33 -0
  59. package/migrations/core_283_claimable_ignores_page_markers.sql +53 -0
  60. package/migrations/core_283_payout_approvals.sql +183 -0
  61. package/migrations/core_284_payout_gates.sql +179 -0
  62. package/migrations/core_285_task_needs.sql +74 -0
  63. package/modules/ai-studio/CLAUDE.md +15 -0
  64. package/modules/ai-studio/billing.js +67 -0
  65. package/modules/ai-studio/context.js +29 -0
  66. package/modules/ai-studio/db.js +172 -0
  67. package/modules/ai-studio/gemini.js +75 -0
  68. package/modules/ai-studio/generate.js +119 -0
  69. package/modules/ai-studio/keys.js +73 -0
  70. package/modules/ai-studio/migrations/ai_studio_001_keys.sql +22 -0
  71. package/modules/ai-studio/migrations/ai_studio_002_ledger.sql +48 -0
  72. package/modules/ai-studio/migrations/ai_studio_003_requests.sql +55 -0
  73. package/modules/ai-studio/module.json +26 -0
  74. package/modules/ai-studio/openrouter.js +90 -0
  75. package/modules/ai-studio/payments.js +105 -0
  76. package/modules/ai-studio/pricing.js +92 -0
  77. package/modules/ai-studio/routes/ai-studio.js +252 -0
  78. package/modules/ai-studio/studio.js +121 -0
  79. package/modules/autonomy/fence.js +64 -1
  80. package/modules/builder-settings/builder-needs.js +27 -1
  81. package/modules/copy-desk/routes/copy-desk.js +5 -0
  82. package/modules/economy/achievements.js +22 -10
  83. package/modules/economy/cost-classify.js +9 -0
  84. package/modules/economy/cost-write-guard.js +52 -0
  85. package/modules/economy/cost.js +2 -1
  86. package/modules/economy/credits.js +18 -15
  87. package/modules/economy/goal-reward.js +161 -0
  88. package/modules/economy/reward.js +4 -0
  89. package/modules/economy/routes/cost.js +33 -7
  90. package/modules/government/catalog.js +6 -0
  91. package/modules/government/db.js +108 -0
  92. package/modules/government/docket.js +36 -0
  93. package/modules/government/migrations/government_035_payout_approve.sql +29 -0
  94. package/modules/government/pollers/board-expiry.js +108 -20
  95. package/modules/government/protected-surfaces.json +1 -0
  96. package/modules/government/routes/government.js +50 -18
  97. package/modules/government/routing.js +39 -5
  98. package/modules/government/waiting.js +74 -0
  99. package/modules/grading/grader-subagent.js +30 -11
  100. package/modules/hall-ui/public/ai-studio-lib.js +268 -0
  101. package/modules/hall-ui/public/ai-studio.css +193 -0
  102. package/modules/hall-ui/public/ai-studio.html +98 -0
  103. package/modules/hall-ui/public/ai-studio.js +556 -0
  104. package/modules/hall-ui/public/ai-studio.states.json +94 -0
  105. package/modules/hall-ui/public/blockers-by-person.js +156 -0
  106. package/modules/hall-ui/public/blockers-lib.js +15 -1
  107. package/modules/hall-ui/public/blockers.html +8 -0
  108. package/modules/hall-ui/public/blockers.js +1 -1
  109. package/modules/hall-ui/public/city.html +15 -15
  110. package/modules/hall-ui/public/claim-action.js +3 -0
  111. package/modules/hall-ui/public/collab.html +12 -0
  112. package/modules/hall-ui/public/craft-mode.js +4 -1
  113. package/modules/hall-ui/public/criterion-uat-ui.js +4 -1
  114. package/modules/hall-ui/public/drachmae.html +1 -1
  115. package/modules/hall-ui/public/genesis/r5-life-1-primordial-sea.jpg +0 -0
  116. package/modules/hall-ui/public/genesis/r5-life-2-first-cells-cut.webp +0 -0
  117. package/modules/hall-ui/public/genesis/r5-life-2-first-cells.jpg +0 -0
  118. package/modules/hall-ui/public/genesis/r5-life-3-genome-cut.webp +0 -0
  119. package/modules/hall-ui/public/genesis/r5-life-3-genome.jpg +0 -0
  120. package/modules/hall-ui/public/genesis/r5-life-4-membrane-cut.webp +0 -0
  121. package/modules/hall-ui/public/genesis/r5-life-4-membrane.jpg +0 -0
  122. package/modules/hall-ui/public/genesis/r5-life-5-nervous-system-cut.webp +0 -0
  123. package/modules/hall-ui/public/genesis/r5-life-5-nervous-system.jpg +0 -0
  124. package/modules/hall-ui/public/goal-inbox.js +1 -1
  125. package/modules/hall-ui/public/goals-render.js +4 -0
  126. package/modules/hall-ui/public/goals.html +8 -0
  127. package/modules/hall-ui/public/gov-living.js +6 -2
  128. package/modules/hall-ui/public/hall-ask.css +5 -0
  129. package/modules/hall-ui/public/hall-ask.js +39 -3
  130. package/modules/hall-ui/public/notes-panel.css +20 -0
  131. package/modules/hall-ui/public/notes-panel.js +146 -0
  132. package/modules/hall-ui/public/project-settings.html +1 -1
  133. package/modules/hall-ui/public/project-settings.js +7 -5
  134. package/modules/hall-ui/public/settings-ai-keys.js +124 -0
  135. package/modules/hall-ui/public/settings.html +15 -0
  136. package/modules/hall-ui/public/street-deck.js +12 -3
  137. package/modules/hall-ui/public/studio.css +90 -8
  138. package/modules/hall-ui/public/studio.html +39 -10
  139. package/modules/hall-ui/public/studio.js +148 -18
  140. package/modules/hall-ui/public/task.html +2 -0
  141. package/modules/hall-ui/public/task.js +4 -0
  142. package/modules/hall-ui/public/tweak-editor.js +12 -3
  143. package/modules/hall-ui/public/welcome-boot.css +42 -6
  144. package/modules/hall-ui/public/welcome-boot.js +20 -6
  145. package/modules/hall-ui/public/work.js +20 -0
  146. package/modules/hall-ui/records/ai-studio.md +36 -0
  147. package/modules/hall-ui/records/blockers-people.md +24 -0
  148. package/modules/lifecycle/db-analytics.js +10 -3
  149. package/modules/lifecycle/db-claims.js +32 -4
  150. package/modules/lifecycle/db-goals.js +48 -18
  151. package/modules/lifecycle/db-shared.js +9 -0
  152. package/modules/lifecycle/db-tasks.js +15 -6
  153. package/modules/lifecycle/db-versions.js +21 -8
  154. package/modules/lifecycle/done-when.js +23 -1
  155. package/modules/lifecycle/lifecycle.js +5 -0
  156. package/modules/lifecycle/migrations/lifecycle_017_notes.sql +46 -0
  157. package/modules/lifecycle/module.json +2 -1
  158. package/modules/lifecycle/notes.js +219 -0
  159. package/modules/lifecycle/page-notice.js +124 -0
  160. package/modules/lifecycle/page-tweak-artist.js +18 -1
  161. package/modules/lifecycle/publish-reconciler.js +67 -20
  162. package/modules/lifecycle/routes/claims.js +5 -2
  163. package/modules/lifecycle/routes/goals.js +3 -1
  164. package/modules/lifecycle/routes/notes.js +91 -0
  165. package/modules/lifecycle/routes/project-settings.js +43 -35
  166. package/modules/lifecycle/routes/task-route-helpers.js +21 -0
  167. package/modules/lifecycle/routes/task-write-routes.js +21 -3
  168. package/modules/lifecycle/routes/tasks.js +12 -12
  169. package/modules/lifecycle/ship-assurance.js +4 -1
  170. package/modules/lifecycle/ship-card.js +8 -2
  171. package/modules/lifecycle/task-needs-gate.js +70 -0
  172. package/modules/market-watch/CLAUDE.md +15 -0
  173. package/modules/market-watch/db.js +340 -0
  174. package/modules/market-watch/key.js +58 -0
  175. package/modules/market-watch/migrations/market_watch_001_tables.sql +249 -0
  176. package/modules/market-watch/migrations/market_watch_002_run.sql +46 -0
  177. package/modules/market-watch/module.json +26 -0
  178. package/modules/market-watch/pollers/hub-seed.js +54 -0
  179. package/modules/market-watch/pollers/weekly-run.js +100 -0
  180. package/modules/market-watch/research.js +350 -0
  181. package/modules/market-watch/run.js +245 -0
  182. package/modules/market-watch/seed/market-data.json +38 -0
  183. package/modules/market-watch/seed/partners-data.json +497 -0
  184. package/modules/market-watch/seed.js +252 -0
  185. package/modules/market-watch/store.js +230 -0
  186. package/modules/memory/routes/memory.js +14 -2
  187. package/modules/memory/routes/search.js +8 -2
  188. package/modules/onboarding/howto-moments.js +8 -1
  189. package/modules/platform-identity/account-logins.js +192 -0
  190. package/modules/platform-identity/migrations/platform_identity_034_account_logins.sql +96 -0
  191. package/modules/platform-identity/platform-identity.js +5 -4
  192. package/modules/platform-identity/routes/my-projects.js +6 -0
  193. package/modules/platform-identity/routes/profile.js +18 -0
  194. package/modules/platform-identity/routes/public-profile.js +10 -1
  195. package/modules/platform-identity/routes/sso.js +26 -1
  196. package/modules/platform-identity/tests/platform-identity.mjs +2 -1
  197. package/modules/provisioning/credential-preflight.js +13 -3
  198. package/modules/provisioning/pollers/app-liveness.js +25 -5
  199. package/modules/provisioning/routes/provisioning.js +1 -1
  200. package/modules/provisioning/starter-bundles.js +8 -2
  201. package/modules/public-landing/public/account.html +10 -2
  202. package/modules/public-landing/public/assets/world/r2-bongos-chrome-b.jpg +0 -0
  203. package/modules/public-landing/public/assets/world/r2-bongos-chrome-b.jpg.json +1 -1
  204. package/modules/public-landing/public/assets/world/r2-bongos-chrome-b.webp +0 -0
  205. package/modules/public-landing/public/assets/world/r2-bongos-chrome-b.webp.json +1 -1
  206. package/modules/public-landing/public/assets/world/r2-chrome-blob-one-cut.webp +0 -0
  207. package/modules/public-landing/public/assets/world/r2-chrome-blob-one-cut.webp.json +1 -1
  208. package/modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg +0 -0
  209. package/modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg.json +1 -1
  210. package/modules/public-landing/public/assets/world/r2-chrome-blob-one.webp +0 -0
  211. package/modules/public-landing/public/assets/world/r2-chrome-blob-one.webp.json +1 -1
  212. package/modules/public-landing/public/assets/world/r2-chrome-blobs-set.jpg +0 -0
  213. package/modules/public-landing/public/assets/world/r2-chrome-blobs-set.jpg.json +1 -1
  214. package/modules/public-landing/public/assets/world/r2-chrome-blobs-set.webp +0 -0
  215. package/modules/public-landing/public/assets/world/r2-chrome-blobs-set.webp.json +1 -1
  216. package/modules/public-landing/public/assets/world/r3-frost-bead-cut.webp +0 -0
  217. package/modules/public-landing/public/assets/world/r3-frost-bead-cut.webp.json +1 -1
  218. package/modules/public-landing/public/assets/world/r3-frost-pair-cut.webp +0 -0
  219. package/modules/public-landing/public/assets/world/r3-frost-pair-cut.webp.json +1 -1
  220. package/modules/public-landing/public/assets/world/r3-gold-blob-cut.webp +0 -0
  221. package/modules/public-landing/public/assets/world/r3-gold-blob-cut.webp.json +1 -1
  222. package/modules/public-landing/public/assets/world/r3-gold-pair-cut.webp +0 -0
  223. package/modules/public-landing/public/assets/world/r3-gold-pair-cut.webp.json +1 -1
  224. package/modules/public-landing/public/assets/world/r3-obsidian-blob-cut.webp +0 -0
  225. package/modules/public-landing/public/assets/world/r3-obsidian-blob-cut.webp.json +1 -1
  226. package/modules/public-landing/public/assets/world/r3-obsidian-pair-cut.webp +0 -0
  227. package/modules/public-landing/public/assets/world/r3-obsidian-pair-cut.webp.json +1 -1
  228. package/modules/public-landing/public/assets/world/r3-space-nebula.jpg +0 -0
  229. package/modules/public-landing/public/assets/world/r3-space-nebula.jpg.json +1 -1
  230. package/modules/public-landing/public/assets/world/r4-card-chrome.jpg +0 -0
  231. package/modules/public-landing/public/assets/world/r4-card-chrome.jpg.json +1 -1
  232. package/modules/public-landing/public/assets/world/r4-card-nebula.jpg +0 -0
  233. package/modules/public-landing/public/assets/world/r4-card-nebula.jpg.json +1 -1
  234. package/modules/public-landing/public/assets/world/r5-life-1-primordial-sea.jpg +0 -0
  235. package/modules/public-landing/public/assets/world/r5-life-1-primordial-sea.jpg.json +1 -1
  236. package/modules/public-landing/public/assets/world/r5-life-2-first-cells-cut.webp +0 -0
  237. package/modules/public-landing/public/assets/world/r5-life-2-first-cells-cut.webp.json +1 -1
  238. package/modules/public-landing/public/assets/world/r5-life-2-first-cells.jpg +0 -0
  239. package/modules/public-landing/public/assets/world/r5-life-2-first-cells.jpg.json +1 -1
  240. package/modules/public-landing/public/assets/world/r5-life-3-genome-cut.webp +0 -0
  241. package/modules/public-landing/public/assets/world/r5-life-3-genome-cut.webp.json +1 -1
  242. package/modules/public-landing/public/assets/world/r5-life-3-genome.jpg +0 -0
  243. package/modules/public-landing/public/assets/world/r5-life-3-genome.jpg.json +1 -1
  244. package/modules/public-landing/public/assets/world/r5-life-4-membrane-cut.webp +0 -0
  245. package/modules/public-landing/public/assets/world/r5-life-4-membrane-cut.webp.json +1 -1
  246. package/modules/public-landing/public/assets/world/r5-life-4-membrane.jpg +0 -0
  247. package/modules/public-landing/public/assets/world/r5-life-4-membrane.jpg.json +1 -1
  248. package/modules/public-landing/public/assets/world/r5-life-5-nervous-system-cut.webp +0 -0
  249. package/modules/public-landing/public/assets/world/r5-life-5-nervous-system-cut.webp.json +1 -1
  250. package/modules/public-landing/public/assets/world/r5-life-5-nervous-system.jpg +0 -0
  251. package/modules/public-landing/public/assets/world/r5-life-5-nervous-system.jpg.json +1 -1
  252. package/modules/public-landing/public/community.html +1 -1
  253. package/modules/public-landing/public/connections.html +2 -2
  254. package/modules/public-landing/public/guild.html +1 -1
  255. package/modules/public-landing/public/invitations.html +2 -2
  256. package/modules/public-landing/public/projects.html +5 -5
  257. package/modules/raise/views/nda.html +2 -0
  258. package/modules/specialities/db.js +32 -1
  259. package/modules/specialities/routes/specialities.js +10 -6
  260. package/modules/status-ui/public/index.html +1 -1
  261. package/package-lock.json +2 -2
  262. package/package.json +1 -1
  263. package/release-notes.json +286 -0
  264. package/scripts/bongos/autobongos-tweak-lane.js +46 -1
  265. package/scripts/bongos/backfill-subagent-rewards.js +2 -2
  266. package/scripts/bongos/claim.js +22 -1
  267. package/scripts/bongos/db-backup-nightly.sh +29 -0
  268. package/scripts/bongos/deploy-divergence.js +7 -0
  269. package/scripts/bongos/doc-cli-guard.js +6 -0
  270. package/scripts/bongos/fitness.js +3 -2
  271. package/scripts/bongos/gen-diagrams.js +3 -3
  272. package/scripts/bongos/lib.sh +4 -5
  273. package/scripts/bongos/migration-namespace.js +13 -1
  274. package/scripts/bongos/plain-cards.js +4 -0
  275. package/scripts/bongos/provision-github-setup.js +3 -1
  276. package/scripts/bongos/provision-units.js +6 -1
  277. package/scripts/bongos/publish-manifest.js +4 -0
  278. package/scripts/bongos/release.js +2 -0
  279. package/scripts/bongos/run-unit-tests.js +268 -82
  280. package/scripts/bongos/seed-tasks.example.json +56 -0
  281. package/scripts/bongos/seed-tasks.js +222 -0
  282. package/scripts/bongos/seed-verify-criteria.js +1 -2
  283. package/scripts/bongos/ship-finish.js +2 -0
  284. package/scripts/bongos/ship-resume.js +2 -0
  285. package/scripts/bongos/strand-lease.js +250 -0
  286. package/scripts/bongos/strand-watch.js +129 -12
  287. package/scripts/bongos/version-literal-guard.js +2 -2
  288. package/scripts/discord/post.js +4 -3
  289. package/scripts/gds/seed-tasks.js +7 -0
  290. package/scripts/gds/{build-bongos.js → strand-lease.js} +3 -3
  291. package/scripts/hall-preview/server.js +21 -0
  292. package/src/bongos/auth-config.js +29 -1
  293. package/src/bongos/auth-discord.js +3 -3
  294. package/src/bongos/auth-github.js +3 -6
  295. package/src/bongos/auth-google.js +217 -0
  296. package/src/bongos/device-approval.js +140 -0
  297. package/src/bongos/llm-pricing.js +17 -1
  298. package/src/bongos/metrics.js +48 -2
  299. package/src/bongos/middleware/rate-limit.js +30 -11
  300. package/src/bongos/module-scope-map.js +16 -1
  301. package/src/bongos/optimizer.js +15 -1
  302. package/src/bongos/payout-approvals.js +342 -0
  303. package/src/bongos/payout-gates.js +364 -0
  304. package/src/bongos/prelaunch-gate.js +7 -9
  305. package/src/bongos/prelaunch-switch.js +20 -0
  306. package/src/bongos/route-rank-check.js +3 -0
  307. package/src/bongos/routes/auth-google.js +246 -0
  308. package/src/bongos/routes/auth.js +38 -1
  309. package/src/bongos/routes/backup.js +33 -9
  310. package/src/bongos/routes/builders.js +57 -30
  311. package/src/bongos/routes/github.js +9 -0
  312. package/src/bongos/routes/me.js +18 -0
  313. package/src/bongos/routes/my-payouts.js +133 -0
  314. package/src/bongos/routes/payout-approvals.js +312 -0
  315. package/src/bongos/routes/payout-gates.js +179 -0
  316. package/src/bongos/routes.js +15 -1
  317. package/src/bongos/secret-box.js +18 -3
  318. package/src/bongos/serve-internal.js +47 -19
  319. package/src/bongos/sign-in-pages.js +138 -0
  320. package/src/bongos/task-needs.js +146 -0
  321. package/src/bongos-downloads.js +18 -1
  322. package/src/instance-config.js +28 -0
  323. package/src/module-api.js +14 -1
  324. package/src/platform-server.js +27 -1
  325. package/tests/account_logins.mjs +326 -0
  326. package/tests/account_logins_db.mjs +161 -0
  327. package/tests/ai_studio_billing.mjs +253 -0
  328. package/tests/ai_studio_generate.mjs +282 -0
  329. package/tests/ai_studio_keys.mjs +159 -0
  330. package/tests/ai_studio_requests.mjs +319 -0
  331. package/tests/auth_backchannel_logout_route.mjs +201 -0
  332. package/tests/auto_satisfy_criteria.mjs +10 -1
  333. package/tests/autobongos_tweak_lane.mjs +144 -0
  334. package/tests/autobongos_tweak_pin_identity.mjs +137 -0
  335. package/tests/backfill_subagent_rewards.mjs +17 -1
  336. package/tests/backup_trigger_lock.mjs +119 -0
  337. package/tests/batched_writes_parity.mjs +340 -0
  338. package/tests/blockers_people.mjs +198 -0
  339. package/tests/bounded_rate_maps.mjs +184 -0
  340. package/tests/claimable_blocker_status.mjs +1 -1
  341. package/tests/claims_batch_routes.mjs +421 -0
  342. package/tests/conductor_main_e2e.mjs +4 -0
  343. package/tests/config_read_cache.mjs +171 -0
  344. package/tests/copy_desk_page_editor.mjs +12 -0
  345. package/tests/cost_write_guard.mjs +200 -0
  346. package/tests/craft_achievements.mjs +33 -10
  347. package/tests/criterion_goal_attach.mjs +1 -1
  348. package/tests/db_backup_nightly.mjs +73 -1
  349. package/tests/deploy_divergence_line.mjs +7 -0
  350. package/tests/effective_visibility_predicate.mjs +12 -0
  351. package/tests/fitness.mjs +19 -0
  352. package/tests/fixtures/per-row-loops-legacy.cjs +245 -0
  353. package/tests/fixtures/seed-tasks/bongos-v1-idea-routing.json +256 -0
  354. package/tests/fixtures/seed-tasks/bv1-profiles.json +592 -0
  355. package/tests/fixtures/seed-tasks/bv2-ideator-surface.json +373 -0
  356. package/tests/fixtures/seed-tasks/fake-api.mjs +80 -0
  357. package/tests/github_one_trip.mjs +34 -0
  358. package/tests/github_repo_visibility.mjs +20 -0
  359. package/tests/goal_achievement.mjs +30 -1
  360. package/tests/goal_achievement_reward.mjs +205 -0
  361. package/tests/goal_archive_disposition.mjs +5 -5
  362. package/tests/goal_sort_staleness.mjs +2 -1
  363. package/tests/goal_tier.mjs +11 -1
  364. package/tests/google_fonts_nonblocking.mjs +84 -0
  365. package/tests/google_sign_in.mjs +401 -0
  366. package/tests/government_board_expiry.mjs +94 -0
  367. package/tests/government_protected_surfaces.mjs +1 -1
  368. package/tests/government_routes.mjs +146 -23
  369. package/tests/grader.mjs +31 -0
  370. package/tests/hall_ai_studio.mjs +347 -0
  371. package/tests/hall_city.mjs +8 -0
  372. package/tests/hall_page_gate_map.mjs +3 -0
  373. package/tests/hall_studio_home.mjs +61 -2
  374. package/tests/home_attention_cards.mjs +1 -1
  375. package/tests/hook_shell_tools.mjs +8 -0
  376. package/tests/hooks_drain.mjs +1 -1
  377. package/tests/host_topology_skips.mjs +2 -0
  378. package/tests/howto_moments.mjs +17 -0
  379. package/tests/human_signal.mjs +141 -0
  380. package/tests/install_script_reader.mjs +51 -0
  381. package/tests/integration_fixture_ids.mjs +82 -0
  382. package/tests/invite_expiry_db.mjs +13 -1
  383. package/tests/lib_sh_resolution.mjs +0 -4
  384. package/tests/market_watch_data.mjs +244 -0
  385. package/tests/market_watch_data_db.mjs +308 -0
  386. package/tests/market_watch_module.mjs +114 -0
  387. package/tests/market_watch_run.mjs +503 -0
  388. package/tests/metrics.mjs +124 -0
  389. package/tests/migration_namespace.mjs +14 -0
  390. package/tests/module_api.mjs +2 -0
  391. package/tests/module_loader.mjs +1 -1
  392. package/tests/module_skills_hook.mjs +69 -0
  393. package/tests/notes.mjs +182 -0
  394. package/tests/own_scope_guard.mjs +5 -0
  395. package/tests/page_tweak_marker_sql.mjs +76 -0
  396. package/tests/page_tweak_no_block.mjs +135 -0
  397. package/tests/page_tweak_notice.mjs +103 -0
  398. package/tests/payout_approvals.mjs +253 -0
  399. package/tests/payout_approvals_db.mjs +106 -0
  400. package/tests/payout_gates.mjs +322 -0
  401. package/tests/payout_gates_db.mjs +113 -0
  402. package/tests/planning_session_skill.mjs +13 -3
  403. package/tests/project_settings_page.mjs +29 -5
  404. package/tests/project_settings_spend_cap_route.mjs +235 -0
  405. package/tests/promotion_sweep.mjs +29 -1
  406. package/tests/provision.mjs +3 -2
  407. package/tests/provisioning_app_status.mjs +18 -0
  408. package/tests/provisioning_credential_preflight.mjs +53 -0
  409. package/tests/provisioning_env_manifest_edit_delete.mjs +223 -0
  410. package/tests/public_landing_projects.mjs +37 -0
  411. package/tests/publish_reconciler_overlap.mjs +60 -0
  412. package/tests/rank_change_broadcast_port.mjs +151 -0
  413. package/tests/seed_tasks.mjs +176 -0
  414. package/tests/seed_verify_criteria.mjs +2 -6
  415. package/tests/session_start_freshness.mjs +66 -1
  416. package/tests/shell_hooks.mjs +209 -0
  417. package/tests/ship_assurance.mjs +28 -0
  418. package/tests/ship_card.mjs +20 -5
  419. package/tests/site_classified_once.mjs +142 -0
  420. package/tests/speciality_db_shape.mjs +23 -0
  421. package/tests/speciality_session_skills.mjs +48 -2
  422. package/tests/strand_lease.mjs +249 -0
  423. package/tests/strand_watch.mjs +58 -0
  424. package/tests/task_criteria_routes.mjs +275 -0
  425. package/tests/task_criteria_unlink_db.mjs +123 -0
  426. package/tests/task_needs.mjs +233 -0
  427. package/tests/task_needs_db.mjs +110 -0
  428. package/tests/unit_runner_serial.mjs +266 -43
  429. package/tests/version_close_route.mjs +1 -1
  430. package/tests/version_literals.mjs +5 -7
  431. package/tests/welcome_boot.mjs +16 -5
  432. package/tests/welcome_boot_browser.mjs +36 -4
  433. package/docs/recipes/bongos-cli-release.md +0 -66
  434. package/scripts/bongos/backfill-disciplines.js +0 -144
  435. package/scripts/bongos/backfill-session-earnings.js +0 -123
  436. package/scripts/bongos/backfill-session-types.js +0 -87
  437. package/scripts/bongos/build-bongos.js +0 -94
  438. package/scripts/bongos/cleanup-orphans.js +0 -74
  439. package/scripts/bongos/seed-bongos-v1-idea-routing-tasks.js +0 -152
  440. package/scripts/bongos/seed-bv1-profiles-tasks.js +0 -135
  441. package/scripts/bongos/seed-bv2-ideator-surface-tasks.js +0 -390
  442. package/scripts/bongos/smoke-batch-claim.sh +0 -238
  443. package/scripts/bongos/smoke-batch-release.sh +0 -316
  444. package/scripts/bongos/smoke-claim-consistency.sh +0 -222
  445. package/scripts/bongos/smoke-dependencies.sh +0 -143
  446. package/scripts/gds/backfill-disciplines.js +0 -7
  447. package/scripts/gds/backfill-session-earnings.js +0 -7
  448. package/scripts/gds/backfill-session-types.js +0 -7
  449. package/scripts/gds/cleanup-orphans.js +0 -7
  450. package/scripts/gds/seed-bongos-v1-idea-routing-tasks.js +0 -6
  451. package/scripts/gds/seed-bv1-profiles-tasks.js +0 -6
  452. package/scripts/gds/seed-bv2-ideator-surface-tasks.js +0 -6
  453. package/scripts/gds/smoke-batch-claim.sh +0 -8
  454. package/scripts/gds/smoke-batch-release.sh +0 -8
  455. package/scripts/gds/smoke-claim-consistency.sh +0 -8
  456. package/scripts/gds/smoke-dependencies.sh +0 -8
  457. package/tests/smoke_dependencies_witness.mjs +0 -46
@@ -8,6 +8,6 @@
8
8
  "task": 1003649,
9
9
  "prompt": "Product render on a pure black background: a pair of bongo drums, one larger and one smaller joined by a short bridge, their shells liquid chrome with iridescent bronze, blue and violet reflections, crisp clean silhouette, seen straight on from slightly below so the drumheads are thin ellipses, faintly translucent drumheads, no hands, no text, no ground plane, no cast shadow or glow on the background. Pure black everywhere the drums are not.",
10
10
  "source": ".impeccable/mocks/world-assets/r2-bongos-chrome-b.jpg",
11
- "encoded": "ffmpeg libwebp quality 88, yuv420p, full resolution, black ground kept at the source JPEG level (task 1003649)",
11
+ "encoded": "ffmpeg libwebp quality 88, yuv420p, full resolution, black ground kept at the source JPEG level (task 1003649); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 78, same 2048x2048 and format, 45.1dB PSNR against the previous file, 156610 -> 99474 bytes (task 1004930)",
12
12
  "use": "dark mode: black plate composited with mix-blend-mode lighten"
13
13
  }
@@ -8,6 +8,6 @@
8
8
  "task": 1003297,
9
9
  "prompt": "Background removed (Higgsfield image_background_remover) from r2-chrome-blob-one: a single liquid-chrome blob, mirror-polished with iridescent bronze, blue and violet reflections. Cut out so the bead can sit on a non-black ground (the landing's light mode, project orbs); the black plate with lighten blend stays the dark-mode material.",
10
10
  "source": ".impeccable/mocks/world-assets/r2-chrome-blob-one-cut.png",
11
- "encoded": "ffmpeg libwebp quality 88, alpha kept, 1600px (task 1003298)",
11
+ "encoded": "ffmpeg libwebp quality 88, alpha kept, 1600px (task 1003298); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 82, same 1600x1600 and format, 45.3dB PSNR against the previous file, 86516 -> 73980 bytes (task 1004930)",
12
12
  "use": "light mode: alpha cutout on the pale ground"
13
13
  }
@@ -7,6 +7,6 @@
7
7
  "round": 2,
8
8
  "prompt": "A single iridescent liquid-chrome blob, a glossy organic form with a crisp clean edge and a mirror-smooth surface reflecting bronze, deep blue and violet with one thin bright rim highlight, centred on a pure black background, nothing else, no text, no ground plane, no shadow or glow on the background. Pure black everywhere the blob is not.",
9
9
  "source": ".impeccable/mocks/world-assets/r2-chrome-blob-one.jpg",
10
- "encoded": "verbatim copy of the plate (task 1003298)",
10
+ "encoded": "verbatim copy of the plate (task 1003298); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 75, same 2048x2048 and format, 46.5dB PSNR against the previous file, 196581 -> 105961 bytes (task 1004930)",
11
11
  "use": "the verbatim plate the .webp is encoded from, kept so a catalog art_url naming it still resolves; the page requests the .webp (task 1003649)"
12
12
  }
@@ -8,6 +8,6 @@
8
8
  "task": 1003649,
9
9
  "prompt": "A single iridescent liquid-chrome blob, a glossy organic form with a crisp clean edge and a mirror-smooth surface reflecting bronze, deep blue and violet with one thin bright rim highlight, centred on a pure black background, nothing else, no text, no ground plane, no shadow or glow on the background. Pure black everywhere the blob is not.",
10
10
  "source": ".impeccable/mocks/world-assets/r2-chrome-blob-one.jpg",
11
- "encoded": "ffmpeg libwebp quality 88, yuv420p, full resolution, black ground kept at the source JPEG level (task 1003649)",
11
+ "encoded": "ffmpeg libwebp quality 88, yuv420p, full resolution, black ground kept at the source JPEG level (task 1003649); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 75, same 2048x2048 and format, 45.9dB PSNR against the previous file, 107264 -> 60982 bytes (task 1004930)",
12
12
  "use": "dark mode: black plate composited with mix-blend-mode lighten"
13
13
  }
@@ -7,6 +7,6 @@
7
7
  "round": 2,
8
8
  "prompt": "Full-frame render on a pure black background: three iridescent liquid-chrome blobs, glossy organic forms with crisp clean edges and mirror-smooth surfaces reflecting bronze, deep blue and violet, thin bright rim highlights, strong depth: one very large blob upper centre-right, a medium blob lower left, a small blob far right, generous empty black space between them, nothing else, no text, no ground plane, no shadows or glow on the background. Pure black everywhere the blobs are not, so the image can be composited with a lighten blend.",
9
9
  "source": ".impeccable/mocks/world-assets/r2-chrome-blobs-set.jpg",
10
- "encoded": "verbatim copy of the plate (task 1003298)",
10
+ "encoded": "verbatim copy of the plate (task 1003298); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 82, same 2752x1536 and format, 45.5dB PSNR against the previous file, 250221 -> 161033 bytes (task 1004930)",
11
11
  "use": "the verbatim plate the .webp is encoded from, kept so a catalog art_url naming it still resolves; the page requests the .webp (task 1003649)"
12
12
  }
@@ -8,6 +8,6 @@
8
8
  "task": 1003649,
9
9
  "prompt": "Full-frame render on a pure black background: three iridescent liquid-chrome blobs, glossy organic forms with crisp clean edges and mirror-smooth surfaces reflecting bronze, deep blue and violet, thin bright rim highlights, strong depth: one very large blob upper centre-right, a medium blob lower left, a small blob far right, generous empty black space between them, nothing else, no text, no ground plane, no shadows or glow on the background. Pure black everywhere the blobs are not, so the image can be composited with a lighten blend.",
10
10
  "source": ".impeccable/mocks/world-assets/r2-chrome-blobs-set.jpg",
11
- "encoded": "ffmpeg libwebp quality 88, yuv420p, full resolution, black ground kept at the source JPEG level (task 1003649)",
11
+ "encoded": "ffmpeg libwebp quality 88, yuv420p, full resolution, black ground kept at the source JPEG level (task 1003649); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 78, same 2752x1536 and format, 45.3dB PSNR against the previous file, 139818 -> 87740 bytes (task 1004930)",
12
12
  "use": "dark mode: black plate composited with mix-blend-mode lighten"
13
13
  }
@@ -10,6 +10,6 @@
10
10
  "object": "the small bead",
11
11
  "prompt": "Background removed (Higgsfield image_background_remover) from r3-frost-bead: the small bead in frosted glass. Cut out so the planet can be masked and colour-blended in the project's accent (the hub's template grammar, task 1003319); alpha verified with ffmpeg alphaextract (min 0, max 255).",
12
12
  "source": ".impeccable/mocks/world-assets/r3-frost-bead-cut.webp",
13
- "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337)",
13
+ "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 86, same 1600x1600 and format, 47.0dB PSNR against the previous file, 152596 -> 123590 bytes (task 1004930)",
14
14
  "use": "the hub's planet in frosted glass: --plate-frost-bead-cut, masked and blended by [data-material=\"frost\"][data-shape=\"bead\"] in cosmos.css"
15
15
  }
@@ -10,6 +10,6 @@
10
10
  "object": "the bongo pair",
11
11
  "prompt": "Background removed (Higgsfield image_background_remover) from r3-frost-pair: the bongo pair in frosted glass. Cut out so the planet can be masked and colour-blended in the project's accent (the hub's template grammar, task 1003319); alpha verified with ffmpeg alphaextract (min 0, max 255).",
12
12
  "source": ".impeccable/mocks/world-assets/r3-frost-pair-cut.webp",
13
- "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337)",
13
+ "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 75, same 1600x1600 and format, 46.9dB PSNR against the previous file, 77806 -> 38486 bytes (task 1004930)",
14
14
  "use": "the hub's planet in frosted glass: --plate-frost-pair-cut, masked and blended by [data-material=\"frost\"][data-shape=\"pair\"] in cosmos.css"
15
15
  }
@@ -10,6 +10,6 @@
10
10
  "object": "the round blob",
11
11
  "prompt": "Background removed (Higgsfield image_background_remover) from r3-gold-blob: the round blob in brushed gold. Cut out so the planet can be masked and colour-blended in the project's accent (the hub's template grammar, task 1003319); alpha verified with ffmpeg alphaextract (min 0, max 255).",
12
12
  "source": ".impeccable/mocks/world-assets/r3-gold-blob-cut.webp",
13
- "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337)",
13
+ "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 86, same 1600x1600 and format, 45.2dB PSNR against the previous file, 205632 -> 177722 bytes (task 1004930)",
14
14
  "use": "the hub's planet in brushed gold: --plate-gold-blob-cut, masked and blended by [data-material=\"gold\"][data-shape=\"blob\"] in cosmos.css"
15
15
  }
@@ -10,6 +10,6 @@
10
10
  "object": "the bongo pair",
11
11
  "prompt": "Background removed (Higgsfield image_background_remover) from r3-gold-pair: the bongo pair in brushed gold. Cut out so the planet can be masked and colour-blended in the project's accent (the hub's template grammar, task 1003319); alpha verified with ffmpeg alphaextract (min 0, max 255).",
12
12
  "source": ".impeccable/mocks/world-assets/r3-gold-pair-cut.webp",
13
- "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337)",
13
+ "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 82, same 1600x1600 and format, 46.6dB PSNR against the previous file, 97590 -> 65536 bytes (task 1004930)",
14
14
  "use": "the hub's planet in brushed gold: --plate-gold-pair-cut, masked and blended by [data-material=\"gold\"][data-shape=\"pair\"] in cosmos.css"
15
15
  }
@@ -10,6 +10,6 @@
10
10
  "object": "the round blob",
11
11
  "prompt": "Background removed (Higgsfield image_background_remover) from r3-obsidian-blob: the round blob in polished obsidian. Cut out so the planet can be masked and colour-blended in the project's accent (the hub's template grammar, task 1003319); alpha verified with ffmpeg alphaextract (min 0, max 255).",
12
12
  "source": ".impeccable/mocks/world-assets/r3-obsidian-blob-cut.webp",
13
- "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337)",
13
+ "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 78, same 1600x1600 and format, 45.0dB PSNR against the previous file, 82578 -> 54188 bytes (task 1004930)",
14
14
  "use": "the hub's planet in polished obsidian: --plate-obsidian-blob-cut, masked and blended by [data-material=\"obsidian\"][data-shape=\"blob\"] in cosmos.css"
15
15
  }
@@ -10,6 +10,6 @@
10
10
  "object": "the bongo pair",
11
11
  "prompt": "Background removed (Higgsfield image_background_remover) from r3-obsidian-pair: the bongo pair in polished obsidian. Cut out so the planet can be masked and colour-blended in the project's accent (the hub's template grammar, task 1003319); alpha verified with ffmpeg alphaextract (min 0, max 255).",
12
12
  "source": ".impeccable/mocks/world-assets/r3-obsidian-pair-cut.webp",
13
- "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337)",
13
+ "encoded": "ffmpeg libwebp quality 88, alpha kept (yuva420p), 1600px (task 1003337); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 75, same 1600x1600 and format, 46.8dB PSNR against the previous file, 75226 -> 57138 bytes (task 1004930)",
14
14
  "use": "the hub's planet in polished obsidian: --plate-obsidian-pair-cut, masked and blended by [data-material=\"obsidian\"][data-shape=\"pair\"] in cosmos.css"
15
15
  }
@@ -8,6 +8,6 @@
8
8
  "task": 1003337,
9
9
  "prompt": "Deep-space photograph on a pure black ground: a faint wide nebula wash in muted violet and deep blue with a soft bronze warmth along one edge, very sparse pin-sharp stars of varied brightness and size, gentle depth, most of the frame near-black, nothing else, no planets, no ground plane, no horizon, no lens flare, no text, no watermark. Pure black dominates.",
10
10
  "source": ".impeccable/mocks/world-assets/r3-space-nebula.jpg",
11
- "encoded": "ffmpeg JPEG -q:v 4, 2752×1536 (task 1003337)",
11
+ "encoded": "ffmpeg JPEG -q:v 4, 2752×1536 (task 1003337); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 75, same 2752x1536 and format, 54.4dB PSNR against the previous file, 74037 -> 33310 bytes (task 1004930)",
12
12
  "use": "the field's ground on /projects: --field-plate, `cover`, a 90s transform drift dead under reduced motion (the builder's recommendation; the owner may swap any candidate)"
13
13
  }
@@ -9,6 +9,6 @@
9
9
  "task": 1003352,
10
10
  "prompt": "Ultra-wide studio photograph on a pure black ground: a single sweeping ribbon of liquid chrome, polished mirror metal with soft neutral specular highlights and a faint cool blue and warm bronze reflection, curving gently through the centre-right of the frame and fading into black at both ends. Abstract material study, not an object, no recognisable shape, no product. The left third and both lower corners stay almost pure black and empty. No text, no watermark, no logo, no border, no reflection of a studio or a person. Pure black dominates the frame.",
11
11
  "source": ".impeccable/mocks/world-assets/r4-card-chrome-src.jpg",
12
- "encoded": "ffmpeg crop=2560:1024:0:24 (21:9 → 5:2, centred), JPEG -q:v 4",
12
+ "encoded": "ffmpeg crop=2560:1024:0:24 (21:9 → 5:2, centred), JPEG -q:v 4; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 75, same 2560x1024 and format, 53.6dB PSNR against the previous file, 47135 -> 19533 bytes (task 1004930)",
13
13
  "use": "the poster card's backdrop on /projects, chosen by an owner as card_backdrop=\"chrome\": a sweeping ribbon of liquid chrome — the world's own material with no object in it. Dark only (ADR 0204); composed so the left third and the lower corners stay near-black, where the card puts its disc, its name and its two figure callouts."
14
14
  }
@@ -9,6 +9,6 @@
9
9
  "task": 1003352,
10
10
  "prompt": "Ultra-wide cinematic deep-space photograph on a pure black ground: a faint nebula wash in muted violet and deep blue with a soft bronze warmth drifting through the centre-right of the frame, very sparse pin-sharp stars of varied brightness, gentle depth. The left third and both lower corners stay almost pure black and empty. No planets, no moons, no ground plane, no horizon, no lens flare, no text, no watermark, no logo, no border. Pure black dominates the frame.",
11
11
  "source": ".impeccable/mocks/world-assets/r4-card-nebula-src.jpg",
12
- "encoded": "ffmpeg crop=2560:1024:0:24 (21:9 → 5:2, centred), eq=gamma=1.75:saturation=1.30, JPEG -q:v 4 — the render was too dark to read at the card's 560px; a gamma lift raises the wash without crushing the black the disc and the name sit on (contrast would have)",
12
+ "encoded": "ffmpeg crop=2560:1024:0:24 (21:9 → 5:2, centred), eq=gamma=1.75:saturation=1.30, JPEG -q:v 4 — the render was too dark to read at the card's 560px; a gamma lift raises the wash without crushing the black the disc and the name sit on (contrast would have); re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 86, same 2560x1024 and format, 45.3dB PSNR against the previous file, 161756 -> 144774 bytes (task 1004930)",
13
13
  "use": "the poster card's backdrop on /projects, chosen by an owner as card_backdrop=\"nebula\": a violet-and-bronze nebula wash, sparse stars — the field's own language in the card's shape. Dark only (ADR 0204); composed so the left third and the lower corners stay near-black, where the card puts its disc, its name and its two figure callouts."
14
14
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "source panel about 220px across the object in a 1024x559 sheet, squared and upscaled to 1024px; soft if shown large, sized for the genesis life strip",
13
13
  "source": "the owner's Gemini sheet, split by the ui-design kit browser (panel detection on the white dividers)",
14
- "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground",
14
+ "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 75, same 1024x1024 and format, 50.1dB PSNR against the previous file, 60596 -> 24504 bytes (task 1004930)",
15
15
  "use": "dark mode: the genesis life strip, stage scope (primordial sea)"
16
16
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "1024x1024 from the same panel",
13
13
  "source": "r5-life-2-first-cells.jpg with the black ground removed: flood-fill from the edges on near-black pixels, luminance-feathered",
14
- "encoded": "canvas WebP quality 0.88 with alpha",
14
+ "encoded": "canvas WebP quality 0.88 with alpha; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 82, same 1024x1024 and format, 45.0dB PSNR against the previous file, 54548 -> 45416 bytes (task 1004930)",
15
15
  "use": "light mode: the genesis life strip, stage strategize (first cells)"
16
16
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "source panel about 220px across the object in a 1024x559 sheet, squared and upscaled to 1024px; soft if shown large, sized for the genesis life strip",
13
13
  "source": "the owner's Gemini sheet, split by the ui-design kit browser (panel detection on the white dividers)",
14
- "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground",
14
+ "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 75, same 1024x1024 and format, 47.4dB PSNR against the previous file, 96788 -> 44064 bytes (task 1004930)",
15
15
  "use": "dark mode: the genesis life strip, stage strategize (first cells)"
16
16
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "1024x1024 from the same panel",
13
13
  "source": "r5-life-3-genome.jpg with the black ground removed: flood-fill from the edges on near-black pixels, luminance-feathered",
14
- "encoded": "canvas WebP quality 0.88 with alpha",
14
+ "encoded": "canvas WebP quality 0.88 with alpha; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 82, same 1024x1024 and format, 45.1dB PSNR against the previous file, 44570 -> 36788 bytes (task 1004930)",
15
15
  "use": "light mode: the genesis life strip, stage charter (the genome)"
16
16
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "source panel about 220px across the object in a 1024x559 sheet, squared and upscaled to 1024px; soft if shown large, sized for the genesis life strip",
13
13
  "source": "the owner's Gemini sheet, split by the ui-design kit browser (panel detection on the white dividers)",
14
- "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground",
14
+ "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 75, same 1024x1024 and format, 47.8dB PSNR against the previous file, 83866 -> 37689 bytes (task 1004930)",
15
15
  "use": "dark mode: the genesis life strip, stage charter (the genome)"
16
16
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "1024x1024 from the same panel",
13
13
  "source": "r5-life-4-membrane.jpg with the black ground removed: flood-fill from the edges on near-black pixels, luminance-feathered; the halo outside the shell rim un-multiplied from black so the glow fades on light paper instead of darkening",
14
- "encoded": "canvas WebP quality 0.88 with alpha",
14
+ "encoded": "canvas WebP quality 0.88 with alpha; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 90, same 1024x1024 and format, 47.5dB PSNR against the previous file, 169868 -> 139758 bytes (task 1004930)",
15
15
  "use": "light mode: the genesis life strip, stage legalize (the membrane)"
16
16
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "source panel about 220px across the object in a 1024x559 sheet, squared and upscaled to 1024px; soft if shown large, sized for the genesis life strip",
13
13
  "source": "the owner's Gemini sheet, split by the ui-design kit browser (panel detection on the white dividers)",
14
- "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground",
14
+ "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 75, same 1024x1024 and format, 49.9dB PSNR against the previous file, 60220 -> 23666 bytes (task 1004930)",
15
15
  "use": "dark mode: the genesis life strip, stage legalize (the membrane)"
16
16
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "1024x1024 from the same panel",
13
13
  "source": "r5-life-5-nervous-system.jpg with the black ground removed: flood-fill from the edges on near-black pixels, luminance-feathered",
14
- "encoded": "canvas WebP quality 0.88 with alpha",
14
+ "encoded": "canvas WebP quality 0.88 with alpha; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (libwebp) quality 82, same 1024x1024 and format, 45.2dB PSNR against the previous file, 71036 -> 59858 bytes (task 1004930)",
15
15
  "use": "light mode: the genesis life strip, stage legislation (the nervous system)"
16
16
  }
@@ -11,6 +11,6 @@
11
11
  "reference": "modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg, uploaded as the material/light/ground reference",
12
12
  "resolution": "source panel about 220px across the object in a 1024x559 sheet, squared and upscaled to 1024px; soft if shown large, sized for the genesis life strip",
13
13
  "source": "the owner's Gemini sheet, split by the ui-design kit browser (panel detection on the white dividers)",
14
- "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground",
14
+ "encoded": "canvas JPEG quality 0.92, 1024x1024, pure black ground; re-encoded 2026-10-28 for page weight with sharp 0.33.5 (mozjpeg) quality 75, same 1024x1024 and format, 46.3dB PSNR against the previous file, 119758 -> 55466 bytes (task 1004930)",
15
15
  "use": "dark mode: the genesis life strip, stage legislation (the nervous system)"
16
16
  }
@@ -344,7 +344,7 @@
344
344
  <p>Sign in to see whether this list is open to you.</p>
345
345
  <a class="btn" id="recruitSignin" href="/api/bongos/auth/web/start?return=/community/recruiters&amp;repos=1">
346
346
  <svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23 .82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2 .82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12 .51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29 .25.54.73 .54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15 .46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
347
- Sign in with GitHub
347
+ Sign in
348
348
  </a>
349
349
  </div>
350
350
  <p class="commMsg" id="recruitClosed" hidden>Only project owners can see this list.</p>
@@ -129,11 +129,11 @@
129
129
  <!-- signed-out door: revealed when GET /me answers nobody, the /account shape -->
130
130
  <section class="aDoor" id="door" hidden aria-labelledby="door-h">
131
131
  <h2 class="vh" id="door-h">Sign in</h2>
132
- <p>Sign in with GitHub to see your connections and the builders asking to connect.</p>
132
+ <p>Sign in to see your connections and the builders asking to connect.</p>
133
133
  <a class="btn" id="signin" href="/api/bongos/auth/web/start?return=/connections&amp;repos=1">
134
134
  <!-- keep the spaces inside this path's numbers: same shape, and they are load-bearing (task 1004401) -->
135
135
  <svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23 .82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2 .82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12 .51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29 .25.54.73 .54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15 .46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
136
- Sign in with GitHub
136
+ Sign in
137
137
  </a>
138
138
  </section>
139
139
 
@@ -190,7 +190,7 @@
190
190
  <a class="btn" id="missingSignin" hidden href="/api/bongos/auth/web/start?repos=1">
191
191
  <!-- keep the spaces inside this path's numbers: same shape, and they are load-bearing (task 1004401) -->
192
192
  <svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23 .82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2 .82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12 .51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29 .25.54.73 .54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15 .46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
193
- Sign in with GitHub
193
+ Sign in
194
194
  </a>
195
195
  </section>
196
196
 
@@ -139,11 +139,11 @@
139
139
  <!-- signed-out door: revealed when GET /me answers nobody, the /account shape -->
140
140
  <section class="aDoor" id="door" hidden aria-labelledby="door-h">
141
141
  <h2 class="vh" id="door-h">Sign in</h2>
142
- <p>Sign in with GitHub to see your invitations and apply to join a project.</p>
142
+ <p>Sign in to see your invitations and apply to join a project.</p>
143
143
  <a class="btn" id="signin" href="/api/bongos/auth/web/start?return=/invitations&amp;repos=1">
144
144
  <!-- keep the spaces inside this path's numbers: same shape, and they are load-bearing (task 1004401) -->
145
145
  <svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23 .82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2 .82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12 .51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29 .25.54.73 .54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15 .46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
146
- Sign in with GitHub
146
+ Sign in
147
147
  </a>
148
148
  </section>
149
149
 
@@ -1046,10 +1046,10 @@ summary{min-height:24px;padding:3px 0;}
1046
1046
  <!-- signed-out gate: identity-only sign-in (ADR 0143 least-privilege — unlike
1047
1047
  /create, listing your own instances needs no repo scope) -->
1048
1048
  <section id="gate" hidden>
1049
- <p class="lede">Every project you own, in one place — its live status, its address, and the controls that matter. Sign in with GitHub to see yours.</p>
1049
+ <p class="lede">Every project you own, in one place — its live status, its address, and the controls that matter. Sign in to see yours.</p>
1050
1050
  <a class="btn" id="signin" href="/api/bongos/auth/web/start?return=/projects%3Fview%3Dmine&amp;repos=1">
1051
1051
  <svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
1052
- Sign in with GitHub
1052
+ Sign in
1053
1053
  </a>
1054
1054
  <div class="alert" id="gateAlert" role="alert"></div>
1055
1055
  </section>
@@ -1137,10 +1137,10 @@ summary{min-height:24px;padding:3px 0;}
1137
1137
 
1138
1138
  <!-- signed out: the same identity-only door the mine view uses (ADR 0143) -->
1139
1139
  <section id="mGate" class="card" hidden>
1140
- <p class="lede">This is a project’s management page — it answers only to the person who owns it. Sign in with GitHub to open yours.</p>
1140
+ <p class="lede">This is a project’s management page — it answers only to the person who owns it. Sign in to open yours.</p>
1141
1141
  <a class="btn" id="mSignin" href="/api/bongos/auth/web/start?return=/projects%3Fview%3Dmine&amp;repos=1">
1142
1142
  <svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
1143
- Sign in with GitHub
1143
+ Sign in
1144
1144
  </a>
1145
1145
  </section>
1146
1146
 
@@ -1548,7 +1548,7 @@ summary{min-height:24px;padding:3px 0;}
1548
1548
  access, so we ask once at sign-in instead of a second "Connect" step later.
1549
1549
  Every hub sign-in door does the same since ADR 0364; the hall + CLI
1550
1550
  sign-ins stay identity-only (ADR 0143 least-privilege default). -->
1551
- <a class="btn big" id="wizSignin" href="/api/bongos/auth/web/start?return=/projects%3Fview%3Dnew&amp;repos=1">
1551
+ <a class="btn big" id="wizSignin" href="/api/bongos/auth/web/start?via=github&amp;return=/projects%3Fview%3Dnew&amp;repos=1">
1552
1552
  <svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
1553
1553
  Continue with GitHub
1554
1554
  </a>
@@ -6,6 +6,8 @@
6
6
  <meta name="robots" content="noindex, nofollow">
7
7
  <title>Confidentiality agreement — Cloud Bongos</title>
8
8
  <link rel="icon" href="{{base}}/assets/favicon.svg" type="image/svg+xml">
9
+ <link rel="preconnect" href="https://fonts.googleapis.com">
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
11
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400&family=Manrope:wght@300;400;500;600&display=swap">
10
12
  <script src="{{base}}/assets/mode.js"></script>
11
13
  <link rel="stylesheet" href="{{base}}/assets/raise.css">
@@ -144,6 +144,37 @@ async function countTraining(specialityId, executor) {
144
144
  return { documentCount: Number(row.documents || 0), learningCount: Number(row.learnings || 0) };
145
145
  }
146
146
 
147
+ // The GET /me read, batched (task 1004923). For every speciality id given: who
148
+ // owns it (the provenance fence needs it) and both training counts — ONE round
149
+ // trip however many specialities the builder holds. The port used to call
150
+ // countTraining + getSpeciality per adoption, serially, on every Conductor prompt.
151
+ // Both counts are served by indexes led by speciality_id (the documents
152
+ // (speciality_id, content_sha) unique key and the learnings primary key).
153
+ // Returns a Map keyed by String(id); an id with no catalogue row is simply absent.
154
+ async function describeTrainingFor(specialityIds, executor) {
155
+ const ids = [...new Set((specialityIds || []).map(String))];
156
+ if (!ids.length) return new Map();
157
+ const q = exec(executor);
158
+ const r = await q(
159
+ `SELECT c.id, c.owner_kind, c.owner_builder_id,
160
+ (SELECT count(*) FROM specialities_documents d WHERE d.speciality_id = c.id) AS documents,
161
+ (SELECT count(*) FROM specialities_learnings l WHERE l.speciality_id = c.id) AS learnings
162
+ FROM specialities_catalog c
163
+ WHERE c.id = ANY($1::bigint[])`,
164
+ [ids],
165
+ );
166
+ const out = new Map();
167
+ for (const row of r.rows) {
168
+ out.set(String(row.id), {
169
+ owner_kind: row.owner_kind,
170
+ owner_builder_id: row.owner_builder_id,
171
+ documentCount: Number(row.documents || 0),
172
+ learningCount: Number(row.learnings || 0),
173
+ });
174
+ }
175
+ return out;
176
+ }
177
+
147
178
  // ── adoption ────────────────────────────────────────────────────────────────
148
179
  // Switching craft speciality is DEACTIVATE-THEN-ACTIVATE inside one statement
149
180
  // pair, because the partial unique index (builder_id, discipline) WHERE active
@@ -277,6 +308,6 @@ module.exports = {
277
308
  UPDATABLE, taskDiscipline, setOffered, listOffered,
278
309
  createSpeciality, getSpeciality, listVisibleTo, updateSpeciality,
279
310
  addDocument, listDocuments, deleteDocument,
280
- linkLearning, countTraining,
311
+ linkLearning, countTraining, describeTrainingFor,
281
312
  adopt, abandon, activeForCraft, listAdoptions, setEnabledSkills,
282
313
  };
@@ -93,15 +93,19 @@ const port = {
93
93
  if (rows.some((r) => r.active && Array.isArray(r.enabled_skills) && r.enabled_skills.length)) {
94
94
  try { installed = installedSkills(); } catch { installed = null; }
95
95
  }
96
+ const active = rows.filter((r) => r.active);
97
+ // ONE read for every active speciality's owner and training counts (task
98
+ // 1004923) — this runs on every Conductor prompt, so a per-adoption pair of
99
+ // queries made the hot path cost 2 round trips per speciality held.
100
+ const facts = active.length ? await db.describeTrainingFor(active.map((r) => r.id)) : new Map();
96
101
  const out = [];
97
- for (const row of rows) {
98
- if (!row.active) continue;
99
- const training = await db.countTraining(row.id);
102
+ for (const row of active) {
103
+ const fact = facts.get(String(row.id)) || null;
104
+ const training = { documentCount: fact ? fact.documentCount : 0, learningCount: fact ? fact.learningCount : 0 };
100
105
  // Self-authored is the common case and stays unfenced; anything adopted from
101
106
  // another builder or from a project carries its provenance into the session.
102
- const full = await db.getSpeciality(row.id);
103
- const selfAuthored = !!full && full.owner_kind === 'builder'
104
- && String(full.owner_builder_id) === String(builderId);
107
+ const selfAuthored = !!fact && fact.owner_kind === 'builder'
108
+ && String(fact.owner_builder_id) === String(builderId);
105
109
  const described = S.describeForApi(row, { ...training, selfAuthored, installed });
106
110
  if (described) out.push({ ...described, discipline: row.discipline, name: row.name });
107
111
  }
@@ -328,7 +328,7 @@
328
328
  <p class="foot__seal">By order of the Senate</p>
329
329
  <!-- task 1002853: every company field is optional, so each clause drops whole when its pack field is empty -->
330
330
  <!--brand-if:companyName--><p>{{worldName}} is the work of <!--brand-if:companySite--><a href="{{companySite}}" target="_blank" rel="noopener"><!--/brand-if:companySite--><strong>{{companyName}}</strong><!--brand-if:companySite--></a><!--/brand-if:companySite--><!--brand-if:companyTagline-->, {{companyTagline}}<!--/brand-if:companyTagline-->.</p><!--/brand-if:companyName-->
331
- <p>{{Currency}} are wrought by the lawmen's review; redemption awaits their seal.</p>
331
+ <p>{{Currency}} are wrought by the lawmen's review; they measure the work, and are never coin.</p>
332
332
  </footer>
333
333
 
334
334
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.23.21",
3
+ "version": "1.24.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.23.21",
9
+ "version": "1.24.1",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.23.21",
3
+ "version": "1.24.1",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",