@bongos/core 1.24.34 → 1.24.36

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 (99) hide show
  1. package/.bongos-core.json +102 -147
  2. package/.claude/skills/merge-mode/SKILL.md +1 -1
  3. package/docs/adr/0228-the-reading-room-owes-a-reference-content-rules-not-a-second-archetype.md +1 -1
  4. package/docs/copy-inventory.md +136 -192
  5. package/docs/copy-registry.json +186 -752
  6. package/docs/module-api-changelog.md +4 -0
  7. package/docs/onboarding/diagrams/README.md +1 -2
  8. package/docs/onboarding/primer.md +66 -22
  9. package/docs/page-inventory.json +7 -101
  10. package/docs/page-readings.json +947 -1413
  11. package/docs/recipes/ui-look-before-you-ship.md +2 -2
  12. package/modules/design-styles/skills/style/SKILL.md +2 -2
  13. package/modules/hall-ui/public/ai-studio.html +2 -2
  14. package/modules/hall-ui/public/atlas.html +2 -2
  15. package/modules/hall-ui/public/blockers.html +2 -2
  16. package/modules/hall-ui/public/board-room.html +2 -2
  17. package/modules/hall-ui/public/builders.js +8 -6
  18. package/modules/hall-ui/public/city.html +2 -2
  19. package/modules/hall-ui/public/collab.html +2 -2
  20. package/modules/hall-ui/public/commands.html +2 -2
  21. package/modules/hall-ui/public/copy-desk.html +2 -2
  22. package/modules/hall-ui/public/craft-mode.js +1 -1
  23. package/modules/hall-ui/public/deploy.html +2 -2
  24. package/modules/hall-ui/public/diagram-viewer.css +1 -1
  25. package/modules/hall-ui/public/diagram-viewer.js +5 -5
  26. package/modules/hall-ui/public/fleet.html +2 -2
  27. package/modules/hall-ui/public/founding-mark.js +3 -2
  28. package/modules/hall-ui/public/gate.html +2 -2
  29. package/modules/hall-ui/public/goal-map.html +2 -2
  30. package/modules/hall-ui/public/goals.html +2 -2
  31. package/modules/hall-ui/public/government.html +2 -2
  32. package/modules/hall-ui/public/hall-render.js +62 -1
  33. package/modules/hall-ui/public/hall-widgets.js +11 -1
  34. package/modules/hall-ui/public/idea.html +2 -2
  35. package/modules/hall-ui/public/ideas.html +2 -2
  36. package/modules/hall-ui/public/index.html +4 -4
  37. package/modules/hall-ui/public/market-watch-item.html +2 -2
  38. package/modules/hall-ui/public/market-watch-rules.html +2 -2
  39. package/modules/hall-ui/public/market-watch.html +2 -2
  40. package/modules/hall-ui/public/modules.html +2 -2
  41. package/modules/hall-ui/public/my-agents.html +2 -2
  42. package/modules/hall-ui/public/palette.js +15 -0
  43. package/modules/hall-ui/public/primer-live.js +188 -0
  44. package/modules/hall-ui/public/primer.html +11 -6
  45. package/modules/hall-ui/public/primer.js +101 -22
  46. package/modules/hall-ui/public/primer.states.json +54 -7
  47. package/modules/hall-ui/public/profile.html +2 -2
  48. package/modules/hall-ui/public/project-settings.html +2 -2
  49. package/modules/hall-ui/public/roadmap.html +2 -2
  50. package/modules/hall-ui/public/room.css +23 -121
  51. package/modules/hall-ui/public/roster.html +2 -2
  52. package/modules/hall-ui/public/sessions.html +2 -2
  53. package/modules/hall-ui/public/settings.html +2 -2
  54. package/modules/hall-ui/public/shell.js +14 -21
  55. package/modules/hall-ui/public/street.html +2 -2
  56. package/modules/hall-ui/public/studio.html +2 -2
  57. package/modules/hall-ui/public/style.css +8 -55
  58. package/modules/hall-ui/public/task.html +2 -2
  59. package/modules/hall-ui/public/thinking.html +2 -2
  60. package/modules/hall-ui/public/tweak-editor.html +2 -2
  61. package/modules/hall-ui/public/watch.html +2 -2
  62. package/modules/hall-ui/public/work.html +2 -2
  63. package/modules/hall-ui/records/founding-mark.md +4 -4
  64. package/modules/hall-ui/records/reading-rooms.md +2 -0
  65. package/modules/hall-ui/records/reference-room.md +2 -0
  66. package/modules/onboarding/founding-mode.js +6 -2
  67. package/modules/ui-design/kit/render.js +1 -1
  68. package/modules/ui-design/styles/README.md +2 -2
  69. package/package-lock.json +2 -2
  70. package/package.json +1 -1
  71. package/release-notes.json +12 -0
  72. package/scripts/bongos/gen-hall-sitemap.js +15 -2
  73. package/scripts/hall-preview/server.js +6 -11
  74. package/src/bongos/serve-internal.js +28 -37
  75. package/src/module-api.js +1 -1
  76. package/tests/craft_mode_home.mjs +6 -2
  77. package/tests/founding_builders.mjs +6 -5
  78. package/tests/founding_mode.mjs +7 -4
  79. package/tests/hall_board_world.mjs +44 -1
  80. package/tests/hall_fullscreen.mjs +1 -1
  81. package/tests/hall_nav.mjs +24 -7
  82. package/tests/hall_page_gate_map.mjs +14 -5
  83. package/tests/hall_reading_room.mjs +426 -0
  84. package/tests/hall_reading_world.mjs +36 -30
  85. package/tests/hall_sitemap.mjs +25 -0
  86. package/tests/nav_permission_atoms.mjs +3 -2
  87. package/tests/rank_tier_single_source.mjs +0 -1
  88. package/tests/ui_design_kit.mjs +1 -1
  89. package/modules/hall-ui/public/diagrams.css +0 -45
  90. package/modules/hall-ui/public/diagrams.html +0 -106
  91. package/modules/hall-ui/public/diagrams.states.json +0 -28
  92. package/modules/hall-ui/public/drachmae.html +0 -110
  93. package/modules/hall-ui/public/drachmae.js +0 -431
  94. package/modules/hall-ui/public/drachmae.states.json +0 -58
  95. package/modules/hall-ui/public/ranks-founding.states.json +0 -12
  96. package/modules/hall-ui/public/ranks.html +0 -83
  97. package/modules/hall-ui/public/ranks.js +0 -229
  98. package/modules/hall-ui/public/ranks.states.json +0 -15
  99. package/tests/hall_reference_world.mjs +0 -352
