@bongos/core 1.19.655 → 1.19.657

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.
@@ -12,7 +12,7 @@
12
12
  "surfaces": {
13
13
  "builders-hall": {
14
14
  "at": "modules/hall-ui/public",
15
- "files": 80,
15
+ "files": 81,
16
16
  "strings": 1270
17
17
  },
18
18
  "status-dashboard": {
@@ -142,9 +142,9 @@
142
142
  "text": "Restricted.",
143
143
  "occurrences": 5,
144
144
  "at": [
145
- "modules/hall-ui/public/board-room.js:493",
145
+ "modules/hall-ui/public/board-room.js:433",
146
146
  "modules/hall-ui/public/gate.js:219",
147
- "modules/hall-ui/public/government.js:933",
147
+ "modules/hall-ui/public/government.js:879",
148
148
  "modules/hall-ui/public/harbor.js:337",
149
149
  "modules/hall-ui/public/watch.js:1265"
150
150
  ]
@@ -302,7 +302,7 @@
302
302
  "occurrences": 3,
303
303
  "at": [
304
304
  "modules/hall-ui/public/gate.js:222",
305
- "modules/hall-ui/public/government.js:936",
305
+ "modules/hall-ui/public/government.js:882",
306
306
  "modules/hall-ui/public/harbor.js:340"
307
307
  ]
308
308
  },
@@ -1937,7 +1937,7 @@
1937
1937
  "surface": "builders-hall",
1938
1938
  "text": ", // membership",
1939
1939
  "file": "modules/hall-ui/public/board-room.js",
1940
- "line": 252,
1940
+ "line": 220,
1941
1941
  "origin": "js-markup",
1942
1942
  "confidence": "certain"
1943
1943
  },
@@ -1973,7 +1973,7 @@
1973
1973
  "surface": "builders-hall",
1974
1974
  "text": ", never quietly ratified — so a clock is worth proposing. The recommended sitting is",
1975
1975
  "file": "modules/hall-ui/public/government.js",
1976
- "line": 641,
1976
+ "line": 605,
1977
1977
  "origin": "js-markup",
1978
1978
  "confidence": "certain"
1979
1979
  },
@@ -2396,7 +2396,7 @@
2396
2396
  "surface": "builders-hall",
2397
2397
  "text": "Amendment {…} passed{…}, and the constitution below is not the one it decided:",
2398
2398
  "file": "modules/hall-ui/public/government.js",
2399
- "line": 669,
2399
+ "line": 633,
2400
2400
  "origin": "js-markup",
2401
2401
  "confidence": "certain"
2402
2402
  },
@@ -2540,7 +2540,7 @@
2540
2540
  "surface": "builders-hall",
2541
2541
  "text": "As configuration:",
2542
2542
  "file": "modules/hall-ui/public/government.js",
2543
- "line": 886,
2543
+ "line": 829,
2544
2544
  "origin": "js-markup",
2545
2545
  "confidence": "certain"
2546
2546
  },
@@ -2585,7 +2585,7 @@
2585
2585
  "surface": "builders-hall",
2586
2586
  "text": "Assigned {…} to builder {…}.",
2587
2587
  "file": "modules/hall-ui/public/government.js",
2588
- "line": 472,
2588
+ "line": 463,
2589
2589
  "origin": "js-notice",
2590
2590
  "confidence": "certain"
2591
2591
  },
@@ -2612,7 +2612,7 @@
2612
2612
  "surface": "builders-hall",
2613
2613
  "text": "Available from the {…} rank up.",
2614
2614
  "file": "modules/hall-ui/public/government.js",
2615
- "line": 936,
2615
+ "line": 882,
2616
2616
  "origin": "js-text-assign",
2617
2617
  "confidence": "certain"
2618
2618
  },
@@ -2945,7 +2945,7 @@
2945
2945
  "surface": "builders-hall",
2946
2946
  "text": "Cast objection",
2947
2947
  "file": "modules/hall-ui/public/board-room.js",
2948
- "line": 336,
2948
+ "line": 276,
2949
2949
  "origin": "js-markup",
