@bongos/core 1.20.79 → 1.20.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 (53) hide show
  1. package/.bongos-core.json +104 -49
  2. package/clients/bongos-client/README.md +1 -1
  3. package/clients/bongos-client/bongos-client.global.js +8 -0
  4. package/clients/bongos-client/index.cjs +8 -0
  5. package/clients/bongos-client/index.d.ts +13 -0
  6. package/clients/bongos-client/index.mjs +8 -0
  7. package/docs/adr/0161-publish-on-merge.md +1 -1
  8. package/docs/adr/0361-merges-publish-as-candidates-release-decides-what-others-are-offered.md +59 -0
  9. package/docs/adr/README.md +1 -0
  10. package/docs/api/openapi.json +258 -4
  11. package/docs/api-reference.md +7 -3
  12. package/docs/copy-inventory.md +59 -53
  13. package/docs/copy-registry.json +120 -66
  14. package/docs/module-api-changelog.md +4 -0
  15. package/docs/page-inventory.json +2 -1
  16. package/docs/page-readings.json +86 -81
  17. package/docs/recipes/private-npm-distribution.md +2 -0
  18. package/docs/recipes/upgrading-the-core.md +1 -1
  19. package/modules/autonomy/cadence.js +3 -0
  20. package/modules/autonomy/db.js +136 -0
  21. package/modules/autonomy/fence.js +88 -3
  22. package/modules/autonomy/migrations/autonomy_005_builder_scope.sql +55 -0
  23. package/modules/autonomy/routes/autonomy.js +123 -3
  24. package/modules/government/catalog.js +9 -1
  25. package/modules/government/migrations/government_022_autonomy_run.sql +38 -0
  26. package/modules/hall-ui/public/gate.html +5 -2
  27. package/modules/hall-ui/public/gate.js +73 -4
  28. package/modules/hall-ui/public/settings-autobongos.js +156 -0
  29. package/modules/hall-ui/public/settings.html +19 -0
  30. package/modules/hall-ui/public/settings.js +1 -0
  31. package/modules/lifecycle/module.json +2 -1
  32. package/modules/lifecycle/routes/lifecycle.js +7 -0
  33. package/modules/lifecycle/workflow-dispatch.js +45 -0
  34. package/modules/npm-release/module.json +2 -1
  35. package/modules/npm-release/public/work.js +74 -0
  36. package/modules/npm-release/release.js +129 -0
  37. package/modules/npm-release/routes/release.js +65 -0
  38. package/modules/npm-release/work.js +16 -0
  39. package/package-lock.json +2 -2
  40. package/package.json +1 -1
  41. package/release-notes.json +16 -0
  42. package/scripts/gds/provision-core-upgrade.js +30 -2
  43. package/scripts/gds/release-core.js +80 -0
  44. package/scripts/gds/update-channel.js +12 -3
  45. package/src/bongos/core-update.js +17 -8
  46. package/src/module-api.js +1 -1
  47. package/tests/autonomy_builder_scope.mjs +474 -0
  48. package/tests/autonomy_fence_priority.mjs +3 -1
  49. package/tests/core_update_banner.mjs +41 -5
  50. package/tests/core_upgrade_runner.mjs +66 -1
  51. package/tests/npm_release_release.mjs +195 -0
  52. package/tests/release_core.mjs +110 -0
  53. package/tests/update_channel.mjs +7 -0
@@ -5,7 +5,7 @@
5
5
  "adr": "0341 D3",
6
6
  "reread": "node scripts/gds/page-reader.js --stale",
7
7
  "how": ["Generated by node scripts/gds/page-reader.js (BV2.TW04, task 1004315; ADR 0341 D3). Do not hand-edit.","One entry per page of docs/page-inventory.json. Lines are in page order: the default state first, and a line only another state shows sits where that state shows it, with its state named.","placement: placed = a docs/copy-registry.json row renders it (file, line, string_id); shared = shell text every page of the surface carries (top bar, sidebar, footer), with its row when the registry has one; unplaced = the registry cannot place it (a rewrite becomes an engineer task, ADR 0341 D4).","text keeps {…} where the registry row has a hole, or where a value the page read from its API was filled in. A string that is only such data is counted under omitted.data, not listed.","reading_hash is over the non-shared lines (key, section, text); files_hash is over the page's inventory files. --check compares files_hash only and never opens a browser.","Rendered through the hall-preview harness (hall) and the ui-design kit stub (landing, status), at 1280x800 with the clock pinned, so a reading is the fixture world's page."],