@@ -34,7 +34,7 @@ The stub runs the page through the **instance's real transforms** — the apex-o
34
34
  ```
35
35
  node modules/ui-design/kit/render.js --page /projects
36
36
  node modules/ui-design/kit/render.js --page / # MSYS_NO_PATHCONV=1 in Git Bash, or the kit reads the mangled root back
37
- node modules/ui-design/kit/render.js --page /builders/ranks --surface hall-ui
37
+ node modules/ui-design/kit/render.js --page /builders/primer --surface hall-ui
38
38
  node modules/ui-design/kit/render.js --page /projects --only in-map,card --modes dark --sizes 390
39
39
  node modules/ui-design/kit/render.js --page / --style expedition # the same page under a look from the style library
40
40
  ```
@@ -81,7 +81,7 @@ Then a state's own `expect` (a band open, a dialog present, a field's value, a c
81
81
 
82
82
  Actions: `click`, `focus`, `press`, `fill`, `wait`, `clickAt x y`, `clickIfVisible`, `dispatchClick`, `check`, `back`, `forward`. Expectations: `expanded`, `dialog`, `visible[]`, `hidden[]`, `open`, `closed`, `activeId`, `activeText`, `expandedIds[]`, `param{}`, `attr[[sel,name,value]]`, `text[[sel,value]]`, `href[[sel,value]]`, `count[[sel,n]]`, `value[[sel,v]]`, `hasClass[[sel,class,bool]]`, `checked`, `noOverflow`, `top[[sel,px]]` (an element's viewport top — assert it closed, open a band, assert it again: the proof an overlay did not push the page). The kit validates the file before it opens a browser and names every problem.
83
83
 
84
- The worked examples: `modules/public-landing/public/projects.states.json` (the hub's thirteen), `modules/public-landing/public/index.states.json` (the landing's four), `modules/hall-ui/public/ranks.states.json` (a second surface under its own prefix — it renders **red**, deliberately: the hall predates the 24px floor and Ranks has no `<h1>`, and the states file declares the shell's un-fixtured feeds rather than hiding the findings; idea 1000863 carries them).
84
+ The worked examples: `modules/public-landing/public/projects.states.json` (the hub's thirteen), `modules/public-landing/public/index.states.json` (the landing's four), `modules/hall-ui/public/primer.states.json` (a second surface under its own prefix, with a redirected deep link as one of its states; the Ranks page's file that used to be cited here went with that page in task 1005046).
85
85
 
86
86
  ## 3. Probe — the interaction contract, as PASS/FAIL lines
87
87
 
@@ -48,7 +48,7 @@ Read the world first, then look at what the library already has, then ask.
48
48
 
49
49
  ```
50
50
  node modules/ui-design/kit/render.js --page / --style <name>
51
- node modules/ui-design/kit/render.js --page /builders/ranks --surface hall-ui --style <name>
51
+ node modules/ui-design/kit/render.js --page /builders/primer --surface hall-ui --style <name>
52
52
  ```
53
53
 
54
54
  The hall's page is worth the second render because it carries the light tier and the fixed status vocabulary a look must not repaint.
@@ -85,7 +85,7 @@ node modules/ui-design/kit/contrast.js --pack <name> # the p
85
85
  node --test --test-reporter=tap tests/ui_design_styles.mjs # the world / hub / hall suites under the pack
86
86
  node modules/ui-design/kit/check-mock.js --file modules/ui-design/styles/<name>/mock.html --pack <name>
87
87
  node modules/ui-design/kit/render.js --page / --style <name> # every state x width x mode, audited
88
- node modules/ui-design/kit/render.js --page /builders/ranks --surface hall-ui --style <name>
88
+ node modules/ui-design/kit/render.js --page /builders/primer --surface hall-ui --style <name>
89
89
  ```
90
90
 
91
91
  Each round: run, read the **named failing pair** the suite prints, make one change, show the owner the shots. Common failures and their one right fix:
@@ -88,8 +88,8 @@
88
88
 
89
89
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
90
90
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
91
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
92
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
91
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
92
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
93
93
  <script src="/builders/palette.js" defer></script>
94
94
  <script src="/builders/tweak-editor-lib.js?v=2026-09-28-tw23"></script>
95
95
  <script src="/builders/studio-lib.js?v=2026-10-09-day"></script>
@@ -91,8 +91,8 @@
91
91
 
92
92
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
93
93
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
94
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
95
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
94
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
95
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
96
96
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
97
97
  <script src="/builders/palette.js" defer></script>
98
98
  <script src="/builders/atlas.js?v=2026-09-02-index" defer></script>
@@ -60,8 +60,8 @@
60
60
  chrome exists before the page script runs. -->
61
61
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
62
62
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
63
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
64
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
63
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
64
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
65
65
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
66
66
  <script src="/builders/palette.js" defer></script>
67
67
  <!-- the branding pack's currency label, loaded BEFORE blockers.js. -->
@@ -62,8 +62,8 @@
62
62
 
63
63
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
64
64
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
65
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
66
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
65
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
66
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
67
67
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
68
68
  <script src="/builders/palette.js" defer></script>
69
69
  <script src="/builders/hall-kit.js"></script>
@@ -148,19 +148,20 @@
148
148
  // Coerce any rank that isn't one of the four live ranks (archon/metic/thetes/
149
149
  // xenos — #692 / ADR 0034) to the entry rank. Reserved values still on the
150
150
  // citizen/divine ladder would otherwise render as a dashed "unknown" plaque
151
- // while /builders/ranks shows them as xenos. Applied to the
151
+ // while the hall elsewhere shows them as xenos. Applied to the
152
152
  // builder-facing standing surfaces — the welcome panel, the profile Standing
153
153
  // badge, and the public Roll — so they agree. NOT applied to the Archon-only
154
154
  // roster below, which intentionally shows the true stored rank so an Archon
155
- // can spot and fix a stray value. Mirrors the RANK_LADDER coercion in ranks.js.
155
+ // can spot and fix a stray value. hall-render.js's "Where you stand" card
156
+ // (task 1005046, from the retired Ranks page) coerces through this too.
156
157
  function normalizeRank(rank) {
157
158
  return RANK_ORDER[rank] ? rank : 'xenos';
158
159
  }
159
160
 
160
161
  // Short one-line summary of what each rank unlocks. Kept terse — the hall's
161
162
  // job is the daily action surface, not the full permissions reference (that
162
- // lives at /builders/ranks). Sourced from docs/canonical-permissions.md.
163
- // Used by the rank-badge hover tooltip (opts.tip) and mirrored in ranks.js.
163
+ // is the Primer's rank-ladder chapter). Sourced from docs/canonical-permissions.md.
164
+ // Used by the rank-badge hover tooltip (opts.tip).
164
165
 
165
166
  // Monotonic counter for unique tooltip ids (aria-describedby). Re-renders
166
167
  // replace innerHTML so duplicates would otherwise collide.
@@ -798,9 +799,10 @@
798
799
  // removed. work.js carries the equivalent rendering for that page.
799
800
 
800
801
  // (task 2174: the red-team bounty rate card — V3.R65 #284 — left Standing for
801
- // /drachmae. It is a published reward SCHEDULE, i.e. reference material that
802
+ // the reference. It is a published reward SCHEDULE, i.e. reference material that
802
803
  // reads the same for every builder, not part of anyone's personal standing.
803
- // drachmae.js now fetches /public/bounty-table and renders it there.)
804
+ // primer-live.js fetches /public/bounty-table and renders it in the Primer's
805
+ // credits chapter since task 1005046 folded the Economy page into it.)
804
806
 
805
807
  // ---- idea-inbox triage cue (task 1471) -----------------------------------
806
808
 
@@ -107,8 +107,8 @@
107
107
 
108
108
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
109
109
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab" defer></script>
110
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch" defer></script>
111
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch" defer></script>
110
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room" defer></script>
111
+ <script src="/builders/shell.js?v=2026-11-04-reading-room" defer></script>
112
112
  <script src="/builders/palette.js" defer></script>
113
113
  <script src="/builders/gov-living.js?v=2026-10-09-positions1" defer></script>
114
114
  <script src="/builders/gov-feeds.js?v=2026-10-09-living3" defer></script>
@@ -161,8 +161,8 @@
161
161
 
162
162
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
163
163
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
164
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
165
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
164
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
165
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
166
166
  <script src="/builders/palette.js" defer></script>
167
167
  <script src="/builders/collab-lib.js?v=2026-09-24-archive"></script>
168
168
  <script src="/builders/collab.js?v=2026-09-24-archive"></script>
@@ -53,8 +53,8 @@
53
53
 
54
54
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
55
55
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
56
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
57
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
56
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
57
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
58
58
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
59
59
  <script src="/builders/palette.js" defer></script>
60
60
  <script src="/builders/hall-kit.js"></script>
@@ -179,8 +179,8 @@
179
179
 
180
180
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
181
181
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
182
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
183
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
182
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
183
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
184
184
  <script src="/builders/palette.js" defer></script>
185
185
  <script src="/builders/hall-kit.js"></script>
186
186
  <script src="/builders/copy-desk.js?v=2026-09-01-redesign"></script>
@@ -103,7 +103,7 @@
103
103
  var MODE_TABS = {
104
104
  building: ['home', 'roadmap', 'goals', 'goal-map', 'work', 'blockers', 'thinking', 'studio',
105
105
  'standing',
106
- 'primer', 'ranks', 'economy', 'commands', 'diagrams', 'atlas', 'modules', 'apidocs', 'market-watch'],
106
+ 'primer', 'commands', 'atlas', 'modules', 'apidocs', 'market-watch'],
107
107
  artistry: ['studio', 'goals', 'thinking'],
108
108
  ideating: ['goal-map', 'thinking', 'goals', 'market-watch'],
109
109
  governing: ['city', 'blockers', 'board-room',
@@ -80,8 +80,8 @@
80
80
 
81
81
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
82
82
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
83
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
84
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
83
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
84
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
85
85
  <script src="/builders/palette.js" defer></script>
86
86
  <script src="/builders/hall-kit.js"></script>
87
87
  <!-- the shared ask card the move is drawn with (task 1004829) -->
@@ -1,6 +1,6 @@
1
1
  /* diagram-viewer.css — pannable / zoomable canvas for the onboarding diagrams
2
2
  (task 1059; rebuilt into the chrome world by task 1003306). Replaces the
3
- static PNG click-to-zoom lightbox on /builders/diagrams and the primer: each
3
+ static PNG click-to-zoom lightbox in the primer: each
4
4
  diagram's vector SVG loads inline into a canvas you DRAG to pan and SCROLL to
5
5
  zoom (Figma-style), with a toolbar and a fullscreen mode.
6
6
 
@@ -1,13 +1,13 @@
1
1
  // diagram-viewer.js — pannable / zoomable canvas for the onboarding diagrams
2
- // (task 1059). Replaces the static PNG click-to-zoom lightbox on
3
- // /builders/diagrams and the Citizen's Primer. Each diagram's vector SVG is
2
+ // (task 1059). Replaces the static PNG click-to-zoom lightbox in the Citizen's
3
+ // Primer, which shows all five since task 1005046 folded the Diagrams page into it. Each diagram's vector SVG is
4
4
  // loaded inline and shown in a canvas you DRAG to pan and SCROLL to zoom
5
5
  // (Figma-style), with a toolbar (− / zoom% / + / Fit / Fullscreen),
6
6
  // double-click-to-zoom, pinch on touch, and keyboard control. No dependencies,
7
7
  // no build step.
8
8
  //
9
9
  // Progressive enhancement: it upgrades the same images the old lightbox did
10
- // (figure.diagram img, figure.primer-figure img). Each diagram's vector .svg
10
+ // (figure.primer-figure img). Each diagram's vector .svg
11
11
  // URL is derived from the <img> .png src; if the SVG can't be fetched the PNG
12
12
  // is left in place (static, exactly as before — graceful degradation). primer.js
13
13
  // injects its figures asynchronously, so a MutationObserver upgrades late
@@ -16,7 +16,7 @@
16
16
  (() => {
17
17
  'use strict';
18
18
 
19
- const SELECTOR = 'figure.diagram img, figure.primer-figure img';
19
+ const SELECTOR = 'figure.primer-figure img';
20
20
  const MIN_SCALE = 0.1;
21
21
  const MAX_SCALE = 8;
22
22
  const ZOOM_STEP = 1.25; // button / keyboard zoom factor
@@ -63,7 +63,7 @@
63
63
 
64
64
  // Namespace the SVG's ids. mermaid-cli emits id="my-svg" PLUS #my-svg style
65
65
  // selectors PLUS url(#my-svg_...) arrowhead markers for EVERY diagram, so
66
- // multiple inline diagrams on one page (the diagrams index has five) would
66
+ // multiple inline diagrams on one page (the primer has five) would
67
67
  // collide. One token rewrite keeps the id, its styles, and its marker refs
68
68
  // mutually consistent while making them unique. ("my-svg" never appears in
69
69
  // the diagrams' label text, so this is safe.)
@@ -59,8 +59,8 @@
59
59
 
60
60
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
61
61
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
62
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
63
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
62
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
63
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
64
64
  <script src="/builders/palette.js" defer></script>
65
65
  <script src="/builders/hall-kit.js"></script>
66
66
  <script src="/builders/fleet-costs.js"></script>
@@ -4,8 +4,9 @@
4
4
  // genesis, numbered in join order; the project owner is "founder". The server works
5
5
  // that out (modules/onboarding/founding-builders.js, GET /api/bongos/founding/builders);
6
6
  // this file only shows it, in the hall's own badge grammar: a pill the height and type
7
- // of .rank-badge, with a seed dot in the accent. Four surfaces read it — the roster,
8
- // the profile, the ranks page and the founding wall on Home — and each one renders
7
+ // of .rank-badge, with a seed dot in the accent. Three surfaces read it — the roster,
8
+ // the profile and the founding wall on Home (the ranks page's ledger went with that
9
+ // page, task 1005046) — and each one renders
9
10
  // exactly as before when the list is empty, which it is on every project that was
10
11
  // never founded (the blend rule: founding is a mode the hall wears, never a re-skin).
11
12
  //
@@ -66,8 +66,8 @@
66
66
 
67
67
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
68
68
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
69
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
70
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
69
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
70
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
71
71
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
72
72
  <script src="/builders/palette.js" defer></script>
73
73
  <script src="/builders/hall-kit.js"></script>
@@ -139,8 +139,8 @@
139
139
 
140
140
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
141
141
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
142
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
143
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
142
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
143
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
144
144
  <script src="/builders/palette.js" defer></script>
145
145
 
146
146
  <script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
@@ -243,8 +243,8 @@
243
243
 
244
244
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
245
245
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
246
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
247
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
246
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
247
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
248
248
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
249
249
  <script src="/builders/palette.js" defer></script>
250
250
  <!-- task 1004727: the ONE karma vote control every task/idea list renders -->
@@ -156,8 +156,8 @@
156
156
 
157
157
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
158
158
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
159
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
160
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
159
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
160
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
161
161
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
162
162
  <script src="/builders/palette.js" defer></script>
163
163
  <script src="/builders/hall-kit.js"></script>
@@ -49,6 +49,66 @@
49
49
  };
50
50
  let rankTipSeq = 0;
51
51
 
52
+ // "Where you stand" (task 1005046): the personal half of the retired Ranks
53
+ // page, now a card on Accomplishments. The ladder itself — every rank and what
54
+ // it unlocks — is the Primer's rank-ladder chapter, written once; this card
55
+ // says only what is true for the VIEWER: their rank, what it is, the rank
56
+ // above, and how they reach it. Moved from ranks.js with the page.
57
+ const RANK_TITLE = {
58
+ xenos: 'The newcomer',
59
+ thetes: 'The proven builder',
60
+ metic: 'The trusted builder',
61
+ archon: 'The steward',
62
+ };
63
+ const RANK_BLURB = {
64
+ xenos: 'A newcomer with a deliberately small surface: onboarding, safe starter tasks, and your own standing.',
65
+ thetes: 'A builder who has shipped their first work — the day-to-day surfaces are open.',
66
+ metic: 'A trusted builder: triage, reviews, planning sessions, and security reporting are open.',
67
+ archon: 'The steward of the whole system — approvals, the roster, budgets, and the Archon pages.',
68
+ };
69
+ // How a builder rises FROM their current rank. NB: these strings contain
70
+ // markup (<strong>) and are injected via innerHTML without escaping, which is
71
+ // safe only because they are author-controlled constants. Never source them
72
+ // from server or user data without switching the render site to escapeHtml.
73
+ const RISE_FROM = {
74
+ xenos:
75
+ `Claim and ship the newcomer-friendly tasks an Archon has opened to newcomers. Each clean ship earns ${curLabel()}; each ratified idea earns karma. On your <strong>third</strong> clean ship you are promoted automatically to <strong>Thetes</strong>, out of the newcomer sandbox with the whole queue open to you. No fee, no application; the third ship does it.`,
76
+ thetes:
77
+ 'You have the run of the queue. Promotion to <strong>Metic</strong> (triage, blockers, planning, the shaping of work) is granted by a standing Archon alone, to a builder whose judgement has earned the project’s trust. Keep shipping; rank is granted, never bought.',
78
+ metic:
79
+ 'The <strong>Archon</strong> rank is granted rarely, by a standing Archon alone, to a Metic who has shaped the project’s direction and earned its deepest trust. There is no checklist, only the weight of what you have built.',
80
+ archon:
81
+ 'You hold the highest rank. There is no rank above it, only the care of everything below.',
82
+ };
83
+ // The rank one rung up, read off the injected tier map rather than a second
84
+ // copy of the ladder (tests/rank_tier_single_source.mjs).
85
+ function nextRank(rank) {
86
+ const want = (RANK_ORDER[rank] || 0) + 1;
87
+ return Object.keys(RANK_ORDER).find((r) => RANK_ORDER[r] === want) || null;
88
+ }
89
+ // Intentionally not on the factory's return object: renderProfile is its one
90
+ // caller, so it repaints whenever the band does, from the same /me payload.
91
+ function renderRankStanding(builder) {
92
+ const host = document.getElementById('rank-standing-body');
93
+ if (!host) return;
94
+ const rank = normalizeRank(builder && builder.rank);
95
+ const next = nextRank(rank);
96
+ // At the top there is no rung to name; RISE_FROM says so in its own words,
97
+ // so the line is left out rather than said twice.
98
+ const nextLine = next
99
+ ? `<p class="ranks-standing__next">The rank above yours is ${renderRankBadge(next)}.</p>`
100
+ : '';
101
+ host.innerHTML = `
102
+ <div class="ranks-standing">
103
+ <div class="ranks-standing__badge">${renderRankBadge(rank)}</div>
104
+ <p class="ranks-standing__title">${escapeHtml(RANK_TITLE[rank] || rankLabel(rank))}</p>
105
+ <p class="ranks-standing__blurb">${escapeHtml(RANK_BLURB[rank] || '')}</p>
106
+ ${nextLine}
107
+ </div>
108
+ <p class="ranks-rise__body">${RISE_FROM[rank] || RISE_FROM.xenos}</p>
109
+ <p class="card-foot"><a href="/primer#the-rank-ladder">Every rank and what it unlocks, in the Primer →</a></p>`;
110
+ }
111
+
52
112
  function renderRankBadge(rank, opts = {}) {
53
113
  const label = escapeHtml(rankLabel(rank));
54
114
  const ariaLabel = rank ? `Rank: ${rankLabel(rank)}` : 'Rank not yet recorded';
@@ -75,7 +135,7 @@
75
135
  const items = RANK_UNLOCKS[rank].map((u) => `<li>${escapeHtml(u)}</li>`).join('');
76
136
  return `<span class="rank-badge-wrap">` +
77
137
  `<span class="rank-badge ${variant} rank-badge--tipped" aria-hidden="true">${label}</span>` +
78
- `<a class="rank-badge-stretch" href="/ranks" ` +
138
+ `<a class="rank-badge-stretch" href="/primer#the-rank-ladder" ` +
79
139
  `aria-describedby="${tipId}" ` +
80
140
  `aria-label="${escapeHtml(ariaLabel)} — see all standings"></a>` +
81
141
  `<span class="rank-tip" id="${tipId}" role="tooltip">` +
@@ -618,6 +678,7 @@
618
678
  // hover it widens left to show the name while .hall-standing__more drops down.
619
679
  const standingChip = document.getElementById('hall-standing');
620
680
  if (standingChip && !ctx.newcomerGated) standingChip.hidden = false;
681
+ renderRankStanding(builder);
621
682
  renderSystemNotices({ rebaseTasks, need, actionNeeds, cost });
622
683
  }
623
684
 
@@ -16,7 +16,8 @@
16
16
  // by question": the Profile card is the band, and every other Standing widget
17
17
  // declares the `group` that answers its question. Achievements folded in from the
18
18
  // retired #achievements hash view; the security-bounty rate card moved off Standing
19
- // to /drachmae (a reward schedule is reference material, not personal standing).
19
+ // to the reference (a reward schedule is not personal standing) — the Primer's
20
+ // credits chapter since task 1005046, which folded the Economy page into it.
20
21
  //
21
22
  // Each widget owns its skeleton markup. mount(host) stamps that skeleton into the
22
23
  // registry-made <section>; builders.js then wires data to the same element ids it
@@ -176,6 +177,15 @@
176
177
 
177
178
  /* -- Progress — how the output has changed over time -- */
178
179
 
180
+ // 4c. Where you stand (task 1005046) — the viewer's rank, the rank above it
181
+ // and how they reach it, moved here from the retired Ranks page. Filled by
182
+ // hall-render.js renderRankStanding from the same /me payload as the band;
183
+ // the ladder itself is the Primer's rank-ladder chapter.
184
+ w('rank-scroll', 'Where you stand', 48,
185
+ '<h2 id="rank-standing-h" class="scroll__h">Where you stand</h2>' +
186
+ '<div id="rank-standing-body"><div class="hall-loading" role="status">Loading…</div></div>',
187
+ { view: 'standing', group: 'progress', labelledby: 'rank-standing-h' });
188
+
179
189
  // 5. CURVE — the builder's development curve (V3.R72 #291, C5).
180
190
  w('analytics-scroll', 'Progress', 50,
181
191
  '<h2 id="curve-h" class="scroll__h">Progress</h2>' +
@@ -52,8 +52,8 @@
52
52
 
53
53
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
54
54
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
55
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
56
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
55
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
56
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
57
57
  <script src="/builders/palette.js" defer></script>
58
58
  <!-- task-detail.js still owns the #/idea/N and #/blocker/N overlay, so a ref
59
59
  written inside an idea's own prose keeps resolving from this page. -->
@@ -227,8 +227,8 @@
227
227
 
228
228
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
229
229
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
230
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
231
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
230
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
231
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
232
232
  <script src="/builders/palette.js" defer></script>
233
233
  <!-- task 1004727: the ONE karma vote control every task/idea list renders -->
234
234
  <script src="/builders/vote-control.js"></script>
@@ -122,8 +122,8 @@
122
122
  before the craft picker so the two never stack. Home only. -->
123
123
  <script src="/builders/welcome-boot.js?v=2026-10-23-city1" defer></script>
124
124
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab" defer></script>
125
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch" defer></script>
126
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch" defer></script>
125
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room" defer></script>
126
+ <script src="/builders/shell.js?v=2026-11-04-reading-room" defer></script>
127
127
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
128
128
  <script src="/builders/palette.js" defer></script>
129
129
  <!-- task 2166: the shared component kit (window.OTBKit) — pager/ledger/rail.
@@ -137,7 +137,7 @@
137
137
  immediately before the builders.js tag below — that anchor is load-bearing
138
138
  (serve-internal.js injectModuleHallWidgets). -->
139
139
  <script src="/builders/founding-mark.js?v=2026-09-30-founding" defer></script>
140
- <script src="/builders/hall-widgets.js?v=2026-09-30-founding" defer></script>
140
+ <script src="/builders/hall-widgets.js?v=2026-11-04-reading-room" defer></script>
141
141
  <!-- The genesis home (task 1004423): a Home banner card that renders only in founding mode. -->
142
142
  <script src="/builders/genesis-home.js?v=2026-10-01-genesis" defer></script>
143
143
  <!-- task 1005054: the project city — the drawing (pure) and the widget — in the
@@ -160,7 +160,7 @@
160
160
  window.OTBHallRender(ctx) once during its own setup. The module
161
161
  hall-widget tags the server injects still anchor on builders.js's tag
162
162
  below (it matches by filename), so they land between the two. -->
163
- <script src="/builders/hall-render.js?v=2026-10-09-positions1" defer></script>
163
+ <script src="/builders/hall-render.js?v=2026-11-04-reading-room-2" defer></script>
164
164
  <!-- task 1002802 (P06): the profile-completion nudge slice. Exposes
165
165
  window.OTBProfileNudge; goal-inbox.js's mount() calls it once it has
166
166
  created the #attention-profile div, so load order is not load-bearing. -->
@@ -73,8 +73,8 @@
73
73
 
74
74
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
75
75
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
76
- <script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
77
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
76
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
77
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
78
78
  <script src="/builders/palette.js" defer></script>
79
79
  <script src="/builders/hall-kit.js"></script>
80
80
  <script src="/builders/market-watch-lib.js"></script>
@@ -42,8 +42,8 @@
42
42
 
43
43
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
44
44
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
45
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
46
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
45
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
46
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
47
47
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
48
48
  <script src="/builders/palette.js" defer></script>
49
49
  <script src="/builders/hall-kit.js"></script>
@@ -187,8 +187,8 @@
187
187
 
188
188
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
189
189
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
190
- <script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
191
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
190
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
191
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
192
192
  <script src="/builders/palette.js" defer></script>
193
193
  <script src="/builders/hall-kit.js"></script>
194
194
  <script src="/builders/market-watch-lib.js"></script>
@@ -127,8 +127,8 @@
127
127
 
128
128
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
129
129
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
130
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
131
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
130
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
131
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
132
132
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
133
133
  <script src="/builders/palette.js" defer></script>
134
134
  <script src="/builders/brand-apply.js"></script>
@@ -83,8 +83,8 @@
83
83
 
84
84
  <script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
85
85
  <script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
86
- <script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
87
- <script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
86
+ <script src="/builders/craft-mode.js?v=2026-11-04-reading-room"></script>
87
+ <script src="/builders/shell.js?v=2026-11-04-reading-room"></script>
88
88
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
89
89
  <script src="/builders/palette.js" defer></script>
90
90
  <script src="/builders/gov-living.js?v=2026-10-10-real1"></script>
@@ -54,6 +54,7 @@
54
54
  // government → government.js makeTabs ids (two rooms since ADR 0266)
55
55
  // settings → settings.js RAIL_GROUPS
56
56
  // my-agents → my-agents.js ANCHORS (the agent settings left Settings, task 1005044)
57
+ // primer → primer.md's h2 slugs + primer-live.js SECTIONS (task 1005046)
57
58
  var SECTIONS = [
58
59
  { parent: 'Accomplishments', gate: 'nav-standing', items: [
59
60
  { label: 'Work', href: '/#accomplishments-work' },
@@ -82,6 +83,20 @@
82
83
  { label: 'Skill voices', href: '/my-agents#skills' },
83
84
  { label: 'What it knows', href: '/my-agents#knows' },
84
85
  ] },
86
+ // task 1005046: the Primer is the one reading room, so the rank ladder, the
87
+ // economy and the diagrams that had pages of their own are its chapters
88
+ // now. Each row is a chapter's h2 slug (md-reader.js slugify over
89
+ // docs/onboarding/primer.md) or one of the credits chapter's live sections
90
+ // (primer-live.js SECTIONS); 'Economy' rides the label so the word a
91
+ // builder used to type still finds the place.
92
+ { parent: 'Primer', gate: 'nav-primer', items: [
93
+ { label: 'Task lifecycle', href: '/primer#the-claim-ship-lifecycle' },
94
+ { label: 'Rank ladder', href: '/primer#the-rank-ladder' },
95
+ { label: 'Credits and karma (Economy)', href: '/primer#credits-and-karma' },
96
+ { label: 'Treasury', href: '/primer#the-treasury' },
97
+ { label: 'Security bounty rates', href: '/primer#security-bounty-rates' },
98
+ { label: 'Versions', href: '/primer#how-versions-organise-the-work' },
99
+ ] },
85
100
  { parent: 'Settings', gate: 'shell-user', items: [
86
101
  { label: 'Account', href: '/settings#account' },
87
102
  { label: 'Access', href: '/settings#access' },