@bongos/core 1.24.79 → 1.24.81

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 (413) hide show
  1. package/.bongos-core.json +554 -394
  2. package/.claude/skills/ask-for-help/SKILL.md +1 -1
  3. package/.claude/skills/builder-sequence/SKILL.md +1 -1
  4. package/.claude/skills/design/SKILL.md +1 -1
  5. package/.claude/skills/goal-create/SKILL.md +1 -1
  6. package/.claude/skills/planning-session/SKILL.md +1 -1
  7. package/clients/bongos-client/README.md +1 -1
  8. package/clients/bongos-client/bongos-client.global.js +8 -0
  9. package/clients/bongos-client/index.cjs +8 -0
  10. package/clients/bongos-client/index.d.ts +11 -0
  11. package/clients/bongos-client/index.mjs +8 -0
  12. package/docs/adr/0274-one-kernel-three-role-packs.md +2 -2
  13. package/docs/adr/0399-the-visor-is-glass-over-the-scene-and-owns-no-camera.md +91 -0
  14. package/docs/adr/0400-a-chain-reserves-work-and-each-sub-quest-is-still-claimed-alone.md +109 -0
  15. package/docs/adr/0401-one-options-menu-opens-every-settings-screen-in-a-frame.md +53 -0
  16. package/docs/adr/0402-helm-is-the-halls-look-and-the-hall-is-dark-only.md +142 -0
  17. package/docs/adr/README.md +4 -0
  18. package/docs/api/openapi.json +195 -3
  19. package/docs/api-reference.md +8 -4
  20. package/docs/architecture.md +7 -3
  21. package/docs/copy-inventory.md +393 -378
  22. package/docs/copy-registry.json +722 -578
  23. package/docs/design/characters/character-sprites-source.webp +0 -0
  24. package/docs/file-map.md +7 -8
  25. package/docs/module-api-changelog.md +4 -0
  26. package/docs/modules-contract.md +5 -0
  27. package/docs/onboarding/slash-commands.md +1 -1
  28. package/docs/packs/{engineer.md → artisan.md} +5 -5
  29. package/docs/packs/artist.md +50 -4
  30. package/docs/page-inventory.json +16 -7
  31. package/docs/page-readings.json +3184 -3338
  32. package/docs/{packs/ideator.md → recipes/ideation-playbook.md} +5 -48
  33. package/migrations/core_296_crafts_artisan_artist.sql +72 -0
  34. package/migrations/core_297_builder_character.sql +30 -0
  35. package/modules/copy-desk/proposals.js +1 -1
  36. package/modules/economy/credits-by-craft.js +29 -15
  37. package/modules/hall-ui/public/ai-studio.html +6 -4
  38. package/modules/hall-ui/public/ai-studio.states.json +1 -0
  39. package/modules/hall-ui/public/atlas.html +5 -5
  40. package/modules/hall-ui/public/atlas.js +3 -1
  41. package/modules/hall-ui/public/atlas.states.json +1 -0
  42. package/modules/hall-ui/public/blockers.html +5 -5
  43. package/modules/hall-ui/public/board-room.html +4 -4
  44. package/modules/hall-ui/public/board-room.states.json +1 -0
  45. package/modules/hall-ui/public/characters/artisan.png +0 -0
  46. package/modules/hall-ui/public/characters/artist.png +0 -0
  47. package/modules/hall-ui/public/characters/patron.png +0 -0
  48. package/modules/hall-ui/public/city.css +3 -4
  49. package/modules/hall-ui/public/city.html +9 -9
  50. package/modules/hall-ui/public/city.js +17 -56
  51. package/modules/hall-ui/public/city.states.json +7 -32
  52. package/modules/hall-ui/public/collab.html +4 -4
  53. package/modules/hall-ui/public/collab.states.json +1 -0
  54. package/modules/hall-ui/public/commands.html +4 -4
  55. package/modules/hall-ui/public/commands.states.json +1 -0
  56. package/modules/hall-ui/public/controls.css +63 -11
  57. package/modules/hall-ui/public/copy-desk.html +4 -4
  58. package/modules/hall-ui/public/copy-desk.states.json +1 -0
  59. package/modules/hall-ui/public/craft-mode.js +258 -64
  60. package/modules/hall-ui/public/deploy.html +4 -4
  61. package/modules/hall-ui/public/deploy.states.json +1 -0
  62. package/modules/hall-ui/public/diagram-viewer.js +2 -1
  63. package/modules/hall-ui/public/dom-utils.js +1 -1
  64. package/modules/hall-ui/public/goal-map.html +9 -6
  65. package/modules/hall-ui/public/goals.html +5 -5
  66. package/modules/hall-ui/public/goals.states.json +1 -0
  67. package/modules/hall-ui/public/government.html +4 -4
  68. package/modules/hall-ui/public/government.states.json +1 -0
  69. package/modules/hall-ui/public/hall-render.js +3 -1
  70. package/modules/hall-ui/public/home-city-draw.js +3 -3
  71. package/modules/hall-ui/public/home-city.css +4 -0
  72. package/modules/hall-ui/public/home-city.js +17 -9
  73. package/modules/hall-ui/public/home-gallery.js +8 -1
  74. package/modules/hall-ui/public/home-idea-box.css +2 -2
  75. package/modules/hall-ui/public/home-idea-box.js +3 -3
  76. package/modules/hall-ui/public/idea.html +5 -5
  77. package/modules/hall-ui/public/idea.states.json +1 -0
  78. package/modules/hall-ui/public/ideas.html +5 -5
  79. package/modules/hall-ui/public/ideas.states.json +1 -0
  80. package/modules/hall-ui/public/index-founding.states.json +1 -0
  81. package/modules/hall-ui/public/index-genesis-decide.states.json +1 -0
  82. package/modules/hall-ui/public/index-genesis-demo.states.json +1 -0
  83. package/modules/hall-ui/public/index-genesis.states.json +1 -0
  84. package/modules/hall-ui/public/index.html +11 -7
  85. package/modules/hall-ui/public/index.states.json +1 -0
  86. package/modules/hall-ui/public/market-watch-item.html +4 -4
  87. package/modules/hall-ui/public/market-watch-item.states.json +1 -0
  88. package/modules/hall-ui/public/market-watch-rules.html +4 -4
  89. package/modules/hall-ui/public/market-watch-rules.states.json +1 -0
  90. package/modules/hall-ui/public/market-watch.html +6 -9
  91. package/modules/hall-ui/public/market-watch.js +22 -45
  92. package/modules/hall-ui/public/market-watch.states.json +1 -0
  93. package/modules/hall-ui/public/modules.html +4 -4
  94. package/modules/hall-ui/public/modules.states.json +1 -0
  95. package/modules/hall-ui/public/money.html +4 -4
  96. package/modules/hall-ui/public/money.states.json +1 -0
  97. package/modules/hall-ui/public/my-agents.html +4 -4
  98. package/modules/hall-ui/public/my-agents.states.json +1 -0
  99. package/modules/hall-ui/public/options-menu.js +409 -0
  100. package/modules/hall-ui/public/paintbrush.js +3 -3
  101. package/modules/hall-ui/public/palette.js +11 -13
  102. package/modules/hall-ui/public/primer.html +5 -5
  103. package/modules/hall-ui/public/primer.states.json +1 -0
  104. package/modules/hall-ui/public/profile-crafts.js +1 -1
  105. package/modules/hall-ui/public/profile-roles.js +23 -19
  106. package/modules/hall-ui/public/profile.css +1 -1
  107. package/modules/hall-ui/public/profile.html +19 -18
  108. package/modules/hall-ui/public/profile.js +19 -18
  109. package/modules/hall-ui/public/profile.states.json +5 -4
  110. package/modules/hall-ui/public/project-settings.html +4 -4
  111. package/modules/hall-ui/public/roster.html +4 -4
  112. package/modules/hall-ui/public/roster.js +3 -3
  113. package/modules/hall-ui/public/roster.states.json +1 -0
  114. package/modules/hall-ui/public/settings.css +24 -4
  115. package/modules/hall-ui/public/settings.html +21 -17
  116. package/modules/hall-ui/public/settings.js +44 -44
  117. package/modules/hall-ui/public/settings.states.json +1 -0
  118. package/modules/hall-ui/public/shell-game.css +110 -0
  119. package/modules/hall-ui/public/shell-game.js +316 -3
  120. package/modules/hall-ui/public/shell.js +15 -66
  121. package/modules/hall-ui/public/sky-interaction.js +7 -0
  122. package/modules/hall-ui/public/speciality-tools.js +1 -2
  123. package/modules/hall-ui/public/street-card.states.json +1 -0
  124. package/modules/hall-ui/public/street-inside.js +3 -4
  125. package/modules/hall-ui/public/street.css +1 -5
  126. package/modules/hall-ui/public/street.html +6 -10
  127. package/modules/hall-ui/public/street.js +8 -59
  128. package/modules/hall-ui/public/street.states.json +7 -32
  129. package/modules/hall-ui/public/studio.html +5 -5
  130. package/modules/hall-ui/public/studio.states.json +1 -0
  131. package/modules/hall-ui/public/style.css +197 -112
  132. package/modules/hall-ui/public/task-detail.js +5 -4
  133. package/modules/hall-ui/public/task.html +5 -5
  134. package/modules/hall-ui/public/task.states.json +1 -0
  135. package/modules/hall-ui/public/thinking.css +10 -0
  136. package/modules/hall-ui/public/thinking.html +9 -6
  137. package/modules/hall-ui/public/thinking.states.json +1 -0
  138. package/modules/hall-ui/public/tweak-editor.html +5 -5
  139. package/modules/hall-ui/public/tweak-editor.js +5 -1
  140. package/modules/hall-ui/public/tweak-editor.states.json +1 -0
  141. package/modules/hall-ui/public/update-pill.js +91 -2
  142. package/modules/hall-ui/public/visor.css +80 -0
  143. package/modules/hall-ui/public/visor.js +316 -0
  144. package/modules/hall-ui/public/watch-repo-invite.js +159 -0
  145. package/modules/hall-ui/public/watch.html +6 -5
  146. package/modules/hall-ui/public/watch.js +17 -2
  147. package/modules/hall-ui/public/watch.states.json +1 -0
  148. package/modules/hall-ui/public/welcome-boot.js +15 -6
  149. package/modules/hall-ui/public/work-founding.states.json +1 -0
  150. package/modules/hall-ui/public/work.html +5 -5
  151. package/modules/hall-ui/public/work.states.json +1 -0
  152. package/modules/hall-ui/records/builders-roster.md +2 -2
  153. package/modules/hall-ui/records/craft-mode.md +13 -11
  154. package/modules/hall-ui/records/game-mode.md +2 -2
  155. package/modules/hall-ui/records/governor-street.md +1 -1
  156. package/modules/hall-ui/records/home-city.md +3 -1
  157. package/modules/hall-ui/records/market-watch-settings.md +2 -0
  158. package/modules/hall-ui/records/options-menu.md +15 -0
  159. package/modules/hall-ui/records/profile-roles.md +11 -11
  160. package/modules/hall-ui/records/sky.md +3 -3
  161. package/modules/hall-ui/records/start-screen.md +25 -0
  162. package/modules/hall-ui/records/tweak-editor.md +1 -1
  163. package/modules/hall-ui/records/update-pill.md +12 -0
  164. package/modules/hall-ui/records/visor.md +23 -0
  165. package/modules/hall-ui/records/welcome-tower.md +5 -5
  166. package/modules/hall-ui/specimens/components.states.json +2 -1
  167. package/modules/ideas/ideator-stats.js +3 -1
  168. package/modules/ideas/inbox.js +2 -2
  169. package/modules/lifecycle/activity.js +1 -1
  170. package/modules/lifecycle/cascade.js +4 -4
  171. package/modules/lifecycle/goal-spec-task.js +1 -1
  172. package/modules/lifecycle/help-requests.js +19 -15
  173. package/modules/lifecycle/kickoff-checklist.js +3 -3
  174. package/modules/lifecycle/kickoff-seed.js +1 -1
  175. package/modules/lifecycle/migrations/lifecycle_021_crafts_artisan_artist.sql +29 -0
  176. package/modules/lifecycle/mingle.js +4 -4
  177. package/modules/lifecycle/page-tweak-write.js +1 -1
  178. package/modules/lifecycle/routes/task-write-routes.js +3 -1
  179. package/modules/lifecycle/routes/tasks.js +3 -3
  180. package/modules/lifecycle/ship-card.js +2 -3
  181. package/modules/lifecycle/task-classifier.js +39 -29
  182. package/modules/lifecycle/tests/cascade.mjs +7 -7
  183. package/modules/onboarding/founding-mode.js +3 -0
  184. package/modules/onboarding/genesis-home.js +21 -1
  185. package/modules/onboarding/routes/onboarding.js +2 -0
  186. package/modules/page-notes/notes.js +3 -2
  187. package/modules/page-notes/split.js +1 -1
  188. package/modules/platform-identity/craft-rollup.js +35 -7
  189. package/modules/platform-identity/migrations/platform_identity_036_crafts_artisan_artist.sql +45 -0
  190. package/modules/platform-identity/platform-identity.js +2 -2
  191. package/modules/platform-identity/routes/community-leaderboard.js +2 -1
  192. package/modules/platform-identity/routes/community-search.js +2 -1
  193. package/modules/platform-identity/routes/sso.js +2 -1
  194. package/modules/platform-identity/tests/platform-identity.mjs +6 -6
  195. package/modules/public-landing/public/community.html +3 -5
  196. package/modules/public-landing/public/index.html +1 -1
  197. package/modules/public-landing/public/projects.html +1 -1
  198. package/modules/specialities/migrations/specialities_004_crafts_artisan_artist.sql +30 -0
  199. package/modules/specialities/routes/specialities.js +2 -2
  200. package/modules/status-ui/public/status.js +1 -1
  201. package/modules/ui-design/kit/fixtures/community-leaderboard.json +10 -10
  202. package/modules/ui-design/kit/fixtures/community-search.json +2 -2
  203. package/modules/ui-design/kit/fixtures/scouting-recruiter.json +1 -1
  204. package/modules/ui-design/public/brand.html +2 -2
  205. package/package-lock.json +2 -2
  206. package/package.json +1 -1
  207. package/release-notes.json +76 -0
  208. package/scripts/bongos/autobongos-loop.js +1 -1
  209. package/scripts/bongos/discipline-modes.json +7 -12
  210. package/scripts/bongos/fitness.js +1 -1
  211. package/scripts/bongos/gen-hall-sitemap.js +7 -7
  212. package/scripts/bongos/grade-smoke.js +2 -2
  213. package/scripts/bongos/init.js +2 -2
  214. package/scripts/bongos/newcomer-floor.config.json +1 -2
  215. package/scripts/bongos/newcomer-floor.js +4 -3
  216. package/scripts/bongos/newcomer-floor.templates.json +10 -12
  217. package/scripts/bongos/newcomer-floor.test.js +47 -38
  218. package/scripts/bongos/role-pack-guard.js +5 -4
  219. package/scripts/bongos/seed-tasks.example.json +3 -3
  220. package/scripts/bongos/setup.js +20 -107
  221. package/scripts/bongos/start.js +2 -2
  222. package/scripts/bongos/task.js +5 -4
  223. package/scripts/bongos/triage.js +1 -1
  224. package/scripts/bongos/worktree.js +16 -4
  225. package/scripts/hall-preview/README.md +2 -3
  226. package/scripts/setup-builder.js +6 -46
  227. package/src/bongos/auth-admission.js +8 -8
  228. package/src/bongos/craft-mode.js +2 -0
  229. package/src/bongos/db.js +39 -1
  230. package/src/bongos/github-repos.js +78 -0
  231. package/src/bongos/module-scope-map.js +22 -0
  232. package/src/bongos/role-stats.js +27 -11
  233. package/src/bongos/routes/github.js +100 -2
  234. package/src/bongos/routes/me.js +33 -0
  235. package/src/bongos/serve-internal.js +33 -11
  236. package/src/crafts.js +66 -0
  237. package/src/hall-helm.js +79 -0
  238. package/src/module-api.js +6 -1
  239. package/src/module-loader/manifest-schema.js +16 -0
  240. package/src/modules.js +2 -2
  241. package/src/role-responsibilities.js +6 -5
  242. package/tests/acclaim_feed_evidence_db.mjs +1 -1
  243. package/tests/activity_rollup_as_of.mjs +1 -1
  244. package/tests/api_alias_caller_ratchet.mjs +3 -3
  245. package/tests/application_lifecycle.mjs +1 -1
  246. package/tests/artist_review.mjs +1 -1
  247. package/tests/artist_review_goal.mjs +1 -1
  248. package/tests/blocker_hall_live_proof.mjs +1 -1
  249. package/tests/blocker_tasks_named_db.mjs +2 -2
  250. package/tests/canonical_profile_url.mjs +1 -1
  251. package/tests/cap_newcomer_tasks.mjs +13 -13
  252. package/tests/character_creation.mjs +294 -0
  253. package/tests/claim_gate_open_blocker.mjs +2 -2
  254. package/tests/claim_gate_rebase.mjs +6 -6
  255. package/tests/claude_materialize.mjs +1 -1
  256. package/tests/clawback_confirmed_backlog.mjs +3 -3
  257. package/tests/collab_page.mjs +8 -9
  258. package/tests/collab_self_settling.mjs +2 -2
  259. package/tests/community_leaderboard_route.mjs +13 -5
  260. package/tests/community_proof_db.mjs +3 -0
  261. package/tests/community_search_route.mjs +7 -6
  262. package/tests/conductor.mjs +1 -1
  263. package/tests/conductor_main_e2e.mjs +8 -8
  264. package/tests/copy_desk_flags_db.mjs +1 -1
  265. package/tests/copy_desk_page_approve.mjs +2 -2
  266. package/tests/copy_desk_page_claim.mjs +2 -2
  267. package/tests/copy_desk_page_next.mjs +1 -1
  268. package/tests/copy_desk_page_release.mjs +1 -1
  269. package/tests/copy_desk_page_submit.mjs +2 -2
  270. package/tests/core_258_box_session_claims_db.mjs +1 -1
  271. package/tests/craft_mode.mjs +48 -34
  272. package/tests/craft_mode_home.mjs +20 -20
  273. package/tests/craft_mode_looks.mjs +16 -15
  274. package/tests/craft_mode_nav.mjs +31 -29
  275. package/tests/craft_review_mode.mjs +46 -41
  276. package/tests/crafts_vocabulary.mjs +70 -0
  277. package/tests/cross_discipline_priority_direction.mjs +5 -5
  278. package/tests/design_reference.mjs +1 -1
  279. package/tests/fitness.mjs +7 -11
  280. package/tests/funded_project_pays_proof_db.mjs +1 -1
  281. package/tests/genesis_home.mjs +21 -1
  282. package/tests/github_chip.mjs +3 -3
  283. package/tests/github_repo_invite.mjs +379 -0
  284. package/tests/goal_criterion_confirm_ui.mjs +1 -1
  285. package/tests/goal_invite_consent.mjs +1 -1
  286. package/tests/goal_map_page.mjs +2 -2
  287. package/tests/goal_sort_staleness.mjs +1 -1
  288. package/tests/goal_spec_task.mjs +1 -1
  289. package/tests/goal_spec_task_db.mjs +3 -3
  290. package/tests/grade_engine.mjs +2 -2
  291. package/tests/grader_no_artifact.mjs +1 -1
  292. package/tests/grader_prompt_fencing.mjs +1 -1
  293. package/tests/grader_prompt_window_bound.mjs +1 -1
  294. package/tests/grader_reader_lens.mjs +2 -2
  295. package/tests/grader_severity_gate.mjs +1 -1
  296. package/tests/grader_unbacked_score.mjs +1 -1
  297. package/tests/hall_approval_queue.mjs +1 -1
  298. package/tests/hall_board_world.mjs +2 -2
  299. package/tests/hall_builders_page_pass.mjs +3 -2
  300. package/tests/hall_city.mjs +16 -30
  301. package/tests/hall_controls.mjs +52 -4
  302. package/tests/hall_fullscreen.mjs +27 -3
  303. package/tests/hall_helm.mjs +187 -0
  304. package/tests/hall_kit_charts.mjs +1 -1
  305. package/tests/hall_landing_boot.mjs +1 -1
  306. package/tests/hall_my_agents.mjs +16 -16
  307. package/tests/hall_nav.mjs +22 -15
  308. package/tests/hall_options_menu.mjs +247 -0
  309. package/tests/hall_oversight_world.mjs +1 -1
  310. package/tests/hall_palette.mjs +8 -9
  311. package/tests/hall_profile_world.mjs +3 -3
  312. package/tests/hall_record_world.mjs +6 -4
  313. package/tests/hall_settings_world.mjs +2 -1
  314. package/tests/hall_sitemap.mjs +6 -5
  315. package/tests/hall_start_screen.mjs +307 -0
  316. package/tests/hall_street.mjs +15 -28
  317. package/tests/hall_street_inside.mjs +17 -9
  318. package/tests/hall_studio_world.mjs +3 -3
  319. package/tests/hall_topbar_320.mjs +4 -2
  320. package/tests/hall_visor.mjs +224 -0
  321. package/tests/help_requests.mjs +47 -15
  322. package/tests/helpers.mjs +4 -4
  323. package/tests/home_city.mjs +6 -4
  324. package/tests/home_city_widget.mjs +33 -14
  325. package/tests/home_gallery_widget.mjs +4 -4
  326. package/tests/home_idea_box.mjs +6 -6
  327. package/tests/hub_community_page.mjs +3 -3
  328. package/tests/hub_craft_rollup.mjs +75 -36
  329. package/tests/hub_recent_ships.mjs +3 -2
  330. package/tests/idea_cascade.mjs +2 -2
  331. package/tests/idea_credit_streams_db.mjs +1 -1
  332. package/tests/idea_detail_page.mjs +1 -1
  333. package/tests/idea_ideate_full.mjs +5 -2
  334. package/tests/idea_spark_hall.mjs +1 -1
  335. package/tests/init.mjs +3 -3
  336. package/tests/instance_manifest.mjs +2 -2
  337. package/tests/kickoff_checklist.mjs +1 -1
  338. package/tests/leaderboard_roles.mjs +34 -25
  339. package/tests/lifecycle_claim_ladder_refs.mjs +55 -0
  340. package/tests/lightbulb.mjs +14 -10
  341. package/tests/main_discipline.mjs +8 -8
  342. package/tests/markdown_line_endings.mjs +1 -1
  343. package/tests/market_watch_pages.mjs +52 -74
  344. package/tests/me_streak_leaderboard_queries.mjs +3 -3
  345. package/tests/migration_allocation.mjs +1 -1
  346. package/tests/mingle.mjs +36 -21
  347. package/tests/module-scope-map.mjs +22 -2
  348. package/tests/module_api.mjs +1 -0
  349. package/tests/module_contributions.mjs +13 -13
  350. package/tests/module_manifest.mjs +29 -0
  351. package/tests/module_skills_hook.mjs +2 -2
  352. package/tests/modules.mjs +14 -7
  353. package/tests/nav_permission_atoms.mjs +2 -1
  354. package/tests/needs_rebase.mjs +1 -1
  355. package/tests/newcomer_restock.mjs +13 -13
  356. package/tests/page_notes_panel.mjs +22 -22
  357. package/tests/page_tweak_no_block.mjs +1 -1
  358. package/tests/paintbrush.mjs +7 -7
  359. package/tests/privacy_matrix.mjs +1 -0
  360. package/tests/profile_activity.mjs +20 -23
  361. package/tests/profile_earnings.mjs +1 -1
  362. package/tests/profile_nudge_prefs.mjs +4 -4
  363. package/tests/profile_role_headline.mjs +73 -46
  364. package/tests/profile_role_stats.mjs +55 -45
  365. package/tests/profile_rollup_consent.mjs +19 -6
  366. package/tests/profile_route.mjs +12 -12
  367. package/tests/profile_ui_cross_project.mjs +4 -4
  368. package/tests/project_invite_suggestions.mjs +2 -2
  369. package/tests/promote_goal_id.mjs +1 -1
  370. package/tests/publish_manifest.mjs +1 -1
  371. package/tests/rank_floor_wiring.mjs +1 -1
  372. package/tests/regrade_actual_minutes.mjs +1 -1
  373. package/tests/removal_proposal.mjs +2 -2
  374. package/tests/reward_gate.mjs +4 -4
  375. package/tests/reward_mode_cost_plus_only.mjs +1 -1
  376. package/tests/role_responsibilities.mjs +18 -12
  377. package/tests/role_stats_db.mjs +17 -16
  378. package/tests/scouting_rollup_fanout.mjs +5 -5
  379. package/tests/seed_tasks.mjs +5 -2
  380. package/tests/session_earnings_mirror_db.mjs +1 -1
  381. package/tests/session_reward_on_land_db.mjs +1 -1
  382. package/tests/session_reward_reconcile_db.mjs +2 -2
  383. package/tests/sessions_kit_pager.mjs +1 -1
  384. package/tests/settings_art_key_absent.mjs +2 -2
  385. package/tests/settings_main_role.mjs +21 -20
  386. package/tests/setup_flow.mjs +3 -3
  387. package/tests/setup_smoke.mjs +20 -0
  388. package/tests/ship_card.mjs +6 -6
  389. package/tests/specialities.mjs +16 -4
  390. package/tests/speciality_db_shape.mjs +6 -6
  391. package/tests/speciality_injection.mjs +17 -17
  392. package/tests/speciality_offer_ui.mjs +5 -5
  393. package/tests/speciality_offered.mjs +6 -5
  394. package/tests/speciality_session_skills.mjs +7 -7
  395. package/tests/speciality_skills.mjs +11 -11
  396. package/tests/speciality_walkthrough_ui.mjs +2 -2
  397. package/tests/sso_checkin_identity_spoof.mjs +2 -1
  398. package/tests/task_classifier_vocab.mjs +10 -0
  399. package/tests/task_cli.mjs +11 -3
  400. package/tests/task_criteria_unlink_db.mjs +2 -2
  401. package/tests/task_discipline_required.mjs +38 -16
  402. package/tests/task_goal_required.mjs +4 -4
  403. package/tests/task_needs_db.mjs +1 -1
  404. package/tests/tweak_replaces_artist_review.mjs +1 -1
  405. package/tests/update_pill.mjs +153 -2
  406. package/tests/upkeep_home.mjs +1 -1
  407. package/tests/v3_c1_options_proof.mjs +145 -0
  408. package/tests/visual_review.mjs +3 -3
  409. package/tests/watch_applications_queue.mjs +8 -5
  410. package/tests/watch_sealed_floor.mjs +3 -1
  411. package/tests/welcome_boot.mjs +12 -9
  412. package/tests/welcome_boot_browser.mjs +13 -13
  413. package/tests/worktree_helper.mjs +16 -1
