@bongos/core 1.18.3 → 1.18.18

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 (469) hide show
  1. package/.bongos-core.json +1575 -285
  2. package/.claude/skills/builder-box/SKILL.md +6 -0
  3. package/.claude/skills/builder-sequence/SKILL.md +97 -0
  4. package/.claude/skills/builder-ship/SKILL.md +8 -2
  5. package/.claude/skills/builder-start/SKILL.md +11 -0
  6. package/.claude/skills/builder-sync/SKILL.md +41 -0
  7. package/.claude/skills/fix-task/SKILL.md +64 -0
  8. package/.claude/skills/goal-create/SKILL.md +158 -0
  9. package/.claude/skills/goal-review/SKILL.md +3 -1
  10. package/.claude/skills/idea-triage/SKILL.md +14 -8
  11. package/.claude/skills/merge-mode/SKILL.md +2 -2
  12. package/.claude/skills/new-project/SKILL.md +1 -0
  13. package/.claude/skills/planning-session/SKILL.md +45 -18
  14. package/.env.local.example +4 -3
  15. package/README.md +4 -2
  16. package/bin/bongos.js +1 -0
  17. package/clients/bongos-client/README.md +2 -2
  18. package/clients/bongos-client/bongos-client.global.js +82 -18
  19. package/clients/bongos-client/index.cjs +82 -18
  20. package/clients/bongos-client/index.d.ts +131 -29
  21. package/clients/bongos-client/index.mjs +82 -18
  22. package/config/branding.neutral.json +6 -1
  23. package/config/governance.neutral.json +21 -0
  24. package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +24 -0
  25. package/docs/adr/0090-metic-task-authoring.md +1 -1
  26. package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +41 -0
  27. package/docs/adr/0144-federated-single-logout-backchannel.md +42 -0
  28. package/docs/adr/0145-devbox-app-branding-driven-module.md +44 -0
  29. package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +62 -0
  30. package/docs/adr/0146-configurable-reward-mode-cost-plus-only.md +53 -0
  31. package/docs/adr/0147-standalone-live-docs-regen.md +39 -0
  32. package/docs/adr/0148-task-scoped-box-source-access.md +48 -0
  33. package/docs/adr/0149-bongos-dev-local-launcher.md +57 -0
  34. package/docs/adr/0150-box-first-boot-bringup-vendored-instances.md +68 -0
  35. package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +229 -0
  36. package/docs/adr/0152-landing-gate-served-by-the-core-app.md +92 -0
  37. package/docs/adr/0152-metic-task-abandonment.md +67 -0
  38. package/docs/adr/0153-sequential-chain-runner.md +51 -0
  39. package/docs/adr/0154-goal-owner-criterion-authoring.md +86 -0
  40. package/docs/adr/README.md +10 -0
  41. package/docs/api/openapi.json +843 -17
  42. package/docs/api-reference.md +23 -10
  43. package/docs/architecture.md +4 -2
  44. package/docs/branding-contract.md +3 -1
  45. package/docs/canonical-permissions.md +21 -8
  46. package/docs/file-map.md +8 -0
  47. package/docs/onboarding/diagrams/01-task-lifecycle.mmd +2 -2
  48. package/docs/onboarding/diagrams/02-rank-ladder.mmd +3 -1
  49. package/docs/onboarding/diagrams/05-versioning.mmd +1 -3
  50. package/docs/onboarding/diagrams/assertions.json +4 -7
  51. package/docs/onboarding/drachmae-and-karma.md +3 -3
  52. package/docs/onboarding/primer.md +17 -16
  53. package/docs/onboarding/slash-commands.md +124 -0
  54. package/docs/recipes/builder-box-lifecycle.md +23 -0
  55. package/docs/recipes/devbox-app-release.md +14 -4
  56. package/docs/recipes/instance-first-run.md +16 -0
  57. package/docs/recipes/local-dev.md +81 -0
  58. package/docs/recipes/ops-gotchas.md +19 -1
  59. package/docs/recipes/overnight-builder.md +1 -1
  60. package/docs/recipes/parallel-goal-waves.md +174 -0
  61. package/docs/recipes/ship-and-regrade.md +2 -2
  62. package/docs/recipes/standalone-live-docs.md +48 -0
  63. package/docs/recipes/work-on-a-task-from-your-dev-box.md +108 -0
  64. package/migrations/003_pms.sql +6 -7
  65. package/migrations/006_pms_v2.sql +3 -31
  66. package/migrations/core_193_task_needs_rebase.sql +28 -0
  67. package/migrations/core_194_confirmed_backlog_clawback.sql +63 -0
  68. package/migrations/core_195_idea_triage_provenance.sql +57 -0
  69. package/migrations/core_196_session_reward_topup.sql +69 -0
  70. package/modules/autonomy/pollers/routine-timers.js +9 -8
  71. package/modules/builder-settings/wandering-prefs.js +61 -18
  72. package/modules/dev-box/app/README.md +73 -0
  73. package/modules/dev-box/app/assets/tray/mac-alertTemplate.png +0 -0
  74. package/modules/dev-box/app/assets/tray/mac-alertTemplate@2x.png +0 -0
  75. package/modules/dev-box/app/assets/tray/mac-busyTemplate.png +0 -0
  76. package/modules/dev-box/app/assets/tray/mac-busyTemplate@2x.png +0 -0
  77. package/modules/dev-box/app/assets/tray/mac-offTemplate.png +0 -0
  78. package/modules/dev-box/app/assets/tray/mac-offTemplate@2x.png +0 -0
  79. package/modules/dev-box/app/assets/tray/mac-onTemplate.png +0 -0
  80. package/modules/dev-box/app/assets/tray/mac-onTemplate@2x.png +0 -0
  81. package/modules/dev-box/app/assets/tray/win-alert.png +0 -0
  82. package/modules/dev-box/app/assets/tray/win-busy.png +0 -0
  83. package/modules/dev-box/app/assets/tray/win-off.png +0 -0
  84. package/modules/dev-box/app/assets/tray/win-on.png +0 -0
  85. package/modules/dev-box/app/build-resources/dmg-background.png +0 -0
  86. package/modules/dev-box/app/build-resources/dmg-background@2x.png +0 -0
  87. package/modules/dev-box/app/build-resources/icon.png +0 -0
  88. package/modules/dev-box/app/electron-builder.tmpl.yml +95 -0
  89. package/modules/dev-box/app/electron-builder.yml +95 -0
  90. package/modules/dev-box/app/package-lock.json +5291 -0
  91. package/modules/dev-box/app/package.json +30 -0
  92. package/modules/dev-box/app/renderer/app.js +319 -0
  93. package/modules/dev-box/app/renderer/index.html +45 -0
  94. package/modules/dev-box/app/renderer/styles.css +246 -0
  95. package/modules/dev-box/app/renderer/theme.generated.css +16 -0
  96. package/modules/dev-box/app/scripts/apply-dmg-backdrop.sh +82 -0
  97. package/modules/dev-box/app/scripts/dmgbuild-settings.py +39 -0
  98. package/modules/dev-box/app/scripts/gen-brand.js +138 -0
  99. package/modules/dev-box/app/scripts/gen-dmg-backdrop.py +323 -0
  100. package/modules/dev-box/app/scripts/gen-icons.js +286 -0
  101. package/modules/dev-box/app/scripts/vendor-client.js +23 -0
  102. package/modules/dev-box/app/src/box-controller.js +287 -0
  103. package/modules/dev-box/app/src/brand.generated.json +13 -0
  104. package/modules/dev-box/app/src/brand.js +16 -0
  105. package/modules/dev-box/app/src/config.js +19 -0
  106. package/modules/dev-box/app/src/gds-client.js +90 -0
  107. package/modules/dev-box/app/src/main.js +610 -0
  108. package/modules/dev-box/app/src/pairing.js +57 -0
  109. package/modules/dev-box/app/src/preload.js +29 -0
  110. package/modules/dev-box/app/src/session-store.js +58 -0
  111. package/modules/dev-box/app/src/ssh-setup.js +569 -0
  112. package/modules/dev-box/app/src/task-picker.js +70 -0
  113. package/modules/dev-box/app/src/tray.js +99 -0
  114. package/modules/dev-box/app/src/updater.js +55 -0
  115. package/modules/dev-box/app/src/vendor/bongos-client.cjs +698 -0
  116. package/modules/dev-box/app/test/unit.mjs +526 -0
  117. package/modules/dev-box/box-access.js +121 -4
  118. package/modules/dev-box/boxes.js +20 -0
  119. package/modules/dev-box/module.json +1 -1
  120. package/modules/dev-box/routes/box.js +87 -3
  121. package/modules/economy/credits.js +116 -25
  122. package/modules/economy/reward.js +8 -0
  123. package/modules/economy/streak.js +2 -1
  124. package/modules/governance/CLAUDE.md +15 -0
  125. package/modules/governance/catalog.js +419 -0
  126. package/modules/governance/config.js +174 -0
  127. package/modules/governance/db.js +125 -0
  128. package/modules/governance/migrations/governance_001_tables.sql +81 -0
  129. package/modules/governance/migrations/governance_002_seed_and_backfill.sql +103 -0
  130. package/modules/governance/migrations/governance_003_task_abandon_metic.sql +28 -0
  131. package/modules/governance/migrations/governance_004_criterion_create.sql +39 -0
  132. package/modules/governance/migrations/governance_005_resync_builder_rank_roles.sql +56 -0
  133. package/modules/governance/module.json +10 -0
  134. package/modules/governance/protected-surfaces.js +88 -0
  135. package/modules/governance/protected-surfaces.json +80 -0
  136. package/modules/governance/rank-roles.js +83 -0
  137. package/modules/governance/resolver.js +221 -0
  138. package/modules/governance/routes/governance.js +89 -0
  139. package/modules/governance/routes/role-sync.js +49 -0
  140. package/modules/governance/session-scopes.js +127 -0
  141. package/modules/governance/session-scopes.json +38 -0
  142. package/modules/hall-ui/public/atlas.css +117 -0
  143. package/modules/hall-ui/public/atlas.html +3 -114
  144. package/modules/hall-ui/public/brand-apply.js +34 -6
  145. package/modules/hall-ui/public/builders.js +187 -219
  146. package/modules/hall-ui/public/diagrams.html +2 -0
  147. package/modules/hall-ui/public/dom-utils.js +27 -0
  148. package/modules/hall-ui/public/drachmae.html +2 -0
  149. package/modules/hall-ui/public/drachmae.js +54 -1
  150. package/modules/hall-ui/public/gate.css +98 -0
  151. package/modules/hall-ui/public/gate.html +3 -95
  152. package/modules/hall-ui/public/goal-inbox.js +4 -1
  153. package/modules/hall-ui/public/goals-page.js +626 -114
  154. package/modules/hall-ui/public/goals.css +79 -1
  155. package/modules/hall-ui/public/goals.html +38 -11
  156. package/modules/hall-ui/public/hall-widgets.js +62 -52
  157. package/modules/hall-ui/public/harbor.css +123 -0
  158. package/modules/hall-ui/public/harbor.html +3 -120
  159. package/modules/hall-ui/public/index.html +11 -4
  160. package/modules/hall-ui/public/instances-panel.js +4 -1
  161. package/modules/hall-ui/public/modules.css +63 -0
  162. package/modules/hall-ui/public/modules.html +3 -60
  163. package/modules/hall-ui/public/new-project-wizard.js +7 -3
  164. package/modules/hall-ui/public/not-ready.html +2 -0
  165. package/modules/hall-ui/public/pair.css +73 -0
  166. package/modules/hall-ui/public/pair.html +3 -70
  167. package/modules/hall-ui/public/palette.js +302 -0
  168. package/modules/hall-ui/public/primer.css +13 -0
  169. package/modules/hall-ui/public/primer.html +2 -0
  170. package/modules/hall-ui/public/profile.html +2 -0
  171. package/modules/hall-ui/public/ranks.html +2 -0
  172. package/modules/hall-ui/public/roadmap.css +179 -0
  173. package/modules/hall-ui/public/roadmap.html +9 -172
  174. package/modules/hall-ui/public/roadmap.js +329 -316
  175. package/modules/hall-ui/public/sessions.css +16 -0
  176. package/modules/hall-ui/public/sessions.html +3 -13
  177. package/modules/hall-ui/public/settings.html +2 -0
  178. package/modules/hall-ui/public/settings.js +4 -4
  179. package/modules/hall-ui/public/shell.js +143 -18
  180. package/modules/hall-ui/public/style.css +231 -39
  181. package/modules/hall-ui/public/task-detail.js +347 -26
  182. package/modules/hall-ui/public/task.html +6 -1
  183. package/modules/hall-ui/public/watch.html +2 -0
  184. package/modules/hall-ui/public/work.html +8 -6
  185. package/modules/hall-ui/public/work.js +1 -1
  186. package/modules/ideas/inbox.js +61 -11
  187. package/modules/ideas/routes/inbox.js +23 -0
  188. package/modules/lifecycle/claim-eligibility.js +72 -0
  189. package/modules/lifecycle/db.js +519 -139
  190. package/modules/lifecycle/done-when.js +18 -3
  191. package/modules/lifecycle/github-push.js +19 -2
  192. package/modules/lifecycle/goal-advisory.js +114 -0
  193. package/modules/lifecycle/goal-authz.js +62 -0
  194. package/modules/lifecycle/lifecycle.js +9 -0
  195. package/modules/lifecycle/publish-reconciler.js +109 -6
  196. package/modules/lifecycle/routes/claims.js +68 -23
  197. package/modules/lifecycle/routes/done-when.js +110 -15
  198. package/modules/lifecycle/routes/goals.js +8 -38
  199. package/modules/lifecycle/routes/tasks.js +38 -6
  200. package/modules/lifecycle/ship-card.js +6 -0
  201. package/modules/onboarding/onboarding-state.js +1 -1
  202. package/modules/platform-identity/CLAUDE.md +15 -0
  203. package/modules/platform-identity/hub-device.js +147 -0
  204. package/modules/platform-identity/hub-keys.js +151 -0
  205. package/modules/platform-identity/migrations/platform_identity_001_tables.sql +114 -0
  206. package/modules/platform-identity/migrations/platform_identity_002_client_origin_index.sql +18 -0
  207. package/modules/platform-identity/migrations/platform_identity_003_project_memberships.sql +42 -0
  208. package/modules/platform-identity/migrations/platform_identity_004_projects.sql +44 -0
  209. package/modules/platform-identity/migrations/platform_identity_005_builder_activity.sql +42 -0
  210. package/modules/platform-identity/module.json +18 -0
  211. package/modules/platform-identity/platform-identity.js +531 -0
  212. package/modules/platform-identity/pollers/code-sweep.js +43 -0
  213. package/modules/platform-identity/routes/my-projects.js +140 -0
  214. package/modules/platform-identity/routes/projects.js +107 -0
  215. package/modules/platform-identity/routes/scouting.js +35 -0
  216. package/modules/platform-identity/routes/sso.js +402 -0
  217. package/modules/platform-identity/tests/platform-identity.mjs +388 -0
  218. package/modules/platform-identity/ui/.gitkeep +0 -0
  219. package/modules/security/routes/reports.js +10 -0
  220. package/modules/sessions/db.js +166 -21
  221. package/modules/sessions/module.json +1 -1
  222. package/modules/sessions/pollers/session-reward-reconcile.js +78 -0
  223. package/modules/sessions/routes/sessions.js +33 -0
  224. package/package-lock.json +2 -2
  225. package/package.json +1 -1
  226. package/public-landing/assets/anim/idle/frame_00.webp +0 -0
  227. package/public-landing/assets/anim/idle/frame_01.webp +0 -0
  228. package/public-landing/assets/anim/idle/frame_02.webp +0 -0
  229. package/public-landing/assets/anim/idle/frame_03.webp +0 -0
  230. package/public-landing/assets/anim/idle/frame_04.webp +0 -0
  231. package/public-landing/assets/anim/idle/frame_05.webp +0 -0
  232. package/public-landing/assets/anim/idle/frame_06.webp +0 -0
  233. package/public-landing/assets/anim/idle/frame_07.webp +0 -0
  234. package/public-landing/assets/anim/idle/frame_08.webp +0 -0
  235. package/public-landing/assets/anim/idle/frame_09.webp +0 -0
  236. package/public-landing/assets/anim/idle/frame_10.webp +0 -0
  237. package/public-landing/assets/anim/idle/frame_11.webp +0 -0
  238. package/public-landing/assets/anim/idle/frame_12.webp +0 -0
  239. package/public-landing/assets/anim/idle/frame_13.webp +0 -0
  240. package/public-landing/assets/anim/idle/frame_14.webp +0 -0
  241. package/public-landing/assets/anim/idle/frame_15.webp +0 -0
  242. package/public-landing/assets/anim/idle/frame_16.webp +0 -0
  243. package/public-landing/assets/anim/idle/frame_17.webp +0 -0
  244. package/public-landing/assets/anim/idle/frame_18.webp +0 -0
  245. package/public-landing/assets/anim/idle/frame_19.webp +0 -0
  246. package/public-landing/assets/anim/idle/frame_20.webp +0 -0
  247. package/public-landing/assets/anim/idle/frame_21.webp +0 -0
  248. package/public-landing/assets/anim/idle/frame_22.webp +0 -0
  249. package/public-landing/assets/anim/idle/frame_23.webp +0 -0
  250. package/public-landing/assets/anim/idle/frame_24.webp +0 -0
  251. package/public-landing/assets/anim/idle/frame_25.webp +0 -0
  252. package/public-landing/assets/anim/idle/frame_26.webp +0 -0
  253. package/public-landing/assets/anim/idle/frame_27.webp +0 -0
  254. package/public-landing/assets/anim/idle/frame_28.webp +0 -0
  255. package/public-landing/assets/anim/idle/frame_29.webp +0 -0
  256. package/public-landing/assets/anim/idle/frame_30.webp +0 -0
  257. package/public-landing/assets/anim/idle/frame_31.webp +0 -0
  258. package/public-landing/assets/anim/idle/frame_32.webp +0 -0
  259. package/public-landing/assets/anim/idle/frame_33.webp +0 -0
  260. package/public-landing/assets/anim/idle/frame_34.webp +0 -0
  261. package/public-landing/assets/anim/idle/frame_35.webp +0 -0
  262. package/public-landing/assets/anim/idle/frame_36.webp +0 -0
  263. package/public-landing/assets/anim/idle/frame_37.webp +0 -0
  264. package/public-landing/assets/anim/idle/frame_38.webp +0 -0
  265. package/public-landing/assets/anim/idle/frame_39.webp +0 -0
  266. package/public-landing/assets/anim/idle/frame_40.webp +0 -0
  267. package/public-landing/assets/anim/idle/frame_41.webp +0 -0
  268. package/public-landing/assets/anim/idle/frame_42.webp +0 -0
  269. package/public-landing/assets/anim/idle/frame_43.webp +0 -0
  270. package/public-landing/create.html +51 -58
  271. package/public-landing/gate/README.md +137 -0
  272. package/public-landing/gate/dispmaps/bar.png +0 -0
  273. package/public-landing/gate/dispmaps/flat.png +0 -0
  274. package/public-landing/gate/dispmaps/key.png +0 -0
  275. package/public-landing/gate/index.html +587 -0
  276. package/public-landing/gate/previews/cloud-bongos.jpg +0 -0
  277. package/public-landing/gate/previews/off-the-boats.jpg +0 -0
  278. package/public-landing/gate/space.css +799 -0
  279. package/public-landing/gate/space.js +1826 -0
  280. package/public-landing/gate/sprites/enter.png +0 -0
  281. package/public-landing/gate/sprites/search.png +0 -0
  282. package/public-landing/gate/sprites/terminal-blank.png +0 -0
  283. package/public-landing/gate/sprites/tile.png +0 -0
  284. package/public-landing/world/assets/clouds/cloud-island-large.png +0 -0
  285. package/public-landing/world/assets/clouds/cloud-puff.png +0 -0
  286. package/public-landing/world/assets/creatures/creature-whale-cargo.png +0 -0
  287. package/public-landing/world/assets/creatures/creature-whale-glide.png +0 -0
  288. package/public-landing/world/assets/plates/plate-clouds-near.png +0 -0
  289. package/public-landing/world/assets/plates/scene-establishing.png +0 -0
  290. package/scripts/gds/abandon.js +6 -4
  291. package/scripts/gds/api.js +10 -5
  292. package/scripts/gds/api.ps1 +26 -0
  293. package/scripts/gds/api.sh +6 -0
  294. package/scripts/gds/audit-ships.js +7 -1
  295. package/scripts/gds/backfill-sessions.js +78 -18
  296. package/scripts/gds/backup.js +23 -1
  297. package/scripts/gds/box-connect-lib.js +124 -31
  298. package/scripts/gds/box-sync.js +66 -0
  299. package/scripts/gds/box.js +225 -53
  300. package/scripts/gds/cf-tunnel.js +145 -6
  301. package/scripts/gds/claim.js +34 -3
  302. package/scripts/gds/cli-lib.js +161 -27
  303. package/scripts/gds/code.js +6 -2
  304. package/scripts/gds/deploy-divergence.js +209 -0
  305. package/scripts/gds/dev-lib.js +309 -0
  306. package/scripts/gds/dev.js +322 -0
  307. package/scripts/gds/doctor.js +90 -61
  308. package/scripts/gds/fetch-art-key.js +1 -1
  309. package/scripts/gds/fetch-sound-prefs.js +2 -2
  310. package/scripts/gds/fitness.js +228 -12
  311. package/scripts/gds/gds-db-backup.service +16 -1
  312. package/scripts/gds/gds-db-offsite.service +9 -1
  313. package/scripts/gds/gen-api-client.js +1 -1
  314. package/scripts/gds/gen-api-docs.js +36 -14
  315. package/scripts/gds/gen-diagrams.js +45 -28
  316. package/scripts/gds/gen-file-map.js +2 -1
  317. package/scripts/gds/gen-freshness.js +32 -0
  318. package/scripts/gds/gen-repo-map.js +3 -2
  319. package/scripts/gds/gen-session-index.js +14 -5
  320. package/scripts/gds/hooks/pre-push.js +2 -2
  321. package/scripts/gds/init.js +60 -3
  322. package/scripts/gds/install-git-hooks.js +1 -1
  323. package/scripts/gds/key-card.js +15 -6
  324. package/scripts/gds/key-status.js +1 -1
  325. package/scripts/gds/linkify-refs.js +35 -9
  326. package/scripts/gds/login.js +16 -1
  327. package/scripts/gds/paste-token.js +7 -1
  328. package/scripts/gds/preflight.js +126 -0
  329. package/scripts/gds/provision.js +123 -12
  330. package/scripts/gds/publish-manifest.js +7 -1
  331. package/scripts/gds/reauth.js +7 -3
  332. package/scripts/gds/regen-instance-docs.js +47 -0
  333. package/scripts/gds/run-unit-tests.js +4 -2
  334. package/scripts/gds/seed-bongos-v1-seo-tasks.js +104 -0
  335. package/scripts/gds/seed-bv1-profiles-tasks.js +126 -0
  336. package/scripts/gds/sequence.js +425 -0
  337. package/scripts/gds/session-cost.js +10 -1
  338. package/scripts/gds/setup.js +31 -5
  339. package/scripts/gds/shell.js +5 -3
  340. package/scripts/gds/ship.js +319 -29
  341. package/scripts/gds/smoke-gds.js +139 -8
  342. package/scripts/gds/start.js +171 -22
  343. package/scripts/gds/status.js +1 -1
  344. package/scripts/gds/triage.js +10 -9
  345. package/scripts/gds/upgrade.js +124 -2
  346. package/scripts/status-mirror-sync.js +114 -84
  347. package/src/bongos/api-errors.js +1 -0
  348. package/src/bongos/auth.js +447 -102
  349. package/src/bongos/db-kernel.js +27 -0
  350. package/src/bongos/db.js +39 -0
  351. package/src/bongos/module-scope-map.js +27 -1
  352. package/src/bongos/permission-path-check.js +136 -102
  353. package/src/bongos/repo-info.js +47 -11
  354. package/src/bongos/route-rank-check.js +429 -46
  355. package/src/bongos/routes/_helpers.js +12 -1
  356. package/src/bongos/routes/auth.js +219 -2
  357. package/src/bongos/routes/backup.js +58 -2
  358. package/src/bongos/routes/me.js +35 -1
  359. package/src/bongos/serve-internal.js +84 -15
  360. package/src/branding.js +32 -0
  361. package/src/instance-config.js +30 -0
  362. package/src/module-api.js +112 -1
  363. package/src/platform-server.js +86 -9
  364. package/tests/abandon_task.mjs +59 -3
  365. package/tests/api_cli_flags.mjs +53 -0
  366. package/tests/auth_page_gate.mjs +13 -0
  367. package/tests/backfill_sessions.mjs +127 -1
  368. package/tests/backup_cli.mjs +54 -0
  369. package/tests/bongos_box_connect.mjs +77 -0
  370. package/tests/box_access.mjs +130 -1
  371. package/tests/box_credential.mjs +125 -0
  372. package/tests/box_host_keys.mjs +24 -0
  373. package/tests/box_infra_resolve.mjs +149 -0
  374. package/tests/box_scope_session.mjs +6 -2
  375. package/tests/box_sync.mjs +55 -0
  376. package/tests/box_task_scope.mjs +99 -0
  377. package/tests/branding.mjs +12 -0
  378. package/tests/cf_ruleset_preflight.mjs +142 -0
  379. package/tests/cf_tunnel.mjs +37 -0
  380. package/tests/claim_gate_rebase.mjs +98 -0
  381. package/tests/clawback_confirmed_backlog.mjs +103 -0
  382. package/tests/cli_lib_formatters.mjs +20 -0
  383. package/tests/confirm_attribution.mjs +30 -46
  384. package/tests/credit_grant.mjs +198 -10
  385. package/tests/criterion_authoring_gate.mjs +272 -0
  386. package/tests/criterion_progress.mjs +33 -1
  387. package/tests/dev_lib.mjs +253 -0
  388. package/tests/devbox_artifact_gate.mjs +75 -0
  389. package/tests/devbox_dmg_backdrop.mjs +137 -0
  390. package/tests/devbox_icons.mjs +304 -0
  391. package/tests/devbox_installer_brand.mjs +232 -0
  392. package/tests/devbox_key_register.mjs +234 -0
  393. package/tests/docs_openapi_route.mjs +110 -0
  394. package/tests/doctor_hooks.mjs +141 -0
  395. package/tests/extract_json.mjs +140 -0
  396. package/tests/fitness.mjs +89 -0
  397. package/tests/gen_freshness.mjs +96 -0
  398. package/tests/goal_advisory.mjs +251 -0
  399. package/tests/goal_criterion_confirm_ui.mjs +269 -0
  400. package/tests/goal_routes.mjs +59 -4
  401. package/tests/goal_tier.mjs +12 -3
  402. package/tests/governance_catalog.mjs +129 -0
  403. package/tests/governance_claim_eligibility.mjs +262 -0
  404. package/tests/governance_config.mjs +187 -0
  405. package/tests/governance_ownership_scope.mjs +410 -0
  406. package/tests/governance_page_gates.mjs +324 -0
  407. package/tests/governance_parity.mjs +336 -0
  408. package/tests/governance_principals.mjs +232 -0
  409. package/tests/governance_protected_surfaces.mjs +208 -0
  410. package/tests/governance_require_permission.mjs +223 -0
  411. package/tests/governance_resolver.mjs +84 -0
  412. package/tests/governance_role_sync.mjs +231 -0
  413. package/tests/governance_seed.mjs +127 -0
  414. package/tests/governance_session_scope.mjs +434 -0
  415. package/tests/governance_vanilla_boot.mjs +203 -0
  416. package/tests/grade_attribution.mjs +7 -7
  417. package/tests/hall_audit.mjs +223 -0
  418. package/tests/hall_nav.mjs +191 -0
  419. package/tests/hall_palette.mjs +206 -0
  420. package/tests/hall_signout.mjs +124 -0
  421. package/tests/hook_user_agents.mjs +10 -0
  422. package/tests/idea_triage.mjs +162 -0
  423. package/tests/idp_device_exchange.mjs +93 -0
  424. package/tests/init.mjs +51 -0
  425. package/tests/instance_config.mjs +65 -0
  426. package/tests/instance_mismatch_guard.mjs +23 -6
  427. package/tests/instance_release_config.mjs +104 -0
  428. package/tests/linkify_refs.mjs +15 -2
  429. package/tests/module_contributions.mjs +55 -0
  430. package/tests/module_loader.mjs +10 -5
  431. package/tests/module_scope_active_claims.mjs +94 -0
  432. package/tests/needs_rebase.mjs +92 -0
  433. package/tests/one_active_claim_per_session.mjs +76 -0
  434. package/tests/override_attribution.mjs +10 -8
  435. package/tests/override_request_ownership.mjs +8 -4
  436. package/tests/parse_cookie_decode.mjs +42 -0
  437. package/tests/pay_on_land.mjs +129 -0
  438. package/tests/platform_boot.mjs +100 -1
  439. package/tests/post_login_landing.mjs +42 -0
  440. package/tests/preflight_checks.mjs +72 -0
  441. package/tests/provision.mjs +132 -7
  442. package/tests/publish_branch_route.mjs +53 -0
  443. package/tests/publish_reconciler.mjs +187 -2
  444. package/tests/repo_info_binding.mjs +248 -0
  445. package/tests/reward_gate.mjs +11 -2
  446. package/tests/reward_mode_cost_plus_only.mjs +116 -0
  447. package/tests/reward_mode_surfacing.mjs +168 -0
  448. package/tests/route_permission_check.mjs +301 -0
  449. package/tests/route_rank_check.mjs +254 -12
  450. package/tests/route_validation.mjs +30 -0
  451. package/tests/sequence.mjs +267 -0
  452. package/tests/session_digest.mjs +44 -0
  453. package/tests/session_index.mjs +18 -6
  454. package/tests/session_records.mjs +39 -1
  455. package/tests/session_reward_on_land.mjs +381 -0
  456. package/tests/session_reward_reconcile.mjs +229 -0
  457. package/tests/ship_api_client_pathspec.mjs +100 -0
  458. package/tests/ship_base_flag.mjs +93 -0
  459. package/tests/ship_ci_deploy.mjs +80 -3
  460. package/tests/ship_upstream_deletion.mjs +57 -0
  461. package/tests/smoke_target.mjs +233 -0
  462. package/tests/start_env_guard.mjs +87 -0
  463. package/tests/start_rebase_warning.mjs +103 -0
  464. package/tests/status_mirror_sync.mjs +122 -0
  465. package/tests/stop_refcheck.mjs +19 -1
  466. package/tests/task_goal_link.mjs +15 -6
  467. package/tests/upgrade.mjs +139 -0
  468. package/tests/web_admission_status.mjs +162 -0
  469. package/tests/write_validation_gaps.mjs +110 -0
