@bongos/core 1.19.380 → 1.19.382

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.
@@ -4,13 +4,13 @@
4
4
  > Deterministic on a given tree — regenerate and commit rather than hand-editing.
5
5
  > Machine-readable twin: [`copy-registry.json`](copy-registry.json).
6
6
 
7
- **1491 strings** across 3 surfaces · 1312 distinct pieces of copy · 1491 certain, 0 heuristic · 140 shown in more than one place.
7
+ **1496 strings** across 3 surfaces · 1317 distinct pieces of copy · 1496 certain, 0 heuristic · 140 shown in more than one place.
8
8
 
9
9
  ## Surfaces
10
10
 
11
11
  | surface | lives at | files | strings |
12
12
  |---|---|---|---|
13
- | `builders-hall` | `modules/hall-ui/public` | 71 | 1124 |
13
+ | `builders-hall` | `modules/hall-ui/public` | 71 | 1129 |
14
14
  | `status-dashboard` | `modules/status-ui/public` | 4 | 98 |
15
15
  | `landing` | `public-landing` | 5 | 269 |
16
16
 
@@ -78,7 +78,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
78
78
  | `12ee050d0180` | 2x | Copy desk | modules/hall-ui/public/copy-desk.html:15, modules/hall-ui/public/copy-desk.html:15 |
79
79
  | … | | _100 more in the JSON registry_ | |
80
80
 
81
- ## `builders-hall` — 1124 strings
81
+ ## `builders-hall` — 1129 strings
82
82
 
83
83
  | id | conf | text | where |
84
84
  |---|---|---|---|
@@ -111,7 +111,6 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
111
111
  | `ac57fe1ccd6e` | certain | , follow its acceptance criteria, stay within touches[], /builder-ship | `modules/hall-ui/public/work.js:839` |
112
112
  | `d36226548dc9` | certain | , membership | `modules/hall-ui/public/government.js:823` |
113
113
  | `741e355954ac` | certain | , not at ship). | `modules/hall-ui/public/diagrams.html:61` |
114
- | `b31a6bd7edc5` | certain | , or | `modules/hall-ui/public/profile.js:271` |
115
114
  | `c7c9b0afc38e` | certain | , then mark it as read on the Home page. | `modules/hall-ui/public/work.html:40` |
116
115
  | `24174ce79df3` | certain | 1 · Task lifecycle | `modules/hall-ui/public/diagrams.html:58` |
117
116
  | `e4e929617054` | certain | 2 · Builder rank ladder | `modules/hall-ui/public/diagrams.html:66` |
@@ -137,6 +136,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
137
136
  | `303f8d90266f` | certain | Achievements could not be loaded. | `modules/hall-ui/public/builders.js:1138` |
138
137
  | `6ca31dd5eb91` | certain | Acknowledge the primer | `modules/hall-ui/public/primer.html:65` |
139
138
  | `4461b13f95c2` | certain | Actions apply at once. Closing stops and deletes the box; you can start a fresh one anytime. | `modules/hall-ui/public/settings.html:162` |
139
+ | `f6036360c90c` | certain | Activity, by craft | `modules/hall-ui/public/profile.html:84` |
140
140
  | `62eded408097` | certain | Add {…} | `modules/hall-ui/public/profile-nudge.js:68` |
141
141
  | `7cf0163d4cde` | certain | Aggregate totals across every recorded work session. | `modules/hall-ui/public/sessions.html:35` |
142
142
  | `8b736e365191` | certain | All builders | `modules/hall-ui/public/hall-render.js:1039` |
@@ -295,7 +295,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
295
295
  | `8f597eabf4ac` | certain | Could not load the drachmae guide. | `modules/hall-ui/public/drachmae.js:162` |
296
296
  | `b2147cc90e36` | certain | Could not load the idea template. Reload, or file from the terminal with capture.js. | `modules/hall-ui/public/ideas.js:438` |
297
297
  | `6264ebc9ede0` | certain | Could not load the primer. | `modules/hall-ui/public/primer.js:620` |
298
- | `7604af13c40e` | certain | Could not load the profile. | `modules/hall-ui/public/profile.js:336` |
298
+ | `7604af13c40e` | certain | Could not load the profile. | `modules/hall-ui/public/profile.js:615` |
299
299
  | `8b69e445592a` | certain | Could not load the question labels; showing the answers as stored. | `modules/hall-ui/public/idea.js:229` |
300
300
  | `edd5bafbe075` | certain | Could not load the queue just now. | `modules/hall-ui/public/ideas.js:387` |
301
301
  | `02bb0570996a` | certain | Could not load the ranks. | `modules/hall-ui/public/ranks.js:197` |
@@ -392,6 +392,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
392
392
  | `44f928d13699` | certain | Event sounds | `modules/hall-ui/public/settings.html:282` |
393
393
  | `8690c6424585` | certain | Every builder in {{worldName}} — rank, {{currency}}, karma, and active claims. | `modules/hall-ui/public/watch.html:61` |
394
394
  | `2ae1eb35611e` | certain | Every done-when criterion for this goal, with its full detail. | `modules/hall-ui/public/goals.html:186` |
395
+ | `8825f1d90dd1` | certain | Every idea this builder captured — promoted, discarded, merged, or still open. | `modules/hall-ui/public/profile.html:104` |
395
396
  | `1e05b7fe42c8` | certain | Every project you build on across the platform. | `modules/hall-ui/public/my-projects.html:24` |