2950
2950
  "confidence": "certain"
2951
2951
  },
@@ -3026,7 +3026,7 @@
3026
3026
  "surface": "builders-hall",
3027
3027
  "text": "Charter library",
3028
3028
  "file": "modules/hall-ui/public/government.js",
3029
- "line": 856,
3029
+ "line": 799,
3030
3030
  "origin": "js-markup",
3031
3031
  "confidence": "certain"
3032
3032
  },
@@ -3593,7 +3593,7 @@
3593
3593
  "surface": "builders-hall",
3594
3594
  "text": "Could not assign: {…}",
3595
3595
  "file": "modules/hall-ui/public/government.js",
3596
- "line": 477,
3596
+ "line": 468,
3597
3597
  "origin": "js-notice",
3598
3598
  "confidence": "certain"
3599
3599
  },
@@ -3692,7 +3692,7 @@
3692
3692
  "surface": "builders-hall",
3693
3693
  "text": "Could not create rank: {…}",
3694
3694
  "file": "modules/hall-ui/public/government.js",
3695
- "line": 457,
3695
+ "line": 448,
3696
3696
  "origin": "js-notice",
3697
3697
  "confidence": "certain"
3698
3698
  },
@@ -3935,7 +3935,7 @@
3935
3935
  "surface": "builders-hall",
3936
3936
  "text": "Could not remove: {…}",
3937
3937
  "file": "modules/hall-ui/public/government.js",
3938
- "line": 378,
3938
+ "line": 369,
3939
3939
  "origin": "js-notice",
3940
3940
  "confidence": "certain"
3941
3941
  },
@@ -3944,7 +3944,7 @@
3944
3944
  "surface": "builders-hall",
3945
3945
  "text": "Could not reset: {…}",
3946
3946
  "file": "modules/hall-ui/public/government.js",
3947
- "line": 310,
3947
+ "line": 301,
3948
3948
  "origin": "js-notice",
3949
3949
  "confidence": "certain"
3950
3950
  },
@@ -4196,7 +4196,7 @@
4196
4196
  "surface": "builders-hall",
4197
4197
  "text": "Could not vote: {…}",
4198
4198
  "file": "modules/hall-ui/public/board-room.js",
4199
- "line": 364,
4199
+ "line": 304,
4200
4200
  "origin": "js-notice",
4201
4201
  "confidence": "certain"
4202
4202
  },
@@ -4214,7 +4214,7 @@
4214
4214
  "surface": "builders-hall",
4215
4215
  "text": "Could not {…}: {…}",
4216
4216
  "file": "modules/hall-ui/public/government.js",
4217
- "line": 323,
4217
+ "line": 314,
4218
4218
  "origin": "js-notice",
4219
4219
  "confidence": "certain"
4220
4220
  },
@@ -4232,7 +4232,7 @@
4232
4232
  "surface": "builders-hall",
4233
4233
  "text": "Create a custom rank first.",
4234
4234
  "file": "modules/hall-ui/public/government.js",
4235
- "line": 468,
4235
+ "line": 459,
4236
4236
  "origin": "js-notice",
4237
4237
  "confidence": "certain"
4238
4238
  },
@@ -4268,7 +4268,7 @@
4268
4268
  "surface": "builders-hall",
4269
4269
  "text": "Created rank {…}.",
4270
4270
  "file": "modules/hall-ui/public/government.js",
4271
- "line": 451,
4271
+ "line": 442,
4272
4272
  "origin": "js-notice",
4273
4273
  "confidence": "certain"
4274
4274
  },
@@ -4700,7 +4700,7 @@
4700
4700
  "surface": "builders-hall",
4701
4701
  "text": "Every closed amendment sitting, ratified and returned alike, with the rule it was decided under.",
4702
4702
  "file": "modules/hall-ui/public/government.js",
4703
- "line": 896,
4703
+ "line": 839,
4704
4704
  "origin": "js-markup",
4705
4705
  "confidence": "certain"
4706
4706
  },
@@ -4736,7 +4736,7 @@
4736
4736
  "surface": "builders-hall",
