@bongos/core 1.19.444 → 1.19.446

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 (63) hide show
  1. package/.bongos-core.json +154 -49
  2. package/docs/adr/0054-session-token-reward-cost-plus.md +17 -0
  3. package/docs/copy-inventory.md +353 -352
  4. package/docs/copy-registry.json +397 -388
  5. package/docs/design/hall-direction-v2.md +295 -0
  6. package/docs/design/mocks/hall/_tokens.css +370 -0
  7. package/docs/design/mocks/hall/board/v1.html +846 -0
  8. package/docs/design/mocks/hall/board/v2.html +858 -0
  9. package/docs/design/mocks/hall/board/v3.html +884 -0
  10. package/docs/design/mocks/hall/goals/v1.html +1212 -0
  11. package/docs/design/mocks/hall/goals/v2.html +1192 -0
  12. package/docs/design/mocks/hall/goals/v3.html +1205 -0
  13. package/docs/design/mocks/hall/hall-sheet.html +244 -0
  14. package/docs/design/mocks/hall/reading/v1.html +1125 -0
  15. package/docs/design/mocks/hall/reading/v2.html +1177 -0
  16. package/docs/design/mocks/hall/reading/v3.html +1150 -0
  17. package/docs/design/mocks/hall/settings/v1.html +1238 -0
  18. package/docs/design/mocks/hall/settings/v2.html +1235 -0
  19. package/docs/design/mocks/hall/settings/v3.html +1299 -0
  20. package/docs/design/mocks/hall/task/v1.html +637 -0
  21. package/docs/design/mocks/hall/task/v2.html +646 -0
  22. package/docs/design/mocks/hall/task/v3.html +651 -0
  23. package/docs/design/vanilla-hall-ui-redesign-scope.md +2 -0
  24. package/docs/module-api-changelog.md +4 -0
  25. package/modules/economy/credits.js +46 -13
  26. package/modules/hall-ui/public/atlas.html +1 -2
  27. package/modules/hall-ui/public/collab.html +1 -2
  28. package/modules/hall-ui/public/copy-desk.css +11 -11
  29. package/modules/hall-ui/public/copy-desk.html +1 -2
  30. package/modules/hall-ui/public/diagrams.html +1 -2
  31. package/modules/hall-ui/public/drachmae.html +1 -2
  32. package/modules/hall-ui/public/gate.html +1 -2
  33. package/modules/hall-ui/public/goals.html +1 -2
  34. package/modules/hall-ui/public/government.html +1 -2
  35. package/modules/hall-ui/public/harbor.html +1 -2
  36. package/modules/hall-ui/public/idea.html +1 -2
  37. package/modules/hall-ui/public/ideas.css +6 -8
  38. package/modules/hall-ui/public/ideas.html +1 -2
  39. package/modules/hall-ui/public/index.html +3 -4
  40. package/modules/hall-ui/public/modules.html +1 -2
  41. package/modules/hall-ui/public/my-projects.html +1 -2
  42. package/modules/hall-ui/public/not-ready.html +1 -2
  43. package/modules/hall-ui/public/pair.html +1 -2
  44. package/modules/hall-ui/public/people.html +1 -2
  45. package/modules/hall-ui/public/primer.html +1 -2
  46. package/modules/hall-ui/public/profile.html +1 -2
  47. package/modules/hall-ui/public/ranks.html +1 -2
  48. package/modules/hall-ui/public/roadmap.html +1 -2
  49. package/modules/hall-ui/public/scouting.html +1 -2
  50. package/modules/hall-ui/public/sessions.html +1 -2
  51. package/modules/hall-ui/public/settings.html +1 -2
  52. package/modules/hall-ui/public/shell.js +35 -2
  53. package/modules/hall-ui/public/style.css +818 -392
  54. package/modules/hall-ui/public/task.html +1 -2
  55. package/modules/hall-ui/public/watch.css +1 -1
  56. package/modules/hall-ui/public/watch.html +1 -2
  57. package/modules/hall-ui/public/work.html +1 -2
  58. package/package-lock.json +2 -2
  59. package/package.json +1 -1
  60. package/scripts/gds/backfill-subagent-rewards.js +485 -0
  61. package/src/module-api.js +1 -1
  62. package/tests/backfill_subagent_rewards.mjs +308 -0
  63. package/tests/hall_tokens.mjs +371 -0