396
397
  | `efafe5ce29ed` | certain | Every task linked to this criterion has shipped — a Metic can confirm it | `modules/hall-ui/public/goals-render.js:588` |
397
398
  | `ddebbccd4b37` | certain | Everyone building across hosted projects, ranked by track record. Descriptive only — cross-project numbers nev | `modules/hall-ui/public/people.html:23` |
@@ -432,6 +433,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
432
433
  | `e2a9e33abe60` | certain | Goal tasks | `modules/hall-ui/public/goals.html:112` |
433
434
  | `e0bc28d10785` | certain | Goals could not be loaded. Refresh to try again. | `modules/hall-ui/public/goals-page.js:867` |
434
435
  | `4517f2253d0f` | certain | Goals couldn’t be loaded just now. Refresh to try again. | `modules/hall-ui/public/goals.js:112` |
436
+ | `6a85997bda21` | certain | Goals created | `modules/hall-ui/public/profile.html:96` |
435
437
  | `2ed2cb8fbffd` | certain | Goals page | `modules/hall-ui/public/goals.js:94` |
436
438
  | `320a0516a33e` | certain | Goals seeded — awaiting kickoff | `modules/hall-ui/public/roadmap.js:205` |
437
439
  | `bba4caf837e9` | certain | Goals — {{worldName}} | `modules/hall-ui/public/goals.html:6` |
@@ -465,6 +467,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
465
467
  | `ba82ec56f1e3` | certain | Idea — {{worldName}} | `modules/hall-ui/public/idea.html:6` |
466
468
  | `ba82ec56f1e3` | certain | Idea — {{worldName}} | `modules/hall-ui/public/idea.html:6` |
467
469
  | `e181637c5a5e` | certain | Ideas awaiting triage | `modules/hall-ui/public/builders.js:845` |
470
+ | `d4e21769ce1c` | certain | Ideas filed, and what became of them | `modules/hall-ui/public/profile.html:103` |
468
471
  | `379b20d548ad` | certain | Ideas whose author has said "I had the thought but not the full picture". Anyone can develop one — the author | `modules/hall-ui/public/ideas.html:33` |
469
472
  | `ef224c9de7c8` | certain | Ideas — {{worldName}} | `modules/hall-ui/public/ideas.html:6` |
470
473
  | `ef224c9de7c8` | certain | Ideas — {{worldName}} | `modules/hall-ui/public/ideas.html:6` |
@@ -538,6 +541,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
538
541
  | `df335a1224ae` | certain | Member since {…} | `modules/hall-ui/public/hall-render.js:490` |
539
542
  | `df335a1224ae` | certain | Member since {…} | `modules/hall-ui/public/hall-render.js:544` |
540
543
  | `df335a1224ae` | certain | Member since {…} | `modules/hall-ui/public/profile.js:58` |
544
+ | `c7a670e9552d` | certain | Merged into | `modules/hall-ui/public/profile.js:322` |
541
545
  | `7637613c231b` | certain | Metic rank and above may vote | `modules/hall-ui/public/builders.js:729` |
542
546
  | `d7ce4a3bb745` | certain | Minimize the welcome panel | `modules/hall-ui/public/hall-widgets.js:52` |
543
547
  | `19b0ed5781ae` | certain | Minimum rank required to claim this task | `modules/hall-ui/public/task-lib.js:65` |
@@ -569,7 +573,6 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
569
573
  | `c255749ec989` | certain | No achievements earned yet. | `modules/hall-ui/public/builders.js:475` |
570
574
  | `c255749ec989` | certain | No achievements earned yet. | `modules/hall-ui/public/profile.js:108` |
571
575
  | `83f62fc94271` | certain | No builder account found for this sign-in. | `modules/hall-ui/public/settings.js:1278` |
572
- | `2e9c154c09cd` | certain | No builder selected. Open a builder from the | `modules/hall-ui/public/profile.js:271` |
573
576
  | `6d6fd2314248` | certain | No cross-project activity reported yet. | `modules/hall-ui/public/profile.js:239` |
574
577
  | `6d6fd2314248` | certain | No cross-project activity reported yet. | `modules/hall-ui/public/scouting.js:29` |
575
578
  | `b1ada579483c` | certain | No custom ranks yet | `modules/hall-ui/public/government.js:309` |
@@ -706,7 +709,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
706
709
  | `aa4db91b5732` | certain | Released #{…}. It returns to the queue. | `modules/hall-ui/public/work.js:892` |
707
710
  | `aa4db91b5732` | certain | Released #{…}. It returns to the queue. | `modules/hall-ui/public/work.js:945` |
708
711
  | `9c74a2572f4d` | certain | Remote control (recommended) | `modules/hall-ui/public/hall-render.js:650` |
709
- | `65e3399a8fbf` | certain | Remove filter | `modules/hall-ui/public/hall-kit.js:249` |
712
+ | `65e3399a8fbf` | certain | Remove filter | `modules/hall-ui/public/hall-kit.js:308` |
710
713
  | `dacd113fb3b2` | certain | Remove your image-generation key? Art generation will stop until you add one again. | `modules/hall-ui/public/settings.js:1080` |