4737
4737
  "text": "Every sitting since has been decided under the constitution below, not the ratified one. Nothing is re-applied automatically — a constitution is changed by a board act, never by a page. Put the amendment back to the board, or ask an operator to check this instance's own configuration.",
4738
4738
  "file": "modules/hall-ui/public/government.js",
4739
- "line": 669,
4739
+ "line": 633,
4740
4740
  "origin": "js-markup",
4741
4741
  "confidence": "certain"
4742
4742
  },
@@ -5348,7 +5348,7 @@
5348
5348
  "surface": "builders-hall",
5349
5349
  "text": "How it has changed",
5350
5350
  "file": "modules/hall-ui/public/government.js",
5351
- "line": 896,
5351
+ "line": 839,
5352
5352
  "origin": "js-markup",
5353
5353
  "confidence": "certain"
5354
5354
  },
@@ -5420,7 +5420,7 @@
5420
5420
  "surface": "builders-hall",
5421
5421
  "text": "How this project is governed.",
5422
5422
  "file": "modules/hall-ui/public/government.js",
5423
- "line": 974,
5423
+ "line": 920,
5424
5424
  "origin": "js-text-assign",
5425
5425
  "confidence": "certain"
5426
5426
  },
@@ -5681,7 +5681,7 @@
5681
5681
  "surface": "builders-hall",
5682
5682
  "text": "It cleared the completeness grade at {…}/100.",
5683
5683
  "file": "modules/hall-ui/public/board-room.js",
5684
- "line": 306,
5684
+ "line": 246,
5685
5685
  "origin": "js-markup",
5686
5686
  "confidence": "certain"
5687
5687
  },
@@ -6032,7 +6032,7 @@
6032
6032
  "surface": "builders-hall",
6033
6033
  "text": "Loading sittings…",
6034
6034
  "file": "modules/hall-ui/public/board-room.js",
6035
- "line": 511,
6035
+ "line": 451,
6036
6036
  "origin": "js-text-assign",
6037
6037
  "confidence": "certain"
6038
6038
  },
@@ -6536,7 +6536,7 @@
6536
6536
  "surface": "builders-hall",
6537
6537
  "text": "No custom ranks yet",
6538
6538
  "file": "modules/hall-ui/public/government.js",
6539
- "line": 367,
6539
+ "line": 358,
6540
6540
  "origin": "js-markup",
6541
6541
  "confidence": "certain"
6542
6542
  },
@@ -7355,7 +7355,7 @@
7355
7355
  "surface": "builders-hall",
7356
7356
  "text": "Permissions is the Archon administration surface. The Constitution and the Board Room are yours to read.",
7357
7357
  "file": "modules/hall-ui/public/government.js",
7358
- "line": 950,
7358
+ "line": 896,
7359
7359
  "origin": "js-markup",
7360
7360
  "confidence": "certain"
7361
7361
  },
@@ -7958,7 +7958,7 @@
7958
7958
  "surface": "builders-hall",
7959
7959
  "text": "Removed {…} from builder {…}.",
7960
7960
  "file": "modules/hall-ui/public/government.js",
7961
- "line": 374,
7961
+ "line": 365,
7962
7962
  "origin": "js-notice",
7963
7963
  "confidence": "certain"
7964
7964
  },
@@ -8120,7 +8120,7 @@
8120
8120
  "surface": "builders-hall",
8121
8121
  "text": "Reset to default",
8122
8122
  "file": "modules/hall-ui/public/government.js",
8123
- "line": 276,
8123
+ "line": 267,
8124
8124
  "origin": "js-text-assign",
8125
8125
  "confidence": "certain"
8126
8126
  },
@@ -8138,7 +8138,7 @@
8138
8138
  "surface": "builders-hall",
8139
8139
  "text": "Reset {…} to its default permissions?\\n\\nEvery change you've made to this rank is discarded, and it takes effect for every builder at this rank on their next request.",
8140
8140
  "file": "modules/hall-ui/public/government.js",
8141
- "line": 302,
8141
+ "line": 293,
8142
8142
  "origin": "js-notice",
8143
8143
  "confidence": "certain"