@@ -0,0 +1,117 @@
1
+ /* atlas.css — Page-local styles for the Repo Atlas page.
2
+ Lifted verbatim out of the page's inline <style> block (task 1002176);
3
+ the ?v= cache-bust is stamped automatically from this file's content hash
4
+ at boot (src/asset-version.js). */
5
+
6
+ /* Repo Atlas — restyled onto the hall design system (task 1737, amending
7
+ ADR 0094's styling clause). The CHROME (card, toolbar, caption, legend,
8
+ popup, badges) rides the hall tokens, so it follows the instance pack and
9
+ dark mode like every other page. The SEMANTIC node/edge palette below
10
+ stays instance-independent — the 0094 invariant: a pack's colors must
11
+ never scramble the map's color-coded meaning. Non-semantic map values
12
+ (label ink/halo, ambient wash, hub glow, badge fills) are scoped vars the
13
+ renderer reads at draw time, with dark variants, so the scene adapts to
14
+ the theme without the pack touching the encoding. */
15
+ .atlas-page{
16
+ /* semantic map palette — FIXED (never pack-driven), tuned for both themes */
17
+ --ab-sun:#6366f1; --ab-sky:#0ea5e9; --ab-coral:#f43f5e; --ab-paper:#b3a284;
18
+ --ab-good:#10b981; --ab-core:#f59e0b; --ab-db:#ef4444; --ab-ghost:#94a3b8; --ab-danger:#dc2626;
19
+ /* theme-dependent, non-semantic scene values (read by atlas.js) */
20
+ --ab-label-ink: var(--ink);
21
+ --ab-label-halo: var(--surface);
22
+ --ab-ambient: rgba(255,255,255,.5);
23
+ --ab-glow: #c7cdf7;
24
+ --ab-b-good-bg:#dcfce7; --ab-b-good-fg:#166534;
25
+ --ab-b-warn-bg:#fef3c7; --ab-b-warn-fg:#92400e;
26
+ --ab-b-danger-bg:#fee2e2; --ab-b-danger-fg:#991b1b;
27
+ --ab-b-info-bg:#e0f2fe; --ab-b-info-fg:#075985;
28
+ color:var(--ink);
29
+ border:1px solid var(--border); border-radius:var(--radius);
30
+ background:
31
+ radial-gradient(ellipse 70% 55% at 50% 46%, color-mix(in srgb, var(--accent) 4%, transparent), transparent 70%),
32
+ var(--surface);
33
+ }
34
+ html[data-theme="dark"] .atlas-page{
35
+ --ab-ambient: rgba(255,255,255,.03);
36
+ --ab-glow: #3b418c;
37
+ --ab-b-good-bg:#123227; --ab-b-good-fg:#5eead4;
38
+ --ab-b-warn-bg:#33260d; --ab-b-warn-fg:#fcd34d;
39
+ --ab-b-danger-bg:#371616; --ab-b-danger-fg:#fca5a5;
40
+ --ab-b-info-bg:#0f2740; --ab-b-info-fg:#7dd3fc;
41
+ }
42
+ @media (prefers-color-scheme: dark){
43
+ html:not([data-theme]) .atlas-page{
44
+ --ab-ambient: rgba(255,255,255,.03);
45
+ --ab-glow: #3b418c;
46
+ --ab-b-good-bg:#123227; --ab-b-good-fg:#5eead4;
47
+ --ab-b-warn-bg:#33260d; --ab-b-warn-fg:#fcd34d;
48
+ --ab-b-danger-bg:#371616; --ab-b-danger-fg:#fca5a5;
49
+ --ab-b-info-bg:#0f2740; --ab-b-info-fg:#7dd3fc;
50
+ }
51
+ }
52
+ .atlas-page *{box-sizing:border-box}
53
+ .atlas-page button{font:inherit}
54
+
55
+ .atlas-toolbar{display:flex; align-items:center; gap:12px 16px; flex-wrap:wrap; padding:16px 20px 0}
56
+ .ab-chip{font-weight:600; font-size:10.5px; text-transform:uppercase; letter-spacing:.1em;
57
+ color:var(--accent-text); background:var(--accent-weak); border:1px solid color-mix(in srgb, var(--accent) 30%, transparent); padding:3px 9px; border-radius:999px}
58
+ .ab-modes{display:inline-flex; gap:0; border:1px solid var(--border-strong); border-radius:var(--radius-sm); overflow:hidden}
59
+ .ab-modes button{font-family:var(--font-body); font-weight:500; font-size:12.5px; cursor:pointer; border:0;
60
+ background:var(--surface); color:var(--ink-soft); padding:6px 14px; transition:background .15s, color .15s}
61
+ .ab-modes button + button{border-left:1px solid var(--border-strong)}
62
+ .ab-modes button.active{background:var(--accent-weak); color:var(--accent-text)}
63
+ .ab-modes button:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
64
+
65
+ .ab-caption{padding:13px 20px 0; margin:0; font-size:13px; line-height:1.5; color:var(--ink-soft); max-width:90ch}
66
+ .ab-caption .sub{display:block; margin-top:3px; font-size:11.5px; color:var(--ink-faint)}
67
+
68
+ .ab-scene{position:relative; width:100%; min-height:500px; padding:6px 0}
69
+ .ab-scene svg{display:block; width:100%; height:auto}
70
+ .ab-hint{position:absolute; left:20px; bottom:12px; font-size:11.5px; color:var(--ink-soft);
71
+ background:color-mix(in srgb, var(--surface) 75%, transparent); backdrop-filter:blur(4px); padding:5px 11px; border-radius:999px; border:1px solid var(--border)}
72
+ .ab-empty{position:absolute; inset:0; display:none; align-items:center; justify-content:center; text-align:center; padding:40px}
73
+ .ab-empty.show{display:flex}
74
+ .ab-empty .card{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:26px 30px; max-width:460px;
75
+ box-shadow:var(--shadow-pop)}
76
+ .ab-empty h2{margin:0 0 8px; font-size:16px; font-weight:650}
77
+ .ab-empty p{margin:0; font-size:13.5px; line-height:1.55; color:var(--ink-soft)}
78
+
79
+ .ab-legend{display:flex; flex-wrap:wrap; gap:8px 18px; padding:12px 20px 6px; font-size:11.5px; color:var(--ink-soft)}
80
+ .ab-legend .lg{display:flex; align-items:center; gap:7px}
81
+ .ab-legend .sw{width:13px; height:13px; border-radius:4px}
82
+ .ab-legend .ln{width:18px; border-top:3px solid}
83
+ .ab-foot{padding:10px 20px 20px; font-size:11px; color:var(--ink-faint); font-variant-numeric:tabular-nums}
84
+
85
+ .ab-popup{position:absolute; z-index:6; width:300px; max-width:88%; background:var(--surface);
86
+ border:1px solid var(--border); border-radius:var(--radius); padding:15px 16px; display:none;
87
+ box-shadow:var(--shadow-pop)}
88
+ .ab-popup.show{display:block}
89
+ .ab-popup-close{position:absolute; top:8px; right:11px; cursor:pointer; border:0; background:transparent;
90
+ font-size:20px; line-height:1; color:var(--ink-faint)}
91
+ .ab-popup-close:hover{color:var(--ink)}
92
+ .ab-ptitle{font-weight:650; font-size:15px; display:flex; align-items:center;
93
+ gap:8px; flex-wrap:wrap; line-height:1.25; padding-right:18px}
94
+ .ab-ppath{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace; font-size:11.5px; color:var(--ink-soft); margin-top:4px; word-break:break-all}
95
+ .ab-pdesc{font-size:12.8px; line-height:1.55; margin:11px 0 0; color:var(--ink-soft)}
96
+ .ab-prow{margin-top:11px; font-size:10.5px; font-weight:600; color:var(--ink-faint); text-transform:uppercase; letter-spacing:.06em}
97
+ .ab-chips{display:flex; flex-wrap:wrap; gap:6px; margin-top:6px}
98
+ .ab-chip2{font-size:11px; font-weight:500; background:var(--surface-2); border:1px solid var(--border);
99
+ padding:4px 9px; border-radius:999px; font-variant-numeric:tabular-nums}
100
+ .ab-badge{font-weight:600; font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; padding:3px 8px; border-radius:999px}
101
+ .ab-b-good{background:var(--ab-b-good-bg); color:var(--ab-b-good-fg)} .ab-b-warn{background:var(--ab-b-warn-bg); color:var(--ab-b-warn-fg)}
102
+ .ab-b-danger{background:var(--ab-b-danger-bg); color:var(--ab-b-danger-fg)} .ab-b-info{background:var(--ab-b-info-bg); color:var(--ab-b-info-fg)}
103
+
104
+ .ab-node{cursor:pointer; transition:opacity .18s}
105
+ .ab-node text{font-family:var(--font-body); paint-order:stroke; stroke:var(--ab-label-halo); stroke-width:3px; stroke-linejoin:round; fill:var(--ab-label-ink)}
106
+ .ab-node text.ab-sub{fill:var(--ink-faint)}
107
+ .ab-node text.ab-badge-text{stroke:none; paint-order:normal}
108
+ svg.focus .ab-node{opacity:.18}
109
+ svg.focus .ab-node.lit{opacity:1}
110
+ .ab-edge{fill:none; opacity:.18; transition:opacity .18s}
111
+ svg.focus .ab-edge{opacity:.04}
112
+ svg.focus .ab-edge.lit{opacity:1}
113
+ .ab-edge.lit{filter:url(#abglow)}
114
+ .ab-sun-glow{animation:abbreathe 5.5s ease-in-out infinite}
115
+ @keyframes abbreathe{0%,100%{opacity:.4}50%{opacity:.8}}
116
+ @media (prefers-reduced-motion: reduce){ .atlas-page *{transition:none!important; animation:none!important} }
117
+ @media (max-width:560px){ .ab-modes{width:100%; display:flex} .ab-modes button{flex:1} }
@@ -10,120 +10,7 @@
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
11
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
12
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
- <style>
14
- /* Repo Atlas — restyled onto the hall design system (task 1737, amending
15
- ADR 0094's styling clause). The CHROME (card, toolbar, caption, legend,
16
- popup, badges) rides the hall tokens, so it follows the instance pack and
17
- dark mode like every other page. The SEMANTIC node/edge palette below
18
- stays instance-independent — the 0094 invariant: a pack's colors must
19
- never scramble the map's color-coded meaning. Non-semantic map values
20
- (label ink/halo, ambient wash, hub glow, badge fills) are scoped vars the
21
- renderer reads at draw time, with dark variants, so the scene adapts to
22
- the theme without the pack touching the encoding. */
23
- .atlas-page{
24
- /* semantic map palette — FIXED (never pack-driven), tuned for both themes */
25
- --ab-sun:#6366f1; --ab-sky:#0ea5e9; --ab-coral:#f43f5e; --ab-paper:#b3a284;
26
- --ab-good:#10b981; --ab-core:#f59e0b; --ab-db:#ef4444; --ab-ghost:#94a3b8; --ab-danger:#dc2626;
27
- /* theme-dependent, non-semantic scene values (read by atlas.js) */
28
- --ab-label-ink: var(--ink);
29
- --ab-label-halo: var(--surface);
30
- --ab-ambient: rgba(255,255,255,.5);
31
- --ab-glow: #c7cdf7;
32
- --ab-b-good-bg:#dcfce7; --ab-b-good-fg:#166534;
33
- --ab-b-warn-bg:#fef3c7; --ab-b-warn-fg:#92400e;
34
- --ab-b-danger-bg:#fee2e2; --ab-b-danger-fg:#991b1b;
35
- --ab-b-info-bg:#e0f2fe; --ab-b-info-fg:#075985;
36
- color:var(--ink);
37
- border:1px solid var(--border); border-radius:var(--radius);
38
- background:
39
- radial-gradient(ellipse 70% 55% at 50% 46%, color-mix(in srgb, var(--accent) 4%, transparent), transparent 70%),
40
- var(--surface);
41
- }
42
- html[data-theme="dark"] .atlas-page{
43
- --ab-ambient: rgba(255,255,255,.03);
44
- --ab-glow: #3b418c;
45
- --ab-b-good-bg:#123227; --ab-b-good-fg:#5eead4;
46
- --ab-b-warn-bg:#33260d; --ab-b-warn-fg:#fcd34d;
47
- --ab-b-danger-bg:#371616; --ab-b-danger-fg:#fca5a5;
48
- --ab-b-info-bg:#0f2740; --ab-b-info-fg:#7dd3fc;
49
- }
50
- @media (prefers-color-scheme: dark){
51
- html:not([data-theme]) .atlas-page{
52
- --ab-ambient: rgba(255,255,255,.03);
53
- --ab-glow: #3b418c;
54
- --ab-b-good-bg:#123227; --ab-b-good-fg:#5eead4;
55
- --ab-b-warn-bg:#33260d; --ab-b-warn-fg:#fcd34d;
56
- --ab-b-danger-bg:#371616; --ab-b-danger-fg:#fca5a5;
57
- --ab-b-info-bg:#0f2740; --ab-b-info-fg:#7dd3fc;
58
- }
59
- }
60
- .atlas-page *{box-sizing:border-box}
61
- .atlas-page button{font:inherit}
62
-
63
- .atlas-toolbar{display:flex; align-items:center; gap:12px 16px; flex-wrap:wrap; padding:16px 20px 0}
64
- .ab-chip{font-weight:600; font-size:10.5px; text-transform:uppercase; letter-spacing:.1em;
65
- color:var(--accent-text); background:var(--accent-weak); border:1px solid color-mix(in srgb, var(--accent) 30%, transparent); padding:3px 9px; border-radius:999px}
66
- .ab-modes{display:inline-flex; gap:0; border:1px solid var(--border-strong); border-radius:var(--radius-sm); overflow:hidden}
67
- .ab-modes button{font-family:var(--font-body); font-weight:500; font-size:12.5px; cursor:pointer; border:0;
68
- background:var(--surface); color:var(--ink-soft); padding:6px 14px; transition:background .15s, color .15s}
69
- .ab-modes button + button{border-left:1px solid var(--border-strong)}
70
- .ab-modes button.active{background:var(--accent-weak); color:var(--accent-text)}
71
- .ab-modes button:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
72
-
73
- .ab-caption{padding:13px 20px 0; margin:0; font-size:13px; line-height:1.5; color:var(--ink-soft); max-width:90ch}
74
- .ab-caption .sub{display:block; margin-top:3px; font-size:11.5px; color:var(--ink-faint)}
75
-
76
- .ab-scene{position:relative; width:100%; min-height:500px; padding:6px 0}
77
- .ab-scene svg{display:block; width:100%; height:auto}
78
- .ab-hint{position:absolute; left:20px; bottom:12px; font-size:11.5px; color:var(--ink-soft);
79
- background:color-mix(in srgb, var(--surface) 75%, transparent); backdrop-filter:blur(4px); padding:5px 11px; border-radius:999px; border:1px solid var(--border)}
80
- .ab-empty{position:absolute; inset:0; display:none; align-items:center; justify-content:center; text-align:center; padding:40px}
81
- .ab-empty.show{display:flex}
82
- .ab-empty .card{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:26px 30px; max-width:460px;
83
- box-shadow:var(--shadow-pop)}
84
- .ab-empty h2{margin:0 0 8px; font-size:16px; font-weight:650}
85
- .ab-empty p{margin:0; font-size:13.5px; line-height:1.55; color:var(--ink-soft)}
86
-
87
- .ab-legend{display:flex; flex-wrap:wrap; gap:8px 18px; padding:12px 20px 6px; font-size:11.5px; color:var(--ink-soft)}
88
- .ab-legend .lg{display:flex; align-items:center; gap:7px}
89
- .ab-legend .sw{width:13px; height:13px; border-radius:4px}
90
- .ab-legend .ln{width:18px; border-top:3px solid}
91
- .ab-foot{padding:10px 20px 20px; font-size:11px; color:var(--ink-faint); font-variant-numeric:tabular-nums}
92
-
93
- .ab-popup{position:absolute; z-index:6; width:300px; max-width:88%; background:var(--surface);
94
- border:1px solid var(--border); border-radius:var(--radius); padding:15px 16px; display:none;
95
- box-shadow:var(--shadow-pop)}
96
- .ab-popup.show{display:block}
97
- .ab-popup-close{position:absolute; top:8px; right:11px; cursor:pointer; border:0; background:transparent;
98
- font-size:20px; line-height:1; color:var(--ink-faint)}
99
- .ab-popup-close:hover{color:var(--ink)}
100
- .ab-ptitle{font-weight:650; font-size:15px; display:flex; align-items:center;
101
- gap:8px; flex-wrap:wrap; line-height:1.25; padding-right:18px}
102
- .ab-ppath{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace; font-size:11.5px; color:var(--ink-soft); margin-top:4px; word-break:break-all}
103
- .ab-pdesc{font-size:12.8px; line-height:1.55; margin:11px 0 0; color:var(--ink-soft)}
104
- .ab-prow{margin-top:11px; font-size:10.5px; font-weight:600; color:var(--ink-faint); text-transform:uppercase; letter-spacing:.06em}
105
- .ab-chips{display:flex; flex-wrap:wrap; gap:6px; margin-top:6px}
106
- .ab-chip2{font-size:11px; font-weight:500; background:var(--surface-2); border:1px solid var(--border);
107
- padding:4px 9px; border-radius:999px; font-variant-numeric:tabular-nums}
108
- .ab-badge{font-weight:600; font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; padding:3px 8px; border-radius:999px}
109
- .ab-b-good{background:var(--ab-b-good-bg); color:var(--ab-b-good-fg)} .ab-b-warn{background:var(--ab-b-warn-bg); color:var(--ab-b-warn-fg)}
110
- .ab-b-danger{background:var(--ab-b-danger-bg); color:var(--ab-b-danger-fg)} .ab-b-info{background:var(--ab-b-info-bg); color:var(--ab-b-info-fg)}
111
-
112
- .ab-node{cursor:pointer; transition:opacity .18s}
113
- .ab-node text{font-family:var(--font-body); paint-order:stroke; stroke:var(--ab-label-halo); stroke-width:3px; stroke-linejoin:round; fill:var(--ab-label-ink)}
114
- .ab-node text.ab-sub{fill:var(--ink-faint)}
115
- .ab-node text.ab-badge-text{stroke:none; paint-order:normal}
116
- svg.focus .ab-node{opacity:.18}
117
- svg.focus .ab-node.lit{opacity:1}
118
- .ab-edge{fill:none; opacity:.18; transition:opacity .18s}
119
- svg.focus .ab-edge{opacity:.04}
120
- svg.focus .ab-edge.lit{opacity:1}
121
- .ab-edge.lit{filter:url(#abglow)}
122
- .ab-sun-glow{animation:abbreathe 5.5s ease-in-out infinite}
123
- @keyframes abbreathe{0%,100%{opacity:.4}50%{opacity:.8}}
124
- @media (prefers-reduced-motion: reduce){ .atlas-page *{transition:none!important; animation:none!important} }
125
- @media (max-width:560px){ .ab-modes{width:100%; display:flex} .ab-modes button{flex:1} }
126
- </style>
13
+ <link rel="stylesheet" href="/builders/atlas.css">
127
14
  </head>
128
15
  <body data-page="atlas" data-page-title="Repo Atlas">
129
16
 
@@ -175,6 +62,8 @@
175
62
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
176
63
 
177
64
  <script src="/builders/shell.js?v=2026-07-02-shell1"></script>
65
+ <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
66
+ <script src="/builders/palette.js" defer></script>
178
67
  <script src="/builders/atlas.js?v=2026-06-27-r1" defer></script>
179
68
  </body>
180
69
  </html>
@@ -73,13 +73,29 @@
73
73
  return opts && opts.caps ? capitalize(label) : label;
74
74
  }
75
75
 
76
+ // perTaskCredit() — does THIS instance actually pay the per-task estimate?
77
+ // Resolved server-side from economy's rewardPolicy and projected onto
78
+ // window.__BRANDING__.reward (ADR 0146); never re-derived here. Absent (an
79
+ // older server) ⇒ true, the paying default, so nothing changes for instances
80
+ // that predate the field.
81
+ function perTaskCredit() {
82
+ var r = brand && brand.reward;
83
+ return !r || r.perTaskCredit !== false;
84
+ }
85
+
76
86
  // task 1957 — a task's drachmae is an ESTIMATE (credits_reward, assigned at
77
- // creation) until the task SETTLES. Credits only land at 'confirmed' and
78
- // persist through 'shipped'; from that point the real payout is credits_awarded
79
- // (the ledger sum the task API surfaces). These helpers centralize the
80
- // "estimate vs actual" decision so every task surface renders it identically:
81
- // unsettled → the estimate with a "<Currency> Est." label; settled → the actual
82
- // ledger payout with a plain "<Currency>" label.
87
+ // creation) until the task SETTLES. Credits land at 'shipped' (ADR 0120 pays
88
+ // on land); from that point the real payout is credits_awarded (the ledger sum
89
+ // the task API surfaces). These helpers centralize the "estimate vs actual"
90
+ // decision so every task surface renders it identically: unsettled → the
91
+ // estimate with a "<Currency> Est." label; settled → the actual ledger payout
92
+ // with a plain "<Currency>" label.
93
+ //
94
+ // task 1002469 — on a cost-plus-only instance that second case is a LIE. The
95
+ // per-task estimate is never paid, so credits_awarded is 0 on every shipped
96
+ // task, taskCreditValue's zero-fallback hands back the estimate, and the plain
97
+ // label then presents that estimate as the actual payout. So the "Est."
98
+ // qualifier is never dropped when the instance doesn't pay per-task.
83
99
  function taskSettled(task) {
84
100
  var s = task && task.status;
85
101
  return s === 'confirmed' || s === 'shipped';
@@ -97,14 +113,26 @@
97
113
  }
98
114
  function taskCreditLabel(task, opts) {
99
115
  var base = currencyLabel(opts);
116
+ if (!perTaskCredit()) return base + ' Est.';
100
117
  return taskSettled(task) ? base : base + ' Est.';
101
118
  }
102
119
 
120
+ // The one-line explanation for a cost-plus-only instance, or '' on a paying
121
+ // one. Surfaces use it as a tooltip/footnote beside an estimate so the number
122
+ // is never read as a promise.
123
+ function rewardModeNote() {
124
+ if (perTaskCredit()) return '';
125
+ return 'This instance pays cost-plus only — the ' + currencyLabel()
126
+ + ' estimate is a guide, not a payout. Builders are paid real session cost + 20%.';
127
+ }
128
+
103
129
  window.OTBBranding = {
104
130
  currencyLabel: currencyLabel,
105
131
  taskSettled: taskSettled,
106
132
  taskCreditValue: taskCreditValue,
107
133
  taskCreditLabel: taskCreditLabel,
134
+ perTaskCredit: perTaskCredit,
135
+ rewardModeNote: rewardModeNote,
108
136
  applyCurrencyLabels: applyCurrencyLabels,
109
137
  };
110
138