711
714
  | `20882d6ffdd0` | certain | Removed {…} from builder {…}. | `modules/hall-ui/public/government.js:316` |
712
715
  | `b06589044b0b` | certain | Render session cards as widgets (prettier, costs tokens) instead of plain text (cheaper, identical info). | `modules/hall-ui/public/settings.js:502` |
@@ -803,6 +806,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
803
806
  | `98d037e427b8` | certain | Stale — describes something that changed | `modules/hall-ui/public/copy-desk.html:94` |
804
807
  | `9d4372b173cf` | certain | Standing sections | `modules/hall-ui/public/index.html:70` |
805
808
  | `ec1c2dae4a90` | certain | Standing there | `modules/hall-ui/public/profile.js:230` |
809
+ | `efe530c0e3a7` | certain | Still open | `modules/hall-ui/public/profile.js:327` |
806
810
  | `4e09b7f4288b` | certain | Stops and deletes your box. Provision a fresh one anytime. | `modules/hall-ui/public/box-panel.js:150` |
807
811
  | `6c6544f5c011` | certain | Stored encrypted; never shown again after saving — only its last four digits. | `modules/hall-ui/public/settings.html:146` |
808
812
  | `1dd8f7dd6139` | certain | Submit "{…}" for review | `modules/hall-ui/public/modules.js:159` |
@@ -916,6 +920,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
916
920
  | `70dc106494cf` | certain | What is wrong with it, and what would better look like? | `modules/hall-ui/public/copy-desk.html:101` |
917
921
  | `ae44a375e814` | certain | What it unlocks | `modules/hall-ui/public/ranks.js:109` |
918
922
  | `00dc1f0f83e1` | certain | What kind of wrong? | `modules/hall-ui/public/copy-desk.html:89` |
923
+ | `5f2b989bbf6a` | certain | What this builder has done, seen one craft at a time. | `modules/hall-ui/public/profile.html:85` |
919
924
  | `41b2aef03c03` | certain | What this project runs today | `modules/hall-ui/public/government.js:657` |
920
925
  | `3dade88f0584` | certain | What your box would cost: | `modules/hall-ui/public/box-panel.js:235` |
921
926
  | `b8743d16eab8` | certain | What {…} unlocks | `modules/hall-ui/public/hall-render.js:82` |
@@ -935,6 +940,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
935
940
  | `c5fd76a9e03d` | certain | Won {…} | `modules/hall-ui/public/builders.js:482` |
936
941
  | `c5fd76a9e03d` | certain | Won {…} | `modules/hall-ui/public/profile.js:115` |
937
942
  | `520d139df9eb` | certain | Work is complete but the version is held — no tasks are being claimed here right now. | `modules/hall-ui/public/roadmap.js:223` |
943
+ | `0e6b8e8f26cc` | certain | Works completed | `modules/hall-ui/public/profile.html:91` |
938
944
  | `52e5fe3c6075` | certain | Write a Full Idea | `modules/hall-ui/public/ideas.html:43` |
939
945
  | `7664f4373d1f` | certain | Write one | `modules/hall-ui/public/idea.js:243` |
940
946
  | `c368b56ecf40` | certain | Xenos builders start with a focused set of pages — ship your first | `modules/hall-ui/public/not-ready.html:26` |
@@ -1090,7 +1096,6 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1090
1096
  | `fac041ec6dd7` | certain | selectable today | `modules/hall-ui/public/government.js:625` |
1091
1097
  | `a6f55d7aa6f7` | certain | shipped (live) | `modules/hall-ui/public/roadmap.js:273` |
1092
1098
  | `026ba1289d4d` | certain | shipped · | `modules/hall-ui/public/goals-render.js:641` |
1093
- | `ec6d8c900bc8` | certain | sign in | `modules/hall-ui/public/profile.js:271` |
1094
1099
  | `da30b952a60b` | certain | system / unattributed | `modules/hall-ui/public/goals-page.js:249` |
1095
1100
  | `da30b952a60b` | certain | system / unattributed | `modules/hall-ui/public/work.js:496` |
1096
1101
  | `cfc61d8cabe6` | certain | tally: {…} yes · {…} no — sitting under | `modules/hall-ui/public/government.js:823` |
@@ -1104,7 +1109,6 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1104
1109
  | `65702f92a8c8` | certain | to claim your first task. | `modules/hall-ui/public/hall-render.js:691` |
1105
1110
  | `5520469f2834` | certain | to copy the task prompt and paste it into a fresh Claude Code session to begin. | `modules/hall-ui/public/work.html:54` |
1106
1111
  | `b8e12f871044` | certain | to graduate and open the rest of {{worldName}}'s builder hub. | `modules/hall-ui/public/not-ready.html:28` |
1107
- | `47204e5f11de` | certain | to see your own profile. | `modules/hall-ui/public/profile.js:271` |
1108
1112
  | `23488ca48320` | certain | to take a task right here — no terminal needed. Then click | `modules/hall-ui/public/work.html:54` |
1109
1113
  | `c0449d0ec0b8` | certain | trend, latest {…} | `modules/hall-ui/public/hall-render.js:1002` |
1110
1114
  | `679c0150f586` | certain | upkeep: undeclared | `modules/hall-ui/public/modules.js:73` |
@@ -1140,6 +1144,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1140
1144
  | `cc5106af4b35` | certain | {…} of {…} criteria satisfied | `modules/hall-ui/public/goals-lib.js:30` |