8144
8144
  },
@@ -8156,7 +8156,7 @@
8156
8156
  "surface": "builders-hall",
8157
8157
  "text": "Restricted.",
8158
8158
  "file": "modules/hall-ui/public/board-room.js",
8159
- "line": 493,
8159
+ "line": 433,
8160
8160
  "origin": "js-text-assign",
8161
8161
  "confidence": "certain"
8162
8162
  },
@@ -8174,7 +8174,7 @@
8174
8174
  "surface": "builders-hall",
8175
8175
  "text": "Restricted.",
8176
8176
  "file": "modules/hall-ui/public/government.js",
8177
- "line": 933,
8177
+ "line": 879,
8178
8178
  "origin": "js-text-assign",
8179
8179
  "confidence": "certain"
8180
8180
  },
@@ -8471,7 +8471,7 @@
8471
8471
  "surface": "builders-hall",
8472
8472
  "text": "Selectable today",
8473
8473
  "file": "modules/hall-ui/public/government.js",
8474
- "line": 856,
8474
+ "line": 799,
8475
8475
  "origin": "js-markup",
8476
8476
  "confidence": "certain"
8477
8477
  },
@@ -9173,7 +9173,7 @@
9173
9173
  "surface": "builders-hall",
9174
9174
  "text": "The Board Room is open to the builders this project’s constitution seats on its board.",
9175
9175
  "file": "modules/hall-ui/public/board-room.js",
9176
- "line": 496,
9176
+ "line": 436,
9177
9177
  "origin": "js-text-assign",
9178
9178
  "confidence": "certain"
9179
9179
  },
@@ -9227,7 +9227,7 @@
9227
9227
  "surface": "builders-hall",
9228
9228
  "text": "The board ratified a change that is not in force.",
9229
9229
  "file": "modules/hall-ui/public/government.js",
9230
- "line": 669,
9230
+ "line": 633,
9231
9231
  "origin": "js-markup",
9232
9232
  "confidence": "certain"
9233
9233
  },
@@ -9263,7 +9263,7 @@
9263
9263
  "surface": "builders-hall",
9264
9264
  "text": "The developmental ladder: {…}. Formality is adopted only where informal coordination breaks.",
9265
9265
  "file": "modules/hall-ui/public/government.js",
9266
- "line": 863,
9266
+ "line": 806,
9267
9267
  "origin": "js-markup",
9268
9268
  "confidence": "certain"
9269
9269
  },
@@ -9542,7 +9542,7 @@
9542
9542
  "surface": "builders-hall",
9543
9543
  "text": "The seven government structures, for getting a team up to speed before deciding when to flip a switch.",
9544
9544
  "file": "modules/hall-ui/public/government.js",
9545
- "line": 856,
9545
+ "line": 799,
9546
9546
  "origin": "js-markup",
9547
9547
  "confidence": "certain"
9548
9548
  },
@@ -9902,7 +9902,7 @@
9902
9902
  "surface": "builders-hall",
9903
9903
  "text": "This sends the idea back to its author. Say why, and which section.",
9904
9904
  "file": "modules/hall-ui/public/board-room.js",
9905
- "line": 336,
9905
+ "line": 276,
9906
9906
  "origin": "js-markup",
9907
9907
  "confidence": "certain"
9908
9908
  },
@@ -10091,7 +10091,7 @@
10091
10091
  "surface": "builders-hall",
10092
10092
  "text": "Vote yes",
10093
10093
  "file": "modules/hall-ui/public/board-room.js",
10094
- "line": 336,
10094
+ "line": 276,
10095
10095
  "origin": "js-markup",
10096
10096
  "confidence": "certain"
10097
10097
  },
@@ -10433,7 +10433,7 @@
10433
10433
  "surface": "builders-hall",
10434
10434
  "text": "Why — the reason the author will act on",
10435
10435
  "file": "modules/hall-ui/public/board-room.js",
10436
- "line": 336,
10436
+ "line": 276,
10437
10437
  "origin": "js-markup",
10438
10438
  "confidence": "certain"
10439
10439
  },