8
- "counts": {"pages":40,"lines":4566,"placed":1610,"shared":245,"unplaced":2711,"omitted_data":2252},
8
+ "counts": {"pages":40,"lines":4571,"placed":1613,"shared":245,"unplaced":2713,"omitted_data":2254},
9
9
  "pages": [
10
10
  {
11
11
  "id": "builders:atlas",
@@ -946,7 +946,7 @@
946
946
  "surface": "builders",
947
947
  "title": "Gate",
948
948
  "states_read": ["queue","out","approve"],
949
- "files_hash": "fce003b152adb982",
949
+ "files_hash": "af5d80b03048ddf1",
950
950
  "reading_hash": "08d3e5d3657e5afb",
951
951
  "counts": {"lines":41,"placed":17,"shared":5,"unplaced":19},
952
952
  "omitted": {"data":34},
@@ -955,17 +955,17 @@
955
955
  {"key":"L0001","section":"skip link","text":"Skip to content","placement":"shared","file":"modules/hall-ui/public/shell.js","line":884,"string_id":"87cee78ca134"},
956
956
  {"key":"L0002","section":"top bar","text":"Gate","placement":"shared"},
957
957
  {"key":"L0003","section":"top bar","text":"Jump to…","placement":"shared","file":"modules/hall-ui/public/shell.js","line":495,"string_id":"eba610d25523"},
958
- {"key":"L0004","section":"top bar","text":"Ctrl K","placement":"shared"},
958
+ {"key":"L0004","section":"top bar","text":"⌘K","placement":"shared"},
959
959
  {"key":"L0005","section":"Gate","text":"Gate","placement":"unplaced"},
960
- {"key":"L0006","section":"Gate","text":"Changes touching protected build surfaces, held for your approval.","placement":"placed","file":"modules/hall-ui/public/gate.js","line":448,"string_id":"4b714191b423"},
960
+ {"key":"L0006","section":"Gate","text":"Changes touching protected build surfaces, held for your approval.","placement":"placed","file":"modules/hall-ui/public/gate.js","line":517,"string_id":"4b714191b423"},
961
961
  {"key":"L0007","section":"Gate","text":"Awaiting your approval","placement":"unplaced"},
962
962
  {"key":"L0008","section":"Gate","text":"held at the gate check","placement":"unplaced"},
963
963
  {"key":"L0009","section":"Gate","text":"Hard-floor holds","placement":"unplaced"},
964
964
  {"key":"L0010","section":"Gate","text":"touch a surface only an owner may clear","placement":"unplaced"},
965
965
  {"key":"L0011","section":"Gate","text":"Trust holds","placement":"unplaced"},
966
966
  {"key":"L0012","section":"Gate","text":"an author the gate does not yet trust","placement":"unplaced"},
967
- {"key":"L0013","section":"Held pull requests","text":"Held pull requests","placement":"placed","file":"modules/hall-ui/public/gate.html","line":63,"string_id":"adac4cd8b973"},
968
- {"key":"L0014","section":"Held pull requests","text":"Each one touched a protected surface and stopped at the gate check. Approving records your seal on that commit and re-runs the check.","placement":"placed","file":"modules/hall-ui/public/gate.html","line":64,"string_id":"77b7e3abfb07"},
967
+ {"key":"L0013","section":"Held pull requests","text":"Held pull requests","placement":"placed","file":"modules/hall-ui/public/gate.html","line":66,"string_id":"adac4cd8b973"},
968
+ {"key":"L0014","section":"Held pull requests","text":"Each one touched a protected surface and stopped at the gate check. Approving records your seal on that commit and re-runs the check.","placement":"placed","file":"modules/hall-ui/public/gate.html","line":67,"string_id":"77b7e3abfb07"},
969
969
  {"key":"L0015","section":"Held pull requests","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","occurrences":2},
970
970
  {"key":"L0016","section":"Held pull requests","text":"Hard floor","placement":"unplaced","occurrences":2},
971
971
  {"key":"L0017","section":"Held pull requests","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":157,"string_id":"4d8ee7d68974","occurrences":2},
@@ -2584,25 +2584,25 @@
2584
2584
  "surface": "builders",
2585
2585
  "title": "Settings",
2586
2586
  "states_read": ["account","access","preferences","skills-walkthrough","offered-skills","sound","update"],
2587
- "files_hash": "e0941c22b8ed0433",
2588
- "reading_hash": "801ade9057081281",
2589
- "counts": {"lines":169,"placed":118,"shared":5,"unplaced":46},
2590
- "omitted": {"data":192},
2587
+ "files_hash": "b0bddb4881e32387",
2588
+ "reading_hash": "3811f66a9bff1f0c",
2589
+ "counts": {"lines":174,"placed":121,"shared":5,"unplaced":48},
2590
+ "omitted": {"data":194},
2591
2591
  "notes": [],
2592
2592
  "lines": [
2593
2593
  {"key":"L0001","section":"skip link","text":"Skip to content","placement":"shared","file":"modules/hall-ui/public/shell.js","line":884,"string_id":"87cee78ca134"},
2594
2594
  {"key":"L0002","section":"top bar","text":"Settings","placement":"shared"},
2595
2595
  {"key":"L0003","section":"top bar","text":"Jump to…","placement":"shared","file":"modules/hall-ui/public/shell.js","line":495,"string_id":"eba610d25523"},
2596
- {"key":"L0004","section":"top bar","text":"Ctrl K","placement":"shared"},
2596
+ {"key":"L0004","section":"top bar","text":"⌘K","placement":"shared"},
2597
2597
  {"key":"L0005","section":"settings","text":"settings","placement":"unplaced"},
2598
2598
  {"key":"L0006","section":"settings","text":"Your preferences, {…}.","placement":"placed","file":"modules/hall-ui/public/settings.js","line":630,"string_id":"e91418db3962"},
2599
2599
  {"key":"L0007","section":"settings","text":"Account","placement":"unplaced"},
2600
2600
  {"key":"L0008","section":"settings","text":"Access & keys","placement":"unplaced"},
2601
2601
  {"key":"L0009","section":"settings","text":"Preferences","placement":"unplaced"},
2602
2602
  {"key":"L0010","section":"settings","text":"Sound","placement":"unplaced"},
2603
- {"key":"L0011","section":"settings","text":"Software update","placement":"placed","file":"modules/hall-ui/public/settings.html","line":373,"string_id":"207af7ce6828"},
2604
- {"key":"L0012","section":"Software update","text":"Software update","placement":"placed","file":"modules/hall-ui/public/settings.html","line":373,"string_id":"207af7ce6828","state":"update"},
2605
- {"key":"L0013","section":"Software update","text":"Which version of Cloud Bongos this project runs, whether a newer one is ready for it, and what each newer version brings.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":374,"string_id":"68da8cb13058","state":"update"},
2603
+ {"key":"L0011","section":"settings","text":"Software update","placement":"placed","file":"modules/hall-ui/public/settings.html","line":390,"string_id":"207af7ce6828"},
2604
+ {"key":"L0012","section":"Software update","text":"Software update","placement":"placed","file":"modules/hall-ui/public/settings.html","line":390,"string_id":"207af7ce6828","state":"update"},
2605
+ {"key":"L0013","section":"Software update","text":"Which version of Cloud Bongos this project runs, whether a newer one is ready for it, and what each newer version brings.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":391,"string_id":"68da8cb13058","state":"update"},
2606
2606
  {"key":"L0014","section":"Software update","text":"{…} project{…}","placement":"placed","file":"modules/hall-ui/public/fleet.js","line":39,"string_id":"771bef3d31b5","state":"update","occurrences":2},
2607
2607
  {"key":"L0015","section":"Software update","text":"— published 21 hours ago","placement":"unplaced","state":"update"},
2608
2608
  {"key":"L0016","section":"Software update","text":"Update ready","placement":"placed","file":"modules/hall-ui/public/settings-software-update.js","line":145,"string_id":"13ced9b2fa12","state":"update"},
@@ -2616,37 +2616,37 @@
2616
2616
  {"key":"L0024","section":"What's new in these 7 versions","text":"Show {…} more version{…}","placement":"placed","file":"modules/hall-ui/public/settings-software-update.js","line":119,"string_id":"44945da22716","state":"update"},
2617
2617
  {"key":"L0025","section":"What's new in these 7 versions","text":"Checked 20 hours ago.","placement":"unplaced","state":"update"},
2618
2618
  {"key":"L0026","section":"footer","text":"Sign out","placement":"shared","file":"modules/hall-ui/public/shell.js","line":471,"string_id":"1883ad7f07fc","state":"update","occurrences":5},
2619
- {"key":"L0027","section":"Skill voices","text":"Skill voices","placement":"placed","file":"modules/hall-ui/public/settings.html","line":314,"string_id":"ecc12c1dd4de","state":"sound"},
2620
- {"key":"L0028","section":"Skill voices","text":"Each slash-command can run on a different model. The system has a default for every skill; choose another to override it, or leave it on Default.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":315,"string_id":"7f1b1c32d360","state":"sound"},
2619
+ {"key":"L0027","section":"Skill voices","text":"Skill voices","placement":"placed","file":"modules/hall-ui/public/settings.html","line":331,"string_id":"ecc12c1dd4de","state":"sound"},
2620
+ {"key":"L0028","section":"Skill voices","text":"Each slash-command can run on a different model. The system has a default for every skill; choose another to override it, or leave it on Default.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":332,"string_id":"7f1b1c32d360","state":"sound"},
2621
2621
  {"key":"L0029","section":"Skill voices","text":"Skill","placement":"placed","file":"modules/hall-ui/public/settings-specialities.js","line":130,"string_id":"4b0ca7d7171f","state":"sound"},
2622
2622
  {"key":"L0030","section":"Skill voices","text":"Default","placement":"unplaced","state":"sound"},
2623
- {"key":"L0031","section":"Skill voices","text":"Your choice","placement":"placed","file":"modules/hall-ui/public/settings.html","line":323,"string_id":"f96bc227dba0","state":"sound"},
2623
+ {"key":"L0031","section":"Skill voices","text":"Your choice","placement":"placed","file":"modules/hall-ui/public/settings.html","line":340,"string_id":"f96bc227dba0","state":"sound"},
2624
2624
  {"key":"L0032","section":"Skill voices","text":"no LLM","placement":"unplaced","state":"sound","occurrences":22},
2625
2625
  {"key":"L0033","section":"Skill voices","text":"Default ({…})","placement":"placed","file":"modules/hall-ui/public/settings.js","line":63,"string_id":"7c6891813679","state":"sound","occurrences":16},
2626
2626
  {"key":"L0034","section":"Skill voices","text":"Opus","placement":"unplaced","state":"sound","occurrences":21},
2627
2627
  {"key":"L0035","section":"Skill voices","text":"Sonnet","placement":"unplaced","state":"sound","occurrences":21},
2628
2628
  {"key":"L0036","section":"Skill voices","text":"Haiku","placement":"unplaced","state":"sound","occurrences":16},
2629
- {"key":"L0037","section":"Skill voices","text":"Changes save the moment you pick. “Default” clears your override and falls back to the system's choice.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":329,"string_id":"cab7a9526ca1","state":"sound"},
2629
+ {"key":"L0037","section":"Skill voices","text":"Changes save the moment you pick. “Default” clears your override and falls back to the system's choice.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":346,"string_id":"cab7a9526ca1","state":"sound"},
2630
2630
  {"key":"L0038","section":"Sounds","text":"Sounds","placement":"unplaced","state":"sound"},
2631
- {"key":"L0039","section":"Sounds","text":"A sound plays at each turn of your work — a gentle chime when Claude finishes, a flourish when a task ships or your rank rises. Turn off any you would rather not hear.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":335,"string_id":"a3185a43c230","state":"sound"},
2631
+ {"key":"L0039","section":"Sounds","text":"A sound plays at each turn of your work — a gentle chime when Claude finishes, a flourish when a task ships or your rank rises. Turn off any you would rather not hear.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":352,"string_id":"a3185a43c230","state":"sound"},
2632
2632
  {"key":"L0040","section":"Sounds","text":"Volume","placement":"placed","file":"modules/hall-ui/public/settings.js","line":216,"string_id":"2940b7828d26","state":"sound"},
2633
- {"key":"L0041","section":"Sounds","text":"Changes save at once and take effect the next time you start a session on this machine.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":346,"string_id":"906c2947dfc1","state":"sound"},
2634
- {"key":"L0042","section":"Event sounds","text":"Event sounds","placement":"placed","file":"modules/hall-ui/public/settings.html","line":351,"string_id":"44f928d13699","state":"sound"},
2635
- {"key":"L0043","section":"Event sounds","text":"Choose which sound plays for each build event — one when Claude waits for your input, another when a task ships, a coin clink when {{currency}} arrive. Each event offers a small set of choices; more will be added as new audio ships.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":352,"string_id":"6c88cdf417f1","state":"sound"},
2633
+ {"key":"L0041","section":"Sounds","text":"Changes save at once and take effect the next time you start a session on this machine.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":363,"string_id":"906c2947dfc1","state":"sound"},
2634
+ {"key":"L0042","section":"Event sounds","text":"Event sounds","placement":"placed","file":"modules/hall-ui/public/settings.html","line":368,"string_id":"44f928d13699","state":"sound"},
2635
+ {"key":"L0043","section":"Event sounds","text":"Choose which sound plays for each build event — one when Claude waits for your input, another when a task ships, a coin clink when {{currency}} arrive. Each event offers a small set of choices; more will be added as new audio ships.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":369,"string_id":"6c88cdf417f1","state":"sound"},
2636
2636
  {"key":"L0044","section":"Event sounds","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","state":"sound","occurrences":2},
2637
2637
  {"key":"L0045","section":"Event sounds","text":"{…} (default)","placement":"unplaced","state":"sound","occurrences":5},
2638
2638
  {"key":"L0046","section":"Event sounds","text":"Play","placement":"unplaced","state":"sound","occurrences":5},
2639
- {"key":"L0047","section":"Event sounds","text":"Task {…}","placement":"placed","file":"modules/hall-ui/public/task.js","line":503,"string_id":"eff70e59d12e","state":"sound"},
2640
- {"key":"L0048","section":"Event sounds","text":"{…} earned","placement":"placed","file":"modules/hall-ui/public/goals-render.js","line":822,"string_id":"cf89ac85440d","state":"sound"},
2641
- {"key":"L0049","section":"Event sounds","text":"Changes save at once. Your new choice plays the next time that event fires.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":359,"string_id":"52384bdc035c","state":"sound"},
2642
- {"key":"L0050","section":"How Claude talks to you","text":"How Claude talks to you","placement":"placed","file":"modules/hall-ui/public/settings.html","line":193,"string_id":"0469a83cf1e8","state":"preferences"},
2643
- {"key":"L0051","section":"How Claude talks to you","text":"How replies are pitched for you — the vocabulary assumed, how much hand-holding local tooling gets, how long an answer runs, and how much of the work behind it is narrated. These reach every session you start. The defaults assume no software-engineering background; change any of them and the rest stay as they are.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":194,"string_id":"63dbe9873b4e","state":"preferences"},
2639
+ {"key":"L0047","section":"Event sounds","text":"Task {…}","placement":"placed","file":"modules/hall-ui/public/task.js","line":512,"string_id":"eff70e59d12e","state":"sound"},
2640
+ {"key":"L0048","section":"Event sounds","text":"{…} earned","placement":"placed","file":"modules/hall-ui/public/goals-render.js","line":828,"string_id":"cf89ac85440d","state":"sound"},
2641
+ {"key":"L0049","section":"Event sounds","text":"Changes save at once. Your new choice plays the next time that event fires.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":376,"string_id":"52384bdc035c","state":"sound"},
2642
+ {"key":"L0050","section":"How Claude talks to you","text":"How Claude talks to you","placement":"placed","file":"modules/hall-ui/public/settings.html","line":210,"string_id":"0469a83cf1e8","state":"preferences"},
2643
+ {"key":"L0051","section":"How Claude talks to you","text":"How replies are pitched for you — the vocabulary assumed, how much hand-holding local tooling gets, how long an answer runs, and how much of the work behind it is narrated. These reach every session you start. The defaults assume no software-engineering background; change any of them and the rest stay as they are.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":211,"string_id":"63dbe9873b4e","state":"preferences"},
2644
2644
  {"key":"L0052","section":"How Claude talks to you","text":"{…} file{…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":151,"string_id":"3efa67dc6e07","state":"preferences"},
2645
- {"key":"L0053","section":"Your specialities","text":"Your specialities","placement":"placed","file":"modules/hall-ui/public/settings.html","line":212,"string_id":"dd419ffd76f0","state":"preferences"},
2646
- {"key":"L0054","section":"Your specialities","text":"A role says how you work. A speciality says what you work on — and how you, as someone who knows the subject, want to be engaged inside it. Whichever one you are using reaches every session where you hold a claim in that role. Train it by adding things you have written; it also picks things up on its own as you work.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":213,"string_id":"244ea2a3564e","state":"preferences"},
2647
- {"key":"L0055","section":"Your specialities","text":"Markets, incentives, and how to price them.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":241,"string_id":"8bdec961e84a","state":"preferences"},
2645
+ {"key":"L0053","section":"Your specialities","text":"Your specialities","placement":"placed","file":"modules/hall-ui/public/settings.html","line":229,"string_id":"dd419ffd76f0","state":"preferences"},
2646
+ {"key":"L0054","section":"Your specialities","text":"A role says how you work. A speciality says what you work on — and how you, as someone who knows the subject, want to be engaged inside it. Whichever one you are using reaches every session where you hold a claim in that role. Train it by adding things you have written; it also picks things up on its own as you work.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":230,"string_id":"244ea2a3564e","state":"preferences"},
2647
+ {"key":"L0055","section":"Your specialities","text":"Markets, incentives, and how to price them.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":258,"string_id":"8bdec961e84a","state":"preferences"},
2648
2648
  {"key":"L0056","section":"Your specialities","text":"What this adds to your sessions — written by someone else","placement":"unplaced","state":"preferences"},
2649
- {"key":"L0057","section":"Your specialities","text":"Argue from mechanism, not vibes. Always name the assumption a number rests on.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":245,"string_id":"d9dd46194f35","state":"preferences"},
2649
+ {"key":"L0057","section":"Your specialities","text":"Argue from mechanism, not vibes. Always name the assumption a number rests on.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":262,"string_id":"d9dd46194f35","state":"preferences"},
2650
2650
  {"key":"L0058","section":"Your specialities","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","state":"preferences","occurrences":46},
2651
2651
  {"key":"L0059","section":"Your specialities","text":"Trained on","placement":"placed","file":"modules/hall-ui/public/settings-specialities.js","line":322,"string_id":"becc35640e42","state":"preferences","occurrences":2},
2652
2652
  {"key":"L0060","section":"Your specialities","text":"document{…} you added · learned","placement":"placed","file":"modules/hall-ui/public/settings-specialities.js","line":322,"string_id":"a3fd52d9513b","state":"preferences","occurrences":2},
@@ -2674,46 +2674,46 @@
2674
2674
  {"key":"L0082","section":"Your specialities","text":"{…} file{…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":151,"string_id":"3efa67dc6e07","state":"offered-skills","occurrences":4},
2675
2675
  {"key":"L0083","section":"Your specialities","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9","state":"offered-skills","occurrences":4},
2676
2676
  {"key":"L0084","section":"Your specialities","text":"Save what it offers","placement":"placed","file":"modules/hall-ui/public/settings-specialities.js","line":276,"string_id":"a98b96e49388","state":"offered-skills"},
2677
- {"key":"L0085","section":"Create one","text":"Create one","placement":"placed","file":"modules/hall-ui/public/settings.html","line":224,"string_id":"20459b66303a","state":"preferences"},
2677
+ {"key":"L0085","section":"Create one","text":"Create one","placement":"placed","file":"modules/hall-ui/public/settings.html","line":241,"string_id":"20459b66303a","state":"preferences"},
2678
2678
  {"key":"L0086","section":"Create one","text":"Name","placement":"unplaced","state":"preferences"},
2679
- {"key":"L0087","section":"Create one","text":"Role it sits under","placement":"placed","file":"modules/hall-ui/public/settings.html","line":230,"string_id":"12af2af5acf2","state":"preferences"},
2680
- {"key":"L0088","section":"Create one","text":"Pick one…","placement":"placed","file":"modules/hall-ui/public/settings.html","line":232,"string_id":"45378ea261f6","state":"preferences"},
2679
+ {"key":"L0087","section":"Create one","text":"Role it sits under","placement":"placed","file":"modules/hall-ui/public/settings.html","line":247,"string_id":"12af2af5acf2","state":"preferences"},
2680
+ {"key":"L0088","section":"Create one","text":"Pick one…","placement":"placed","file":"modules/hall-ui/public/settings.html","line":249,"string_id":"45378ea261f6","state":"preferences"},
2681
2681
  {"key":"L0089","section":"Create one","text":"Ideator","placement":"unplaced","state":"preferences"},
2682
2682
  {"key":"L0090","section":"Create one","text":"Artist","placement":"unplaced","state":"preferences"},
2683
- {"key":"L0091","section":"Create one","text":"UI design","placement":"placed","file":"modules/hall-ui/public/settings.html","line":236,"string_id":"6516cc82021a","state":"preferences"},
2683
+ {"key":"L0091","section":"Create one","text":"UI design","placement":"placed","file":"modules/hall-ui/public/settings.html","line":253,"string_id":"6516cc82021a","state":"preferences"},
2684
2684
  {"key":"L0092","section":"Create one","text":"Summary","placement":"unplaced","state":"preferences"},
2685
2685
  {"key":"L0093","section":"Create one","text":"(optional)","placement":"unplaced","state":"preferences","occurrences":3},
2686
- {"key":"L0094","section":"Create one","text":"Markets, incentives, and how to price them.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":241,"string_id":"8bdec961e84a","attr":"placeholder","state":"preferences"},
2687
- {"key":"L0095","section":"Create one","text":"How Claude should engage you in it","placement":"placed","file":"modules/hall-ui/public/settings.html","line":244,"string_id":"6dd3c797943b","state":"preferences"},
2688
- {"key":"L0096","section":"Create one","text":"Argue from mechanism, not vibes. Always name the assumption a number rests on.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":245,"string_id":"d9dd46194f35","attr":"placeholder","state":"preferences"},
2689
- {"key":"L0097","section":"Create one","text":"Who can use it","placement":"placed","file":"modules/hall-ui/public/settings.html","line":248,"string_id":"b79ea4077bc5","state":"preferences"},
2690
- {"key":"L0098","section":"Create one","text":"Only me","placement":"placed","file":"modules/hall-ui/public/settings.html","line":250,"string_id":"45b667751b95","state":"preferences"},
2691
- {"key":"L0099","section":"Create one","text":"Anyone in the owning project","placement":"placed","file":"modules/hall-ui/public/settings.html","line":251,"string_id":"8832c7204180","state":"preferences"},
2692
- {"key":"L0100","section":"Create one","text":"Anyone on this instance","placement":"placed","file":"modules/hall-ui/public/settings.html","line":252,"string_id":"7d2ab55d4112","state":"preferences"},
2693
- {"key":"L0101","section":"Create one","text":"May be offered for sale later","placement":"placed","file":"modules/hall-ui/public/settings.html","line":257,"string_id":"6e73716aec6c","state":"preferences"},
2694
- {"key":"L0102","section":"Create one","text":"Records your decision only — there is no marketplace yet, and nothing is listed anywhere.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":259,"string_id":"b40c4a61070e","state":"preferences"},
2695
- {"key":"L0103","section":"Create one","text":"Skills it offers","placement":"placed","file":"modules/hall-ui/public/settings.html","line":263,"string_id":"bbbb6e8ab564","state":"preferences"},
2696
- {"key":"L0104","section":"Create one","text":"Create speciality","placement":"placed","file":"modules/hall-ui/public/settings.html","line":267,"string_id":"af21de422c14","state":"preferences"},
2686
+ {"key":"L0094","section":"Create one","text":"Markets, incentives, and how to price them.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":258,"string_id":"8bdec961e84a","attr":"placeholder","state":"preferences"},
2687
+ {"key":"L0095","section":"Create one","text":"How Claude should engage you in it","placement":"placed","file":"modules/hall-ui/public/settings.html","line":261,"string_id":"6dd3c797943b","state":"preferences"},
2688
+ {"key":"L0096","section":"Create one","text":"Argue from mechanism, not vibes. Always name the assumption a number rests on.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":262,"string_id":"d9dd46194f35","attr":"placeholder","state":"preferences"},
2689
+ {"key":"L0097","section":"Create one","text":"Who can use it","placement":"placed","file":"modules/hall-ui/public/settings.html","line":265,"string_id":"b79ea4077bc5","state":"preferences"},
2690
+ {"key":"L0098","section":"Create one","text":"Only me","placement":"placed","file":"modules/hall-ui/public/settings.html","line":267,"string_id":"45b667751b95","state":"preferences"},
2691
+ {"key":"L0099","section":"Create one","text":"Anyone in the owning project","placement":"placed","file":"modules/hall-ui/public/settings.html","line":268,"string_id":"8832c7204180","state":"preferences"},
2692
+ {"key":"L0100","section":"Create one","text":"Anyone on this instance","placement":"placed","file":"modules/hall-ui/public/settings.html","line":269,"string_id":"7d2ab55d4112","state":"preferences"},
2693
+ {"key":"L0101","section":"Create one","text":"May be offered for sale later","placement":"placed","file":"modules/hall-ui/public/settings.html","line":274,"string_id":"6e73716aec6c","state":"preferences"},
2694
+ {"key":"L0102","section":"Create one","text":"Records your decision only — there is no marketplace yet, and nothing is listed anywhere.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":276,"string_id":"b40c4a61070e","state":"preferences"},
2695
+ {"key":"L0103","section":"Create one","text":"Skills it offers","placement":"placed","file":"modules/hall-ui/public/settings.html","line":280,"string_id":"bbbb6e8ab564","state":"preferences"},
2696
+ {"key":"L0104","section":"Create one","text":"Create speciality","placement":"placed","file":"modules/hall-ui/public/settings.html","line":284,"string_id":"af21de422c14","state":"preferences"},
2697
2697
  {"key":"L0105","section":"Wandering","text":"Wandering","placement":"unplaced","state":"preferences"},
2698
- {"key":"L0106","section":"Wandering","text":"How readily Claude opens a","placement":"placed","file":"modules/hall-ui/public/settings.html","line":279,"string_id":"0bae5deb899d","state":"preferences"},
2699
- {"key":"L0107","section":"Wandering","text":"new thread","placement":"placed","file":"modules/hall-ui/public/settings.html","line":280,"string_id":"86f235ddfe01","state":"preferences"},
2700
- {"key":"L0108","section":"Wandering","text":"of work — a tangent, an investigation, an unprompted suggestion — instead of staying on your claimed task. It never limits the work on the task itself. Your rank sets the starting point; newcomers stay locked low.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":280,"string_id":"99f88f2af2ee","state":"preferences"},
2698
+ {"key":"L0106","section":"Wandering","text":"How readily Claude opens a","placement":"placed","file":"modules/hall-ui/public/settings.html","line":296,"string_id":"0bae5deb899d","state":"preferences"},
2699
+ {"key":"L0107","section":"Wandering","text":"new thread","placement":"placed","file":"modules/hall-ui/public/settings.html","line":297,"string_id":"86f235ddfe01","state":"preferences"},
2700
+ {"key":"L0108","section":"Wandering","text":"of work — a tangent, an investigation, an unprompted suggestion — instead of staying on your claimed task. It never limits the work on the task itself. Your rank sets the starting point; newcomers stay locked low.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":297,"string_id":"99f88f2af2ee","state":"preferences"},
2701
2701
  {"key":"L0109","section":"Wandering","text":"{…} file{…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":151,"string_id":"3efa67dc6e07","state":"preferences"},
2702
2702
  {"key":"L0110","section":"Wandering","text":"default for your rank","placement":"placed","file":"modules/hall-ui/public/settings.js","line":420,"string_id":"4a287afb0892","state":"preferences"},
2703
2703
  {"key":"L0111","section":"Wandering","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","state":"preferences"},
2704
2704
  {"key":"L0112","section":"Wandering","text":"Now: {…}. Your rank allows up to {…}.","placement":"unplaced","state":"preferences"},
2705
2705
  {"key":"L0113","section":"Rendering","text":"Rendering","placement":"unplaced","state":"preferences"},
2706
- {"key":"L0114","section":"Rendering","text":"How much your session cards — what","placement":"placed","file":"modules/hall-ui/public/settings.html","line":298,"string_id":"160adde1e398","state":"preferences"},
2707
- {"key":"L0115","section":"Rendering","text":", claiming, and shipping show — spend on explaining themselves. Richer cards say more and cost more tokens; leaner ones carry the same facts for less. By default this follows how Claude talks to you, so you can set it once in","placement":"placed","file":"modules/hall-ui/public/settings.html","line":299,"string_id":"1f8aceffb15e","state":"preferences"},
2708
- {"key":"L0116","section":"Rendering","text":"How Claude talks to you","placement":"placed","file":"modules/hall-ui/public/settings.html","line":193,"string_id":"0469a83cf1e8","state":"preferences"},
2709
- {"key":"L0117","section":"Rendering","text":"and leave this alone.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":303,"string_id":"2177da93be9b","state":"preferences"},
2706
+ {"key":"L0114","section":"Rendering","text":"How much your session cards — what","placement":"placed","file":"modules/hall-ui/public/settings.html","line":315,"string_id":"160adde1e398","state":"preferences"},
2707
+ {"key":"L0115","section":"Rendering","text":", claiming, and shipping show — spend on explaining themselves. Richer cards say more and cost more tokens; leaner ones carry the same facts for less. By default this follows how Claude talks to you, so you can set it once in","placement":"placed","file":"modules/hall-ui/public/settings.html","line":316,"string_id":"1f8aceffb15e","state":"preferences"},
2708
+ {"key":"L0116","section":"Rendering","text":"How Claude talks to you","placement":"placed","file":"modules/hall-ui/public/settings.html","line":210,"string_id":"0469a83cf1e8","state":"preferences"},
2709
+ {"key":"L0117","section":"Rendering","text":"and leave this alone.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":320,"string_id":"2177da93be9b","state":"preferences"},
2710
2710
  {"key":"L0118","section":"Rendering","text":"Session card richness","placement":"placed","file":"modules/hall-ui/public/settings-render.js","line":83,"string_id":"64a1f055129e","state":"preferences"},
2711
2711
  {"key":"L0119","section":"Rendering","text":"How much the claim and ship cards show. Richer cards explain more and cost more tokens; the confirmation line is always there whichever you pick.","placement":"placed","file":"modules/hall-ui/public/settings-render.js","line":84,"string_id":"d76a5fcbde7c","state":"preferences"},
2712
2712
  {"key":"L0120","section":"Rendering","text":"Match my interaction profile","placement":"unplaced","state":"preferences"},
2713
2713
  {"key":"L0121","section":"Rendering","text":"default ({…})","placement":"placed","file":"modules/hall-ui/public/settings-render.js","line":64,"string_id":"4adbb8da9999","state":"preferences"},
2714
2714
  {"key":"L0122","section":"Rendering","text":"{…} Change that profile and this follows it.","placement":"placed","file":"modules/hall-ui/public/settings-render.js","line":65,"string_id":"de5b58a187c6","state":"preferences"},
2715
2715
  {"key":"L0123","section":"Rendering","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","state":"preferences"},
2716
- {"key":"L0124","section":"Rendering","text":"Saves the moment you choose; applies from your next session.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":307,"string_id":"72f24fcbe9e0","state":"preferences"},
2716
+ {"key":"L0124","section":"Rendering","text":"Saves the moment you choose; applies from your next session.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":324,"string_id":"72f24fcbe9e0","state":"preferences"},
2717
2717
  {"key":"L0125","section":"Rendering","text":"Using this speciality.","placement":"placed","file":"modules/hall-ui/public/settings-specialities.js","line":454,"string_id":"e1ecd543a2ca","state":"skills-walkthrough"},
2718
2718
  {"key":"L0126","section":"CLI access","text":"CLI access","placement":"placed","file":"modules/hall-ui/public/settings.html","line":133,"string_id":"a015a43bfc7f","state":"access"},
2719
2719
  {"key":"L0127","section":"CLI access","text":"Mint a fresh CLI token using this browser session and paste it into your terminal — the quick way back in when a","placement":"placed","file":"modules/hall-ui/public/settings.html","line":134,"string_id":"64e91044df43","state":"access"},
@@ -2732,33 +2732,38 @@
2732
2732
  {"key":"L0140","section":"Active sessions","text":"Sign out everywhere","placement":"placed","file":"modules/hall-ui/public/settings.html","line":160,"string_id":"8ad669ab2565","state":"access"},
2733
2733
  {"key":"L0141","section":"Active sessions","text":"ends every session including this one — you will be asked to sign in again.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":161,"string_id":"12a23cc46ace","state":"access"},
2734
2734
  {"key":"L0142","section":"Active sessions","text":"Ending a session takes effect immediately; the token stops working on its very next request.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":163,"string_id":"8e82771e5b63","state":"access"},
2735
- {"key":"L0143","section":"Image-generation key","text":"Image-generation key","placement":"placed","file":"modules/hall-ui/public/settings.html","line":173,"string_id":"783853467d52","state":"access","occurrences":2},
2736
- {"key":"L0144","section":"Image-generation key","text":"The art pipeline draws tiles and sprites with Google AI Studio (Gemini). Needed only if you generate art — your key, your bill, paid only for what you make.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":174,"string_id":"600b90074021","state":"access"},
2737
- {"key":"L0145","section":"Image-generation key","text":"Your key","placement":"placed","file":"modules/hall-ui/public/settings.js","line":828,"string_id":"51fd6f1ecb2f","state":"access"},
2738
- {"key":"L0146","section":"Image-generation key","text":"Paste your Google AI Studio key","placement":"unplaced","attr":"placeholder","state":"access"},
2739
- {"key":"L0147","section":"Image-generation key","text":"Save key","placement":"placed","file":"modules/hall-ui/public/settings.js","line":832,"string_id":"0c79b504aebe","state":"access"},
2740
- {"key":"L0148","section":"Image-generation key","text":"Get a free key ↗","placement":"placed","file":"modules/hall-ui/public/settings.js","line":800,"string_id":"2ae2114b61db","state":"access"},
2741
- {"key":"L0149","section":"Image-generation key","text":"· Stored encrypted; never shown again after saving.","placement":"placed","file":"modules/hall-ui/public/settings.js","line":834,"string_id":"b3757ba3bb46","state":"access"},
2742
- {"key":"L0150","section":"Image-generation key","text":"Stored encrypted; never shown again after saving — only its last four digits.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":182,"string_id":"6c6544f5c011","state":"access"},
2743
- {"key":"L0151","section":"Connections","text":"Connections","placement":"unplaced"},
2744
- {"key":"L0152","section":"Connections","text":"Link your Discord account and you're added to the {{worldName}} server with your rank role already set — no invite to share or leak.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":64,"string_id":"64e85f1691f9"},
2745
- {"key":"L0153","section":"Connections","text":"Discord connected ✓","placement":"placed","file":"modules/hall-ui/public/settings.js","line":676,"string_id":"0f685daf1bd5"},
2746
- {"key":"L0154","section":"Connections","text":"You're in the {…} server with your rank role.","placement":"placed","file":"modules/hall-ui/public/settings.js","line":677,"string_id":"8e1915b19274"},
2747
- {"key":"L0155","section":"Connections","text":"Unlink","placement":"unplaced"},
2748
- {"key":"L0156","section":"Connections","text":"Linking opens Discord's consent screen; unlinking applies at once.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":69,"string_id":"9a31cf5fe05b"},
2749
- {"key":"L0157","section":"Display name","text":"Display name","placement":"placed","file":"modules/hall-ui/public/settings.html","line":77,"string_id":"3e561393f4e9","occurrences":2},
2750
- {"key":"L0158","section":"Display name","text":"The name shown beside your work — in the roster, the leaderboard, and the work feed. Your sign-in and the credit for shipped work stay tied to your account, not this label.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":78,"string_id":"82479c539fca"},
2751
- {"key":"L0159","section":"Display name","text":"Your display name","placement":"placed","file":"modules/hall-ui/public/settings.html","line":87,"string_id":"909b0b7c6ffa","attr":"placeholder"},
2752
- {"key":"L0160","section":"Display name","text":"Save","placement":"unplaced"},
2753
- {"key":"L0161","section":"Display name","text":"Saves when you press Save; shows everywhere at once.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":91,"string_id":"e8e4e49fe8f4"},
2754
- {"key":"L0162","section":"Preferred roles","text":"Preferred roles","placement":"placed","file":"modules/hall-ui/public/settings.html","line":115,"string_id":"e883f2789cae"},
2755
- {"key":"L0163","section":"Preferred roles","text":"The kinds of work you prefer. Task suggestions lean toward your choices — pick one, several, or none.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":116,"string_id":"9f45c63c9697"},
2756
- {"key":"L0164","section":"Preferred roles","text":"Artist","placement":"unplaced"},
2757
- {"key":"L0165","section":"Preferred roles","text":"Ideator","placement":"unplaced"},
2758
- {"key":"L0166","section":"Preferred roles","text":"UI","placement":"unplaced"},
2759
- {"key":"L0167","section":"Preferred roles","text":"Save","placement":"unplaced"},
2760
- {"key":"L0168","section":"Preferred roles","text":"Saves when you press Save; your next","placement":"placed","file":"modules/hall-ui/public/settings.html","line":125,"string_id":"42cbc20a6ec8"},
2761
- {"key":"L0169","section":"Preferred roles","text":"reflects it.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":125,"string_id":"26da1df6fd4a"}
2735
+ {"key":"L0143","section":"Your Autobongos runner","text":"Your Autobongos runner","placement":"placed","file":"modules/hall-ui/public/settings.html","line":173,"string_id":"3749997eef4a","state":"access"},
2736
+ {"key":"L0144","section":"Your Autobongos runner","text":"Choose which goals your own runner works while you are away. You can only choose from the goals the project allows. If you choose none, your runner takes no work.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":174,"string_id":"2b504633779f","state":"access"},
2737
+ {"key":"L0145","section":"Your Autobongos runner","text":"Goal {…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":288,"string_id":"ec88b946ad16","state":"access","occurrences":2},
2738
+ {"key":"L0146","section":"Your Autobongos runner","text":"Save","placement":"unplaced","state":"access"},
2739
+ {"key":"L0147","section":"Your Autobongos runner","text":"Your runner works 1 goal.","placement":"unplaced","state":"access"},
2740
+ {"key":"L0148","section":"Image-generation key","text":"Image-generation key","placement":"placed","file":"modules/hall-ui/public/settings.html","line":190,"string_id":"783853467d52","state":"access","occurrences":2},
2741
+ {"key":"L0149","section":"Image-generation key","text":"The art pipeline draws tiles and sprites with Google AI Studio (Gemini). Needed only if you generate art — your key, your bill, paid only for what you make.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":191,"string_id":"600b90074021","state":"access"},
2742
+ {"key":"L0150","section":"Image-generation key","text":"Your key","placement":"placed","file":"modules/hall-ui/public/settings.js","line":828,"string_id":"51fd6f1ecb2f","state":"access"},
2743
+ {"key":"L0151","section":"Image-generation key","text":"Paste your Google AI Studio key","placement":"unplaced","attr":"placeholder","state":"access"},
2744
+ {"key":"L0152","section":"Image-generation key","text":"Save key","placement":"placed","file":"modules/hall-ui/public/settings.js","line":832,"string_id":"0c79b504aebe","state":"access"},
2745
+ {"key":"L0153","section":"Image-generation key","text":"Get a free key ↗","placement":"placed","file":"modules/hall-ui/public/settings.js","line":800,"string_id":"2ae2114b61db","state":"access"},
2746
+ {"key":"L0154","section":"Image-generation key","text":"· Stored encrypted; never shown again after saving.","placement":"placed","file":"modules/hall-ui/public/settings.js","line":834,"string_id":"b3757ba3bb46","state":"access"},
2747
+ {"key":"L0155","section":"Image-generation key","text":"Stored encrypted; never shown again after saving — only its last four digits.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":199,"string_id":"6c6544f5c011","state":"access"},
2748
+ {"key":"L0156","section":"Connections","text":"Connections","placement":"unplaced"},
2749
+ {"key":"L0157","section":"Connections","text":"Link your Discord account and you're added to the {{worldName}} server with your rank role already set — no invite to share or leak.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":64,"string_id":"64e85f1691f9"},
2750
+ {"key":"L0158","section":"Connections","text":"Discord connected ✓","placement":"placed","file":"modules/hall-ui/public/settings.js","line":676,"string_id":"0f685daf1bd5"},
2751
+ {"key":"L0159","section":"Connections","text":"You're in the {…} server with your rank role.","placement":"placed","file":"modules/hall-ui/public/settings.js","line":677,"string_id":"8e1915b19274"},
2752
+ {"key":"L0160","section":"Connections","text":"Unlink","placement":"unplaced"},
2753
+ {"key":"L0161","section":"Connections","text":"Linking opens Discord's consent screen; unlinking applies at once.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":69,"string_id":"9a31cf5fe05b"},
2754
+ {"key":"L0162","section":"Display name","text":"Display name","placement":"placed","file":"modules/hall-ui/public/settings.html","line":77,"string_id":"3e561393f4e9","occurrences":2},
2755
+ {"key":"L0163","section":"Display name","text":"The name shown beside your work — in the roster, the leaderboard, and the work feed. Your sign-in and the credit for shipped work stay tied to your account, not this label.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":78,"string_id":"82479c539fca"},
2756
+ {"key":"L0164","section":"Display name","text":"Your display name","placement":"placed","file":"modules/hall-ui/public/settings.html","line":87,"string_id":"909b0b7c6ffa","attr":"placeholder"},
2757
+ {"key":"L0165","section":"Display name","text":"Save","placement":"unplaced"},
2758
+ {"key":"L0166","section":"Display name","text":"Saves when you press Save; shows everywhere at once.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":91,"string_id":"e8e4e49fe8f4"},
2759
+ {"key":"L0167","section":"Preferred roles","text":"Preferred roles","placement":"placed","file":"modules/hall-ui/public/settings.html","line":115,"string_id":"e883f2789cae"},
2760
+ {"key":"L0168","section":"Preferred roles","text":"The kinds of work you prefer. Task suggestions lean toward your choices — pick one, several, or none.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":116,"string_id":"9f45c63c9697"},
2761
+ {"key":"L0169","section":"Preferred roles","text":"Artist","placement":"unplaced"},
2762
+ {"key":"L0170","section":"Preferred roles","text":"Ideator","placement":"unplaced"},
2763
+ {"key":"L0171","section":"Preferred roles","text":"UI","placement":"unplaced"},
2764
+ {"key":"L0172","section":"Preferred roles","text":"Save","placement":"unplaced"},
2765
+ {"key":"L0173","section":"Preferred roles","text":"Saves when you press Save; your next","placement":"placed","file":"modules/hall-ui/public/settings.html","line":125,"string_id":"42cbc20a6ec8"},
2766
+ {"key":"L0174","section":"Preferred roles","text":"reflects it.","placement":"placed","file":"modules/hall-ui/public/settings.html","line":125,"string_id":"26da1df6fd4a"}
2762
2767
  ]
2763
2768
  },
2764
2769
  {
@@ -57,6 +57,8 @@ npm publish ./clients/bongos-client # real (publishConfig makes it
57
57
 
58
58
  **Publishing is automatic on merge** as of 2026-08-08: the `publish` workflow rides behind the required `unit` check and waits for the `integration` lane's verdict on the commit it releases (task 1004290), auto-bumps a patch when nobody bumped, builds through the fail-closed no-leak gate, publishes, and tags — see the workflow header (`.github/workflows/publish.yml`) and ADR 0161. It ships inert until the owner arms it: repo variable `PUBLISH_ON_MERGE=1`, a **trusted publisher** registered on npmjs.com for `@bongos/core` naming this repo + `publish.yml`, and the secret `RELEASE_PUSH_TOKEN` (contents:write, for the bump commit). There is deliberately **no** `NPM_TOKEN` — the lane authenticates by OIDC, and the workflow sets neither `NPM_TOKEN` nor `NODE_AUTH_TOKEN` because either one would send npm down the legacy token path and skip the OIDC exchange entirely. A **minor/major bump stays a human in-task edit**. The update subscription ([ADR 0136](../adr/0136-update-channel-subscription-policy.md)) consumes whatever is published, on its next sweep.
59
59
 
60
+ **Candidates and Release** ([ADR 0361](../adr/0361-merges-publish-as-candidates-release-decides-what-others-are-offered.md), task 1004298). With the repo variable `PUBLISH_AS_CANDIDATE=1`, each merge publishes under the `next` label: the platform hall runs it, and no other project is offered it. **Release** on /deploy runs `publish.yml`'s `release` job (`workflow_dispatch`, input `release_version`), which moves `latest` to that version over the same OIDC trusted publisher. It needs **Allow npm dist-tag** ticked on the `publish.yml` trusted-publisher entry, and the server's GitHub App needs **Actions: write** to start the job. From a terminal the same job runs as `gh workflow run publish.yml -f release_version=<x.y.z>`. The arming order is in the ADR.
61
+
60
62
  The steps below remain as the **manual fallback** (lane disarmed, npm outage, or a deliberate out-of-band release):
61
63
 
62
64
  1. **Bump `CORE_VERSION`** in [`src/module-api.js`](../../src/module-api.js) (semver; a **patch** for a fix, **minor** for additive surface — a **major** is a deliberate, human-only event) and append an entry to the release ledger [`docs/module-api-changelog.md`](../module-api-changelog.md) in the same commit ([ADR 0203](../adr/0203-doorway-changelog-out-of-module-api.md) moved that ledger out of `module-api.js`). This bump is a normal claimed task, not a release-tool side effect — the version's provenance stays in the git history + ledger.
@@ -97,7 +97,7 @@ A **major** is never automatic; prereleases are never auto-targeted.
97
97
  | `released` *(default)* | versions at or below the registry's `latest` label, what the owner has released | every project |
98
98
  | `candidates` | every published version, as soon as it is published | **the platform's own hall only** |
99
99
 
100
- An instance that follows releases and whose `latest` label cannot be read is **skipped**, never upgraded on a guess. Until candidates publish under their own label (task 1004298), `latest` is the newest version, so the two follows pick the same target. Set the platform's own entry to `"follow": "candidates"` **before** that split lands, or the platform stops taking candidates the day they appear.
100
+ An instance that follows releases and whose `latest` label cannot be read is **skipped**, never upgraded on a guess. Once merges publish as candidates (task 1004298, [ADR 0361](../adr/0361-merges-publish-as-candidates-release-decides-what-others-are-offered.md), switched on by the repo variable `PUBLISH_AS_CANDIDATE=1`), `latest` moves only when the owner presses **Release** on /deploy, and the two follows part. Until that variable is set, `latest` is the newest version and they pick the same target. Set the platform's own entry to `"follow": "candidates"` **before** setting it, or the platform stops taking new versions the moment it is set. The platform's runner for hosted projects needs no roster entry: the `control-plane` row follows candidates and every other project follows releases.
101
101
 
102
102
  **Crossing a minor from /deploy** (task [1004405](https://cloudbongos.com/builders#/task/1004405)): set the project's update rule to **Fixes and new releases** (`minor`), or press **Allow new releases and move** on the refused move — either is the explicit "this crosses a minor version" choice. That only works once the box runs a core whose runner reads the rule (core 1.20.29 or later, task [1004445](https://cloudbongos.com/builders#/task/1004445)). A box on anything older runs the old runner, which bounds every move to `patch` whatever the rule says, so its **first** crossing is the manual `upgrade.js --to <version>` above; every later one goes through /deploy.
103
103
 
@@ -161,6 +161,9 @@ function classifyEvent(row = {}) {
161
161
 
162
162
  if (event === 'fenced') {
163
163
  if (code === 'kill_switch') return { class: 'stopped', detail: row.reason || 'an owner stopped the runner' };
164
+ // The per-builder stops (task 1004501) are the same kind of fact as the project
165
+ // switch: a person decided, and probing will not change their mind.
166
+ if (code === 'builder_paused' || code === 'not_permitted') return { class: 'stopped', detail: row.reason || 'this builder’s runner is stopped' };
164
167
  if (code === 'grader_unavailable') return { class: 'transient', detail: 'the grader is unavailable, and it is the only review there is' };
165
168
  if (code === 'fence_unreadable') return { class: 'transient', detail: 'the fence could not be read' };
166
169
  // no_allowlist / goal_not_allowlisted / protected_path: the fence is working
@@ -157,6 +157,138 @@ async function disallowGoal(goalId) {
157
157
  return { removed: rowCount > 0 };
158
158
  }
159
159
 
160
+ // ── each builder's runner scope (task 1004501) ───────────────────────────────
161
+ //
162
+ // The builder's half of the fence: which allowlisted goals THEIR runner works, and
163
+ // whether the owner has paused it. The composition with the project fence is pure
164
+ // and lives in ../fence.js (effectiveFence); these stay dumb.
165
+
166
+ // readBuilderScope — one builder's picks and pause, or null when they have neither
167
+ // (which effectiveFence reads as "no goals", by owner ruling). The picks join the
168
+ // allowlist so a pick can never outlive its goal there, on top of the CASCADE.
169
+ async function readBuilderScope(builderId) {
170
+ const [scope, goals] = await Promise.all([
171
+ pool.query('SELECT owner_paused, owner_paused_reason, owner_paused_by, updated_at FROM autonomy_builder_scope WHERE builder_id = $1', [builderId]),
172
+ pool.query(
173
+ `SELECT bg.goal_id FROM autonomy_builder_goals bg
174
+ JOIN autonomy_allowed_goals ag ON ag.goal_id = bg.goal_id
175
+ WHERE bg.builder_id = $1 ORDER BY bg.goal_id`,
176
+ [builderId]
177
+ ),
178
+ ]);
179
+ const row = scope.rows[0];
180
+ if (!row && !goals.rows.length) return null;
181
+ return {
182
+ goals: goals.rows.map((g) => Number(g.goal_id)),
183
+ owner_paused: !!(row && row.owner_paused === true),
184
+ owner_paused_reason: (row && row.owner_paused_reason) || null,
185
+ owner_paused_by: row && row.owner_paused_by ? String(row.owner_paused_by) : null,
186
+ updated_at: row ? row.updated_at : null,
187
+ };
188
+ }
189
+
190
+ // setBuilderGoals — replace one builder's picks with `goalIds`, in one transaction.
191
+ // Every id must already be on the allowlist; if any is not, NOTHING is written and
192
+ // `{ notAllowed: [...] }` says which, so the Settings page can name them. An empty
193
+ // list is a valid answer and means "my runner takes no work".
194
+ async function setBuilderGoals({ builderId, goalIds }) {
195
+ const ids = [...new Set((goalIds || []).map(Number))];
196
+ const client = await pool.connect();
197
+ try {
198
+ await client.query('BEGIN');
199
+ if (ids.length) {
200
+ const { rows } = await client.query('SELECT goal_id FROM autonomy_allowed_goals WHERE goal_id = ANY($1::bigint[])', [ids]);
201
+ const allowed = new Set(rows.map((r) => Number(r.goal_id)));
202
+ const notAllowed = ids.filter((g) => !allowed.has(g));
203
+ if (notAllowed.length) { await client.query('ROLLBACK'); return { notAllowed }; }
204
+ }
205
+ await client.query('DELETE FROM autonomy_builder_goals WHERE builder_id = $1', [builderId]);
206
+ if (ids.length) {
207
+ await client.query(
208
+ 'INSERT INTO autonomy_builder_goals (builder_id, goal_id) SELECT $1, unnest($2::bigint[])',
209
+ [builderId, ids]
210
+ );
211
+ }
212
+ // Bump the scope row so the change reaches a waiting runner as a signal.
213
+ await client.query(
214
+ `INSERT INTO autonomy_builder_scope (builder_id, updated_at) VALUES ($1, now())
215
+ ON CONFLICT (builder_id) DO UPDATE SET updated_at = now()`,
216
+ [builderId]
217
+ );
218
+ await client.query('COMMIT');
219
+ return { goals: ids.slice().sort((a, b) => a - b) };
220
+ } catch (err) {
221
+ try { await client.query('ROLLBACK'); } catch (_) { /* the original error is the one to report */ }
222
+ throw err;
223
+ } finally {
224
+ client.release();
225
+ }
226
+ }
227
+
228
+ // setBuilderPause — the owner pauses or resumes ONE builder's runner. The reason
229
+ // is kept only while paused, like the project switch. Returns null when no such
230
+ // builder exists, so a typo in the id is a 404 rather than an inert orphan row.
231
+ async function setBuilderPause({ builderId, paused, reason = null, byBuilderId = null }) {
232
+ const { rows } = await pool.query(
233
+ `INSERT INTO autonomy_builder_scope (builder_id, owner_paused, owner_paused_reason, owner_paused_by, updated_at)
234
+ SELECT $1, $2, $3, $4, now() WHERE EXISTS (SELECT 1 FROM builders WHERE id = $1)
235
+ ON CONFLICT (builder_id) DO UPDATE SET
236
+ owner_paused = EXCLUDED.owner_paused,
237
+ owner_paused_reason = EXCLUDED.owner_paused_reason,
238
+ owner_paused_by = EXCLUDED.owner_paused_by,
239
+ updated_at = now()
240
+ RETURNING builder_id, owner_paused, owner_paused_reason, updated_at`,
241
+ [builderId, paused === true, paused === true ? (reason || 'paused by the owner') : null, byBuilderId]
242
+ );
243
+ const r = rows[0];
244
+ return r ? { ...r, builder_id: String(r.builder_id) } : null;
245
+ }
246
+
247
+ // readAllRunnerScopes — the owner's view: every builder who has a runner scope or
248
+ // has ever had a runner check in, with their picks, pause, and runners. Three
249
+ // small reads joined here rather than one wide SQL join, so a builder with picks
250
+ // but no runner and one with a runner but no picks both appear.
251
+ async function readAllRunnerScopes() {
252
+ const [scopes, picks, beats] = await Promise.all([
253
+ pool.query('SELECT builder_id, owner_paused, owner_paused_reason, updated_at FROM autonomy_builder_scope'),
254
+ pool.query(
255
+ `SELECT bg.builder_id, bg.goal_id FROM autonomy_builder_goals bg
256
+ JOIN autonomy_allowed_goals ag ON ag.goal_id = bg.goal_id ORDER BY bg.goal_id`
257
+ ),
258
+ // Capped PER BUILDER, at readRunnerHeartbeats' own 20, so one builder's many
259
+ // hosts can never push a quieter builder out of the owner's view.
260
+ pool.query(
261
+ `SELECT builder_id, host, pid, started_at, mode, consecutive_failures, last_event, working_task_id, working_goal_id,
262
+ head, disk_head, main_head, claude_account, last_seen_at
263
+ FROM (SELECT h.*, row_number() OVER (PARTITION BY builder_id ORDER BY last_seen_at DESC) AS rn
264
+ FROM autonomy_runner_heartbeat h) t
265
+ WHERE rn <= 20
266
+ ORDER BY last_seen_at DESC`
267
+ ),
268
+ ]);
269
+ const byId = new Map();
270
+ const entry = (id) => {
271
+ const k = String(id);
272
+ if (!byId.has(k)) byId.set(k, { builder_id: k, goals: [], owner_paused: false, owner_paused_reason: null, runners: [] });
273
+ return byId.get(k);
274
+ };
275
+ for (const s of scopes.rows) Object.assign(entry(s.builder_id), { owner_paused: s.owner_paused === true, owner_paused_reason: s.owner_paused_reason || null });
276
+ for (const p of picks.rows) entry(p.builder_id).goals.push(Number(p.goal_id));
277
+ for (const b of beats.rows) {
278
+ entry(b.builder_id).runners.push({
279
+ ...b, builder_id: undefined,
280
+ working_task_id: b.working_task_id ? String(b.working_task_id) : null,
281
+ working_goal_id: b.working_goal_id ? String(b.working_goal_id) : null,
282
+ });
283
+ }
284
+ const ids = [...byId.keys()];
285
+ if (ids.length) {
286
+ const { rows } = await pool.query('SELECT id, github_login, display_name, rank FROM builders WHERE id = ANY($1::bigint[])', [ids]);
287
+ for (const r of rows) Object.assign(byId.get(String(r.id)), { github_login: r.github_login, display_name: r.display_name, rank: r.rank });
288
+ }
289
+ return [...byId.values()];
290
+ }
291
+
160
292
  // ── the runner heartbeat (task 1003905) ──────────────────────────────────────
161
293
 
162
294
  // recordRunnerHeartbeat — upsert one host's check-in. ON CONFLICT so the normal
@@ -225,4 +357,8 @@ module.exports = {
225
357
  allowGoal,
226
358
  disallowGoal,
227
359
  setPriorityGoal,
360
+ readBuilderScope,
361
+ setBuilderGoals,
362
+ setBuilderPause,
363
+ readAllRunnerScopes,
228
364
  };