@bongos/core 1.19.903 → 1.19.905
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 +45 -20
- package/docs/copy-inventory.md +10 -11
- package/docs/copy-registry.json +13 -22
- package/docs/module-api-changelog.md +4 -0
- package/migrations/core_251_credit_log_idea_size_index.sql +61 -0
- package/modules/economy/credits.js +8 -0
- package/modules/economy/idea-size-historical.js +149 -0
- package/modules/economy/idea-size.js +381 -0
- package/modules/economy/reward.js +17 -0
- package/modules/hall-ui/public/collab-lib.js +22 -0
- package/modules/hall-ui/public/collab.js +17 -2
- package/modules/hall-ui/public/profile.js +42 -5
- package/modules/ideas/routes/inbox.js +9 -0
- package/modules/ideas/trail-size.js +88 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/collab_page.mjs +44 -0
- package/tests/idea_size.mjs +776 -0
package/.bongos-core.json
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/gds/package-core.js",
|
|
5
|
-
"core_version": "1.19.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.905",
|
|
6
|
+
"core_contract": "1.19.905",
|
|
7
|
+
"source_commit": "dc5ca8cc91d1d88f957f722664f60778d2bdc4f1",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-20T13:17:59.483Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 502,
|
|
13
13
|
"agent_docs_stubbed": 26,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2283,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 2811,
|
|
20
|
+
"tree_sha256": "85790109607eeddc8439f8473f642747ed158cfb88a269f55222c30bc45016e5",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -2097,12 +2097,12 @@
|
|
|
2097
2097
|
{
|
|
2098
2098
|
"path": "docs/copy-inventory.md",
|
|
2099
2099
|
"mode": "0000644",
|
|
2100
|
-
"sha256": "
|
|
2100
|
+
"sha256": "3e657714f3647bfb041f4eda9e4982a2b60747c4aceec0d8d8cbf8ee0de6eb47"
|
|
2101
2101
|
},
|
|
2102
2102
|
{
|
|
2103
2103
|
"path": "docs/copy-registry.json",
|
|
2104
2104
|
"mode": "0000644",
|
|
2105
|
-
"sha256": "
|
|
2105
|
+
"sha256": "1ba7f556256ee4cbb637b9809698c69aff529c080131949b4055058f8fb4716b"
|
|
2106
2106
|
},
|
|
2107
2107
|
{
|
|
2108
2108
|
"path": "docs/design/apex-pass-2-direction.md",
|
|
@@ -2632,7 +2632,7 @@
|
|
|
2632
2632
|
{
|
|
2633
2633
|
"path": "docs/module-api-changelog.md",
|
|
2634
2634
|
"mode": "0000644",
|
|
2635
|
-
"sha256": "
|
|
2635
|
+
"sha256": "ade94268540de319c8d071b7b70654fca4cb4bdd7bcfbbfe8ddca5710329545b"
|
|
2636
2636
|
},
|
|
2637
2637
|
{
|
|
2638
2638
|
"path": "docs/modules-contract.md",
|
|
@@ -3734,6 +3734,11 @@
|
|
|
3734
3734
|
"mode": "0000644",
|
|
3735
3735
|
"sha256": "599449a48b3850eb457a34630a7bd5d95d354602f1a9e9b887593183a457cd21"
|
|
3736
3736
|
},
|
|
3737
|
+
{
|
|
3738
|
+
"path": "migrations/core_251_credit_log_idea_size_index.sql",
|
|
3739
|
+
"mode": "0000644",
|
|
3740
|
+
"sha256": "75bb644b32a70b52ac544edb901abff91aad07701848a470cc52103dc7e74234"
|
|
3741
|
+
},
|
|
3737
3742
|
{
|
|
3738
3743
|
"path": "modules/agents/CLAUDE.md",
|
|
3739
3744
|
"mode": "0000644",
|
|
@@ -4182,7 +4187,17 @@
|
|
|
4182
4187
|
{
|
|
4183
4188
|
"path": "modules/economy/credits.js",
|
|
4184
4189
|
"mode": "0000644",
|
|
4185
|
-
"sha256": "
|
|
4190
|
+
"sha256": "736eed2c89863d6eb28072627a40ac4f8945832cfb7b1d1aba10e6cc65483901"
|
|
4191
|
+
},
|
|
4192
|
+
{
|
|
4193
|
+
"path": "modules/economy/idea-size-historical.js",
|
|
4194
|
+
"mode": "0000644",
|
|
4195
|
+
"sha256": "f99f62eb4eaeda10b32284dbe27f87e64d5b6b82c9eb4aa442057d0de13be761"
|
|
4196
|
+
},
|
|
4197
|
+
{
|
|
4198
|
+
"path": "modules/economy/idea-size.js",
|
|
4199
|
+
"mode": "0000644",
|
|
4200
|
+
"sha256": "d1fa5fda6b34bd2a8cf8d563c780bc4b12f1cdfb955e13f51799a589609ac1c0"
|
|
4186
4201
|
},
|
|
4187
4202
|
{
|
|
4188
4203
|
"path": "modules/economy/migrations/economy_001_fix_gds_shipper_description.sql",
|
|
@@ -4207,7 +4222,7 @@
|
|
|
4207
4222
|
{
|
|
4208
4223
|
"path": "modules/economy/reward.js",
|
|
4209
4224
|
"mode": "0000644",
|
|
4210
|
-
"sha256": "
|
|
4225
|
+
"sha256": "ef4b939d83324c927dd1b1c8e3200212d0b5da973a87db6f9810c9c7edb942ad"
|
|
4211
4226
|
},
|
|
4212
4227
|
{
|
|
4213
4228
|
"path": "modules/economy/routes/cost.js",
|
|
@@ -4647,7 +4662,7 @@
|
|
|
4647
4662
|
{
|
|
4648
4663
|
"path": "modules/hall-ui/public/collab-lib.js",
|
|
4649
4664
|
"mode": "0000644",
|
|
4650
|
-
"sha256": "
|
|
4665
|
+
"sha256": "bfadae8700cc22ea13f8bc39a3e2a1876b58da6151032e9a973402bc9bd0aaa7"
|
|
4651
4666
|
},
|
|
4652
4667
|
{
|
|
4653
4668
|
"path": "modules/hall-ui/public/collab.css",
|
|
@@ -4662,7 +4677,7 @@
|
|
|
4662
4677
|
{
|
|
4663
4678
|
"path": "modules/hall-ui/public/collab.js",
|
|
4664
4679
|
"mode": "0000644",
|
|
4665
|
-
"sha256": "
|
|
4680
|
+
"sha256": "91a0751cebcbc179f28ad1cac7a6c447f90369ae40f29e5f60c1bd934ac68f85"
|
|
4666
4681
|
},
|
|
4667
4682
|
{
|
|
4668
4683
|
"path": "modules/hall-ui/public/collab.states.json",
|
|
@@ -5037,7 +5052,7 @@
|
|
|
5037
5052
|
{
|
|
5038
5053
|
"path": "modules/hall-ui/public/profile.js",
|
|
5039
5054
|
"mode": "0000644",
|
|
5040
|
-
"sha256": "
|
|
5055
|
+
"sha256": "04015850c00627f2439ec919358516c841d4c32c64a7ba18ca758b3804e804b5"
|
|
5041
5056
|
},
|
|
5042
5057
|
{
|
|
5043
5058
|
"path": "modules/hall-ui/public/profile.states.json",
|
|
@@ -5377,7 +5392,7 @@
|
|
|
5377
5392
|
{
|
|
5378
5393
|
"path": "modules/ideas/routes/inbox.js",
|
|
5379
5394
|
"mode": "0000644",
|
|
5380
|
-
"sha256": "
|
|
5395
|
+
"sha256": "cd4e4d741dcbc4bb581f86aeec5b1e17dfe630712a0e5466a108daba78c74429"
|
|
5381
5396
|
},
|
|
5382
5397
|
{
|
|
5383
5398
|
"path": "modules/ideas/routing.js",
|
|
@@ -5399,6 +5414,11 @@
|
|
|
5399
5414
|
"mode": "0000644",
|
|
5400
5415
|
"sha256": "2d0693b00dded081b6a0082c450762763d324d54f098a8f42a9aa25ec27370c4"
|
|
5401
5416
|
},
|
|
5417
|
+
{
|
|
5418
|
+
"path": "modules/ideas/trail-size.js",
|
|
5419
|
+
"mode": "0000644",
|
|
5420
|
+
"sha256": "f1e60dbc8c6dc0e9f5f5cb93bf26c659422503e8ec66937a3dcee5b64971e995"
|
|
5421
|
+
},
|
|
5402
5422
|
{
|
|
5403
5423
|
"path": "modules/lifecycle/CLAUDE.md",
|
|
5404
5424
|
"mode": "0000644",
|
|
@@ -7762,12 +7782,12 @@
|
|
|
7762
7782
|
{
|
|
7763
7783
|
"path": "package-lock.json",
|
|
7764
7784
|
"mode": "0000644",
|
|
7765
|
-
"sha256": "
|
|
7785
|
+
"sha256": "3b60452f407da16a6c09df92482e570ca061e920dd7537a6f2f84569a13e0545"
|
|
7766
7786
|
},
|
|
7767
7787
|
{
|
|
7768
7788
|
"path": "package.json",
|
|
7769
7789
|
"mode": "0000644",
|
|
7770
|
-
"sha256": "
|
|
7790
|
+
"sha256": "3af5e528e00f1047c76f56189ef168ea8c879f09762b735160b5c6d2e81f9d24"
|
|
7771
7791
|
},
|
|
7772
7792
|
{
|
|
7773
7793
|
"path": "public-docs/index.html",
|
|
@@ -9762,7 +9782,7 @@
|
|
|
9762
9782
|
{
|
|
9763
9783
|
"path": "src/module-api.js",
|
|
9764
9784
|
"mode": "0000644",
|
|
9765
|
-
"sha256": "
|
|
9785
|
+
"sha256": "2489905dea4c9defd22089221f6dce7c522f9860e6b684c9e6cea03a2600a17d"
|
|
9766
9786
|
},
|
|
9767
9787
|
{
|
|
9768
9788
|
"path": "src/module-loader/catalog.js",
|
|
@@ -10602,7 +10622,7 @@
|
|
|
10602
10622
|
{
|
|
10603
10623
|
"path": "tests/collab_page.mjs",
|
|
10604
10624
|
"mode": "0000644",
|
|
10605
|
-
"sha256": "
|
|
10625
|
+
"sha256": "b710669fabe9e747fe37abf429356e80c1f7a36cd63ac308dda2a933243e2e6d"
|
|
10606
10626
|
},
|
|
10607
10627
|
{
|
|
10608
10628
|
"path": "tests/compose_demo_credentials.mjs",
|
|
@@ -11849,6 +11869,11 @@
|
|
|
11849
11869
|
"mode": "0000644",
|
|
11850
11870
|
"sha256": "3a2c5d2e6c3231f69847e1e2aea073e78caf26228b500dbdf612b5bae354d0a2"
|
|
11851
11871
|
},
|
|
11872
|
+
{
|
|
11873
|
+
"path": "tests/idea_size.mjs",
|
|
11874
|
+
"mode": "0000644",
|
|
11875
|
+
"sha256": "c307e7c796e7e9f30b38b04144b426895642ea2d978ea5ace0f701ba7744420c"
|
|
11876
|
+
},
|
|
11852
11877
|
{
|
|
11853
11878
|
"path": "tests/idea_spark_hall.mjs",
|
|
11854
11879
|
"mode": "0000644",
|
package/docs/copy-inventory.md
CHANGED
|
@@ -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
|
-
**
|
|
7
|
+
**1826 strings** across 3 surfaces · 1584 distinct pieces of copy · 1826 certain, 0 heuristic · 166 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` | 84 |
|
|
13
|
+
| `builders-hall` | `modules/hall-ui/public` | 84 | 1336 |
|
|
14
14
|
| `status-dashboard` | `modules/status-ui/public` | 4 | 100 |
|
|
15
15
|
| `landing` | `modules/public-landing/public` | 5 | 390 |
|
|
16
16
|
|
|
@@ -78,7 +78,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
78
78
|
| `996edffc1966` | 2x | Access requests | modules/hall-ui/public/watch.html:46, modules/hall-ui/public/watch.html:61 |
|
|
79
79
|
| … | | _126 more in the JSON registry_ | |
|
|
80
80
|
|
|
81
|
-
## `builders-hall` —
|
|
81
|
+
## `builders-hall` — 1336 strings
|
|
82
82
|
|
|
83
83
|
| id | conf | text | where |
|
|
84
84
|
|---|---|---|---|
|
|
@@ -135,7 +135,6 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
135
135
|
| `0b9adf029094` | certain | A task cannot wait for itself. | `modules/hall-ui/public/task.js:890` |
|
|
136
136
|
| `0aaa0f2c4bdc` | certain | A title is required. | `modules/hall-ui/public/blockers.js:345` |
|
|
137
137
|
| `daf73127afff` | certain | A word on why | `modules/hall-ui/public/hall-render.js:294` |
|
|
138
|
-
| `9fe51a2e1e71` | certain | A {…} — you are a {…}. Mingle pairs across roles. | `modules/hall-ui/public/collab.js:421` |
|
|
139
138
|
| `996edffc1966` | certain | Access requests | `modules/hall-ui/public/watch.html:46` |
|
|
140
139
|
| `996edffc1966` | certain | Access requests | `modules/hall-ui/public/watch.html:61` |
|
|
141
140
|
| `303f8d90266f` | certain | Achievements could not be loaded. | `modules/hall-ui/public/builders.js:1196` |
|
|
@@ -304,12 +303,12 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
304
303
|
| `90691bceaf68` | certain | Could not load | `modules/hall-ui/public/task.js:982` |
|
|
305
304
|
| `589a4cfc5442` | certain | Could not load idea {…}. | `modules/hall-ui/public/ideas.js:644` |
|
|
306
305
|
| `192c893fc64e` | certain | Could not load modules. | `modules/hall-ui/public/modules.js:318` |
|
|
307
|
-
| `
|
|
306
|
+
| `9912c3835136` | certain | Could not load requests — reload to try again. | `modules/hall-ui/public/collab.js:529` |
|
|
308
307
|
| `7775fec0fa85` | certain | Could not load sessions. | `modules/hall-ui/public/sessions.js:399` |
|
|
309
308
|
| `7775fec0fa85` | certain | Could not load sessions. | `modules/hall-ui/public/sessions.js:437` |
|
|
310
309
|
| `a2f2e8babef5` | certain | Could not load that page. Try again. | `modules/hall-ui/public/blockers.js:274` |
|
|
311
310
|
| `b2147cc90e36` | certain | Could not load the idea template. Reload, or file from the terminal with capture.js. | `modules/hall-ui/public/ideas.js:626` |
|
|
312
|
-
| `7604af13c40e` | certain | Could not load the profile. | `modules/hall-ui/public/profile.js:
|
|
311
|
+
| `7604af13c40e` | certain | Could not load the profile. | `modules/hall-ui/public/profile.js:873` |
|
|
313
312
|
| `8b69e445592a` | certain | Could not load the question labels; showing the answers as stored. | `modules/hall-ui/public/idea.js:244` |
|
|
314
313
|
| `edd5bafbe075` | certain | Could not load the queue just now. | `modules/hall-ui/public/ideas.js:565` |
|
|
315
314
|
| `02bb0570996a` | certain | Could not load the ranks. | `modules/hall-ui/public/ranks.js:197` |
|
|
@@ -601,7 +600,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
601
600
|
| `6e73716aec6c` | certain | May be offered for sale later | `modules/hall-ui/public/settings.html:297` |
|
|
602
601
|
| `df335a1224ae` | certain | Member since {…} | `modules/hall-ui/public/hall-render.js:563` |
|
|
603
602
|
| `df335a1224ae` | certain | Member since {…} | `modules/hall-ui/public/profile.js:94` |
|
|
604
|
-
| `c7a670e9552d` | certain | Merged into | `modules/hall-ui/public/profile.js:
|
|
603
|
+
| `c7a670e9552d` | certain | Merged into | `modules/hall-ui/public/profile.js:489` |
|
|
605
604
|
| `dce0546c9e34` | certain | Merging work does not put it in front of anyone. This is the step that does: it moves this platform — or any p | `modules/hall-ui/public/deploy.html:39` |
|
|
606
605
|
| `7637613c231b` | certain | Metic rank and above may vote | `modules/hall-ui/public/builders.js:781` |
|
|
607
606
|
| `91328a97fe68` | certain | Mingle pairs you with someone from another role. Saying no costs nothing. | `modules/hall-ui/public/collab.html:87` |
|
|
@@ -669,7 +668,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
669
668
|
| `c72e0bdb834a` | certain | Not declared in module.json — this is who ships the module. | `modules/hall-ui/public/modules.js:62` |
|
|
670
669
|
| `361b353ded5e` | certain | Not enough shipped work yet to chart. | `modules/hall-ui/public/hall-widgets.js:184` |
|
|
671
670
|
| `90230572d017` | certain | Not found | `modules/hall-ui/public/task.js:970` |
|
|
672
|
-
| `8226c979db4d` | certain | Not now | `modules/hall-ui/public/collab.js:
|
|
671
|
+
| `8226c979db4d` | certain | Not now | `modules/hall-ui/public/collab.js:435` |
|
|
673
672
|
| `5ffcdc1a0176` | certain | Not scored — this builder’s own profile waived every signal, or the session predates this measure. | `modules/hall-ui/public/sessions.js:100` |
|
|
674
673
|
| `61250b49a90b` | certain | Not scored. | `modules/hall-ui/public/idea.js:84` |
|
|
675
674
|
| `8d6afe6def47` | certain | Not signed in | `modules/hall-ui/public/settings.html:40` |
|
|
@@ -847,7 +846,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
847
846
|
| `42cbc20a6ec8` | certain | Saves when you press Save; your next | `modules/hall-ui/public/settings.html:136` |
|
|
848
847
|
| `645dd8117cf3` | certain | Say why it is being retired — the reason goes in the record. | `modules/hall-ui/public/task.js:924` |
|
|
849
848
|
| `fc9d783ed0f5` | certain | Say why it is better. Whoever reviews this decides it from your reason, without asking you. | `modules/hall-ui/public/copy-desk.js:446` |
|
|
850
|
-
| `12c1ec21a2c6` | certain | Say yes | `modules/hall-ui/public/collab.js:
|
|
849
|
+
| `12c1ec21a2c6` | certain | Say yes | `modules/hall-ui/public/collab.js:435` |
|
|
851
850
|
| `46711f7bc3df` | certain | Search every string the product shows a person, by what it says or the file it lives in. | `modules/hall-ui/public/copy-desk.html:65` |
|
|
852
851
|
| `5d2ba8e72fa1` | certain | Search failed. | `modules/hall-ui/public/copy-desk.js:343` |
|
|
853
852
|
| `373a7639bcb9` | certain | Sections in this primer | `modules/hall-ui/public/primer.html:52` |
|
|
@@ -919,7 +918,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
919
918
|
| `9d4372b173cf` | certain | Standing sections | `modules/hall-ui/public/index.html:79` |
|
|
920
919
|
| `ec1c2dae4a90` | certain | Standing there | `modules/hall-ui/public/profile.js:314` |
|
|
921
920
|
| `eaad12cacb9d` | certain | Start over | `modules/hall-ui/public/studio.js:235` |
|
|
922
|
-
| `efe530c0e3a7` | certain | Still open | `modules/hall-ui/public/profile.js:
|
|
921
|
+
| `efe530c0e3a7` | certain | Still open | `modules/hall-ui/public/profile.js:494` |
|
|
923
922
|
| `9a4ced1afb6c` | certain | Stop waiting on task {…} | `modules/hall-ui/public/task.js:278` |
|
|
924
923
|
| `b0861c874a2f` | certain | Stopped using it. | `modules/hall-ui/public/settings-specialities.js:200` |
|
|
925
924
|
| `6c6544f5c011` | certain | Stored encrypted; never shown again after saving — only its last four digits. | `modules/hall-ui/public/settings.html:193` |
|
|
@@ -1353,7 +1352,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
1353
1352
|
| `cc5106af4b35` | certain | {…} of {…} criteria satisfied | `modules/hall-ui/public/goals-lib.js:32` |
|
|
1354
1353
|
| `cc5106af4b35` | certain | {…} of {…} criteria satisfied | `modules/hall-ui/public/goals-render.js:682` |
|
|
1355
1354
|
| `cc5106af4b35` | certain | {…} of {…} criteria satisfied | `modules/hall-ui/public/goals.js:45` |
|
|
1356
|
-
| `c3d9687e2375` | certain | {…} of {…} shipped | `modules/hall-ui/public/profile.js:
|
|
1355
|
+
| `c3d9687e2375` | certain | {…} of {…} shipped | `modules/hall-ui/public/profile.js:595` |
|
|
1357
1356
|
| `f32710d0ef37` | certain | {…} of {…} steps cleared. | `modules/hall-ui/public/hall-render.js:1037` |
|
|
1358
1357
|
| `60743fe1e40d` | certain | {…} per page | `modules/hall-ui/public/hall-kit.js:74` |
|
|
1359
1358
|
| `154bc518bab4` | certain | {…} proposed | `modules/hall-ui/public/government.js:695` |
|
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": 1826,
|
|
7
|
+
"unique_ids": 1584,
|
|
8
|
+
"certain": 1826,
|
|
9
9
|
"heuristic": 0,
|
|
10
10
|
"duplicate_ids": 166
|
|
11
11
|
},
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"builders-hall": {
|
|
14
14
|
"at": "modules/hall-ui/public",
|
|
15
15
|
"files": 84,
|
|
16
|
-
"strings":
|
|
16
|
+
"strings": 1336
|
|
17
17
|
},
|
|
18
18
|
"status-dashboard": {
|
|
19
19
|
"at": "modules/status-ui/public",
|
|
@@ -2253,15 +2253,6 @@
|
|
|
2253
2253
|
"origin": "js-markup",
|
|
2254
2254
|
"confidence": "certain"
|
|
2255
2255
|
},
|
|
2256
|
-
{
|
|
2257
|
-
"id": "9fe51a2e1e71",
|
|
2258
|
-
"surface": "builders-hall",
|
|
2259
|
-
"text": "A {…} — you are a {…}. Mingle pairs across roles.",
|
|
2260
|
-
"file": "modules/hall-ui/public/collab.js",
|
|
2261
|
-
"line": 421,
|
|
2262
|
-
"origin": "js-markup",
|
|
2263
|
-
"confidence": "certain"
|
|
2264
|
-
},
|
|
2265
2256
|
{
|
|
2266
2257
|
"id": "996edffc1966",
|
|
2267
2258
|
"surface": "builders-hall",
|
|
@@ -3775,11 +3766,11 @@
|
|
|
3775
3766
|
"confidence": "certain"
|
|
3776
3767
|
},
|
|
3777
3768
|
{
|
|
3778
|
-
"id": "
|
|
3769
|
+
"id": "9912c3835136",
|
|
3779
3770
|
"surface": "builders-hall",
|
|
3780
|
-
"text": "Could not load requests.",
|
|
3771
|
+
"text": "Could not load requests — reload to try again.",
|
|
3781
3772
|
"file": "modules/hall-ui/public/collab.js",
|
|
3782
|
-
"line":
|
|
3773
|
+
"line": 529,
|
|
3783
3774
|
"origin": "js-text-assign",
|
|
3784
3775
|
"confidence": "certain"
|
|
3785
3776
|
},
|
|
@@ -3824,7 +3815,7 @@
|
|
|
3824
3815
|
"surface": "builders-hall",
|
|
3825
3816
|
"text": "Could not load the profile.",
|
|
3826
3817
|
"file": "modules/hall-ui/public/profile.js",
|
|
3827
|
-
"line":
|
|
3818
|
+
"line": 873,
|
|
3828
3819
|
"origin": "js-notice",
|
|
3829
3820
|
"confidence": "certain"
|
|
3830
3821
|
},
|
|
@@ -6452,7 +6443,7 @@
|
|
|
6452
6443
|
"surface": "builders-hall",
|
|
6453
6444
|
"text": "Merged into",
|
|
6454
6445
|
"file": "modules/hall-ui/public/profile.js",
|
|
6455
|
-
"line":
|
|
6446
|
+
"line": 489,
|
|
6456
6447
|
"origin": "js-markup",
|
|
6457
6448
|
"confidence": "certain"
|
|
6458
6449
|
},
|
|
@@ -7064,7 +7055,7 @@
|
|
|
7064
7055
|
"surface": "builders-hall",
|
|
7065
7056
|
"text": "Not now",
|
|
7066
7057
|
"file": "modules/hall-ui/public/collab.js",
|
|
7067
|
-
"line":
|
|
7058
|
+
"line": 435,
|
|
7068
7059
|
"origin": "js-markup",
|
|
7069
7060
|
"confidence": "certain"
|
|
7070
7061
|
},
|
|
@@ -8666,7 +8657,7 @@
|
|
|
8666
8657
|
"surface": "builders-hall",
|
|
8667
8658
|
"text": "Say yes",
|
|
8668
8659
|
"file": "modules/hall-ui/public/collab.js",
|
|
8669
|
-
"line":
|
|
8660
|
+
"line": 435,
|
|
8670
8661
|
"origin": "js-markup",
|
|
8671
8662
|
"confidence": "certain"
|
|
8672
8663
|
},
|
|
@@ -9314,7 +9305,7 @@
|
|
|
9314
9305
|
"surface": "builders-hall",
|
|
9315
9306
|
"text": "Still open",
|
|
9316
9307
|
"file": "modules/hall-ui/public/profile.js",
|
|
9317
|
-
"line":
|
|
9308
|
+
"line": 494,
|
|
9318
9309
|
"origin": "js-markup",
|
|
9319
9310
|
"confidence": "certain"
|
|
9320
9311
|
},
|
|
@@ -13220,7 +13211,7 @@
|
|
|
13220
13211
|
"surface": "builders-hall",
|
|
13221
13212
|
"text": "{…} of {…} shipped",
|
|
13222
13213
|
"file": "modules/hall-ui/public/profile.js",
|
|
13223
|
-
"line":
|
|
13214
|
+
"line": 595,
|
|
13224
13215
|
"origin": "js-markup",
|
|
13225
13216
|
"confidence": "certain"
|
|
13226
13217
|
},
|
|
@@ -2280,5 +2280,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2280
2280
|
landed since 1.19.901 with no explicit bump. run 35497860558. (task 1002620)
|
|
2281
2281
|
1.19.903 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2282
2282
|
landed since 1.19.902 with no explicit bump. run 35510679104. (task 1002620)
|
|
2283
|
+
1.19.904 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2284
|
+
landed since 1.19.903 with no explicit bump. run 35511494246. (task 1002620)
|
|
2285
|
+
1.19.905 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2286
|
+
landed since 1.19.904 with no explicit bump. run 35513060618. (task 1002620)
|
|
2283
2287
|
---------------------------------------------------------------------------
|
|
2284
2288
|
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
-- core_251 an index for SIZE -- the per-idea rollup of the stream-1 ledger
|
|
2
|
+
-- Applied under task 1004093 (BV2.R12, goal 1000095).
|
|
3
|
+
--
|
|
4
|
+
-- WHY. modules/economy/idea-size.js answers "what has this idea's descent
|
|
5
|
+
-- paid" by summing credit_log rows whose reason embeds the idea:
|
|
6
|
+
--
|
|
7
|
+
-- idea.credit.task_ship:<ideaId>:<taskId>
|
|
8
|
+
--
|
|
9
|
+
-- That needs no column and no new table -- the ledger already carries the
|
|
10
|
+
-- attribution, which is why this task needed no SCHEMA change. What it does
|
|
11
|
+
-- need is a way to reach those rows without reading the whole ledger.
|
|
12
|
+
--
|
|
13
|
+
-- WHAT IT COSTS WITHOUT ONE. credit_log is the whole-instance, append-only
|
|
14
|
+
-- credit ledger: every task payout, every session reward, every bonus, for
|
|
15
|
+
-- every builder, forever. The size read runs on GET /inbox/by-builder/:id --
|
|
16
|
+
-- an ordinary page view of a builder's idea trail -- so an unindexed version
|
|
17
|
+
-- is a sequential scan of the entire lifetime ledger on every such view, and
|
|
18
|
+
-- its cost grows with total credit events rather than with anything about the
|
|
19
|
+
-- idea being looked at. A grader panel flagged exactly this on the first round
|
|
20
|
+
-- of task 1004093, and it was right to.
|
|
21
|
+
--
|
|
22
|
+
-- THE SHAPE. A PARTIAL EXPRESSION index:
|
|
23
|
+
--
|
|
24
|
+
-- * the EXPRESSION is split_part(reason, ':', 2) -- the idea id, taken off
|
|
25
|
+
-- the separator. The read groups on that same expression rather than on a
|
|
26
|
+
-- per-idea LIKE, because a prefix match is correct only by virtue of its
|
|
27
|
+
-- trailing colon and dropping it makes idea 1 absorb every payout of ideas
|
|
28
|
+
-- 10, 100 and 1000, silently. An index on the expression is what lets the
|
|
29
|
+
-- honest form of the query stay cheap.
|
|
30
|
+
-- * PARTIAL on the stream-1 prefix, so the index covers only ideator
|
|
31
|
+
-- task-ship rows. Those are a small minority of credit_log: the bulk is
|
|
32
|
+
-- task.shipped and session.token_reward, whose split_part(reason,':',2) is
|
|
33
|
+
-- the empty string and which no size read will ever want. A full index
|
|
34
|
+
-- would be several times the size to answer the same questions.
|
|
35
|
+
--
|
|
36
|
+
-- THE PREDICATE IS A LITERAL ON BOTH SIDES, AND THAT IS LOAD-BEARING. Postgres
|
|
37
|
+
-- only uses a partial index when it can prove the query's WHERE implies the
|
|
38
|
+
-- index predicate, and it cannot prove that about a parameterised
|
|
39
|
+
-- `reason LIKE $1 || '%'` -- the parameter's value is not known when a generic
|
|
40
|
+
-- plan is made. So idea-size.js spells the prefix into the SQL TEXT as a
|
|
41
|
+
-- literal (validated at module load), matching the string below character for
|
|
42
|
+
-- character. If the two ever drift, nothing errors and nothing renders
|
|
43
|
+
-- differently: the index is simply never used again and the scan quietly comes
|
|
44
|
+
-- back. tests/idea_size.mjs reads THIS FILE and holds its predicate against the
|
|
45
|
+
-- economy constant, so the drift reds a test instead of a page.
|
|
46
|
+
--
|
|
47
|
+
-- THE UNDERSCORE IS ESCAPED, and it is not decoration. In LIKE, _ matches any
|
|
48
|
+
-- single character, so an unescaped 'idea.credit.task_ship:%' also matches
|
|
49
|
+
-- 'idea.credit.taskXship:'. No such key exists, which is precisely why nobody
|
|
50
|
+
-- would ever notice; backslash is LIKE's default escape in Postgres, so no
|
|
51
|
+
-- ESCAPE clause is needed and idea-size.js generates the identical string.
|
|
52
|
+
--
|
|
53
|
+
-- Additive and idempotent: it creates an index and touches no row. Not
|
|
54
|
+
-- CONCURRENTLY -- the migration runner wraps each file in a transaction and
|
|
55
|
+
-- CREATE INDEX CONCURRENTLY cannot run inside one. On an instance whose ledger
|
|
56
|
+
-- is large enough for that lock to matter, build it by hand outside the runner
|
|
57
|
+
-- and this statement becomes a no-op.
|
|
58
|
+
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_credit_log_idea_task_ship
|
|
60
|
+
ON credit_log ((split_part(reason, ':', 2)))
|
|
61
|
+
WHERE reason LIKE 'idea.credit.task\_ship:%';
|
|
@@ -1273,6 +1273,14 @@ module.exports = {
|
|
|
1273
1273
|
IDEA_FULL_PASS_CREDIT,
|
|
1274
1274
|
IDEA_FULL_PASS_BAR,
|
|
1275
1275
|
IDEA_TASK_SHIP_BASE,
|
|
1276
|
+
// The two pieces of the stream-1 payout ARITHMETIC, exported for
|
|
1277
|
+
// modules/economy/idea-size.js (task 1004097 / BV2.R18). A pre-existing
|
|
1278
|
+
// idea backfills the payouts its descent never received, and a second copy
|
|
1279
|
+
// of this arithmetic would make the backfilled figure differ from the money
|
|
1280
|
+
// the same descent will earn from now on — the exact drift the
|
|
1281
|
+
// ideaGradeFactor comment above exists to prevent.
|
|
1282
|
+
ideaGradeFactor,
|
|
1283
|
+
descentPayoutMaxDepth,
|
|
1276
1284
|
QUICK_IDEA_FACTOR,
|
|
1277
1285
|
IDEA_GOVERNANCE_PASS_MAX,
|
|
1278
1286
|
IDEA_GOVERNANCE_PASS_FLOOR,
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// modules/economy/idea-size-historical.js — THE HISTORICAL HALF OF SIZE
|
|
4
|
+
// (task 1004097, BV2.R18, goal 1000095; spec
|
|
5
|
+
// docs/specs/bongos-v2-ideator-surface.md decision 17).
|
|
6
|
+
//
|
|
7
|
+
// WHAT IS MISSING WITHOUT THIS, and it is not what the task title suggests.
|
|
8
|
+
// A pre-existing idea's ledger figure is not ABSENT, it is PARTIAL. Stream 1's
|
|
9
|
+
// direct payout has existed since ADR 0172, so a task promoted from an idea and
|
|
10
|
+
// shipped since then really was paid and really is in credit_log. What never
|
|
11
|
+
// happened is the DESCENT payout: awardIdeaDescentShipCredit only started
|
|
12
|
+
// paying with task 1004088, so every hop below the first, for every task that
|
|
13
|
+
// shipped before that, earned its origin nothing and never will.
|
|
14
|
+
//
|
|
15
|
+
// So the backfill is not "compute a size for ideas that have none". It is the
|
|
16
|
+
// GAP between the descent an idea actually has and the part of that descent the
|
|
17
|
+
// ledger was there to pay for.
|
|
18
|
+
//
|
|
19
|
+
// NO MONEY IS BOOKED (spec decision 17, the owner's ruling on interview Q6).
|
|
20
|
+
// Nothing here writes to credit_log, and nothing here is reachable from a ship
|
|
21
|
+
// path. The estimate is computed at READ time, every time, from the descent as
|
|
22
|
+
// it stands. Re-paying work already paid for once is exactly what the owner
|
|
23
|
+
// declined, and a backfill that wrote rows would also break stream 1's
|
|
24
|
+
// idempotency key — the ledger would then hold a payment for a ship that never
|
|
25
|
+
// triggered one.
|
|
26
|
+
//
|
|
27
|
+
// WHICH IS WHY THE TWO HALVES ARE KEPT APART RATHER THAN ADDED UP AND FORGOTTEN.
|
|
28
|
+
// `paid` is money that moved; `estimated` is money that did not. A single total
|
|
29
|
+
// with no marker is the number the spec calls a quiet lie, and the done-when
|
|
30
|
+
// asks for the opposite — that anywhere size is shown makes clear which kind of
|
|
31
|
+
// number it is. So this returns both, always, and the surfaces carry the split
|
|
32
|
+
// rather than a boolean bolted on at the end.
|
|
33
|
+
//
|
|
34
|
+
// THE ARITHMETIC IS NOT REIMPLEMENTED HERE. `ideaGradeFactor`,
|
|
35
|
+
// `descentPayoutMaxDepth` and `IDEA_TASK_SHIP_BASE` come from credits.js, which
|
|
36
|
+
// is where the real payout gets them. A second copy would make an idea's
|
|
37
|
+
// backfilled past disagree with the money the same descent earns from tomorrow
|
|
38
|
+
// — the same drift the "EXTRACTED so the two cannot disagree" note on
|
|
39
|
+
// ideaGradeFactor was written to prevent, one module over.
|
|
40
|
+
|
|
41
|
+
const {
|
|
42
|
+
IDEA_TASK_SHIP_BASE,
|
|
43
|
+
ideaGradeFactor,
|
|
44
|
+
descentPayoutMaxDepth,
|
|
45
|
+
} = require('./credits');
|
|
46
|
+
|
|
47
|
+
// priceDescentForIdea — PURE. What one idea's descent is worth, split into the
|
|
48
|
+
// part the ledger actually paid and the part it never did.
|
|
49
|
+
//
|
|
50
|
+
// tasks — every task under this idea, each { task_id, depth, status }.
|
|
51
|
+
// Depth 0 is a task the idea was promoted INTO; depth n is n
|
|
52
|
+
// hops below one of those. Shortest depth per task, which is the
|
|
53
|
+
// rule the walk and the payout both already apply.
|
|
54
|
+
// grade — the idea's grade ('quick' | 'spark' | 'full')
|
|
55
|
+
// completeness— its completeness score, or null
|
|
56
|
+
// decay — the resolved per-instance dial (reward-policy ideaDescentDecay)
|
|
57
|
+
// paidByTask — Map<taskIdString, creditsPaid> from credit_log, per task
|
|
58
|
+
//
|
|
59
|
+
// Returns { paid, estimated, payments, estimatedPayments }.
|
|
60
|
+
//
|
|
61
|
+
// ONLY A SHIPPED TASK COUNTS. The payout fires at ship, so a ready or abandoned
|
|
62
|
+
// descendant has earned its origin nothing and estimating for it would credit
|
|
63
|
+
// work that has not happened — the surface would then show a size that FELL
|
|
64
|
+
// when the task was later abandoned. Everything here is anchored on ships that
|
|
65
|
+
// actually occurred.
|
|
66
|
+
//
|
|
67
|
+
// PAID ALWAYS WINS FOR A TASK THE LEDGER KNOWS. If credit_log holds a payment
|
|
68
|
+
// for (idea, task), that figure is used verbatim and no estimate is made for it
|
|
69
|
+
// — money that moved is not re-derived. This is what keeps the paid half
|
|
70
|
+
// immutable while the arithmetic around it is free to change: a later decay dial
|
|
71
|
+
// or a re-scored completeness cannot retroactively alter what was banked.
|
|
72
|
+
//
|
|
73
|
+
// ROUNDED ONCE PER PAYMENT, the way the writer rounds — per (idea, task), never
|
|
74
|
+
// on the total. Rounding the sum would make the backfilled figure differ from
|
|
75
|
+
// what the same descent would have been paid hop by hop, which is the whole
|
|
76
|
+
// thing this function exists to reproduce.
|
|
77
|
+
function priceDescentForIdea({ tasks, grade, completeness, decay, paidByTask } = {}) {
|
|
78
|
+
const out = { paid: 0, estimated: 0, payments: 0, estimatedPayments: 0 };
|
|
79
|
+
const list = Array.isArray(tasks) ? tasks : [];
|
|
80
|
+
const paidMap = paidByTask instanceof Map ? paidByTask : new Map();
|
|
81
|
+
|
|
82
|
+
// A decay of 0 is a legal instance setting meaning "only the direct task
|
|
83
|
+
// pays", and it makes the cap 0 — so depth 0 is still priced and nothing
|
|
84
|
+
// below it is. Guarding on the cap rather than on the rate keeps that in one
|
|
85
|
+
// place.
|
|
86
|
+
const rate = Number.isFinite(Number(decay)) && Number(decay) >= 0 && Number(decay) < 1 ? Number(decay) : null;
|
|
87
|
+
if (rate === null) return out;
|
|
88
|
+
const maxDepth = descentPayoutMaxDepth(rate);
|
|
89
|
+
const factor = ideaGradeFactor(grade, completeness);
|
|
90
|
+
|
|
91
|
+
// One entry per task: a task reachable twice is one ship and owes one
|
|
92
|
+
// payment, at its shortest depth. The caller hands shortest-depth rows, and
|
|
93
|
+
// this keeps the guarantee local rather than trusting it.
|
|
94
|
+
const seen = new Set();
|
|
95
|
+
for (const t of list) {
|
|
96
|
+
const key = String(t && t.task_id);
|
|
97
|
+
if (!/^[1-9]\d*$/.test(key) || seen.has(key)) continue;
|
|
98
|
+
seen.add(key);
|
|
99
|
+
|
|
100
|
+
if (paidMap.has(key)) {
|
|
101
|
+
out.paid += Number(paidMap.get(key)) || 0;
|
|
102
|
+
out.payments += 1;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (t.status !== 'shipped') continue;
|
|
107
|
+
const depth = Number(t.depth);
|
|
108
|
+
if (!Number.isInteger(depth) || depth < 0) continue;
|
|
109
|
+
// Depth 0 is the direct payout at full share; below that the cap applies,
|
|
110
|
+
// because past it even a perfect idea's decayed share rounds away.
|
|
111
|
+
if (depth > 0 && (rate === 0 || depth > maxDepth)) continue;
|
|
112
|
+
const delta = Math.round(IDEA_TASK_SHIP_BASE * factor * Math.pow(rate, depth));
|
|
113
|
+
if (delta <= 0) continue;
|
|
114
|
+
out.estimated += delta;
|
|
115
|
+
out.estimatedPayments += 1;
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// descentRowsFromTrail — the tasks under an idea, as the TRAIL already holds
|
|
121
|
+
// them. Pure, and deliberately not a walk.
|
|
122
|
+
//
|
|
123
|
+
// modules/ideas/trail-descent.js has already walked the whole page by the time
|
|
124
|
+
// size is attached (the route composes them in that order), so the trail path
|
|
125
|
+
// re-uses that result and costs no extra round trip at all. `lineage_tasks` are
|
|
126
|
+
// the idea's own tasks — depth 0, the full-share hop — and `descent_tasks` are
|
|
127
|
+
// everything below them, already carrying their shortest depth and their status.
|
|
128
|
+
//
|
|
129
|
+
// A lineage row that also appears in the descent is dropped by the depth-0 entry
|
|
130
|
+
// winning: the Set in priceDescentForIdea keeps the first sighting, and the
|
|
131
|
+
// direct tasks are emitted first for exactly that reason.
|
|
132
|
+
function descentRowsFromTrail(idea) {
|
|
133
|
+
const rows = [];
|
|
134
|
+
const direct = Array.isArray(idea && idea.lineage_tasks) ? idea.lineage_tasks : [];
|
|
135
|
+
for (const t of direct) rows.push({ task_id: t.task_id, depth: 0, status: t.status });
|
|
136
|
+
// The legacy single-FK promotion, for rows that predate ideas_task_lineage —
|
|
137
|
+
// the same fallback the trail and trail-descent both apply.
|
|
138
|
+
if (direct.length === 0 && idea && idea.promoted_to_task_id != null) {
|
|
139
|
+
rows.push({ task_id: idea.promoted_to_task_id, depth: 0, status: idea.promoted_task_status ?? null });
|
|
140
|
+
}
|
|
141
|
+
const below = Array.isArray(idea && idea.descent_tasks) ? idea.descent_tasks : [];
|
|
142
|
+
for (const t of below) rows.push({ task_id: t.task_id, depth: t.depth, status: t.status });
|
|
143
|
+
return rows;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = {
|
|
147
|
+
priceDescentForIdea,
|
|
148
|
+
descentRowsFromTrail,
|
|
149
|
+
};
|