@@ -10631,7 +10631,7 @@
10631
10631
  "surface": "builders-hall",
10632
10632
  "text": "You {…}. One vote per member.",
10633
10633
  "file": "modules/hall-ui/public/board-room.js",
10634
- "line": 408,
10634
+ "line": 348,
10635
10635
  "origin": "js-markup",
10636
10636
  "confidence": "certain"
10637
10637
  },
@@ -10793,7 +10793,7 @@
10793
10793
  "surface": "builders-hall",
10794
10794
  "text": "Your own idea. You may vote, but it can’t be decided by your vote alone, and a vote on your own idea earns no karma.",
10795
10795
  "file": "modules/hall-ui/public/board-room.js",
10796
- "line": 334,
10796
+ "line": 274,
10797
10797
  "origin": "js-markup",
10798
10798
  "confidence": "certain"
10799
10799
  },
@@ -10982,7 +10982,7 @@
10982
10982
  "surface": "builders-hall",
10983
10983
  "text": "active builder{…}: {…}",
10984
10984
  "file": "modules/hall-ui/public/government.js",
10985
- "line": 856,
10985
+ "line": 799,
10986
10986
  "origin": "js-markup",
10987
10987
  "confidence": "certain"
10988
10988
  },
@@ -11054,7 +11054,7 @@
11054
11054
  "surface": "builders-hall",
11055
11055
  "text": "as configuration: {…}",
11056
11056
  "file": "modules/hall-ui/public/government.js",
11057
- "line": 842,
11057
+ "line": 785,
11058
11058
  "origin": "js-markup",
11059
11059
  "confidence": "certain"
11060
11060
  },
@@ -11144,7 +11144,7 @@
11144
11144
  "surface": "builders-hall",
11145
11145
  "text": "cannot be read, so",
11146
11146
  "file": "modules/hall-ui/public/government.js",
11147
- "line": 583,
11147
+ "line": 547,
11148
11148
  "origin": "js-markup",
11149
11149
  "confidence": "certain"
11150
11150
  },
@@ -11306,7 +11306,7 @@
11306
11306
  "surface": "builders-hall",
11307
11307
  "text": "first vote",
11308
11308
  "file": "modules/hall-ui/public/government.js",
11309
- "line": 606,
11309
+ "line": 570,
11310
11310
  "origin": "js-markup",
11311
11311
  "confidence": "certain"
11312
11312
  },
@@ -11594,7 +11594,7 @@
11594
11594
  "surface": "builders-hall",
11595
11595
  "text": "means expressible through the real configuration — a rank-based membership plus a pass rule — with no new code. This project has",
11596
11596
  "file": "modules/hall-ui/public/government.js",
11597
- "line": 856,
11597
+ "line": 799,
11598
11598
  "origin": "js-markup",
11599
11599
  "confidence": "certain"
11600
11600
  },
@@ -11666,7 +11666,7 @@
11666
11666
  "surface": "builders-hall",
11667
11667
  "text": "no clock",
11668
11668
  "file": "modules/hall-ui/public/government.js",
11669
- "line": 643,
11669
+ "line": 607,
11670
11670
  "origin": "js-markup",
11671
11671
  "confidence": "certain"
11672
11672
  },
@@ -11774,7 +11774,7 @@
11774
11774
  "surface": "builders-hall",
11775
11775
  "text": "objected to",
11776
11776
  "file": "modules/hall-ui/public/board-room.js",
11777
- "line": 200,
11777
+ "line": 168,
11778
11778
  "origin": "js-markup",
11779
11779
  "confidence": "certain"
11780
11780
  },
@@ -11873,7 +11873,7 @@
11873
11873
  "surface": "builders-hall",
11874
11874
  "text": "or above",
11875
11875
  "file": "modules/hall-ui/public/government.js",
11876
- "line": 600,
11876
+ "line": 564,
11877
11877
  "origin": "js-markup",
11878
11878
  "confidence": "certain"
11879
11879
  },
@@ -12224,7 +12224,7 @@
12224
12224
  "surface": "builders-hall",
12225
12225
  "text": "unanimous agreement",