@@ -192,7 +192,7 @@ module.exports = function buildSpecialitiesRouter() {
192
192
 
193
193
  const draft = {
194
194
  name: String(b.name).trim(),
195
- discipline: b.discipline,
195
+ discipline: api.crafts.normalizeCraft(b.discipline), // old spellings read as today's (task 1005141)
196
196
  summary: b.summary || '',
197
197
  contract_md: b.contract_md || '',
198
198
  visibility: b.visibility || 'private',
@@ -247,7 +247,7 @@ module.exports = function buildSpecialitiesRouter() {
247
247
  const b = req.body || {};
248
248
  const draft = {
249
249
  name: String(b.name).trim(),
250
- discipline: b.discipline,
250
+ discipline: api.crafts.normalizeCraft(b.discipline), // old spellings read as today's (task 1005141)
251
251
  summary: b.summary || '',
252
252
  contract_md: b.contract_md || '',
253
253
  visibility: b.visibility || 'private',
@@ -987,7 +987,7 @@ function renderAchievementRow(ids) {
987
987
  // task 1004437 (WA6.RP07): each row names its roles, main first — the crafts
988
988
  // the builder has EARNED in, from the row's own `roles.shown`, not only what
989
989
  // they declared. The same words the hall's roster uses. Text only, never markup.
990
- const ROLE_WORD = { engineer: 'Engineer', artist: 'Artist', ideator: 'Ideator' };
990
+ const ROLE_WORD = { artisan: 'Artisan', artist: 'Artist' };
991
991
  function renderRoles(roles) {
992
992
  const shown = roles && Array.isArray(roles.shown) ? roles.shown.filter((c) => ROLE_WORD[c]) : [];
993
993
  if (!shown.length) return null;
@@ -2,27 +2,27 @@
2
2
  "_": "GET /community/leaderboard for the kit stub (task 1003363): one ranked list per window, already in the route's order (credits, ships, karma, handle). The stub filters by discipline and numbers `place`. Names are invented; the long one tests the row's wrap.",
3
3
  "boards": {
4
4
  "all": [
5
- { "handle": "priya-nair", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "credits": 18420, "tasks_shipped": 212, "karma": 64, "disciplines": ["engineer", "ui"] },
6
- { "handle": "tomas-ek", "github_login": "tomasek", "display_name": "Tomas Ek", "avatar_url": "/__kit/avatar.svg", "credits": 9310, "tasks_shipped": 131, "karma": 40, "disciplines": ["engineer"] },
5
+ { "handle": "priya-nair", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "credits": 18420, "tasks_shipped": 212, "karma": 64, "disciplines": ["artisan", "ui"] },
6
+ { "handle": "tomas-ek", "github_login": "tomasek", "display_name": "Tomas Ek", "avatar_url": "/__kit/avatar.svg", "credits": 9310, "tasks_shipped": 131, "karma": 40, "disciplines": ["artisan"] },
7
7
  { "handle": "ada-okafor", "github_login": "adaokafor", "display_name": "Ada Okafor", "avatar_url": "/__kit/avatar.svg", "credits": 6125, "tasks_shipped": 77, "karma": 52, "disciplines": ["artist"] },
8
- { "handle": "lin-wei", "github_login": "linwei", "display_name": "Lin Wei", "avatar_url": null, "credits": 2480, "tasks_shipped": 31, "karma": 18, "disciplines": ["ideator", "engineer"] },
8
+ { "handle": "lin-wei", "github_login": "linwei", "display_name": "Lin Wei", "avatar_url": null, "credits": 2480, "tasks_shipped": 31, "karma": 18, "disciplines": ["artist", "artisan"] },
9
9
  { "handle": "maximiliana-van-der-berghe-lindqvist", "github_login": "mvdbl", "display_name": "Maximiliana van der Berghe-Lindqvist", "avatar_url": "/__kit/avatar.svg", "credits": 940, "tasks_shipped": 12, "karma": 7, "disciplines": ["ui"] },
10
- { "handle": "jo-park", "github_login": "jopark", "display_name": null, "avatar_url": "/__kit/avatar.svg", "credits": 310, "tasks_shipped": 1, "karma": 0, "disciplines": ["ideator"] }
10
+ { "handle": "jo-park", "github_login": "jopark", "display_name": null, "avatar_url": "/__kit/avatar.svg", "credits": 310, "tasks_shipped": 1, "karma": 0, "disciplines": ["artist"] }
11
11
  ],
12
12
  "365d": [
13
- { "handle": "priya-nair", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "credits": 12200, "tasks_shipped": 150, "karma": 41, "disciplines": ["engineer", "ui"] },
13
+ { "handle": "priya-nair", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "credits": 12200, "tasks_shipped": 150, "karma": 41, "disciplines": ["artisan", "ui"] },
14
14
  { "handle": "ada-okafor", "github_login": "adaokafor", "display_name": "Ada Okafor", "avatar_url": "/__kit/avatar.svg", "credits": 6125, "tasks_shipped": 77, "karma": 52, "disciplines": ["artist"] },
15
- { "handle": "tomas-ek", "github_login": "tomasek", "display_name": "Tomas Ek", "avatar_url": "/__kit/avatar.svg", "credits": 4020, "tasks_shipped": 58, "karma": 22, "disciplines": ["engineer"] },
16
- { "handle": "lin-wei", "github_login": "linwei", "display_name": "Lin Wei", "avatar_url": null, "credits": 2480, "tasks_shipped": 31, "karma": 18, "disciplines": ["ideator", "engineer"] }
15
+ { "handle": "tomas-ek", "github_login": "tomasek", "display_name": "Tomas Ek", "avatar_url": "/__kit/avatar.svg", "credits": 4020, "tasks_shipped": 58, "karma": 22, "disciplines": ["artisan"] },
16
+ { "handle": "lin-wei", "github_login": "linwei", "display_name": "Lin Wei", "avatar_url": null, "credits": 2480, "tasks_shipped": 31, "karma": 18, "disciplines": ["artist", "artisan"] }
17
17
  ],
18
18
  "30d": [
19
19
  { "handle": "ada-okafor", "github_login": "adaokafor", "display_name": "Ada Okafor", "avatar_url": "/__kit/avatar.svg", "credits": 1340, "tasks_shipped": 19, "karma": 9, "disciplines": ["artist"] },
20
- { "handle": "priya-nair", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "credits": 880, "tasks_shipped": 11, "karma": 4, "disciplines": ["engineer", "ui"] },
21
- { "handle": "jo-park", "github_login": "jopark", "display_name": null, "avatar_url": "/__kit/avatar.svg", "credits": 310, "tasks_shipped": 1, "karma": 0, "disciplines": ["ideator"] }
20
+ { "handle": "priya-nair", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "credits": 880, "tasks_shipped": 11, "karma": 4, "disciplines": ["artisan", "ui"] },
21
+ { "handle": "jo-park", "github_login": "jopark", "display_name": null, "avatar_url": "/__kit/avatar.svg", "credits": 310, "tasks_shipped": 1, "karma": 0, "disciplines": ["artist"] }
22
22
  ],
23
23
  "7d": [
24
24
  { "handle": "ada-okafor", "github_login": "adaokafor", "display_name": "Ada Okafor", "avatar_url": "/__kit/avatar.svg", "credits": 420, "tasks_shipped": 6, "karma": 3, "disciplines": ["artist"] },
25
- { "handle": "tomas-ek", "github_login": "tomasek", "display_name": "Tomas Ek", "avatar_url": "/__kit/avatar.svg", "credits": -15, "tasks_shipped": 0, "karma": 1, "disciplines": ["engineer"] }
25
+ { "handle": "tomas-ek", "github_login": "tomasek", "display_name": "Tomas Ek", "avatar_url": "/__kit/avatar.svg", "credits": -15, "tasks_shipped": 0, "karma": 1, "disciplines": ["artisan"] }
26
26
  ]
27
27
  }
28
28
  }
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "_": "GET /community/search for the kit stub (task 1003363): the public, existence-visible builders the stub matches by name or handle. Sam Rivera hides their numbers, so `disciplines` is null: found by name, dropped by any craft filter (builder-search.js).",
3
3
  "directory": [
4
- { "handle": "priya-nair", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "disciplines": ["engineer", "ui"] },
4
+ { "handle": "priya-nair", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "disciplines": ["artisan", "ui"] },
5
5
  { "handle": "priyanka-shah", "github_login": "pshah", "display_name": "Priyanka Shah", "avatar_url": "/__kit/avatar.svg", "disciplines": ["artist"] },
6
- { "handle": "tomas-ek", "github_login": "tomasek", "display_name": "Tomas Ek", "avatar_url": "/__kit/avatar.svg", "disciplines": ["engineer"] },
6
+ { "handle": "tomas-ek", "github_login": "tomasek", "display_name": "Tomas Ek", "avatar_url": "/__kit/avatar.svg", "disciplines": ["artisan"] },
7
7
  { "handle": "ada-okafor", "github_login": "adaokafor", "display_name": "Ada Okafor", "avatar_url": "/__kit/avatar.svg", "disciplines": ["artist"] },
8
8
  { "handle": "sam-rivera", "github_login": "samrivera", "display_name": "Sam Rivera", "avatar_url": "/__kit/avatar.svg", "disciplines": null }
9
9
  ]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_": "GET /scouting for a viewer the recruiting door admits — a project owner (task 1003363). `builders` is the ranked tier, which the community page never draws (the leaderboard already shows those numbers to everyone); `name_only` is ADR 0334's hidden-but-open-to-recruiters tier, login, name and avatar only, alphabetical by login as listScoutingNameOnly sends it.",
3
3
  "builders": [
4
- { "github_id": "9001", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "project_count": 3, "total_credits": 18420, "total_tasks_shipped": 212, "total_karma": 64, "last_active": "2026-10-20T10:00:00Z", "disciplines": ["engineer", "ui"] }
4
+ { "github_id": "9001", "github_login": "priyanair", "display_name": "Priya Nair", "avatar_url": "/__kit/avatar.svg", "project_count": 3, "total_credits": 18420, "total_tasks_shipped": 212, "total_karma": 64, "last_active": "2026-10-20T10:00:00Z", "disciplines": ["artisan", "ui"] }
5
5
  ],
6
6
  "name_only": [
7
7
  { "github_login": "kemi-a", "display_name": "Kemi Adeyemi", "avatar_url": "/__kit/avatar.svg" },
@@ -45,13 +45,13 @@
45
45
  <h2 class="scroll__h" id="ref-colour-h">Colour</h2>
46
46
  <p class="scroll__lede">The thirteen colours of the branding pack. An instance replaces them in its own pack; in dark mode only the neutrals flip, and the accent, sea and terracotta stay the pack’s.</p>
47
47
 
48
- <ul class="ref-list" role="list"><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--bg)" aria-hidden="true"></span><code class="ref-name">--bg</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#edecee</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#000000</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--bg-card)" aria-hidden="true"></span><code class="ref-name">--bg-card</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#fbfafc</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#101012</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--bg-deep)" aria-hidden="true"></span><code class="ref-name">--bg-deep</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#e2e1e4</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#000000</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--bg-frame)" aria-hidden="true"></span><code class="ref-name">--bg-frame</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#f6f5f7</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#08080a</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--ink)" aria-hidden="true"></span><code class="ref-name">--ink</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#17181a</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#ffffff</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--ink-soft)" aria-hidden="true"></span><code class="ref-name">--ink-soft</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#55565a</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#c0c0c0</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--ink-faint)" aria-hidden="true"></span><code class="ref-name">--ink-faint</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#65656a</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#a8a8a8</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--rule)" aria-hidden="true"></span><code class="ref-name">--rule</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#c6c6c8</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(255, 255, 255, .16)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--rule-soft)" aria-hidden="true"></span><code class="ref-name">--rule-soft</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#dcdbdd</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(255, 255, 255, .08)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent)" aria-hidden="true"></span><code class="ref-name">--accent</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#fb9569</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>same as light</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-deep)" aria-hidden="true"></span><code class="ref-name">--accent-deep</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#a3481a</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>same as light</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--sea)" aria-hidden="true"></span><code class="ref-name">--sea</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#5b6fd0</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>same as light</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--terracotta)" aria-hidden="true"></span><code class="ref-name">--terracotta</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#c9512c</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>same as light</code></span></li></ul>
48
+ <ul class="ref-list" role="list"><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--bg)" aria-hidden="true"></span><code class="ref-name">--bg</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#edecee</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#050d16</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--bg-card)" aria-hidden="true"></span><code class="ref-name">--bg-card</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#fbfafc</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#0a1622</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--bg-deep)" aria-hidden="true"></span><code class="ref-name">--bg-deep</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#e2e1e4</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#050d16</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--bg-frame)" aria-hidden="true"></span><code class="ref-name">--bg-frame</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#f6f5f7</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#07111b</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--ink)" aria-hidden="true"></span><code class="ref-name">--ink</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#17181a</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#ffffff</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--ink-soft)" aria-hidden="true"></span><code class="ref-name">--ink-soft</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#55565a</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#c8f1f7</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--ink-faint)" aria-hidden="true"></span><code class="ref-name">--ink-faint</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#65656a</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#a9cdd4</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--rule)" aria-hidden="true"></span><code class="ref-name">--rule</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#c6c6c8</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(200, 241, 247, .4)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--rule-soft)" aria-hidden="true"></span><code class="ref-name">--rule-soft</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#dcdbdd</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(200, 241, 247, .2)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent)" aria-hidden="true"></span><code class="ref-name">--accent</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#fb9569</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>same as light</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-deep)" aria-hidden="true"></span><code class="ref-name">--accent-deep</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#a3481a</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>same as light</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--sea)" aria-hidden="true"></span><code class="ref-name">--sea</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#5b6fd0</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>same as light</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--terracotta)" aria-hidden="true"></span><code class="ref-name">--terracotta</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#c9512c</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>same as light</code></span></li></ul>
49
49
  <h3 class="ref-sub">The status vocabulary</h3>
50
50
  <p class="ref-note">Fixed, not taken from the pack, and the one exception to the fifteen tokens: a status is always a word as well as a colour.</p>
51
51
  <ul class="ref-list" role="list"><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--ok)" aria-hidden="true"></span><code class="ref-name">--ok</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#187444</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#4ade80</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--ok-weak)" aria-hidden="true"></span><code class="ref-name">--ok-weak</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, #187444 12%, var(--bg-card))</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, #4ade80 14%, var(--bg-card))</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--warn)" aria-hidden="true"></span><code class="ref-name">--warn</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#895c00</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#fbbf24</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--warn-weak)" aria-hidden="true"></span><code class="ref-name">--warn-weak</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, #895c00 14%, var(--bg-card))</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, #fbbf24 14%, var(--bg-card))</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--danger)" aria-hidden="true"></span><code class="ref-name">--danger</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#b42318</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#f87171</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--danger-weak)" aria-hidden="true"></span><code class="ref-name">--danger-weak</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, #b42318 10%, var(--bg-card))</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, #f87171 14%, var(--bg-card))</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--info)" aria-hidden="true"></span><code class="ref-name">--info</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--sea) 86%, #000000)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--sea) 80%, #ffffff)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--info-weak)" aria-hidden="true"></span><code class="ref-name">--info-weak</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--info) 9%, var(--bg-card))</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--info) 14%, var(--bg-card))</code></span></li></ul>
52
52
  <h3 class="ref-sub">Derived colours</h3>
53
53
  <p class="ref-note">Mixed from the thirteen, never typed as a new colour. Black and white with alpha appear only as a scrim, a shadow or glass.</p>
54
- <ul class="ref-list" role="list"><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--glass)" aria-hidden="true"></span><code class="ref-name">--glass</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(23, 24, 26, .05)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(255, 255, 255, .11)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--glass-strong)" aria-hidden="true"></span><code class="ref-name">--glass-strong</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(23, 24, 26, .08)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(255, 255, 255, .17)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--glass-edge)" aria-hidden="true"></span><code class="ref-name">--glass-edge</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(23, 24, 26, .12)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(255, 255, 255, .13)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--void)" aria-hidden="true"></span><code class="ref-name">--void</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#050508</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#000000</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--void-ink)" aria-hidden="true"></span><code class="ref-name">--void-ink</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#ffffff</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>var(--ink)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--void-edge)" aria-hidden="true"></span><code class="ref-name">--void-edge</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(23, 24, 26, .12)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(255, 255, 255, .16)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--skeleton)" aria-hidden="true"></span><code class="ref-name">--skeleton</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--ink) 10%, var(--bg-card))</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--ink) 10%, var(--bg-card))</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-ink)" aria-hidden="true"></span><code class="ref-name">--accent-ink</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--accent) 45%, #240e00)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>var(--accent)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-lift)" aria-hidden="true"></span><code class="ref-name">--accent-lift</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--accent) 58%, #ffffff)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--accent) 58%, #ffffff)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-tint)" aria-hidden="true"></span><code class="ref-name">--accent-tint</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--accent) 30%, #fffdf9)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--accent) 22%, #0b0a09)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-on)" aria-hidden="true"></span><code class="ref-name">--accent-on</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#2a1305</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#2a1305</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--focus)" aria-hidden="true"></span><code class="ref-name">--focus</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--accent-deep) 82%, #3a1400)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>var(--accent)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--scrim)" aria-hidden="true"></span><code class="ref-name">--scrim</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(0, 0, 0, .55)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(0, 0, 0, .55)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--surface-2)" aria-hidden="true"></span><code class="ref-name">--surface-2</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--ink) 5%, var(--bg-card))</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--ink) 6%, var(--bg-card))</code></span></li></ul>
54
+ <ul class="ref-list" role="list"><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--glass)" aria-hidden="true"></span><code class="ref-name">--glass</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(23, 24, 26, .05)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(200, 241, 247, .1)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--glass-strong)" aria-hidden="true"></span><code class="ref-name">--glass-strong</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(23, 24, 26, .08)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(200, 241, 247, .16)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--glass-edge)" aria-hidden="true"></span><code class="ref-name">--glass-edge</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(23, 24, 26, .12)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(200, 241, 247, .2)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--void)" aria-hidden="true"></span><code class="ref-name">--void</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#050508</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#050d16</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--void-ink)" aria-hidden="true"></span><code class="ref-name">--void-ink</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#ffffff</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>var(--ink)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--void-edge)" aria-hidden="true"></span><code class="ref-name">--void-edge</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(23, 24, 26, .12)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(200, 241, 247, .4)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--skeleton)" aria-hidden="true"></span><code class="ref-name">--skeleton</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--ink) 10%, var(--bg-card))</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--ink) 10%, var(--bg-card))</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-ink)" aria-hidden="true"></span><code class="ref-name">--accent-ink</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--accent) 45%, #240e00)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>var(--accent)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-lift)" aria-hidden="true"></span><code class="ref-name">--accent-lift</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--accent) 58%, #ffffff)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--accent) 58%, #ffffff)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-tint)" aria-hidden="true"></span><code class="ref-name">--accent-tint</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--accent) 30%, #fffdf9)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--accent) 22%, #050d16)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--accent-on)" aria-hidden="true"></span><code class="ref-name">--accent-on</code><span class="ref-val"><span class="ref-val__k">light</span> <code>#2a1305</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>#2a1305</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--focus)" aria-hidden="true"></span><code class="ref-name">--focus</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--accent-deep) 82%, #3a1400)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>var(--accent)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--scrim)" aria-hidden="true"></span><code class="ref-name">--scrim</code><span class="ref-val"><span class="ref-val__k">light</span> <code>rgba(0, 0, 0, .55)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>rgba(0, 0, 0, .55)</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--surface-2)" aria-hidden="true"></span><code class="ref-name">--surface-2</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--ink) 5%, var(--bg-card))</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--ink) 6%, var(--bg-card))</code></span></li><li class="ref-row ref-row--colour"><span class="ref-swatch" style="background: var(--night-glass)" aria-hidden="true"></span><code class="ref-name">--night-glass</code><span class="ref-val"><span class="ref-val__k">light</span> <code>color-mix(in srgb, var(--bg) 72%, transparent)</code></span><span class="ref-val"><span class="ref-val__k">dark</span> <code>color-mix(in srgb, var(--bg) 72%, transparent)</code></span></li></ul>
55
55
  </section>
