@bongos/core 1.19.816 → 1.19.817
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.
- package/.bongos-core.json +44 -34
- package/.claude/skills/worktree-clean/SKILL.md +3 -2
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +6 -0
- package/clients/bongos-client/index.cjs +6 -0
- package/clients/bongos-client/index.d.ts +9 -0
- package/clients/bongos-client/index.mjs +6 -0
- package/docs/api/openapi.json +178 -3
- package/docs/api-reference.md +5 -2
- package/docs/copy-inventory.md +41 -38
- package/docs/copy-registry.json +67 -40
- package/docs/module-api-changelog.md +2 -0
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +6 -0
- package/modules/government/catalog.js +1 -1
- package/modules/hall-ui/public/settings-specialities.js +56 -2
- package/modules/hall-ui/public/settings.html +1 -0
- package/modules/lifecycle/routes/task-route-helpers.js +50 -3
- package/modules/specialities/db.js +41 -2
- package/modules/specialities/migrations/specialities_002_offered.sql +57 -0
- package/modules/specialities/routes/specialities.js +64 -0
- package/modules/specialities/specialities.js +30 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/category-advisory-guard.js +49 -8
- package/scripts/gds/stale-worktrees.js +50 -6
- package/src/module-api.js +1 -1
- package/tests/government_require_permission.mjs +90 -14
- package/tests/migration_allocation.mjs +70 -0
- package/tests/speciality_offered.mjs +212 -0
- package/tests/stale_worktrees.mjs +54 -0
package/docs/copy-registry.json
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"generator": "scripts/gds/copy-inventory.js",
|
|
4
4
|
"goal": 1000074,
|
|
5
5
|
"counts": {
|
|
6
|
-
"strings":
|
|
7
|
-
"unique_ids":
|
|
8
|
-
"certain":
|
|
6
|
+
"strings": 1863,
|
|
7
|
+
"unique_ids": 1617,
|
|
8
|
+
"certain": 1863,
|
|
9
9
|
"heuristic": 0,
|
|
10
10
|
"duplicate_ids": 170
|
|
11
11
|
},
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"builders-hall": {
|
|
14
14
|
"at": "modules/hall-ui/public",
|
|
15
15
|
"files": 86,
|
|
16
|
-
"strings":
|
|
16
|
+
"strings": 1373
|
|
17
17
|
},
|
|
18
18
|
"status-dashboard": {
|
|
19
19
|
"at": "modules/status-ui/public",
|
|
@@ -911,7 +911,7 @@
|
|
|
911
911
|
"occurrences": 2,
|
|
912
912
|
"at": [
|
|
913
913
|
"modules/hall-ui/public/settings.html:260",
|
|
914
|
-
"modules/hall-ui/public/settings.html:
|
|
914
|
+
"modules/hall-ui/public/settings.html:366"
|
|
915
915
|
]
|
|
916
916
|
},
|
|
917
917
|
{
|
|
@@ -2010,7 +2010,7 @@
|
|
|
2010
2010
|
"surface": "builders-hall",
|
|
2011
2011
|
"text": ", claiming, and shipping show — spend on explaining themselves. Richer cards say more and cost more tokens; leaner ones carry the same facts for less. By default this follows how Claude talks to you, so you can set it once in",
|
|
2012
2012
|
"file": "modules/hall-ui/public/settings.html",
|
|
2013
|
-
"line":
|
|
2013
|
+
"line": 362,
|
|
2014
2014
|
"origin": "html-text",
|
|
2015
2015
|
"confidence": "certain"
|
|
2016
2016
|
},
|
|
@@ -2298,7 +2298,7 @@
|
|
|
2298
2298
|
"surface": "builders-hall",
|
|
2299
2299
|
"text": "A sound plays at each turn of your work — a gentle chime when Claude finishes, a flourish when a task ships or your rank rises. Turn off any you would rather not hear.",
|
|
2300
2300
|
"file": "modules/hall-ui/public/settings.html",
|
|
2301
|
-
"line":
|
|
2301
|
+
"line": 398,
|
|
2302
2302
|
"origin": "html-text",
|
|
2303
2303
|
"confidence": "certain"
|
|
2304
2304
|
},
|
|
@@ -2595,7 +2595,7 @@
|
|
|
2595
2595
|
"surface": "builders-hall",
|
|
2596
2596
|
"text": "Anyone in the owning project",
|
|
2597
2597
|
"file": "modules/hall-ui/public/settings.html",
|
|
2598
|
-
"line":
|
|
2598
|
+
"line": 318,
|
|
2599
2599
|
"origin": "html-text",
|
|
2600
2600
|
"confidence": "certain"
|
|
2601
2601
|
},
|
|
@@ -2604,7 +2604,7 @@
|
|
|
2604
2604
|
"surface": "builders-hall",
|
|
2605
2605
|
"text": "Anyone on this instance",
|
|
2606
2606
|
"file": "modules/hall-ui/public/settings.html",
|
|
2607
|
-
"line":
|
|
2607
|
+
"line": 319,
|
|
2608
2608
|
"origin": "html-text",
|
|
2609
2609
|
"confidence": "certain"
|
|
2610
2610
|
},
|
|
@@ -2712,7 +2712,7 @@
|
|
|
2712
2712
|
"surface": "builders-hall",
|
|
2713
2713
|
"text": "Argue from mechanism, not vibes. Always name the assumption a number rests on.",
|
|
2714
2714
|
"file": "modules/hall-ui/public/settings.html",
|
|
2715
|
-
"line":
|
|
2715
|
+
"line": 312,
|
|
2716
2716
|
"origin": "html-attr:placeholder",
|
|
2717
2717
|
"confidence": "certain"
|
|
2718
2718
|
},
|
|
@@ -3153,7 +3153,7 @@
|
|
|
3153
3153
|
"surface": "builders-hall",
|
|
3154
3154
|
"text": "Changes save at once and take effect the next time you start a session on this machine.",
|
|
3155
3155
|
"file": "modules/hall-ui/public/settings.html",
|
|
3156
|
-
"line":
|
|
3156
|
+
"line": 409,
|
|
3157
3157
|
"origin": "html-text",
|
|
3158
3158
|
"confidence": "certain"
|
|
3159
3159
|
},
|
|
@@ -3162,7 +3162,7 @@
|
|
|
3162
3162
|
"surface": "builders-hall",
|
|
3163
3163
|
"text": "Changes save at once. Your new choice plays the next time that event fires.",
|
|
3164
3164
|
"file": "modules/hall-ui/public/settings.html",
|
|
3165
|
-
"line":
|
|
3165
|
+
"line": 422,
|
|
3166
3166
|
"origin": "html-text",
|
|
3167
3167
|
"confidence": "certain"
|
|
3168
3168
|
},
|
|
@@ -3171,7 +3171,7 @@
|
|
|
3171
3171
|
"surface": "builders-hall",
|
|
3172
3172
|
"text": "Changes save the moment you pick. “Default” clears your override and falls back to the system's choice.",
|
|
3173
3173
|
"file": "modules/hall-ui/public/settings.html",
|
|
3174
|
-
"line":
|
|
3174
|
+
"line": 392,
|
|
3175
3175
|
"origin": "html-text",
|
|
3176
3176
|
"confidence": "certain"
|
|
3177
3177
|
},
|
|
@@ -3252,7 +3252,7 @@
|
|
|
3252
3252
|
"surface": "builders-hall",
|
|
3253
3253
|
"text": "Choose which sound plays for each build event — one when Claude waits for your input, another when a task ships, a coin clink when {{currency}} arrive. Each event offers a small set of choices; more will be added as new audio ships.",
|
|
3254
3254
|
"file": "modules/hall-ui/public/settings.html",
|
|
3255
|
-
"line":
|
|
3255
|
+
"line": 415,
|
|
3256
3256
|
"origin": "html-text",
|
|
3257
3257
|
"confidence": "certain"
|
|
3258
3258
|
},
|
|
@@ -4440,7 +4440,7 @@
|
|
|
4440
4440
|
"surface": "builders-hall",
|
|
4441
4441
|
"text": "Craft it sits under",
|
|
4442
4442
|
"file": "modules/hall-ui/public/settings.html",
|
|
4443
|
-
"line":
|
|
4443
|
+
"line": 297,
|
|
4444
4444
|
"origin": "html-text",
|
|
4445
4445
|
"confidence": "certain"
|
|
4446
4446
|
},
|
|
@@ -4458,7 +4458,7 @@
|
|
|
4458
4458
|
"surface": "builders-hall",
|
|
4459
4459
|
"text": "Create one",
|
|
4460
4460
|
"file": "modules/hall-ui/public/settings.html",
|
|
4461
|
-
"line":
|
|
4461
|
+
"line": 291,
|
|
4462
4462
|
"origin": "html-text",
|
|
4463
4463
|
"confidence": "certain"
|
|
4464
4464
|
},
|
|
@@ -4476,7 +4476,7 @@
|
|
|
4476
4476
|
"surface": "builders-hall",
|
|
4477
4477
|
"text": "Create speciality",
|
|
4478
4478
|
"file": "modules/hall-ui/public/settings.html",
|
|
4479
|
-
"line":
|
|
4479
|
+
"line": 330,
|
|
4480
4480
|
"origin": "html-text",
|
|
4481
4481
|
"confidence": "certain"
|
|
4482
4482
|
},
|
|
@@ -4863,7 +4863,7 @@
|
|
|
4863
4863
|
"surface": "builders-hall",
|
|
4864
4864
|
"text": "Each slash-command can run on a different model. The system has a default for every skill; choose another to override it, or leave it on Default.",
|
|
4865
4865
|
"file": "modules/hall-ui/public/settings.html",
|
|
4866
|
-
"line":
|
|
4866
|
+
"line": 378,
|
|
4867
4867
|
"origin": "html-text",
|
|
4868
4868
|
"confidence": "certain"
|
|
4869
4869
|
},
|
|
@@ -4944,7 +4944,7 @@
|
|
|
4944
4944
|
"surface": "builders-hall",
|
|
4945
4945
|
"text": "Event sounds",
|
|
4946
4946
|
"file": "modules/hall-ui/public/settings.html",
|
|
4947
|
-
"line":
|
|
4947
|
+
"line": 414,
|
|
4948
4948
|
"origin": "html-text",
|
|
4949
4949
|
"confidence": "certain"
|
|
4950
4950
|
},
|
|
@@ -5592,7 +5592,7 @@
|
|
|
5592
5592
|
"surface": "builders-hall",
|
|
5593
5593
|
"text": "How Claude should engage you in it",
|
|
5594
5594
|
"file": "modules/hall-ui/public/settings.html",
|
|
5595
|
-
"line":
|
|
5595
|
+
"line": 311,
|
|
5596
5596
|
"origin": "html-text",
|
|
5597
5597
|
"confidence": "certain"
|
|
5598
5598
|
},
|
|
@@ -5610,7 +5610,7 @@
|
|
|
5610
5610
|
"surface": "builders-hall",
|
|
5611
5611
|
"text": "How Claude talks to you",
|
|
5612
5612
|
"file": "modules/hall-ui/public/settings.html",
|
|
5613
|
-
"line":
|
|
5613
|
+
"line": 366,
|
|
5614
5614
|
"origin": "html-text",
|
|
5615
5615
|
"confidence": "certain"
|
|
5616
5616
|
},
|
|
@@ -5655,7 +5655,7 @@
|
|
|
5655
5655
|
"surface": "builders-hall",
|
|
5656
5656
|
"text": "How much your session cards — what",
|
|
5657
5657
|
"file": "modules/hall-ui/public/settings.html",
|
|
5658
|
-
"line":
|
|
5658
|
+
"line": 361,
|
|
5659
5659
|
"origin": "html-text",
|
|
5660
5660
|
"confidence": "certain"
|
|
5661
5661
|
},
|
|
@@ -5673,7 +5673,7 @@
|
|
|
5673
5673
|
"surface": "builders-hall",
|
|
5674
5674
|
"text": "How readily Claude opens a",
|
|
5675
5675
|
"file": "modules/hall-ui/public/settings.html",
|
|
5676
|
-
"line":
|
|
5676
|
+
"line": 342,
|
|
5677
5677
|
"origin": "html-text",
|
|
5678
5678
|
"confidence": "certain"
|
|
5679
5679
|
},
|
|
@@ -6591,7 +6591,7 @@
|
|
|
6591
6591
|
"surface": "builders-hall",
|
|
6592
6592
|
"text": "Markets, incentives, and how to price them.",
|
|
6593
6593
|
"file": "modules/hall-ui/public/settings.html",
|
|
6594
|
-
"line":
|
|
6594
|
+
"line": 308,
|
|
6595
6595
|
"origin": "html-attr:placeholder",
|
|
6596
6596
|
"confidence": "certain"
|
|
6597
6597
|
},
|
|
@@ -6600,7 +6600,7 @@
|
|
|
6600
6600
|
"surface": "builders-hall",
|
|
6601
6601
|
"text": "May be offered for sale later",
|
|
6602
6602
|
"file": "modules/hall-ui/public/settings.html",
|
|
6603
|
-
"line":
|
|
6603
|
+
"line": 324,
|
|
6604
6604
|
"origin": "html-text",
|
|
6605
6605
|
"confidence": "certain"
|
|
6606
6606
|
},
|
|
@@ -7113,7 +7113,7 @@
|
|
|
7113
7113
|
"surface": "builders-hall",
|
|
7114
7114
|
"text": "No specialities yet. Create one below — it takes a name and a craft, and you can train it afterwards.",
|
|
7115
7115
|
"file": "modules/hall-ui/public/settings-specialities.js",
|
|
7116
|
-
"line":
|
|
7116
|
+
"line": 169,
|
|
7117
7117
|
"origin": "js-markup",
|
|
7118
7118
|
"confidence": "certain"
|
|
7119
7119
|
},
|
|
@@ -7473,7 +7473,7 @@
|
|
|
7473
7473
|
"surface": "builders-hall",
|
|
7474
7474
|
"text": "Only me",
|
|
7475
7475
|
"file": "modules/hall-ui/public/settings.html",
|
|
7476
|
-
"line":
|
|
7476
|
+
"line": 317,
|
|
7477
7477
|
"origin": "html-text",
|
|
7478
7478
|
"confidence": "certain"
|
|
7479
7479
|
},
|
|
@@ -7860,7 +7860,7 @@
|
|
|
7860
7860
|
"surface": "builders-hall",
|
|
7861
7861
|
"text": "Pick one…",
|
|
7862
7862
|
"file": "modules/hall-ui/public/settings.html",
|
|
7863
|
-
"line":
|
|
7863
|
+
"line": 299,
|
|
7864
7864
|
"origin": "html-text",
|
|
7865
7865
|
"confidence": "certain"
|
|
7866
7866
|
},
|
|
@@ -8382,7 +8382,7 @@
|
|
|
8382
8382
|
"surface": "builders-hall",
|
|
8383
8383
|
"text": "Records your decision only — there is no marketplace yet, and nothing is listed anywhere.",
|
|
8384
8384
|
"file": "modules/hall-ui/public/settings.html",
|
|
8385
|
-
"line":
|
|
8385
|
+
"line": 326,
|
|
8386
8386
|
"origin": "html-text",
|
|
8387
8387
|
"confidence": "certain"
|
|
8388
8388
|
},
|
|
@@ -8823,7 +8823,7 @@
|
|
|
8823
8823
|
"surface": "builders-hall",
|
|
8824
8824
|
"text": "Saves the moment you choose; applies from your next session.",
|
|
8825
8825
|
"file": "modules/hall-ui/public/settings.html",
|
|
8826
|
-
"line":
|
|
8826
|
+
"line": 370,
|
|
8827
8827
|
"origin": "html-text",
|
|
8828
8828
|
"confidence": "certain"
|
|
8829
8829
|
},
|
|
@@ -9363,7 +9363,7 @@
|
|
|
9363
9363
|
"surface": "builders-hall",
|
|
9364
9364
|
"text": "Skill voices",
|
|
9365
9365
|
"file": "modules/hall-ui/public/settings.html",
|
|
9366
|
-
"line":
|
|
9366
|
+
"line": 377,
|
|
9367
9367
|
"origin": "html-text",
|
|
9368
9368
|
"confidence": "certain"
|
|
9369
9369
|
},
|
|
@@ -9448,12 +9448,21 @@
|
|
|
9448
9448
|
"origin": "js-notice",
|
|
9449
9449
|
"confidence": "certain"
|
|
9450
9450
|
},
|
|
9451
|
+
{
|
|
9452
|
+
"id": "d03aa6752970",
|
|
9453
|
+
"surface": "builders-hall",
|
|
9454
|
+
"text": "Specialities this project recommends. Nothing here is switched on — read what each one adds to your sessions, then choose.",
|
|
9455
|
+
"file": "modules/hall-ui/public/settings-specialities.js",
|
|
9456
|
+
"line": 137,
|
|
9457
|
+
"origin": "js-markup",
|
|
9458
|
+
"confidence": "certain"
|
|
9459
|
+
},
|
|
9451
9460
|
{
|
|
9452
9461
|
"id": "01f1d2b03eb4",
|
|
9453
9462
|
"surface": "builders-hall",
|
|
9454
9463
|
"text": "Speciality created.",
|
|
9455
9464
|
"file": "modules/hall-ui/public/settings-specialities.js",
|
|
9456
|
-
"line":
|
|
9465
|
+
"line": 267,
|
|
9457
9466
|
"origin": "js-notice",
|
|
9458
9467
|
"confidence": "certain"
|
|
9459
9468
|
},
|
|
@@ -9534,7 +9543,7 @@
|
|
|
9534
9543
|
"surface": "builders-hall",
|
|
9535
9544
|
"text": "Stopped using it.",
|
|
9536
9545
|
"file": "modules/hall-ui/public/settings-specialities.js",
|
|
9537
|
-
"line":
|
|
9546
|
+
"line": 200,
|
|
9538
9547
|
"origin": "js-notice",
|
|
9539
9548
|
"confidence": "certain"
|
|
9540
9549
|
},
|
|
@@ -9583,6 +9592,15 @@
|
|
|
9583
9592
|
"origin": "html-text",
|
|
9584
9593
|
"confidence": "certain"
|
|
9585
9594
|
},
|
|
9595
|
+
{
|
|
9596
|
+
"id": "a1482eff4ead",
|
|
9597
|
+
"surface": "builders-hall",
|
|
9598
|
+
"text": "Suggested for you",
|
|
9599
|
+
"file": "modules/hall-ui/public/settings-specialities.js",
|
|
9600
|
+
"line": 137,
|
|
9601
|
+
"origin": "js-markup",
|
|
9602
|
+
"confidence": "certain"
|
|
9603
|
+
},
|
|
9586
9604
|
{
|
|
9587
9605
|
"id": "1e40f33483eb",
|
|
9588
9606
|
"surface": "builders-hall",
|
|
@@ -10749,7 +10767,7 @@
|
|
|
10749
10767
|
"surface": "builders-hall",
|
|
10750
10768
|
"text": "UI design",
|
|
10751
10769
|
"file": "modules/hall-ui/public/settings.html",
|
|
10752
|
-
"line":
|
|
10770
|
+
"line": 303,
|
|
10753
10771
|
"origin": "html-text",
|
|
10754
10772
|
"confidence": "certain"
|
|
10755
10773
|
},
|
|
@@ -10780,12 +10798,21 @@
|
|
|
10780
10798
|
"origin": "js-markup",
|
|
10781
10799
|
"confidence": "certain"
|
|
10782
10800
|
},
|
|
10801
|
+
{
|
|
10802
|
+
"id": "e7e2a99a2bea",
|
|
10803
|
+
"surface": "builders-hall",
|
|
10804
|
+
"text": "Use this",
|
|
10805
|
+
"file": "modules/hall-ui/public/settings-specialities.js",
|
|
10806
|
+
"line": 148,
|
|
10807
|
+
"origin": "js-markup",
|
|
10808
|
+
"confidence": "certain"
|
|
10809
|
+
},
|
|
10783
10810
|
{
|
|
10784
10811
|
"id": "e1ecd543a2ca",
|
|
10785
10812
|
"surface": "builders-hall",
|
|
10786
10813
|
"text": "Using this speciality.",
|
|
10787
10814
|
"file": "modules/hall-ui/public/settings-specialities.js",
|
|
10788
|
-
"line":
|
|
10815
|
+
"line": 199,
|
|
10789
10816
|
"origin": "js-notice",
|
|
10790
10817
|
"confidence": "certain"
|
|
10791
10818
|
},
|
|
@@ -11181,7 +11208,7 @@
|
|
|
11181
11208
|
"surface": "builders-hall",
|
|
11182
11209
|
"text": "Who can use it",
|
|
11183
11210
|
"file": "modules/hall-ui/public/settings.html",
|
|
11184
|
-
"line":
|
|
11211
|
+
"line": 315,
|
|
11185
11212
|
"origin": "html-text",
|
|
11186
11213
|
"confidence": "certain"
|
|
11187
11214
|
},
|
|
@@ -11505,7 +11532,7 @@
|
|
|
11505
11532
|
"surface": "builders-hall",
|
|
11506
11533
|
"text": "Your choice",
|
|
11507
11534
|
"file": "modules/hall-ui/public/settings.html",
|
|
11508
|
-
"line":
|
|
11535
|
+
"line": 386,
|
|
11509
11536
|
"origin": "html-text",
|
|
11510
11537
|
"confidence": "certain"
|
|
11511
11538
|
},
|
|
@@ -11883,7 +11910,7 @@
|
|
|
11883
11910
|
"surface": "builders-hall",
|
|
11884
11911
|
"text": "and leave this alone.",
|
|
11885
11912
|
"file": "modules/hall-ui/public/settings.html",
|
|
11886
|
-
"line":
|
|
11913
|
+
"line": 366,
|
|
11887
11914
|
"origin": "html-text",
|
|
11888
11915
|
"confidence": "certain"
|
|
11889
11916
|
},
|
|
@@ -12549,7 +12576,7 @@
|
|
|
12549
12576
|
"surface": "builders-hall",
|
|
12550
12577
|
"text": "new thread",
|
|
12551
12578
|
"file": "modules/hall-ui/public/settings.html",
|
|
12552
|
-
"line":
|
|
12579
|
+
"line": 343,
|
|
12553
12580
|
"origin": "html-text",
|
|
12554
12581
|
"confidence": "certain"
|
|
12555
12582
|
},
|
|
@@ -12693,7 +12720,7 @@
|
|
|
12693
12720
|
"surface": "builders-hall",
|
|
12694
12721
|
"text": "of work — a tangent, an investigation, an unprompted suggestion — instead of staying on your claimed task. It never limits the work on the task itself. Your rank sets the starting point; newcomers stay locked low.",
|
|
12695
12722
|
"file": "modules/hall-ui/public/settings.html",
|
|
12696
|
-
"line":
|
|
12723
|
+
"line": 343,
|
|
12697
12724
|
"origin": "html-text",
|
|
12698
12725
|
"confidence": "certain"
|
|
12699
12726
|
},
|
|
@@ -2106,5 +2106,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2106
2106
|
landed since 1.19.814 with no explicit bump. run 35197139985. (task 1002620)
|
|
2107
2107
|
1.19.816 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2108
2108
|
landed since 1.19.815 with no explicit bump. run 35198566737. (task 1002620)
|
|
2109
|
+
1.19.817 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2110
|
+
landed since 1.19.816 with no explicit bump. run 35200117750. (task 1002620)
|
|
2109
2111
|
---------------------------------------------------------------------------
|
|
2110
2112
|
```
|
|
@@ -856,6 +856,12 @@ function createClient(opts = {}) {
|
|
|
856
856
|
postSpecialitiesIdDocuments: (args) => request("POST", "/specialities/{id}/documents", { hasBody: true }, args),
|
|
857
857
|
// DELETE /specialities/{id}/documents/{docId} — rank: any-builder — DELETE /specialities/:id/documents/:docId
|
|
858
858
|
deleteSpecialitiesIdDocumentsDocId: (args) => request("DELETE", "/specialities/{id}/documents/{docId}", { hasBody: false }, args),
|
|
859
|
+
// POST /specialities/{id}/offer — rank: metic+archon — POST /specialities/:id/offer
|
|
860
|
+
postSpecialitiesIdOffer: (args) => request("POST", "/specialities/{id}/offer", { hasBody: true }, args),
|
|
861
|
+
// POST /specialities/{id}/unoffer — rank: metic+archon — POST /specialities/:id/unoffer
|
|
862
|
+
postSpecialitiesIdUnoffer: (args) => request("POST", "/specialities/{id}/unoffer", { hasBody: true }, args),
|
|
863
|
+
// GET /specialities/offered — rank: any-builder — GET /specialities/offered
|
|
864
|
+
getSpecialitiesOffered: (args) => request("GET", "/specialities/offered", { hasBody: false }, args),
|
|
859
865
|
},
|
|
860
866
|
"sso": {
|
|
861
867
|
// POST /sso/activity/rollup — rank: public — POST /sso/activity/rollup
|
|
@@ -238,7 +238,7 @@ const PERMISSIONS = [
|
|
|
238
238
|
// anyone in a room with a stranger on its own.
|
|
239
239
|
{ key: 'mingle.manage', system: false, floor: 'metic', guards: 'PUT /mingle/project (the project half of mingle consent), POST /mingle/round (run a pairing round) — task 1003177, goal 1000075' },
|
|
240
240
|
{ key: 'project.settings.manage', system: false, floor: 'metic', guards: "PATCH /project-settings/* — the project's own live knobs (the rot timer today) and the work-category set's shape (PATCH /work-categories/:id). Metic, matching goal.create's reasoning that extending the project's vocabulary is a planning act rather than an administrative one — task 1003280, goal 1000072" },
|
|
241
|
-
{ key: 'project.curate', system: false, floor: 'metic', guards: 'platform-identity: GET/POST /projects, /projects/invite, PATCH /projects/:id/featured, PATCH /projects/:id/status (the takedown lever — ADR 0252 §5.1), GET /scouting (ADR 0157, was archon)' },
|
|
241
|
+
{ key: 'project.curate', system: false, floor: 'metic', guards: 'platform-identity: GET/POST /projects, /projects/invite, PATCH /projects/:id/featured, PATCH /projects/:id/status (the takedown lever — ADR 0252 §5.1), GET /scouting (ADR 0157, was archon); specialities: POST /specialities/:id/{offer,unoffer} — putting the project name behind a speciality, which reaches the sessions of everyone who accepts it (task 1003972)' },
|
|
242
242
|
{ key: 'override_request.decide', system: false, floor: 'metic', guards: 'GET /override-requests, POST .../:id/decide (ADR 0157, was archon)' },
|
|
243
243
|
{ key: 'claim.release.any', system: false, floor: 'metic', scope: 'any', resource: 'claim', verb: 'release', guards: 'POST /claims/:id/release-on-behalf (ADR 0157, was archon)' },
|
|
244
244
|
{ key: 'idea.ratify', system: false, floor: 'metic', guards: 'POST /inbox/:id/ratify (ADR 0157, was archon)' },
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
const { escapeHtml, $ } = window.OTB;
|
|
25
25
|
const toast = (msg) => window.OTB.toast(msg);
|
|
26
26
|
|
|
27
|
-
const state = { rows: [], openId: null, busy: false };
|
|
27
|
+
const state = { rows: [], suggestions: [], openId: null, busy: false };
|
|
28
28
|
|
|
29
29
|
const el = (id) => document.getElementById(id);
|
|
30
30
|
const statusLine = (msg) => { const s = el('specialities-status'); if (s) s.textContent = msg || ''; };
|
|
@@ -124,7 +124,45 @@
|
|
|
124
124
|
</form>`;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
// WHAT THE PROJECT SUGGESTS. Rendered as an offer and never as a fait
|
|
128
|
+
// accompli: nothing here is adopted until the builder presses the button, and
|
|
129
|
+
// the contract is shown in full first, exactly as for any other speciality
|
|
130
|
+
// somebody else wrote. A suggestion is the project's judgement, so it says
|
|
131
|
+
// whose — a builder taking on a standing instruction should see who stood
|
|
132
|
+
// behind it.
|
|
133
|
+
function renderSuggestions() {
|
|
134
|
+
const host = el('speciality-suggestions');
|
|
135
|
+
if (!host) return;
|
|
136
|
+
if (!state.suggestions.length) { host.innerHTML = ''; return; }
|
|
137
|
+
host.innerHTML = `
|
|
138
|
+
<h3 class="speciality-create__h">Suggested for you</h3>
|
|
139
|
+
<p class="prow__hint">
|
|
140
|
+
Specialities this project recommends. Nothing here is switched on — read what
|
|
141
|
+
each one adds to your sessions, then choose.
|
|
142
|
+
</p>
|
|
143
|
+
<ul class="prows">${state.suggestions.map(suggestionHtml).join('')}</ul>`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function suggestionHtml(s) {
|
|
147
|
+
const who = s.offered_by ? ` · suggested by builder ${escapeHtml(String(s.offered_by))}` : '';
|
|
148
|
+
return `
|
|
149
|
+
<li class="prow speciality-card" data-id="${escapeHtml(String(s.id))}">
|
|
150
|
+
<div class="prow__main">
|
|
151
|
+
<div class="prow__label">
|
|
152
|
+
<strong>${escapeHtml(s.name)}</strong>
|
|
153
|
+
<span class="speciality-craft">${escapeHtml(s.discipline)}</span>
|
|
154
|
+
</div>
|
|
155
|
+
<p class="prow__hint">${escapeHtml(s.summary || 'No summary yet.')}${who}</p>
|
|
156
|
+
${contractHtml(s)}
|
|
157
|
+
</div>
|
|
158
|
+
<div class="prow__actions">
|
|
159
|
+
<button type="button" class="btn" data-act="adopt" data-id="${escapeHtml(String(s.id))}">Use this</button>
|
|
160
|
+
</div>
|
|
161
|
+
</li>`;
|
|
162
|
+
}
|
|
163
|
+
|
|
127
164
|
function render() {
|
|
165
|
+
renderSuggestions();
|
|
128
166
|
const host = el('specialities-rows');
|
|
129
167
|
if (!host) return;
|
|
130
168
|
if (!state.rows.length) {
|
|
@@ -138,8 +176,13 @@
|
|
|
138
176
|
|
|
139
177
|
async function load() {
|
|
140
178
|
try {
|
|
141
|
-
const [cat, mine] = await Promise.all([
|
|
179
|
+
const [cat, mine, offered] = await Promise.all([
|
|
180
|
+
call('GET', '/specialities'),
|
|
181
|
+
call('GET', '/me/specialities'),
|
|
182
|
+
call('GET', '/specialities/offered'),
|
|
183
|
+
]);
|
|
142
184
|
if (!cat) return;
|
|
185
|
+
state.suggestions = (offered && offered.suggestions) || [];
|
|
143
186
|
const activeIds = new Set(((mine && mine.adoptions) || []).filter((a) => a.active).map((a) => String(a.id)));
|
|
144
187
|
state.rows = ((cat && cat.specialities) || []).map((s) => ({ ...s, active: activeIds.has(String(s.id)) }));
|
|
145
188
|
render();
|
|
@@ -164,6 +207,17 @@
|
|
|
164
207
|
}
|
|
165
208
|
|
|
166
209
|
function wire() {
|
|
210
|
+
// The suggestions block reuses the same delegated handlers — an "adopt" from a
|
|
211
|
+
// suggestion and from the catalogue are the same act and must not drift.
|
|
212
|
+
const suggestHost = el('speciality-suggestions');
|
|
213
|
+
if (suggestHost) {
|
|
214
|
+
suggestHost.addEventListener('click', (e) => {
|
|
215
|
+
const btn = e.target.closest('button[data-act]');
|
|
216
|
+
if (!btn) return;
|
|
217
|
+
act(btn.dataset.act, btn.dataset.id);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
167
221
|
const host = el('specialities-rows');
|
|
168
222
|
if (host) {
|
|
169
223
|
host.addEventListener('click', (e) => {
|
|
@@ -284,6 +284,7 @@
|
|
|
284
284
|
Train it by adding things you have written; it also picks things up on its own
|
|
285
285
|
as you work.
|
|
286
286
|
</p>
|
|
287
|
+
<div id="speciality-suggestions"></div>
|
|
287
288
|
<ul class="prows" id="specialities-rows"></ul>
|
|
288
289
|
|
|
289
290
|
<form id="speciality-create" class="speciality-create">
|
|
@@ -45,8 +45,50 @@ const VALID_FITS = new Set(['autonomous', 'parallel']);
|
|
|
45
45
|
// whole-token, case-insensitive. The former scripts/gds/capture.js mirror was
|
|
46
46
|
// deleted with the same task: captured ideas have no touches[] and the server
|
|
47
47
|
// re-detects on create, so the CLI copy earned its keep no longer.
|
|
48
|
+
// task 1003910: "schema" is QUALIFIED, not bare.
|
|
49
|
+
//
|
|
50
|
+
// WHAT ACTUALLY WENT WRONG. The bug was filed as "the non-DB compound strip does
|
|
51
|
+
// not cover --json-schema". It does (the `json` arm below has always been there),
|
|
52
|
+
// and the live false positive it cites — task 1003902, flagged though it alters no
|
|
53
|
+
// table — was not triggered by the flag at all. It was triggered by a LATER,
|
|
54
|
+
// unqualified back-reference in the same paragraph: "`result` is EMPTY when a
|
|
55
|
+
// schema is in play". A bare noun, with no compound around it for any strip to
|
|
56
|
+
// catch.
|
|
57
|
+
//
|
|
58
|
+
// WHY THE SHAPE CHANGED RATHER THAN THE LIST. A blocklist of non-database
|
|
59
|
+
// compounds cannot be finished: every new way of saying "schema" about something
|
|
60
|
+
// that is not a table is another false positive, and each one costs a reserved
|
|
61
|
+
// migration number (task 1002614 burned 213), floors the task at Metic (ADR 0270)
|
|
62
|
+
// and halts an unattended chain. Enumerating `json-schema`, `schema.org` and
|
|
63
|
+
// `--output-schema` would have bought three phrasings and left the one in the bug
|
|
64
|
+
// report still flagging. So "schema" now has to be ATTACHED to a database noun or
|
|
65
|
+
// to a change verb to count — an allowlist, which fails the safe way: an
|
|
66
|
+
// unrecognised phrasing no longer flags, instead of flagging on sight.
|
|
67
|
+
//
|
|
68
|
+
// The other three keywords are untouched: `migration(s)`, `alter table` and
|
|
69
|
+
// `create table` are already unambiguous, and they are what catches genuine
|
|
70
|
+
// schema work whose prose never says the word "schema".
|
|
71
|
+
//
|
|
72
|
+
// A missed detection stays correctable by PATCH, exactly as a false one was.
|
|
73
|
+
const DB_SCHEMA_RE = [
|
|
74
|
+
// a database noun in front: "DB schema", "table-schema", "column schema"
|
|
75
|
+
/\b(?:db|database|table|column|postgres|pg|sql|index)[-\s]+schemas?\b/.source,
|
|
76
|
+
// a change noun behind: "schema change", "schema migration", "schema bump"
|
|
77
|
+
/\bschemas?[-\s]+(?:migrations?|changes?|bumps?|updates?|diffs?|drift)\b/.source,
|
|
78
|
+
// a change verb in front: "change the schema", "alter the table schema"
|
|
79
|
+
// The noun slot before "schema" excludes the API/transport nouns the old
|
|
80
|
+
// blocklist covered: a change verb is not evidence on its own, and "update the
|
|
81
|
+
// response schema" is the task 1002648 false-positive class wearing a verb.
|
|
82
|
+
// Anything else ("the task schema", "the tasks schema") still counts.
|
|
83
|
+
// The noun slot before "schema" excludes the API/transport nouns the old
|
|
84
|
+
// blocklist covered: a change verb is not evidence on its own, and "update the
|
|
85
|
+
// response schema" is the task 1002648 false-positive class wearing a verb.
|
|
86
|
+
// Anything else ("the task schema", "the tasks schema") still counts.
|
|
87
|
+
/\b(?:change|changing|alter|altering|update|updating|modify|modifying|extend|extending)\s+(?:the\s+)?(?:(?!(?:request|response|body|validation|patch|post|put|delete|json|openapi|api|error|output|input|result|payload|event)\b)\w+\s+)?schemas?\b/.source,
|
|
88
|
+
].join('|');
|
|
89
|
+
|
|
48
90
|
const MIGRATION_KEYWORD_RE =
|
|
49
|
-
/\bmigrations?\b
|
|
91
|
+
new RegExp([/\bmigrations?\b/.source, DB_SCHEMA_RE, /\balter\s+table\b/.source, /\bcreate\s+table\b/.source].join('|'), 'i');
|
|
50
92
|
|
|
51
93
|
// task 1002648 (idea 1000642): compounds where the keyword is qualified by a
|
|
52
94
|
// NON-database noun are refactor/API language, not schema work, and are blanked
|
|
@@ -59,8 +101,13 @@ const NON_DB_COMPOUND_RE = new RegExp(
|
|
|
59
101
|
[
|
|
60
102
|
/\b(?:gate|route|code)s?[-\s]+migrations?\b/.source,
|
|
61
103
|
/\bmigrations?\s+of\s+(?:gate|route|code)s?\b/.source,
|
|
62
|
-
|
|
63
|
-
|
|
104
|
+
// The API-schema arms this list used to carry (`request schema`, `:751
|
|
105
|
+
// schema`, `json schema`) are GONE, not lost: they existed only to subtract
|
|
106
|
+
// from a bare-"schema" rule that no longer exists. "the PATCH schema declares
|
|
107
|
+
// 11 keys" has no database noun and no change verb, so it never reaches a
|
|
108
|
+
// strip — and neither does the phrasing they missed. Keeping them would leave
|
|
109
|
+
// two mechanisms answering the same question, which is how the list grew a
|
|
110
|
+
// gap in the first place.
|
|
64
111
|
].join('|'),
|
|
65
112
|
'gi'
|
|
66
113
|
);
|
|
@@ -17,7 +17,8 @@ const exec = (executor) => executor || ((text, params) => pool.query(text, param
|
|
|
17
17
|
|
|
18
18
|
const COLUMNS = `id, slug, name, discipline, summary, contract_md,
|
|
19
19
|
owner_kind, owner_builder_id, owner_project_id,
|
|
20
|
-
visibility, sellable,
|
|
20
|
+
visibility, sellable, offered, offered_by, offered_at,
|
|
21
|
+
created_by, created_at, updated_at`;
|
|
21
22
|
|
|
22
23
|
async function createSpeciality(row, executor) {
|
|
23
24
|
const q = exec(executor);
|
|
@@ -225,8 +226,46 @@ async function taskDiscipline(taskId, executor) {
|
|
|
225
226
|
return (r.rows[0] && r.rows[0].discipline) || null;
|
|
226
227
|
}
|
|
227
228
|
|
|
229
|
+
// Flip the recommendation. `offered_by` and `offered_at` are written together
|
|
230
|
+
// with it so a suggestion always carries whose judgement it is — a builder
|
|
231
|
+
// deciding whether to accept a standing instruction can see who stood behind it.
|
|
232
|
+
// Clearing an offer clears the witness too rather than leaving a stale name on a
|
|
233
|
+
// recommendation nobody is making any more.
|
|
234
|
+
async function setOffered(id, { offered, builderId }, executor) {
|
|
235
|
+
const q = exec(executor);
|
|
236
|
+
const r = await q(
|
|
237
|
+
`UPDATE specialities_catalog
|
|
238
|
+
SET offered = $2,
|
|
239
|
+
offered_by = CASE WHEN $2 THEN $3::bigint ELSE NULL END,
|
|
240
|
+
offered_at = CASE WHEN $2 THEN now() ELSE NULL END,
|
|
241
|
+
updated_at = now()
|
|
242
|
+
WHERE id = $1
|
|
243
|
+
RETURNING ${COLUMNS}, offered, offered_by, offered_at`,
|
|
244
|
+
[id, !!offered, builderId || null],
|
|
245
|
+
);
|
|
246
|
+
return r.rows[0] || null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Everything on offer that this viewer could see at all. The RULE that decides
|
|
250
|
+
// what is actually suggested is specialities.offeredTo — this is the cheap
|
|
251
|
+
// prefilter, exactly as listVisibleTo is for the catalogue.
|
|
252
|
+
async function listOffered({ builderId, projectIds = [], discipline = null }, executor) {
|
|
253
|
+
const q = exec(executor);
|
|
254
|
+
const params = [builderId, projectIds.length ? projectIds : [null]];
|
|
255
|
+
let sql = `SELECT ${COLUMNS}, offered, offered_by, offered_at
|
|
256
|
+
FROM specialities_catalog
|
|
257
|
+
WHERE offered
|
|
258
|
+
AND (visibility = 'public'
|
|
259
|
+
OR (owner_kind = 'builder' AND owner_builder_id = $1)
|
|
260
|
+
OR (owner_kind = 'project' AND visibility = 'project' AND owner_project_id = ANY($2)))`;
|
|
261
|
+
if (discipline) { params.push(discipline); sql += ` AND discipline = $${params.length}`; }
|
|
262
|
+
sql += ' ORDER BY discipline ASC, name ASC';
|
|
263
|
+
const r = await q(sql, params);
|
|
264
|
+
return r.rows;
|
|
265
|
+
}
|
|
266
|
+
|
|
228
267
|
module.exports = {
|
|
229
|
-
UPDATABLE, taskDiscipline,
|
|
268
|
+
UPDATABLE, taskDiscipline, setOffered, listOffered,
|
|
230
269
|
createSpeciality, getSpeciality, listVisibleTo, updateSpeciality,
|
|
231
270
|
addDocument, listDocuments, getDocument, deleteDocument,
|
|
232
271
|
linkLearning, countTraining,
|