1141
1145
  | `cc5106af4b35` | certain | {…} of {…} criteria satisfied | `modules/hall-ui/public/goals-render.js:566` |
1142
1146
  | `cc5106af4b35` | certain | {…} of {…} criteria satisfied | `modules/hall-ui/public/goals.js:45` |
1147
+ | `c3d9687e2375` | certain | {…} of {…} shipped | `modules/hall-ui/public/profile.js:428` |
1143
1148
  | `f32710d0ef37` | certain | {…} of {…} steps cleared. | `modules/hall-ui/public/hall-render.js:879` |
1144
1149
  | `60743fe1e40d` | certain | {…} per page | `modules/hall-ui/public/hall-kit.js:71` |
1145
1150
  | `e41b92264220` | certain | {…} places · {…} | `modules/hall-ui/public/copy-desk.js:117` |
@@ -3,9 +3,9 @@
3
3
  "generator": "scripts/gds/copy-inventory.js",
4
4
  "goal": 1000074,
5
5
  "counts": {
6
- "strings": 1491,
7
- "unique_ids": 1312,
8
- "certain": 1491,
6
+ "strings": 1496,
7
+ "unique_ids": 1317,
8
+ "certain": 1496,
9
9
  "heuristic": 0,
10
10
  "duplicate_ids": 140
11
11
  },
@@ -13,7 +13,7 @@
13
13
  "builders-hall": {
14
14
  "at": "modules/hall-ui/public",
15
15
  "files": 71,
16
- "strings": 1124
16
+ "strings": 1129
17
17
  },
18
18
  "status-dashboard": {
19
19
  "at": "modules/status-ui/public",
@@ -1740,15 +1740,6 @@
1740
1740
  "origin": "html-text",
1741
1741
  "confidence": "certain"
1742
1742
  },
1743
- {
1744
- "id": "b31a6bd7edc5",
1745
- "surface": "builders-hall",
1746
- "text": ", or",
1747
- "file": "modules/hall-ui/public/profile.js",
1748
- "line": 271,
1749
- "origin": "js-markup",
1750
- "confidence": "certain"
1751
- },
1752
1743
  {
1753
1744
  "id": "c7c9b0afc38e",
1754
1745
  "surface": "builders-hall",
@@ -1974,6 +1965,15 @@
1974
1965
  "origin": "html-text",
1975
1966
  "confidence": "certain"
1976
1967
  },
1968
+ {
1969
+ "id": "f6036360c90c",
1970
+ "surface": "builders-hall",
1971
+ "text": "Activity, by craft",
1972
+ "file": "modules/hall-ui/public/profile.html",
1973
+ "line": 84,
1974
+ "origin": "html-text",
1975
+ "confidence": "certain"
1976
+ },
1977
1977
  {
1978
1978
  "id": "62eded408097",
1979
1979
  "surface": "builders-hall",
@@ -3401,7 +3401,7 @@
3401
3401
  "surface": "builders-hall",
3402
3402
  "text": "Could not load the profile.",
3403
3403
  "file": "modules/hall-ui/public/profile.js",
3404
- "line": 336,
3404
+ "line": 615,
3405
3405
  "origin": "js-notice",
3406
3406
  "confidence": "certain"
3407
3407
  },
@@ -4269,6 +4269,15 @@
4269
4269
  "origin": "html-text",
4270
4270
  "confidence": "certain"
4271
4271
  },
4272
+ {
4273
+ "id": "8825f1d90dd1",
4274
+ "surface": "builders-hall",
4275
+ "text": "Every idea this builder captured — promoted, discarded, merged, or still open.",
4276
+ "file": "modules/hall-ui/public/profile.html",
4277
+ "line": 104,
4278
+ "origin": "html-text",
4279
+ "confidence": "certain"
4280
+ },
4272
4281
  {
4273
4282
  "id": "1e05b7fe42c8",
4274
4283
  "surface": "builders-hall",
@@ -4629,6 +4638,15 @@
4629
4638
  "origin": "js-markup",
4630
4639
  "confidence": "certain"
4631
4640
  },
4641
+ {
4642
+ "id": "6a85997bda21",
4643
+ "surface": "builders-hall",
4644
+ "text": "Goals created",
4645
+ "file": "modules/hall-ui/public/profile.html",
4646
+ "line": 96,
4647
+ "origin": "html-text",
4648
+ "confidence": "certain"
4649
+ },
4632
4650
  {
4633
4651
  "id": "2ed2cb8fbffd",
4634
4652
  "surface": "builders-hall",
@@ -4926,6 +4944,15 @@
4926
4944
  "origin": "js-markup",
4927
4945
  "confidence": "certain"
4928
4946
  },
4947
+ {
4948
+ "id": "d4e21769ce1c",
4949
+ "surface": "builders-hall",
4950
+ "text": "Ideas filed, and what became of them",
4951
+ "file": "modules/hall-ui/public/profile.html",
4952
+ "line": 103,
4953
+ "origin": "html-text",
4954
+ "confidence": "certain"
4955
+ },
4929
4956
  {
4930
4957
  "id": "379b20d548ad",
4931
4958
  "surface": "builders-hall",
@@ -5583,6 +5610,15 @@
5583
5610
  "origin": "js-markup",
5584
5611
  "confidence": "certain"
5585
5612
  },