56
56
  <section class="scroll ref-sec" id="ref-type" aria-labelledby="ref-type-h">
57
57
  <h2 class="scroll__h" id="ref-type-h">Type</h2>
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.24.79",
3
+ "version": "1.24.81",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.24.79",
9
+ "version": "1.24.81",
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.24.79",
3
+ "version": "1.24.81",
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",
@@ -11513,5 +11513,81 @@
11513
11513
  "id": "1005186",
11514
11514
  "text": "Closed a gap opened by letting Autobongos run on any device. The runner now keeps its own sign-in in its own folder, and the rule that stops an AI session from opening sign-in files did not yet cover that folder. It does now,"
11515
11515
  }
11516
+ ],
11517
+ "1.24.80": [
11518
+ {
11519
+ "id": "1005193",
11520
+ "text": "New versions can be published again: the checks broken by the craft rename pass, and projects on older versions no longer show the old craft name on the hub."
11521
+ },
11522
+ {
11523
+ "id": "1005148",
11524
+ "text": "In game mode, each builder now sees the project through a visor: their character's actions on the glass, their own character and credits in the corner, and a list of every action on the A key."
11525
+ },
11526
+ {
11527
+ "id": "1005145",
11528
+ "text": "Checked and locked in: after signing in and pressing Start there is no sidebar, and sound, the command-line key and module switches are all reached inside the one options menu; the old settings pages now only send you there."
11529
+ },
11530
+ {
11531
+ "id": "1004794",
11532
+ "text": "Modules can now say what language they are written in, and one naming a language Bongos cannot run yet is turned away with a clear reason."
11533
+ },
11534
+ {
11535
+ "id": "1004793",
11536
+ "text": "Work on the module store can now be planned under a goal, because its code finally has an owner in the project map."
11537
+ },
11538
+ {
11539
+ "id": "1005147",
11540
+ "text": "Builders now pick one of three characters (Artisan, Artist or Patron, drawn from the owner's art) when they join; the pick follows them to every device and shows as their sprite in the top bar."
11541
+ },
11542
+ {
11543
+ "id": "1005144",
11544
+ "text": "Every setting now lives in one options menu with a search box, and in game mode Escape opens it and closes it again."
11545
+ },
11546
+ {
11547
+ "id": "1005191",
11548
+ "text": "A project that is behind now asks its owner, in a clear pop-up, whether to update the builders hall."
11549
+ },
11550
+ {
11551
+ "id": "1005143",
11552
+ "text": "Signing in now opens a start screen (Start, Options, Achievements, Extras, Quit). Start plays a short load screen where the project city builds up week by week with a tip, then the hall opens full screen."
11553
+ },
11554
+ {
11555
+ "id": "1005158",
11556
+ "text": "Design written for claiming work as a chain: a chain reserves a run of tasks for you and your party, while each task inside it is still claimed on its own through the same safety checks as today. Nobody outside the party can g"
11557
+ },
11558
+ {
11559
+ "id": "1005190",
11560
+ "text": "A project owner can now skip the setup stages and open the full hall straight away, with the skip recorded."
11561
+ },
11562
+ {
11563
+ "id": "1005189",
11564
+ "text": "Setting up as a new builder no longer stops to ask for an optional image-generation key."
11565
+ },
11566
+ {
11567
+ "id": "1005146",
11568
+ "text": "Decided how the game's first-person visor sits over the city and the sky, and what the Escape key closes first. Also found a small bug where closing a city card brings the sidebar back."
11569
+ },
11570
+ {
11571
+ "id": "1005066",
11572
+ "text": "Project owners can now invite someone to the project's GitHub repository from the hall's invite box, always read-only, so a person who signs in to the hall can also see the code on their own GitHub once they accept GitHub's em"
11573
+ },
11574
+ {
11575
+ "id": "1005185",
11576
+ "text": "Making a new worktree on a hosted project now tells you the claim command that actually works there (npx bongos claim), instead of one that fails."
11577
+ },
11578
+ {
11579
+ "id": "1005183",
11580
+ "text": "The notes that guide agents around the claim rules pointed at the wrong lines of code. They now name the code directly, and a test stops them going stale again."
11581
+ },
11582
+ {
11583
+ "id": "1005141",
11584
+ "text": "The builders' crafts now carry their game names: Engineers are Artisans, Ideators join the Artists, and Patron is the third character; old links and old records keep working."
11585
+ }
11586
+ ],
11587
+ "1.24.81": [
11588
+ {
11589
+ "id": "1005192",
11590
+ "text": "The hall now wears the new Helm look: deep night panels, ice-blue text, wide capital titles and cut-corner buttons, all from one shared design system. The start and load screens are rebuilt to match, and the hall is dark only."
11591
+ }
11516
11592
  ]