12226
12226
  "file": "modules/hall-ui/public/government.js",
12227
- "line": 623,
12227
+ "line": 587,
12228
12228
  "origin": "js-markup",
12229
12229
  "confidence": "certain"
12230
12230
  },
@@ -12350,7 +12350,7 @@
12350
12350
  "surface": "builders-hall",
12351
12351
  "text": "your vote",
12352
12352
  "file": "modules/hall-ui/public/board-room.js",
12353
- "line": 195,
12353
+ "line": 163,
12354
12354
  "origin": "js-markup",
12355
12355
  "confidence": "certain"
12356
12356
  },
@@ -12602,7 +12602,7 @@
12602
12602
  "surface": "builders-hall",
12603
12603
  "text": "{…} proposed",
12604
12604
  "file": "modules/hall-ui/public/government.js",
12605
- "line": 760,
12605
+ "line": 695,
12606
12606
  "origin": "js-markup",
12607
12607
  "confidence": "certain"
12608
12608
  },
@@ -12611,7 +12611,7 @@
12611
12611
  "surface": "builders-hall",
12612
12612
  "text": "{…} reset to its default {…} permissions.",
12613
12613
  "file": "modules/hall-ui/public/government.js",
12614
- "line": 306,
12614
+ "line": 297,
12615
12615
  "origin": "js-notice",
12616
12616
  "confidence": "certain"
12617
12617
  },
@@ -12782,7 +12782,7 @@
12782
12782
  "surface": "builders-hall",
12783
12783
  "text": "{…} · who votes, and how it {…}",
12784
12784
  "file": "modules/hall-ui/public/board-room.js",
12785
- "line": 417,
12785
+ "line": 357,
12786
12786
  "origin": "js-markup",
12787
12787
  "confidence": "certain"
12788
12788
  },
@@ -12854,7 +12854,7 @@
12854
12854
  "surface": "builders-hall",
12855
12855
  "text": "{…}s only",
12856
12856
  "file": "modules/hall-ui/public/government.js",
12857
- "line": 950,
12857
+ "line": 896,
12858
12858
  "origin": "js-markup",
12859
12859
  "confidence": "certain"
12860
12860
  },
@@ -1759,5 +1759,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
1759
1759
  landed since 1.19.653 with no explicit bump. run 34544345437. (task 1002620)
1760
1760
  1.19.655 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1761
1761
  landed since 1.19.654 with no explicit bump. run 34545744588. (task 1002620)
1762
+ 1.19.656 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1763
+ landed since 1.19.655 with no explicit bump. run 34546461767. (task 1002620)
1764
+ 1.19.657 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1765
+ landed since 1.19.656 with no explicit bump. run 34546894776. (task 1002620)
1762
1766
  ---------------------------------------------------------------------------