@@ -6,6 +6,8 @@
6
6
 
7
7
  **Status:** scope for hand-off. Owner to seed tasks from §12–§14.
8
8
 
9
+ > **The LOOK below is superseded by [`hall-direction-v2.md`](hall-direction-v2.md)** (task 1003302, goal 1000081, 2026-08-30), which composed the hall into the chrome world `DESIGN.md` records. Everything else here still stands and was deliberately not reopened by that round: the information architecture, the component taxonomy (§9), the sizing and responsive system (§10), the voice neutralization (§11) and the implementation seams (§13). Where this document describes colour, typography or visual treatment, read `hall-direction-v2.md` instead.
10
+
9
11
  **Visual companion:** the annotated wireframes for every surface below are rendered as an interactive artifact — [Cloud Bongos — Vanilla UI Redesign Scope](https://claude.ai/code/artifact/b6992395-ff5b-4356-8acb-99908a574aa8).
10
12
 
11
13
  **Locked decisions (owner, 2026-07-02):**
@@ -1325,5 +1325,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
1325
1325
  landed since 1.19.442 with no explicit bump. run 33330337830. (task 1002620)
1326
1326
  1.19.444 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1327
1327
  landed since 1.19.443 with no explicit bump. run 33334908383. (task 1002620)
1328
+ 1.19.445 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1329
+ landed since 1.19.444 with no explicit bump. run 33337122866. (task 1002620)
1330
+ 1.19.446 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1331
+ landed since 1.19.445 with no explicit bump. run 33341626697. (task 1002620)
1328
1332
  ---------------------------------------------------------------------------
1329
1333
  ```
@@ -605,24 +605,56 @@ async function awardIdeaTaskShipCredit(client, { taskId, config = rewardConfig()
605
605
  // nothing was owed this time; `settled` says why — 'up_to_date' (already paid in
606
606
  // full, the ordinary idempotent case) or 'legacy' (a row predating reward_basis,
607
607
  // deliberately left for a signed-off backfill rather than paid out on deploy).
608
- async function awardSessionTokenReward(client, builderId, sessionId, modelUsage, totalTokens = 0) {
608
+ // sessionTrueCostUsd — what one session's stored usage is worth in USD, by the
609
+ // SAME rule the reward books from. Pure, exported, and the single definition:
610
+ // carved out of awardSessionTokenReward (task 1003436) so a backfill can ask
611
+ // "what is this session worth" without re-deriving the formula and drifting from
612
+ // what actually paid.
613
+ //
614
+ // Cost-plus zero-out fallback (task 1676). priceModelUsage returns $0 when
615
+ // model_usage is empty or carries no token counts — the exact dev-box/CI symptom
616
+ // ADR 0097 records ("upload no priced model usage"). When that happens but the
617
+ // session DID carry real tokens, price the total at the opus rate so the reward
618
+ // reflects the real spend instead of silently rounding to 0. The blend assumes a
619
+ // marathon agent session is cache_read-dominated (the real cost driver — a large
620
+ // context re-read each turn), so this conservatively UNDER-estimates rather than
621
+ // over-pays vs. a true per-tier split.
622
+ function sessionTrueCostUsd(modelUsage, totalTokens = 0) {
609
623
  const { true_cost_usd: pricedCostUsd, unknown_models: unknownModels } =
610
624
  priceModelUsage(modelUsage);
611
- // Cost-plus zero-out fallback (task 1676). priceModelUsage returns $0 when
612
- // model_usage is empty or carries no token counts — the exact dev-box/CI symptom
613
- // ADR 0097 records ("upload no priced model usage"). When that happens but the
614
- // session DID carry real tokens, price the total at the opus rate so the reward
615
- // reflects the real spend instead of silently rounding to 0. The blend assumes a
616
- // marathon agent session is cache_read-dominated (the real cost driver — a large
617
- // context re-read each turn), so this conservatively UNDER-estimates rather than
618
- // over-pays vs. a true per-tier split.
619
- let trueCostUsd = pricedCostUsd;
620
- let pricedFromTotalTokens = false;
621
625
  const tt = Math.max(0, Math.trunc(Number(totalTokens) || 0));
622
626
  if (!(pricedCostUsd > 0) && tt > 0) {
623
- trueCostUsd = Math.round(((tt * PRICES.opus.cache_read) / 1e6) * 10000) / 10000;
624
- pricedFromTotalTokens = true;
627
+ return {
628
+ trueCostUsd: Math.round(((tt * PRICES.opus.cache_read) / 1e6) * 10000) / 10000,
629
+ unknownModels,
630
+ pricedFromTotalTokens: true,
631
+ };
625
632
  }
633
+ return { trueCostUsd: pricedCostUsd, unknownModels, pricedFromTotalTokens: false };
634
+ }
635
+
636
+ // extraCostUsd (task 1003436) — real, already-ledgered cost this session incurred
637
+ // that `modelUsage` cannot express. It exists for exactly one caller: the
638
+ // subagent-reward backfill, which recovers a pre-fix session's subagent leg from
639
+ // its `session:subagent` cost_log row (the transcripts that would prove it live
640
+ // only on builders' machines). Defaults to 0, so every existing call site is
641
+ // unchanged. Routing the backfill through THIS function rather than its own
642
+ // INSERT is deliberate: the watermark, the legacy guard, the no-clawback rule and
643
+ // the (session_id, reward_basis) uniqueness all keep applying, so a backfill row
644
+ // is just a top-up at a higher basis and a later ship still books only its own
645
+ // increment.
646
+ async function awardSessionTokenReward(
647
+ client, builderId, sessionId, modelUsage, totalTokens = 0, extraCostUsd = 0
648
+ ) {
649
+ const {
650
+ trueCostUsd: pricedCostUsd, unknownModels, pricedFromTotalTokens,
651
+ } = sessionTrueCostUsd(modelUsage, totalTokens);
652
+ // Finite + non-negative. Infinity would otherwise survive `Number(x) || 0` and
653
+ // turn a top-up into an unbounded mint; the only caller reads a trusted
654
+ // cost_log column, but this is the payout path and the guard is one line.
655
+ const extraRaw = Number(extraCostUsd);
656
+ const extra = Number.isFinite(extraRaw) ? Math.max(0, extraRaw) : 0;
657
+ const trueCostUsd = Math.round((pricedCostUsd + extra) * 10000) / 10000;
626
658
  const { marginPct, usdPeg } = rewardConfig();
627
659
  const { drachmae, description } = computeSessionTokenReward(trueCostUsd, marginPct, usdPeg);
628
660
 
@@ -786,6 +818,7 @@ module.exports = {
786
818
  rewardPolicy,
787
819
  rewardConfig,
788
820
  computeSessionTokenReward,
821
+ sessionTrueCostUsd,
789
822
  applyKindMultiplier,
790
823
  insertMultipliedConfirmCredit,
791
824
  maybeAwardIdeaPromotionBonus,
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='25' font-size='26' text-anchor='middle'>🪘</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/atlas.css">
14
13
  </head>
@@ -20,7 +19,7 @@
20
19
  <div class="app-body">
21
20
  <header class="app-topbar" id="app-topbar"></header>
22
21
  <div class="app-content">
23
- <main>
22
+ <main id="hall-main">
24
23
  <!-- The atlas chrome rides the hall tokens (pack + dark aware, task 1737);
25
24
  only the semantic node/edge palette stays instance-independent so a
26
25
  pack can never scramble the map's color-coded meaning (ADR 0094). -->
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/collab.css">
14
13
  </head>
@@ -24,7 +23,7 @@
24
23
  <p class="page-head__sub" id="cb-sub">Loading…</p>
25
24
  </div>
26
25
 
27
- <main>
26
+ <main id="hall-main">
28
27
  <!-- ASKED OF YOU comes first: it is the half where someone is waiting on a
29
28
  human. Your own asks are below, because they are a status check, not a
30
29
  call to act. -->
@@ -17,9 +17,9 @@
17
17
  flex-direction: column;
18
18
  gap: 0.15rem;
19
19
  padding: 0.75rem 0.9rem;
20
- border: 1px solid var(--line, rgba(255, 255, 255, 0.12));
20
+ border: 1px solid var(--rule-soft);
21
21
  border-radius: 0.5rem;
22
- background: var(--panel, rgba(255, 255, 255, 0.03));
22
+ background: var(--surface-2);
23
23
  }
24
24
  .cd-stat__n { font-size: 1.6rem; font-weight: 700; line-height: 1.1; }
25
25
  .cd-stat__l { font-size: 0.8rem; opacity: 0.7; }
@@ -28,7 +28,7 @@
28
28
  .cd-note code {
29
29
  padding: 0.05rem 0.3rem;
30
30
  border-radius: 0.25rem;
31
- background: var(--panel, rgba(255, 255, 255, 0.06));
31
+ background: var(--surface-2);
32
32
  font-size: 0.95em;
33
33
  }
34
34
 
@@ -40,9 +40,9 @@
40
40
  .cd-dialog__input,
41
41
  .cd-dialog__text {
42
42
  padding: 0.4rem 0.6rem;
43
- border: 1px solid var(--line, rgba(255, 255, 255, 0.15));
43
+ border: 1px solid var(--rule-soft);
44
44
  border-radius: 0.35rem;
45
- background: var(--panel, rgba(0, 0, 0, 0.2));
45
+ background: var(--bg-deep);
46
46
  color: inherit;
47
47
  font: inherit;
48
48
  }
@@ -56,9 +56,9 @@
56
56
 
57
57
  .cd-card {
58
58
  padding: 0.85rem 1rem;
59
- border: 1px solid var(--line, rgba(255, 255, 255, 0.12));
59
+ border: 1px solid var(--rule-soft);
60
60
  border-radius: 0.5rem;
61
- background: var(--panel, rgba(255, 255, 255, 0.03));
61
+ background: var(--surface-2);
62
62
  }
63
63
  .cd-card--slim { padding: 0.6rem 0.8rem; }
64
64
  .cd-card__head { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin-bottom: 0.4rem; }
@@ -85,7 +85,7 @@
85
85
  .cd-tag {
86
86
  display: inline-block;
87
87
  padding: 0.1rem 0.45rem;
88
- border: 1px solid var(--line, rgba(255, 255, 255, 0.18));
88
+ border: 1px solid var(--rule);
89
89
  border-radius: 999px;
90
90
  font-size: 0.72rem;
91
91
  letter-spacing: 0.02em;
@@ -103,9 +103,9 @@
103
103
  .cd-dialog {
104
104
  width: min(34rem, 92vw);
105
105
  padding: 1.25rem;
106
- border: 1px solid var(--line, rgba(255, 255, 255, 0.18));
106
+ border: 1px solid var(--rule);
107
107
  border-radius: 0.6rem;
108
- background: var(--bg, #12131a);
108
+ background: var(--bg-card);
109
109
  color: inherit;
110
110
  }
111
111
  .cd-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
@@ -115,5 +115,5 @@
115
115
  .cd-dialog__hint { display: block; font-weight: 400; font-size: 0.78rem; opacity: 0.65; line-height: 1.45; margin-top: 0.1rem; }
116
116
  .cd-dialog__select, .cd-dialog__input, .cd-dialog__text { width: 100%; }
117
117
  .cd-dialog__text { resize: vertical; line-height: 1.5; }
118
- .cd-dialog__err { min-height: 1.2rem; margin: 0.5rem 0 0; font-size: 0.85rem; color: var(--danger, #ff8080); line-height: 1.45; }
118
+ .cd-dialog__err { min-height: 1.2rem; margin: 0.5rem 0 0; font-size: 0.85rem; color: var(--danger); line-height: 1.45; }
119
119
  .cd-dialog__actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 0.9rem; }
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/copy-desk.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="cd-sub">Loading the copy desk…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <!-- The counts. Deliberately four numbers and not a dashboard: open work,
27
26
  the fast pile (targets that have since been edited away), untouched
28
27
  duplicates, and how big the inventory is. -->
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/diagram-viewer.css?v=2026-06-14-diagviewer-1">
14
13
  <style>
@@ -42,7 +41,7 @@
42
41
  <p class="page-head__sub">Five diagrams that show, at a glance, how work flows through {{worldName}}'s development system. <em>Drag to pan, scroll to zoom</em> — or open any diagram fullscreen.</p>
43
42
  </div>
44
43
 
45
- <main>
44
+ <main id="hall-main">
46
45
 
47
46
  <section class="scroll" aria-labelledby="legend-h">
48
47
  <h2 id="legend-h" class="scroll__h">Reading the diagrams</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>◈</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/primer.css?v=2026-07-02-shell1">
14
13
  </head>
@@ -28,7 +27,7 @@
28
27
  <p class="page-head__sub">How you get paid, and how you earn trust — the reward model in plain language. About a five-minute read.</p>
29
28
  </div>
30
29
 
31
- <main>
30
+ <main id="hall-main">
32
31
  <div class="primer-layout">
33
32
 
34
33
  <!-- Sticky left-rail table of contents, built from the article's h2s. -->
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/gate.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="gate-sub">Loading…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <p class="gate-sealed" id="gate-sealed" hidden>Archons only.</p>
27
26
 
28
27
  <section id="gate-body" hidden>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-03-goals1">
13
12
  <!-- Page-local styles (task 2171) — extracted from the old inline <style>
14
13
  block per the hall placement rules; shared pager/filter/tab/count-pill
@@ -35,7 +34,7 @@
35
34
  <p class="page-head__sub" id="goals-sub">Loading goals…</p>
36
35
  </div>
37
36
 
38
- <main>
37
+ <main id="hall-main">
39
38
  <!-- LIST view -->
40
39
  <section id="goals-list-view" aria-labelledby="goals-list-h">
41
40
  <h2 id="goals-list-h" class="sr-only">All goals</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/government.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="gov-sub">Loading…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <p class="gov-sealed" id="gov-sealed" hidden>Archons only.</p>
27
26
 
28
27
  <section id="gov-body" hidden>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/harbor.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="harbor-sub">Loading dev boxes…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <p class="harbor-sealed" id="harbor-sealed" hidden>Archons only.</p>
27
26
 
28
27
  <section id="harbor-body" hidden>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/idea.css">
14
13
  </head>
@@ -28,7 +27,7 @@
28
27
  <p class="page-head__sub" id="idea-sub">Loading idea…</p>
29
28
  </div>
30
29
 
31
- <main>
30
+ <main id="hall-main">
32
31
  <section class="scroll" id="idea-scroll" aria-labelledby="idea-h">
33
32
  <div id="idea-body">
34
33
  <p class="deeplink-card__title" id="idea-h">Loading…</p>
@@ -6,14 +6,12 @@
6
6
  meter alongside, collapsing to one column where there is no room for it.
7
7
 
8
8
  USES THE REAL TOKEN NAMES — --border / --surface-2 / --accent / --ok / --warn /
9
- --danger / --radius. Note for anyone copying a sibling sheet: copy-desk.css
10
- reaches for `var(--line, rgba(255,255,255,.12))` and `var(--panel, …)`, and
11
- NEITHER --line NOR --panel is defined in style.css — so those fallbacks apply,
12
- and they assume a dark ground the hall does not have by default (--bg is
13
- #f5f6f8). Borders drawn that way are invisible on the light theme. This sheet
14
- deliberately does not inherit that. The hall's dark theme flips only the
15
- neutrals, so every token below re-derives on its own and this page needs no
16
- theme-specific block at all. */
9
+ --danger / --radius, so every token below re-derives on its own and this page
10
+ needs no theme-specific block at all. (The sibling trap this note used to warn
11
+ about — copy-desk.css reaching for an undefined --line / --panel and getting a
12
+ dark-ground fallback on the light theme — was fixed in task 1003303, when the
13
+ chrome-world tier defined --line as a WIDTH and those borders would otherwise
14
+ have gone invalid.) */
17
15
 
18
16
  /* The composer and its meter sit side by side once there is room. Below that
19
17
  width the meter stacks ABOVE the fields — a readout you cannot see while
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/ideas.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="fi-sub">Loading the idea template…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <!-- The spark queue (task 1002930 / R154). ABOVE the composer, because
27
26
  "what is already waiting" is the thing to scan before starting
28
27
  something new — and because a queue nobody sees is not a pickup
@@ -14,7 +14,6 @@
14
14
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
15
15
  <link rel="preconnect" href="https://fonts.googleapis.com">
16
16
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
17
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
18
17
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
19
18
  </head>
20
19
  <body data-page="home">
@@ -41,12 +40,12 @@
41
40
  — core (hall-widgets.js) and module-contributed (a module's own client
42
41
  script) — registers into the hall-widget registry (window.OTB,
43
42
  dom-utils.js), and builders.js stamps the registered <section>s into the
44
- view containers below (falling back to <main> itself). The registry stays
43
+ view containers below (falling back to <main id="hall-main"> itself). The registry stays
45
44
  the single source of truth for what the hall shows; a fitness check
46
45
  (scripts/gds/fitness.js checkHallSectionRegistry) reds the build if a
47
- <section class="scroll"> is hardcoded back inside this <main>. The
46
+ <section class="scroll"> is hardcoded back inside this <main id="hall-main">. The
48
47
  .view/.view-zone wrappers are shell layout only. -->
49
- <main class="app-views">
48
+ <main class="app-views" id="hall-main">
50
49
  <section class="view" id="view-home" data-view-title="Home">
51
50
  <div class="view-zone" id="zone-home-banner">
52
51
  <!-- Landing card for signed-out visitors (builders.js renderLanding)
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/modules.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="modules-sub">Loading modules…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <!-- Browse — one filter over both grids below (task 1001772). -->
27
26
  <div class="mod-browse">
28
27
  <label class="mod-browse__label" for="mod-search">Search the catalog</label>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/my-projects.css">
14
13
  </head>
@@ -24,7 +23,7 @@
24
23
  <p class="page-head__sub">Every project you build on across the platform.</p>
25
24
  </div>
26
25
 
27
- <main>
26
+ <main id="hall-main">
28
27
  <section class="scroll" aria-labelledby="owned-h">
29
28
  <h2 id="owned-h" class="scroll__h">Projects you own</h2>
30
29
  <div id="owned"><p class="empty">—</p></div>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  </head>
14
13
  <body data-page="not-ready" data-page-title="Locked">
@@ -19,7 +18,7 @@
19
18
  <div class="app-body">
20
19
  <header class="app-topbar" id="app-topbar"></header>
21
20
  <div class="app-content">
22
- <main>
21
+ <main id="hall-main">
23
22
  <section class="scroll">
24
23
  <h2 class="scroll__h">Not yet available</h2>
25
24
  <p class="scroll__lede">This page unlocks as you advance.</p>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/pair.css">
14
13
  </head>
@@ -21,7 +20,7 @@
21
20
  <header class="app-topbar" id="app-topbar"></header>
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="pair-sub">Reading the request…</p></div>
24
- <main>
23
+ <main id="hall-main">
25
24
  <section class="scroll" id="pair-scroll" aria-labelledby="pair-h">
26
25
  <h2 id="pair-h" class="scroll__h">A device is asking to act as you</h2>
27
26
  <div id="pair-body">
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  </head>
14
13
  <body data-page="people" data-page-title="People">
@@ -23,7 +22,7 @@
23
22
  <p class="page-head__sub">Everyone building across hosted projects, ranked by track record. Descriptive only — cross-project numbers never carry authority here.</p>
24
23
  </div>
25
24
 
26
- <main>
25
+ <main id="hall-main">
27
26
  <section class="scroll" id="people-scroll" aria-labelledby="people-h">
28
27
  <h2 id="people-h" class="scroll__h">Builder directory</h2>
29
28
  <div id="people-filters"></div>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/primer.css?v=2026-07-02-shell1">
14
13
  <link rel="stylesheet" href="/builders/diagram-viewer.css?v=2026-06-14-diagviewer-1">
@@ -31,7 +30,7 @@
31
30
  <p class="page-head__sub">Everything a new builder needs before claiming their first task. About a ten-minute read.</p>
32
31
  </div>
33
32
 
34
- <main>
33
+ <main id="hall-main">
35
34
  <div class="primer-layout">
36
35
 
37
36
  <!-- Sticky left-rail table of contents. Built from the article's h2s after
@@ -13,7 +13,6 @@
13
13
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
14
14
  <link rel="preconnect" href="https://fonts.googleapis.com">
15
15
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
16
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
17
16
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
18
17
  </head>
19
18
  <body data-page="profile" data-page-title="Profile">
@@ -28,7 +27,7 @@
28
27
  <p class="page-head__sub" id="profile-sub">Loading profile…</p>
29
28
  </div>
30
29
 
31
- <main>
30
+ <main id="hall-main">
32
31
  <!-- Standing — avatar, name, rank badge, member-since. Filled by profile.js. -->
33
32
  <section class="scroll" id="standing-scroll" aria-labelledby="standing-h">
34
33
  <h2 id="standing-h" class="sr-only">Standing</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  </head>
14
13
  <body data-page="ranks" data-page-title="Ranks">
@@ -23,7 +22,7 @@
23
22
  <p class="page-head__sub" id="ranks-sub">Loading your rank…</p>
24
23
  </div>
25
24
 
26
- <main>
25
+ <main id="hall-main">
27
26
  <!-- Current rank summary — filled by ranks.js once /me resolves. -->
28
27
  <section class="scroll" id="standing-scroll" aria-labelledby="standing-h">
29
28
  <h2 id="standing-h" class="scroll__h">Where you stand</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-24-deck1">
13
12
  <link rel="stylesheet" href="/builders/roadmap.css">
14
13
  </head>
@@ -24,7 +23,7 @@
24
23
  <p class="page-head__sub" id="roadmap-sub">Loading the roadmap…</p>
25
24
  </div>
26
25
 
27
- <main>
26
+ <main id="hall-main">
28
27
  <div id="rm-root">
29
28
  <div class="profile__placeholder">Loading the roadmap…</div>
30
29
  </div>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <style>
14
13
  #body .who { font-weight: 600; }
@@ -26,7 +25,7 @@
26
25
  <p class="page-head__sub">Builders active across all hosted projects — an internal talent view. Descriptive only; it grants no authority anywhere.</p>
27
26
  </div>
28
27
 
29
- <main>
28
+ <main id="hall-main">
30
29
  <section class="scroll" aria-labelledby="scouting-h">
31
30
  <h2 id="scouting-h" class="scroll__h">Cross-project builders</h2>
32
31
  <div id="body" class="profile__placeholder">Loading…</div>