5613
+ {
5614
+ "id": "c7a670e9552d",
5615
+ "surface": "builders-hall",
5616
+ "text": "Merged into",
5617
+ "file": "modules/hall-ui/public/profile.js",
5618
+ "line": 322,
5619
+ "origin": "js-markup",
5620
+ "confidence": "certain"
5621
+ },
5586
5622
  {
5587
5623
  "id": "7637613c231b",
5588
5624
  "surface": "builders-hall",
@@ -5862,15 +5898,6 @@
5862
5898
  "origin": "js-text-assign",
5863
5899
  "confidence": "certain"
5864
5900
  },
5865
- {
5866
- "id": "2e9c154c09cd",
5867
- "surface": "builders-hall",
5868
- "text": "No builder selected. Open a builder from the",
5869
- "file": "modules/hall-ui/public/profile.js",
5870
- "line": 271,
5871
- "origin": "js-markup",
5872
- "confidence": "certain"
5873
- },
5874
5901
  {
5875
5902
  "id": "6d6fd2314248",
5876
5903
  "surface": "builders-hall",
@@ -7100,7 +7127,7 @@
7100
7127
  "surface": "builders-hall",
7101
7128
  "text": "Remove filter",
7102
7129
  "file": "modules/hall-ui/public/hall-kit.js",
7103
- "line": 249,
7130
+ "line": 308,
7104
7131
  "origin": "js-markup",
7105
7132
  "confidence": "certain"
7106
7133
  },
@@ -7968,6 +7995,15 @@
7968
7995
  "origin": "js-markup",
7969
7996
  "confidence": "certain"
7970
7997
  },
7998
+ {
7999
+ "id": "efe530c0e3a7",
8000
+ "surface": "builders-hall",
8001
+ "text": "Still open",
8002
+ "file": "modules/hall-ui/public/profile.js",
8003
+ "line": 327,
8004
+ "origin": "js-markup",
8005
+ "confidence": "certain"
8006
+ },
7971
8007
  {
7972
8008
  "id": "4e09b7f4288b",
7973
8009
  "surface": "builders-hall",
@@ -8985,6 +9021,15 @@
8985
9021
  "origin": "html-text",
8986
9022
  "confidence": "certain"
8987
9023
  },
9024
+ {
9025
+ "id": "5f2b989bbf6a",
9026
+ "surface": "builders-hall",
9027
+ "text": "What this builder has done, seen one craft at a time.",
9028
+ "file": "modules/hall-ui/public/profile.html",
9029
+ "line": 85,
9030
+ "origin": "html-text",
9031
+ "confidence": "certain"
9032
+ },
8988
9033
  {
8989
9034
  "id": "41b2aef03c03",
8990
9035
  "surface": "builders-hall",
@@ -9156,6 +9201,15 @@
9156
9201
  "origin": "js-markup",
9157
9202
  "confidence": "certain"
9158
9203
  },
9204
+ {
9205
+ "id": "0e6b8e8f26cc",
9206
+ "surface": "builders-hall",
9207
+ "text": "Works completed",
9208
+ "file": "modules/hall-ui/public/profile.html",
9209
+ "line": 91,
9210
+ "origin": "html-text",
9211
+ "confidence": "certain"
9212
+ },
9159
9213
  {
9160
9214
  "id": "52e5fe3c6075",
9161
9215
  "surface": "builders-hall",
@@ -10551,15 +10605,6 @@
10551
10605
  "origin": "js-markup",
10552
10606
  "confidence": "certain"
10553
10607
  },
10554
- {
10555
- "id": "ec6d8c900bc8",
10556
- "surface": "builders-hall",
10557
- "text": "sign in",
10558
- "file": "modules/hall-ui/public/profile.js",
10559
- "line": 271,
10560
- "origin": "js-markup",
10561
- "confidence": "certain"
10562
- },
10563
10608
  {
10564
10609
  "id": "da30b952a60b",
10565
10610
  "surface": "builders-hall",
@@ -10677,15 +10722,6 @@
10677
10722
  "origin": "html-text",
10678
10723
  "confidence": "certain"
10679
10724
  },
10680
- {
10681
- "id": "47204e5f11de",
10682
- "surface": "builders-hall",
10683
- "text": "to see your own profile.",
10684
- "file": "modules/hall-ui/public/profile.js",
10685
- "line": 271,
10686
- "origin": "js-markup",
10687
- "confidence": "certain"
10688
- },
10689
10725
  {
10690
10726
  "id": "23488ca48320",
10691
10727
  "surface": "builders-hall",
@@ -11001,6 +11037,15 @@
11001
11037
  "origin": "js-markup",
11002
11038
  "confidence": "certain"
11003
11039
  },