11517
11593
  }
@@ -82,7 +82,7 @@ function buildWorkerArgs({ sessionId, model = DEFAULT_MODEL, isRoot = false } =
82
82
  // runs unattended with the power to ship, so that text must never be able to
83
83
  // instruct it. Reuses the grader's hardened fence rather than re-typing one, so
84
84
  // there is a single place this class of text is scrubbed and delimited.
85
- function buildWorkerPrompt({ task, packPath = 'docs/packs/engineer.md' } = {}) {
85
+ function buildWorkerPrompt({ task, packPath = 'docs/packs/artisan.md' } = {}) {
86
86
  if (!task || !task.id) throw new Error('buildWorkerPrompt: a task with an id is required');
87
87
  return [
88
88
  `You are an autonomous builder working ONE claimed task end to end. Read CLAUDE.md and ${packPath} for context. The task is ${task.id}.`,
@@ -1,20 +1,15 @@
1
1
  {
2
- "_doc": "The ROLE REGISTRY: discipline -> the operating playbook that craft works from (task 1267; reshaped by task 1002990). Since the kernel/pack split, a CORE craft names a `pack` — a markdown role pack under docs/packs/ that carries everything the root CLAUDE.md kernel deliberately does not, because it is true for one craft only. A module-contributed discipline may instead name a `skill` (a slash-command playbook under .claude/skills/), which is how `ui` -> /design still works (ADR 0272 keeps ui-design's contribution unchanged). An entry may carry both; it must carry at least one. GET /me reads this (src/bongos/craft-mode.js) and puts each active claim's entry — `directive` plus pack path — on the claim as `craft_mode`; the Conductor hook injects the one for the claim bound to the session's worktree, so the session opens the right playbook without anyone reading terminal output (task 1002992). claim.js reads it too, printing only the one role line and running `materializeModuleSkills`. There is NO classification step — `discipline` is already a column on the task. One registry, never a server-side copy. A missing or invalid version of this file must never break a claim (claim.js fails open) — but fitness.js DOES hard-fail CI when an entry names a pack that is not in the tree, so the fail-open runtime cannot hide a broken registry from the build. GOVERNOR IS DEFERRED: three packs, not four, until the owner decides (criterion wa6-kernel-and-packs). A mode entry may also set \"materializeModuleSkills\": true to have the claim land that mode's module-owned skills into this checkout's .claude/skills/ (task 1003486) — opt-in per discipline, core-checkout only, and fail-open like the hint itself.",
2
+ "_doc": "The ROLE REGISTRY: discipline -> the operating playbook that craft works from (task 1267; reshaped by task 1002990). Since the kernel/pack split, a CORE craft names a `pack` — a markdown role pack under docs/packs/ that carries everything the root CLAUDE.md kernel deliberately does not, because it is true for one craft only. A module-contributed discipline may instead name a `skill` (a slash-command playbook under .claude/skills/), which is how `ui` -> /design still works (ADR 0272 keeps ui-design's contribution unchanged). An entry may carry both; it must carry at least one. GET /me reads this (src/bongos/craft-mode.js) and puts each active claim's entry — `directive` plus pack path — on the claim as `craft_mode`; the Conductor hook injects the one for the claim bound to the session's worktree, so the session opens the right playbook without anyone reading terminal output (task 1002992). claim.js reads it too, printing only the one role line and running `materializeModuleSkills`. There is NO classification step — `discipline` is already a column on the task. One registry, never a server-side copy. A missing or invalid version of this file must never break a claim (claim.js fails open) — but fitness.js DOES hard-fail CI when an entry names a pack that is not in the tree, so the fail-open runtime cannot hide a broken registry from the build. THE GAME'S CHARACTERS (task 1005141, BONGOS-V3): engineer is now artisan, and the ideator folded into the artist, so there are two core packs — artisan.md and artist.md (which carries the ideation half). Patron is a character, not a task craft, and has no pack yet. A task row still holding an old spelling is read as the new one (src/crafts.js normalizeCraft). A mode entry may also set \"materializeModuleSkills\": true to have the claim land that mode's module-owned skills into this checkout's .claude/skills/ (task 1003486) — opt-in per discipline, core-checkout only, and fail-open like the hint itself.",
3
3
  "modes": {
4
- "engineer": {
5
- "pack": "docs/packs/engineer.md",
6
- "label": "Engineering session",
7
- "directive": "This is an ENGINEER task. Read the Engineer pack now, before working — it is the operating playbook for this craft and the only place the standard build loop is written down: understand the code before editing -> make the smallest correct, scoped change -> VERIFY it (smoke tests + the preview/verification workflow when observable) -> /builder-ship with real notes. Engineering is already the default way you'd work, so the pack is the standard made explicit (plus the autonomous-mode guardrails: be conservative, verify hard, don't wander), not a redirect."
8
- },
9
- "ideator": {
10
- "pack": "docs/packs/ideator.md",
11
- "label": "Ideation session",
12
- "directive": "This is an IDEATOR task. Read the Ideator pack now and work from it — it is the operating playbook for ideation and the only place the experience is defined. It inverts the usual dynamic: you (the human ideator) are the creative driver and Claude is your sounding board / research arm / devil's advocate, not a content generator filing ideas on command. Quick ideas stay ONE LINE, and after one is filed Claude asks whether to develop it into a Full Idea — five questions, drawn out of the conversation in the ideator's own words and scored on completeness. If no human is present (autonomous / bypass-permissions), the pack runs a self-adversarial divergence-and-critique loop instead of dumping a fixed batch. THE SURFACE, not just the behavior (ADR 0271): an ideator session is QUIET about its own machinery. Report outcomes, not mechanism — do not narrate tool calls, file paths, script names, API routes or task/claim bookkeeping unless they ask or something actually failed. Speak in the language of the idea, not the plumbing. If a step breaks, say plainly what broke and what you need — quiet never means hiding a problem."
4
+ "artisan": {
5
+ "pack": "docs/packs/artisan.md",
6
+ "label": "Artisan session",
7
+ "directive": "This is an ARTISAN task (the craft once called engineer). Read the Artisan pack now, before working — it is the operating playbook for this craft and the only place the standard build loop is written down: understand the code before editing -> make the smallest correct, scoped change -> VERIFY it (smoke tests + the preview/verification workflow when observable) -> /builder-ship with real notes. Building is already the default way you'd work, so the pack is the standard made explicit (plus the autonomous-mode guardrails: be conservative, verify hard, don't wander), not a redirect."
13
8
  },
14
9
  "artist": {
15
10
  "pack": "docs/packs/artist.md",
16
- "label": "Art session",
17
- "directive": "This is an ARTIST task. Read the Artist pack now and work from it — it is the operating playbook for art sessions and the only place the experience is defined. It is show-first and low-text: communicate in pictures and rendered surfaces, not paragraphs about what ran. Interpret as little as possible — take the brief literally, you are the artist's hands and not their art director — and arrive precalculated: load the look, have the options already rendered, never open with a form of intake questions. The artist's subject is how the project LOOKS AND READS, which is core (ADR 0272); a pixel-art or asset pipeline is a host module the pack drives only when the instance ships one. If no human is present (autonomous / bypass-permissions), make it, gate it hard, stage the passes and park the visuals for human review."
11
+ "label": "Artist session",
12
+ "directive": "This is an ARTIST task. Read the Artist pack now and work from it — it is the operating playbook for the artist craft, which holds both halves of what used to be two crafts (task 1005141): how the project LOOKS AND READS, and its IDEAS. It is show-first and low-text: communicate in pictures and rendered surfaces, not paragraphs about what ran. Interpret as little as possible — take the brief literally, you are the artist's hands and not their art director — and arrive precalculated: load the look, have the options already rendered, never open with a form of intake questions. The artist's subject is how the project LOOKS AND READS, which is core (ADR 0272); a pixel-art or asset pipeline is a host module the pack drives only when the instance ships one. If no human is present (autonomous / bypass-permissions), make it, gate it hard, stage the passes and park the visuals for human review. When the work is an idea rather than a surface, the pack's ideation half applies: It inverts the usual dynamic: you (the human artist) are the creative driver and Claude is your sounding board / research arm / devil's advocate, not a content generator filing ideas on command. Quick ideas stay ONE LINE, and after one is filed Claude asks whether to develop it into a Full Idea — five questions, drawn out of the conversation in the ideator's own words and scored on completeness. If no human is present (autonomous / bypass-permissions), the pack runs a self-adversarial divergence-and-critique loop instead of dumping a fixed batch. THE SURFACE, not just the behavior (ADR 0271): an ideation session is QUIET about its own machinery. Report outcomes, not mechanism — do not narrate tool calls, file paths, script names, API routes or task/claim bookkeeping unless they ask or something actually failed. Speak in the language of the idea, not the plumbing. If a step breaks, say plainly what broke and what you need — quiet never means hiding a problem."
18
13
  },
19
14
  "ui": {
20
15
  "skill": "design",
@@ -524,7 +524,7 @@ const KERNEL_FILES = [
524
524
  'src/module-api.js', // the published doorway
525
525
  'src/modules.js', // the registry/resolver facade
526
526
  'src/module-seams.js', // the seam registry (ports/events/contributions)
527
- 'src/role-responsibilities.js', 'src/html-escape.js', 'src/sleep.js', // owner's role statements (task 1003732) + THE server HTML escaper (task 1004876) + THE server sleep (task 1004893) — all import nothing
527
+ 'src/crafts.js', 'src/role-responsibilities.js', 'src/html-escape.js', 'src/sleep.js', // the craft vocabulary (task 1005141) + owner's role statements (task 1003732) + THE server HTML escaper (task 1004876) + THE server sleep (task 1004893) — all import nothing
528
528
  'src/module-loader/loader.js', // the disk loader (discover → validate → mount)
529
529
  'src/module-loader/manifest-schema.js', // the manifest validator
530
530
  'src/module-loader/semver.js', // coreVersion compatibility
@@ -46,7 +46,7 @@ const vm = require('vm');
46
46
  const ROOT = path.resolve(__dirname, '..', '..');
47
47
  const HALL = 'modules/hall-ui/public';
48
48
  const OUT = 'docs/hall-sitemap.md';
49
- const CRAFTS = ['building', 'artistry', 'ideating', 'governing'];
49
+ const CRAFTS = ['artisan', 'artist', 'patron']; // the game's characters (task 1005141)
50
50
 
51
51
  // URLs the server answers that are not a page file in the hall. A link to one is not broken.
52
52
  // A NEW route a page links to belongs here, with where the server serves it; the audit fails
@@ -69,7 +69,7 @@ const ROUTES = {
69
69
  // Targets that leave the hall on purpose: sign-in, the hub's /account (platform-server.js;
70
70
  // settings.js points the link at the hub), the API, module assets, and any file with an extension.
71
71
  const EXTERNAL = [/^\/api\//, /^\/auth\b/, /^\/login\b/, /^\/logout\b/, /^\/signin\b/, /^\/status\b/,
72
- /^\/account\b/, /^\/modules\//, /^\/docs\b/, /^\/diagrams\//, /^\/healthz\b/, /^\/version\b/, /\.[a-z0-9]{2,5}$/i];
72
+ /^\/account\b/, /^\/modules\//, /^\/docs\b/, /^\/diagrams\//, /^\/characters\//, /^\/healthz\b/, /^\/version\b/, /\.[a-z0-9]{2,5}$/i];
73
73
 
74
74
  // Pages whose words come from a markdown file they fetch. A link in that file to a hall page's
75
75
  // own file (../../modules/hall-ui/public/<page>.html) opens the page in the hall (primer.js,
@@ -155,6 +155,7 @@ const LINK_RES = [
155
155
  /href=\\?["']\$\{(?![^}]*\bhub)[^}]*\}(\/[a-z0-9-][^"'\\\s$`{]*)/g,
156
156
  /Href\([^)]*\)\s*\{\s*return\s+'(\/[^'\s$]*)'/g, // function itemHref(id) { return '/x?id=' + … }
157
157
  /\bhref\s*:\s*'(\/[^'\s$]*)'/g, // { href: '/x' }
158
+ /\bembed\s*:\s*'(\/[^'\s$]*)'/g, // { embed: '/x' } — an options menu entry opens it in a frame (task 1005144)
158
159
  /\.href\s*=\s*'(\/[^'\s$]*)'/g, // a.href = '/x'
159
160
  /setAttribute\(\s*'href'\s*,\s*'(\/[^'\s$]*)'/g, // setAttribute('href', '/x')
160
161
  /location\.(?:assign|replace)\(\s*'(\/[^'\s$]*)'/g, // location.assign('/x')
@@ -288,12 +289,11 @@ function dedupe(list) {
288
289
  }
289
290
 
290
291
  // ---- the document ----
291
- const CRAFT_NAME = { building: 'Building', artistry: 'Artistry', ideating: 'Ideating', governing: 'Governing' };
292
+ const CRAFT_NAME = { artisan: 'Artisan', artist: 'Artist', patron: 'Patron' };
292
293
  const CRAFT_HOME = {
293
- building: '/ — the project city',
294
- artistry: '/ — the gallery',
295
- ideating: '/ — the sky over the city',
296
- governing: '/street — the governor\'s street (Home hops there)',
294
+ artisan: '/ — the project city',
295
+ artist: '/ — the gallery',
296
+ patron: '/street — the governor\'s street (Home hops there)',
297
297
  };
298
298
  function list(xs) { return xs.length ? xs.map((x) => '`' + x + '`').join(', ') : '—'; }
299
299
  function render(m) {
@@ -35,7 +35,7 @@ Acceptance:
35
35
  - One unit test in tests/util.mjs covers two cases (positive + negative).
36
36
  Out of scope: anything to do with timezones; calendar-aware durations.`,
37
37
  kind: 'feature',
38
- discipline: 'engineer',
38
+ discipline: 'artisan',
39
39
  version_id: 'GDS-V3',
40
40
  };
41
41
  const GOOD_VALUE_SUMMARY =
@@ -85,7 +85,7 @@ Acceptance:
85
85
  - One smoke test that exercises the charge → row → rollback paths.
86
86
  Out of scope: refund flow.`,
87
87
  kind: 'feature',
88
- discipline: 'engineer',
88
+ discipline: 'artisan',
89
89
  version_id: 'GDS-V3',
90
90
  };
91
91
  const BAD_VALUE_SUMMARY =
@@ -784,7 +784,7 @@ async function seedViaApi(spec, { dryRun, log = console.log, api = apiCall } = {
784
784
  attempted++;
785
785
  const res = await api('POST', '/api/bongos/tasks', {
786
786
  version_id: vp.id, goal_id: goalId, title: t.title, description: t.description || '', status: 'ready',
787
- kind: t.kind || 'infra', discipline: t.discipline || 'engineer', source: 'bongos-init', ...extra,
787
+ kind: t.kind || 'infra', discipline: t.discipline || 'artisan', source: 'bongos-init', ...extra,
788
788
  });
789
789
  if (!res.ok) failures.push({ title: t.title, status: res.status, detail: JSON.stringify(res.data) });
790
790
  return res.ok;
@@ -794,7 +794,7 @@ async function seedViaApi(spec, { dryRun, log = console.log, api = apiCall } = {
794
794
  let created = 0;
795
795
  for (const t of starters) {
796
796
  // task 1002988: `discipline: undefined` used to sit in this extras object, and
797
- // because `...extra` spreads AFTER postTask's own `t.discipline || 'engineer'`
797
+ // because `...extra` spreads AFTER postTask's own `t.discipline || 'artisan'`
798
798
  // it clobbered that default back to nothing — which is why a freshly scaffolded
799
799
  // instance was born with role-less starter tasks. Dropped, so starters inherit
800
800
  // the same default every other seeded task already got.
@@ -6,9 +6,8 @@
6
6
  "auto_promote": true,
7
7
  "max_generate_per_run": 8,
8
8
  "disciplines": {
9
- "engineer": { "floor": 2 },
9
+ "artisan": { "floor": 2 },
10
10
  "artist": { "floor": 3 },
11
- "ideator": { "floor": 2 },
12
11
  "ui": { "floor": 2 }
13
12
  }
14
13
  }
@@ -10,8 +10,8 @@
10
10
  // session, so the floor silently drained to 0/0/0 and stayed there.
11
11
  //
12
12
  // WHAT THIS DOES NOW: each discipline defines a LIST of EVERGREEN chores in
13
- // `newcomer-floor.templates.json` (engineer = "add a unit test" + the constrained
14
- // docs-hygiene sweep; artist = generate an asset; ideator = file ideas). A chore's
13
+ // `newcomer-floor.templates.json` (artisan = "add a unit test" + the constrained
14
+ // docs-hygiene sweep; artist = generate an asset, or file ideas). A chore's
15
15
  // definition never changes, yet running it is always valuable. Each chore keeps its
16
16
  // OWN standing pool to its OWN per-template `floor`; when a chore's ready copies drop
17
17
  // below that floor, this script stamps fresh IDENTICAL claimable COPIES of it. No AI,
@@ -64,7 +64,7 @@ const HARD_MAX_MINUTES = 60; // newcomer scope ceiling, never exceeded (task 614
64
64
  // It is the craft VOCABULARY, which is why 'unclassified' is absent. Keep in step
65
65
  // with the keys in newcomer-floor.templates.json ('ui' added by task 1003487); the
66
66
  // server-side restock reads the live offered set instead (newcomer-restock.js).
67
- const VALID_DISCIPLINES = new Set(['engineer', 'artist', 'ideator', 'ui']);
67
+ const VALID_DISCIPLINES = new Set(['artisan', 'artist', 'ui']);
68
68
  // Every status a copy's source_ref could occupy — scanned so `seq` is globally
69
69
  // monotonic and never recycles a ref already used by a shipped/abandoned copy.
70
70
  const ALL_STATUSES = ['backlog', 'ready', 'active', 'completed', 'confirmed', 'shipped', 'blocked', 'abandoned'];
@@ -307,6 +307,7 @@ async function main() {
307
307
  discipline: arg('--discipline', args),
308
308
  configPath: arg('--config', args) || DEFAULT_CONFIG_PATH,
309
309
  };
310
+ if (FLAGS.discipline) FLAGS.discipline = ({ engineer: 'artisan', ideator: 'artist' })[FLAGS.discipline] || FLAGS.discipline;
310
311
  if (FLAGS.discipline && !VALID_DISCIPLINES.has(FLAGS.discipline)) {
311
312
  console.error(`bad --discipline "${FLAGS.discipline}"; valid: ${[...VALID_DISCIPLINES].join(', ')}`);
312
313
  process.exit(2);