1763
1767
  ```
@@ -0,0 +1,165 @@
1
+ // modules/hall-ui/public/board-lib.js — the vocabulary the Government page and
2
+ // the Board Room BOTH speak (task 1003761; the carve that split them is ADR 0266).
3
+ //
4
+ // WHY THIS FILE EXISTS. ADR 0266 carved the Board Room onto its own page, and
5
+ // the carve cut straight through a shared middle: the Constitution panel (which
6
+ // stayed on /government) and the sitting card (which moved to /board-room) both
7
+ // have to say who governs, how a sitting passes, and how long it runs — in the
8
+ // same words, from the same ladder. The carve COPIED that vocabulary instead of
9
+ // hoisting it, which is the state modules/government/CLAUDE.md forbids outright:
10
+ // "The grammar is written ONCE." Task 1003094 is the bug that produced the rule.
11
+ // The failure mode is specific, not hypothetical — a Constitution panel and a
12
+ // sitting card describing the SAME board differently, one of them wrong about
13
+ // who governs.
14
+ //
15
+ // It also weakened the ladder guard. While the literal sat in two page files,
16
+ // tests/rank_tier_single_source.mjs had to allowlist BOTH, so a drift between
17
+ // them was permitted by construction: the exact-literal pin proved each matched
18
+ // the canonical ladder, but nothing held the two membershipRankKeys equal to
19
+ // EACH OTHER, and only one of them was ever lifted and run against the server
20
+ // parser. With the grammar here there is one copy to pin and one to lift.
21
+ //
22
+ // So this is the goals-lib.js / collab-lib.js precedent: a flat namespace of
23
+ // PURE presentational helpers — no page state, no fetch, no DOM. Both pages load
24
+ // it before their own script.
25
+ //
26
+ // It reads window.OTB (escapeHtml, fmtInt, rankLabel) at CALL time, never at
27
+ // load, so load order between this file and dom-utils.js cannot matter.
28
+ //
29
+ // WHAT IS DELIBERATELY NOT HERE. SECTION_LABELS and fmtRemaining have exactly
30
+ // one reader each (the Board Room), so they stay in board-room.js — this lib is
31
+ // the vocabulary the two pages SHARE, and moving a single-reader constant here
32
+ // would buy indirection without removing any drift. The same test that mirrors
33
+ // SECTION_LABELS against modules/ideas/templates.js still guards it where it is.
34
+
35
+ (() => {
36
+ 'use strict';
37
+
38
+ const esc = (s) => window.OTB.escapeHtml(s);
39
+
40
+ // The predicate grammar, in plain language (task 1003094). This MIRRORS
41
+ // modules/government/membership-predicate.js — browser code cannot import a
42
+ // server module, which is the established pattern here — and
43
+ // tests/government_constitution_view.mjs runs the two against each other over
44
+ // every predicate form.
45
+ //
46
+ // THAT TEST IS WHY ONE COPY MATTERS, and the tree was wrong about it. Three
47
+ // comments (board-room.js's header, government.js, and this array's row in
48
+ // tests/rank_tier_single_source.mjs) each claimed
49
+ // tests/government_board_vote_ui.mjs held the BOARD-ROOM copy equal to the
50
+ // server. It never did — that file has no parser assertion of any kind, so the
51
+ // second copy shipped with no behavioural pin at all while three comments said
52
+ // otherwise. With one copy the single lift covers the whole hall.
53
+ //
54
+ // Rendering the raw predicate was fine while the only form was `rank:<key>`.
55
+ // It is not fine now: `rank:metic+` would read as "builders holding the metic+
56
+ // rank", which names a rank that does not exist and hides the very thing the
57
+ // suffix says.
58
+ //
59
+ // THE LADDER LITERAL LIVES HERE NOW, and tests/rank_tier_single_source.mjs's
60
+ // STATIC_LADDER_FILES follows it here from the two page files — that array is
61
+ // what makes the copy provable rather than merely allowed.
62
+ const STANDARD_LADDER = ['xenos', 'thetes', 'metic', 'archon'];
63
+
64
+ function membershipRankKeys(predicate) {
65
+ const m = String(predicate || '');
66
+ if (!m.startsWith('rank:')) return null;
67
+ const body = m.slice(5);
68
+ if (!body) return null;
69
+ const keys = [];
70
+ for (const element of body.split(',')) {
71
+ const match = /^([a-z][a-z0-9_-]*)(\+?)$/.exec(element);
72
+ if (!match) return null;
73
+ let expanded;
74
+ if (match[2] === '+') {
75
+ const i = STANDARD_LADDER.indexOf(match[1]);
76
+ if (i === -1) return null; // "and above" is undefined off the ladder
77
+ expanded = STANDARD_LADDER.slice(i);
78
+ } else {
79
+ expanded = [match[1]];
80
+ }
81
+ for (const k of expanded) if (keys.indexOf(k) === -1) keys.push(k);
82
+ }
83
+ return keys.length ? keys : null;
84
+ }
85
+
86
+ // A list of rank keys as their display labels, in a phrase a person would say
87
+ // ("Metic or Archon"). Rank KEYS never surface: the label comes from the
88
+ // branding pack via OTB.rankLabel, as on every other hall surface. The one
89
+ // place a raw predicate still shows is an UNREADABLE one, where the broken
90
+ // string is the actionable fact and hiding it would help nobody — that branch
91
+ // belongs to the caller.
92
+ //
93
+ // government.js's membershipSentence spells its own labels inline because it
94
+ // wraps each in <strong>; do not route it through here expecting one wording.
95
+ function rankNames(keys) {
96
+ const labels = keys.map((k) => esc(window.OTB.rankLabel(k)));
97
+ if (labels.length === 1) return labels[0];
98
+ return `${labels.slice(0, -1).join(', ')} or ${labels[labels.length - 1]}`;
99
+ }
100
+
101
+ // A sitting length in the unit a person would say it in. The config stores
102
+ // minutes; "2880 minutes" is a number nobody converts in their head. Read by
103
+ // the Constitution panel's windowSentence AND the sitting card — the two
104
+ // readers whose "keep it in step by hand" note this file retires.
105
+ function fmtWindow(minutes) {
106
+ const m = Number(minutes);
107
+ if (!Number.isFinite(m) || m <= 0) return `${esc(String(minutes))} minutes`;
108
+ const plural = (n, word) => `${n} ${word}${n === 1 ? '' : 's'}`;
109
+ if (m % 1440 === 0) return plural(m / 1440, 'day');
110
+ if (m % 60 === 0) return plural(m / 60, 'hour');
111
+ return plural(m, 'minute');
112
+ }
113
+
114
+ // The two renderings of ONE vocabulary: the short name for a place a sentence
115
+ // will not fit (the amendment-history line on /government), and the sentence
116
+ // itself (the sitting card on /board-room). They had one reader each and lived
117
+ // in separate files, which is how two descriptions of the same pass rule drift
118
+ // apart. Adjacent here, they cannot.
119
+ const PASS_RULE_NAME = {
120
+ first_ratifier: 'by first ratifier',
121
+ consent: 'by consent',
122
+ majority: 'by majority',
123
+ unanimous: 'by unanimous agreement',
124
+ };
125
+
126
+ const PASS_RULE_PLAIN = {
127
+ first_ratifier: 'The first vote decides it: a yes ratifies, an objection returns it to its author.',
128
+ consent: 'It passes unless someone objects — silence is agreement, and one reasoned objection returns it.',
129
+ majority: 'It passes only when more than half the board votes yes. Silence is not agreement here.',
130
+ unanimous: 'Everyone who votes must vote yes, and at least one member must. One objection sends it back for revision.',
131
+ };
132
+
133
+ // ---- shared row pieces ---------------------------------------------------
134
+ //
135
+ // board-room.js's header called these per-page boilerplate "by convention
136
+ // (gate.js, harbor.js and watch.js each carry their own)". That is not what
137
+ // the tree says: those three write .fact-pill markup inline and carry no such
138
+ // helper. This exact trio is declared in precisely two files — these two — as
139
+ // byte-identical copies, so it is a two-file duplication like the rest.
140
+
141
+ // A state pill in the shell's vocabulary. `mod` is one of the .fact-pill
142
+ // states (ok / warn / danger / info / quiet); the label is what the reader sees.
143
+ const pill = (mod, label) => `<span class="fact-pill fact-pill--${mod}">${esc(label)}</span>`;
144
+
145
+ const groupHead = (name, n, note) =>
146
+ `<div class="ov-group__head"><span class="ov-group__name">${esc(name)}</span>` +
147
+ (n === undefined ? '' : `<span class="ov-group__n">${window.OTB.fmtInt(n)}</span>`) +
148
+ (note ? `<span class="ov-group__note">${esc(note)}</span>` : '') +
149
+ '</div>';
150
+
151
+ // A timestamp the way the rows have always shown one: "2026-08-30 14:05".
152
+ const when = (iso) => esc(String(iso || '').slice(0, 16).replace('T', ' '));
153
+
154
+ window.OTBBoardLib = {
155
+ STANDARD_LADDER,
156
+ membershipRankKeys,
157
+ rankNames,
158
+ fmtWindow,
159
+ PASS_RULE_NAME,
160
+ PASS_RULE_PLAIN,
161
+ pill,
162
+ groupHead,
163
+ when,
164
+ };
165
+ })();