11040
+ {
11041
+ "id": "c3d9687e2375",
11042
+ "surface": "builders-hall",
11043
+ "text": "{…} of {…} shipped",
11044
+ "file": "modules/hall-ui/public/profile.js",
11045
+ "line": 428,
11046
+ "origin": "js-markup",
11047
+ "confidence": "certain"
11048
+ },
11004
11049
  {
11005
11050
  "id": "f32710d0ef37",
11006
11051
  "surface": "builders-hall",
@@ -0,0 +1,61 @@
1
+ -- core_228_idea_inbox_captured_by_idx.sql — task 1003281 (grader panel finding,
2
+ -- efficiency worker, on the goal-1000072 activity log).
3
+ --
4
+ -- THE ACTIVITY LOG IS THE FIRST SURFACE THAT ASKS "WHAT DID *THIS PERSON* DO".
5
+ -- Every read that came before scoped by version, by status, or by goal, so those
6
+ -- are the columns that got indexed. Three per-person predicates arrived with this
7
+ -- task, each on a route any signed-in builder can hit repeatedly — once per
8
+ -- profile load, again per craft switch, again per pager click — and each paired
9
+ -- with a COUNT(*) that has no LIMIT to escape through. Unindexed, all three
10
+ -- sequentially scan a shared table on every one of those requests.
11
+ --
12
+ -- 1. idea_inbox (captured_by, captured_at DESC) — THE FLAGGED ONE.
13
+ -- Migration 006 indexed `status` and `captured_at`, exactly right for every
14
+ -- idea read that existed until now: all of them are scoped to what is still
15
+ -- OPEN and ordered newest-first. `captured_by` was never a predicate.
16
+ -- GET /inbox/by-builder/:id inverts that — it drops the status filter entirely
17
+ -- (a triaged idea must NOT leave the trail; that IS the criterion) and scopes
18
+ -- on the author instead.
19
+ --
20
+ -- 2. tasks (shipped_by, shipped_at DESC) WHERE status = 'shipped' — the works
21
+ -- half. The only existing index on `shipped_by` is core_193's, partial on
22
+ -- `WHERE needs_rebase`, which cannot serve this at all. PARTIAL on the status
23
+ -- because the predicate is always `status = 'shipped'` and shipped tasks are a
24
+ -- minority of the table: the index stays small and every row in it is a row
25
+ -- the query wants.
26
+ --
27
+ -- 3. tasks (goal_id) — the goals half's rollup CTE derives each goal's craft set
28
+ -- and progress from its tasks, and nothing indexed `goal_id` (migration 160
29
+ -- added the column and an FK, not an index). This one is the broadest win
30
+ -- here: it is the join every per-goal rollup in the codebase makes.
31
+ --
32
+ -- EQUALITY LEADS, SORT TRAILS, in 1 and 2. The btree seeks straight to one
33
+ -- person's rows and then walks them already ordered, so the page window stops at
34
+ -- LIMIT instead of sorting a whole history to return ten rows. A bare
35
+ -- (captured_by) index would serve the COUNT and leave the list with a sort.
36
+ --
37
+ -- DELIBERATELY NOT INDEXED: goals.created_by. The `mine` CTE filters it, but the
38
+ -- goals table holds tens of rows, not thousands — an index there would cost more
39
+ -- to maintain than the scan it replaces. Revisit if a project ever carries
40
+ -- thousands of goals.
41
+ --
42
+ -- NOT THE MODULE'S MIGRATION, deliberately. `idea_inbox` and `tasks` are CORE
43
+ -- tables (both predate the module system), and fitness.js
44
+ -- checkModuleMigrationsAdditive hard-fails a CREATE INDEX against a
45
+ -- non-`ideas_`-prefixed table from modules/ideas/migrations/ (ADR 0083
46
+ -- §Decision #5). Task 1002447 hit the same wall — core_195 began life as
47
+ -- ideas_001 — so this lands in core beside it.
48
+ --
49
+ -- Additive and reversible: an index carries no data and no constraint, so a
50
+ -- rollback is a DROP INDEX and nothing depends on it for correctness, only for
51
+ -- speed. This migration changes no column, no type and no row.
52
+ CREATE INDEX IF NOT EXISTS idx_idea_inbox_captured_by
53
+ ON idea_inbox (captured_by, captured_at DESC);
54
+
55
+ CREATE INDEX IF NOT EXISTS idx_tasks_shipped_by_shipped_at
56
+ ON tasks (shipped_by, shipped_at DESC) WHERE status = 'shipped';
57
+
58
+ CREATE INDEX IF NOT EXISTS idx_tasks_goal ON tasks (goal_id);
59
+
60
+ INSERT INTO schema_migrations (version) VALUES ('core_228_idea_inbox_captured_by_idx')
61
+ ON CONFLICT (version) DO NOTHING;
@@ -222,6 +222,8 @@ function createClient(opts = {}) {
222
222
  "builders": {
223
223
  // GET /builders/{id}/active-claims — rank: metic+archon — GET /builders/:id/active-claims
224
224
  getBuildersIdActiveClaims: (args) => request("GET", "/builders/{id}/active-claims", { hasBody: false }, args),
225
+ // GET /builders/{id}/activity — rank: any-builder — GET /builders/:id/activity
226
+ getBuildersIdActivity: (args) => request("GET", "/builders/{id}/activity", { hasBody: false }, args),
225
227
  // PATCH /builders/{id}/budget — rank: metic+archon — PATCH /builders/:id/budget
226
228
  patchBuildersIdBudget: (args) => request("PATCH", "/builders/{id}/budget", { hasBody: true }, args),
227
229
  // GET /builders/{id}/onboarding — rank: public — GET /builders/:id/onboarding
@@ -440,6 +442,8 @@ function createClient(opts = {}) {
440
442
  postInboxIdSpark: (args) => request("POST", "/inbox/{id}/spark", { hasBody: true }, args),
441
443
  // GET /inbox/awaiting-nod — rank: metic+archon — GET /inbox/awaiting-nod
442
444
  getInboxAwaitingNod: (args) => request("GET", "/inbox/awaiting-nod", { hasBody: false }, args),
445
+ // GET /inbox/by-builder/{id} — rank: any-builder — GET /inbox/by-builder/:id
446
+ getInboxByBuilderId: (args) => request("GET", "/inbox/by-builder/{id}", { hasBody: false }, args),
443
447
  // POST /inbox/score — rank: any-builder — POST /inbox/score
444
448
  postInboxScore: (args) => request("POST", "/inbox/score", { hasBody: true }, args),
445
449
  // GET /inbox/sparks — rank: any-builder — GET /inbox/sparks
@@ -115,6 +115,43 @@
115
115
  if (sel && sel.value !== String(p.perPage)) sel.value = String(p.perPage);
116
116
  }
117
117
 
118
+ // ---- server-offset paging (task 1003281) -----------------------------------
119
+ //
120
+ // `paginate()` above slices an array the browser already holds. Some lists
121
+ // cannot be held: the profile's activity log pages ONE builder's whole record,
122
+ // and hall-ui/CLAUDE.md's own rule says that when you need a server-offset
123
+ // pager you add the mode to the kit rather than hand-rolling a second copy
124
+ // (sessions.js is the one grandfathered hand-roll, audited task 2179).
125
+ //
126
+ // The pager object is the SAME object — page, perPage, per-page persistence
127
+ // and wirePager all work unchanged. Only the slicing moves: the caller asks
128
+ // the server for `pageOffset(p)`..`+perPage` and then reports back what it got
129
+ // with `renderServerPage`. That keeps ONE pager contract in the kit instead of
130
+ // two, which is the whole reason this lives here.
131
+
132
+ // Row offset of the pager's current page — what a `?offset=` query takes.
133
+ function pageOffset(p) {
134
+ return Math.max(0, (p.page - 1) * p.perPage);
135
+ }
136
+
137
+ // Paint the bar for a server-paged list: `total` is the server's count of the
138
+ // whole filtered set, `shownCount` the rows this page actually returned.
139
+ // Clamps `p.page` down when the set shrank under the caller (a re-filter, a
140
+ // background change) and returns true when it did — the caller re-fetches, so
141
+ // the bar and the rows can never disagree about which page is showing.
142
+ function renderServerPage(p, total, shownCount) {
143
+ const totalPages = Math.max(1, Math.ceil(total / p.perPage));
144
+ const clamped = p.page > totalPages || p.page < 1;
145
+ if (clamped) p.page = Math.min(Math.max(1, p.page), totalPages);
146
+ const offset = pageOffset(p);
147
+ // "Showing 11–13 of 12" is what an unclamped count reads as when the rows
148
+ // and the total come from two statements that disagree. The total is the
149
+ // authority for the range, so the shown count can never run past it.
150
+ const shown = Math.max(0, Math.min(shownCount, total - offset));
151
+ renderPagerBar(p, total, totalPages, offset, shown);
152
+ return clamped;
153
+ }
154
+
118
155
  // Wire a pager's controls once. `rerender` re-renders that list; a per-page
119
156
  // change resets to page 1 and persists. Fills the per-page <select> from the
120
157
  // pager's own options so pagerBarHtml stays option-agnostic.
@@ -136,35 +173,57 @@
136
173
  }
137
174
 
138
175
  // ---- ledger ----------------------------------------------------------------
139
- // makeLedger({ mount, columns, rowHtml, emptyMsg, emptyAction?, pager? })
176
+ // makeLedger({ mount, columns, rowHtml, emptyMsg, emptyAction?, pager?, serverPager?, onPage? })
140
177
  // Stamps the standard table.ledger (+ pager bar when a pager is given) into
141
- // `mount` and returns { el, tbody, render(rows) }. `columns` entries are
178
+ // `mount` and returns { el, tbody, render(rows, opts) }. `columns` entries are
142
179
  // strings or { label, class }. `rowHtml(row, i)` returns a <tr> string —
143
180
  // callers keep full control of cells (and must esc() their own data).
144
- function makeLedger({ mount, columns = [], rowHtml, emptyMsg = 'Nothing here yet.', emptyAction = null, pager = null }) {
181
+ //
182
+ // `pager` slices client-side (the browser holds the whole list). `serverPager`
183
+ // is the same pager object driving a SERVER-offset list (task 1003281): the
184
+ // rows handed to render() are already one page, so nothing is sliced, and the
185
+ // caller passes `{ total }` — the server's count of the whole set — so the bar
186
+ // can say "of N". Page/per-page clicks call `onPage(pageOffset(p))`; the
187
+ // caller fetches and calls render() again. Pass one or the other, never both.
188
+ function makeLedger({
189
+ mount, columns = [], rowHtml, emptyMsg = 'Nothing here yet.', emptyAction = null,
190
+ pager = null, serverPager = null, onPage = null,
191
+ }) {
145
192
  if (!mount || typeof rowHtml !== 'function') {
146
193
  throw new Error('makeLedger({ mount, columns, rowHtml, … }) requires mount + rowHtml()');
147
194
  }
195
+ if (pager && serverPager) {
196
+ throw new Error('makeLedger: pass pager (client-sliced) OR serverPager (server-offset), not both');
197
+ }
148
198
  const head = columns.map((c) => {
149
199
  const col = typeof c === 'string' ? { label: c } : c;
150
200
  return `<th${col.class ? ` class="${esc(col.class)}"` : ''}>${esc(col.label)}</th>`;
151
201
  }).join('');
202
+ const bar = pager || serverPager;
152
203
  mount.innerHTML = `
153
204
  <table class="ledger">
154
205
  <thead><tr>${head}</tr></thead>
155
206
  <tbody></tbody>
156
207
  </table>
157
- ${pager ? pagerBarHtml(pager.prefix, { label: 'rows' }) : ''}`;
208
+ ${bar ? pagerBarHtml(bar.prefix, { label: 'rows' }) : ''}`;
158
209
  const tbody = mount.querySelector('tbody');
159
210
  let last = [];
160
- function render(rows) {
211
+ let lastTotal = 0;
212
+ function render(rows, opts = {}) {
161
213
  if (Array.isArray(rows)) last = rows;
162
- const slice = pager ? paginate(last, pager) : last;
214
+ if (typeof opts.total === 'number') lastTotal = opts.total;
215
+ let slice = last;
216
+ if (pager) slice = paginate(last, pager);
217
+ else if (serverPager) renderServerPage(serverPager, lastTotal, last.length);
163
218
  tbody.innerHTML = slice.length
164
219
  ? slice.map((r, i) => rowHtml(r, i)).join('')
165
220
  : `<tr><td class="ledger__empty" colspan="${columns.length || 1}">${emptyStateHtml(emptyMsg, emptyAction)}</td></tr>`;
166
221
  }
167
222
  if (pager) wirePager(pager, () => render());
223
+ // A server-paged ledger cannot re-render from what it holds — it has to go
224
+ // ask. wirePager has already moved p.page by the time onPage runs, so the
225
+ // offset it hands over is the NEW page's.
226
+ if (serverPager) wirePager(serverPager, () => { if (onPage) onPage(pageOffset(serverPager)); });
168
227
  return { el: mount, tbody, render };
169
228
  }
170
229
 
@@ -552,6 +611,8 @@
552
611
  esc,
553
612
  // pager (low-level exports so pages can adopt incrementally)
554
613
  makePager, pagerBarHtml, paginate, renderPagerBar, wirePager,
614
+ // server-offset paging (task 1003281) — same pager object, server slicing
615
+ pageOffset, renderServerPage,
555
616
  // composed primitives
556
617
  makeLedger, makeFilterBar, makeTabs, makeSectionRail,
557
618
  // states
@@ -75,6 +75,38 @@
75
75
  </table>
76
76
  </section>
77
77
 
78
+ <!-- Activity, by craft — task 1003281, goal 1000072 / criterion
79
+ legibility-activity-by-role. A view per role over the same record:
80
+ the tasks this builder completed, the goals they created, and (in
81
+ the ideator view) every idea they filed with what became of it.
82
+ All three ledgers page server-side; profile.js fills them. -->
83
+ <section class="scroll" id="activity-scroll" aria-labelledby="activity-h">
84
+ <h2 id="activity-h" class="scroll__h">Activity, by craft</h2>
85
+ <p class="scroll__lede" id="activity-lede">What this builder has done, seen one craft at a time.</p>
86
+ <div id="activity-tabs"></div>
87
+ <div id="activity-body">
88
+ <div class="profile__placeholder" id="activity-placeholder">…</div>
89
+
90
+ <div id="activity-tasks-panel" hidden>
91
+ <h3 class="scroll__h">Works completed</h3>
92
+ <div id="activity-tasks"></div>
93
+ </div>
94
+
95
+ <div id="activity-goals-panel" hidden>
96
+ <h3 class="scroll__h">Goals created</h3>
97
+ <div id="activity-goals"></div>
98
+ </div>
99
+
100
+ <!-- The idea trail. Revealed only in the craft views where filing an
101
+ idea is the work being shown (all + ideator) — see profile.js. -->
102
+ <div id="activity-ideas-panel" hidden>
103
+ <h3 class="scroll__h">Ideas filed, and what became of them</h3>
104
+ <p class="scroll__lede">Every idea this builder captured — promoted, discarded, merged, or still open.</p>
105
+ <div id="activity-ideas"></div>
106
+ </div>
107
+ </div>
108
+ </section>
109
+
78
110
  <!-- Reserved slots — connections, guilds, and actions (profile-page
79
111
  spec sections 6–8) mount here in later phases; keeping the order
80
112
  fixed now means the page is not re-laid-out twice (Decision 5). -->
@@ -97,7 +129,7 @@
97
129
  <script src="/builders/brand-apply.js?v=2026-06-27-r75"></script>
98
130
  <!-- hall-kit (window.OTBKit) — profile.js renders ship-time task visuals through
99
131
  its shared thumbnail helper (task 1003109), so it must load first. -->
100
- <script src="/builders/hall-kit.js?v=2026-08-25-visual"></script>
101
- <script src="/builders/profile.js?v=2026-08-25-visual"></script>
132
+ <script src="/builders/hall-kit.js?v=2026-08-27-activity"></script>
133
+ <script src="/builders/profile.js?v=2026-08-27-activity"></script>
102
134
  </body>
103
135
  </html>