@bongos/core 1.19.1065 → 1.19.1067
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 +40 -30
- package/docs/adr/0341-the-page-is-the-unit-of-tweak-mode.md +3 -0
- package/docs/branding-contract.md +1 -1
- package/docs/copy-inventory.md +24 -24
- package/docs/copy-registry.json +28 -28
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-readings.json +12 -12
- package/modules/copy-desk/page-status.js +4 -2
- package/modules/copy-desk/routes/copy-desk.js +3 -2
- package/modules/economy/credits.js +77 -0
- package/modules/economy/reward-policy.js +7 -1
- package/modules/economy/reward.js +4 -0
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/studio.js +12 -9
- package/modules/lifecycle/cascade.js +48 -96
- package/modules/lifecycle/db-ship.js +14 -5
- package/modules/lifecycle/routes/lifecycle.js +9 -9
- package/modules/lifecycle/tests/cascade.mjs +106 -160
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/src/module-api.js +1 -1
- package/tests/artist_page_credit.mjs +272 -0
- package/tests/grader_reader_lens.mjs +16 -24
- package/tests/removal_verdict.mjs +5 -2
- package/tests/tweak_replaces_artist_review.mjs +170 -0
package/docs/copy-registry.json
CHANGED
|
@@ -1110,8 +1110,8 @@
|
|
|
1110
1110
|
"text": "Let it be for now",
|
|
1111
1111
|
"occurrences": 2,
|
|
1112
1112
|
"at": [
|
|
1113
|
-
"modules/hall-ui/public/studio.js:
|
|
1114
|
-
"modules/hall-ui/public/studio.js:
|
|
1113
|
+
"modules/hall-ui/public/studio.js:218",
|
|
1114
|
+
"modules/hall-ui/public/studio.js:233"
|
|
1115
1115
|
]
|
|
1116
1116
|
},
|
|
1117
1117
|
{
|
|
@@ -2010,8 +2010,8 @@
|
|
|
2010
2010
|
"text": "to tend now · {…}",
|
|
2011
2011
|
"occurrences": 2,
|
|
2012
2012
|
"at": [
|
|
2013
|
-
"modules/hall-ui/public/studio.js:
|
|
2014
|
-
"modules/hall-ui/public/studio.js:
|
|
2013
|
+
"modules/hall-ui/public/studio.js:218",
|
|
2014
|
+
"modules/hall-ui/public/studio.js:233"
|
|
2015
2015
|
]
|
|
2016
2016
|
},
|
|
2017
2017
|
{
|
|
@@ -3924,7 +3924,7 @@
|
|
|
3924
3924
|
"surface": "builders-hall",
|
|
3925
3925
|
"text": "Coach the grader",
|
|
3926
3926
|
"file": "modules/hall-ui/public/studio.js",
|
|
3927
|
-
"line":
|
|
3927
|
+
"line": 196,
|
|
3928
3928
|
"origin": "js-markup",
|
|
3929
3929
|
"confidence": "certain"
|
|
3930
3930
|
},
|
|
@@ -5121,7 +5121,7 @@
|
|
|
5121
5121
|
"surface": "builders-hall",
|
|
5122
5122
|
"text": "Dismissed — the copy and visuals are good as shipped.",
|
|
5123
5123
|
"file": "modules/hall-ui/public/studio.js",
|
|
5124
|
-
"line":
|
|
5124
|
+
"line": 371,
|
|
5125
5125
|
"origin": "js-notice",
|
|
5126
5126
|
"confidence": "certain"
|
|
5127
5127
|
},
|
|
@@ -5589,7 +5589,7 @@
|
|
|
5589
5589
|
"surface": "builders-hall",
|
|
5590
5590
|
"text": "Filed as task {…} — this review is closed against it.",
|
|
5591
5591
|
"file": "modules/hall-ui/public/studio.js",
|
|
5592
|
-
"line":
|
|
5592
|
+
"line": 460,
|
|
5593
5593
|
"origin": "js-notice",
|
|
5594
5594
|
"confidence": "certain"
|
|
5595
5595
|
},
|
|
@@ -6741,7 +6741,7 @@
|
|
|
6741
6741
|
"surface": "builders-hall",
|
|
6742
6742
|
"text": "It shipped and it is live. Say what you see — your review coaches the grader and never blocks what shipped.",
|
|
6743
6743
|
"file": "modules/hall-ui/public/studio.js",
|
|
6744
|
-
"line":
|
|
6744
|
+
"line": 216,
|
|
6745
6745
|
"origin": "js-markup",
|
|
6746
6746
|
"confidence": "certain"
|
|
6747
6747
|
},
|
|
@@ -6750,7 +6750,7 @@
|
|
|
6750
6750
|
"surface": "builders-hall",
|
|
6751
6751
|
"text": "It shipped and it is live. Your review coaches the grader on how it judged the work, then remakes or tweaks the words or art only if they need it — it never blocks what shipped.",
|
|
6752
6752
|
"file": "modules/hall-ui/public/studio.js",
|
|
6753
|
-
"line":
|
|
6753
|
+
"line": 217,
|
|
6754
6754
|
"origin": "js-markup",
|
|
6755
6755
|
"confidence": "certain"
|
|
6756
6756
|
},
|
|
@@ -7029,7 +7029,7 @@
|
|
|
7029
7029
|
"surface": "builders-hall",
|
|
7030
7030
|
"text": "Let it be for now",
|
|
7031
7031
|
"file": "modules/hall-ui/public/studio.js",
|
|
7032
|
-
"line":
|
|
7032
|
+
"line": 218,
|
|
7033
7033
|
"origin": "js-markup",
|
|
7034
7034
|
"confidence": "certain"
|
|
7035
7035
|
},
|
|
@@ -7038,7 +7038,7 @@
|
|
|
7038
7038
|
"surface": "builders-hall",
|
|
7039
7039
|
"text": "Let it be for now",
|
|
7040
7040
|
"file": "modules/hall-ui/public/studio.js",
|
|
7041
|
-
"line":
|
|
7041
|
+
"line": 233,
|
|
7042
7042
|
"origin": "js-markup",
|
|
7043
7043
|
"confidence": "certain"
|
|
7044
7044
|
},
|
|
@@ -7290,7 +7290,7 @@
|
|
|
7290
7290
|
"surface": "builders-hall",
|
|
7291
7291
|
"text": "Looks good",
|
|
7292
7292
|
"file": "modules/hall-ui/public/studio.js",
|
|
7293
|
-
"line":
|
|
7293
|
+
"line": 176,
|
|
7294
7294
|
"origin": "js-markup",
|
|
7295
7295
|
"confidence": "certain"
|
|
7296
7296
|
},
|
|
@@ -7578,7 +7578,7 @@
|
|
|
7578
7578
|
"surface": "builders-hall",
|
|
7579
7579
|
"text": "Needs work",
|
|
7580
7580
|
"file": "modules/hall-ui/public/studio.js",
|
|
7581
|
-
"line":
|
|
7581
|
+
"line": 176,
|
|
7582
7582
|
"origin": "js-markup",
|
|
7583
7583
|
"confidence": "certain"
|
|
7584
7584
|
},
|
|
@@ -8190,7 +8190,7 @@
|
|
|
8190
8190
|
"surface": "builders-hall",
|
|
8191
8191
|
"text": "Note it",
|
|
8192
8192
|
"file": "modules/hall-ui/public/studio.js",
|
|
8193
|
-
"line":
|
|
8193
|
+
"line": 176,
|
|
8194
8194
|
"origin": "js-markup",
|
|
8195
8195
|
"confidence": "certain"
|
|
8196
8196
|
},
|
|
@@ -8199,7 +8199,7 @@
|
|
|
8199
8199
|
"surface": "builders-hall",
|
|
8200
8200
|
"text": "Noted on the review — it stays open.",
|
|
8201
8201
|
"file": "modules/hall-ui/public/studio.js",
|
|
8202
|
-
"line":
|
|
8202
|
+
"line": 403,
|
|
8203
8203
|
"origin": "js-notice",
|
|
8204
8204
|
"confidence": "certain"
|
|
8205
8205
|
},
|
|
@@ -8406,7 +8406,7 @@
|
|
|
8406
8406
|
"surface": "builders-hall",
|
|
8407
8407
|
"text": "Only if it needs it — with the AI at your side, or on your own.",
|
|
8408
8408
|
"file": "modules/hall-ui/public/studio.js",
|
|
8409
|
-
"line":
|
|
8409
|
+
"line": 196,
|
|
8410
8410
|
"origin": "js-markup",
|
|
8411
8411
|
"confidence": "certain"
|
|
8412
8412
|
},
|
|
@@ -8532,7 +8532,7 @@
|
|
|
8532
8532
|
"surface": "builders-hall",
|
|
8533
8533
|
"text": "Open in the copy desk",
|
|
8534
8534
|
"file": "modules/hall-ui/public/studio.js",
|
|
8535
|
-
"line":
|
|
8535
|
+
"line": 233,
|
|
8536
8536
|
"origin": "js-markup",
|
|
8537
8537
|
"confidence": "certain"
|
|
8538
8538
|
},
|
|
@@ -8604,7 +8604,7 @@
|
|
|
8604
8604
|
"surface": "builders-hall",
|
|
8605
8605
|
"text": "Open this review",
|
|
8606
8606
|
"file": "modules/hall-ui/public/studio.js",
|
|
8607
|
-
"line":
|
|
8607
|
+
"line": 218,
|
|
8608
8608
|
"origin": "js-markup",
|
|
8609
8609
|
"confidence": "certain"
|
|
8610
8610
|
},
|
|
@@ -9450,7 +9450,7 @@
|
|
|
9450
9450
|
"surface": "builders-hall",
|
|
9451
9451
|
"text": "Remake or tweak",
|
|
9452
9452
|
"file": "modules/hall-ui/public/studio.js",
|
|
9453
|
-
"line":
|
|
9453
|
+
"line": 196,
|
|
9454
9454
|
"origin": "js-markup",
|
|
9455
9455
|
"confidence": "certain"
|
|
9456
9456
|
},
|
|
@@ -9765,7 +9765,7 @@
|
|
|
9765
9765
|
"surface": "builders-hall",
|
|
9766
9766
|
"text": "Review how it judged this work, and teach it what good looked like.",
|
|
9767
9767
|
"file": "modules/hall-ui/public/studio.js",
|
|
9768
|
-
"line":
|
|
9768
|
+
"line": 196,
|
|
9769
9769
|
"origin": "js-markup",
|
|
9770
9770
|
"confidence": "certain"
|
|
9771
9771
|
},
|
|
@@ -10602,7 +10602,7 @@
|
|
|
10602
10602
|
"surface": "builders-hall",
|
|
10603
10603
|
"text": "Start over",
|
|
10604
10604
|
"file": "modules/hall-ui/public/studio.js",
|
|
10605
|
-
"line":
|
|
10605
|
+
"line": 249,
|
|
10606
10606
|
"origin": "js-markup",
|
|
10607
10607
|
"confidence": "certain"
|
|
10608
10608
|
},
|
|
@@ -11133,7 +11133,7 @@
|
|
|
11133
11133
|
"surface": "builders-hall",
|
|
11134
11134
|
"text": "The headline lands, but the sub-line reads like a brochure.",
|
|
11135
11135
|
"file": "modules/hall-ui/public/studio.js",
|
|
11136
|
-
"line":
|
|
11136
|
+
"line": 176,
|
|
11137
11137
|
"origin": "js-markup",
|
|
11138
11138
|
"confidence": "certain"
|
|
11139
11139
|
},
|
|
@@ -12636,7 +12636,7 @@
|
|
|
12636
12636
|
"surface": "builders-hall",
|
|
12637
12637
|
"text": "What you saw",
|
|
12638
12638
|
"file": "modules/hall-ui/public/studio.js",
|
|
12639
|
-
"line":
|
|
12639
|
+
"line": 176,
|
|
12640
12640
|
"origin": "js-markup",
|
|
12641
12641
|
"confidence": "certain"
|
|
12642
12642
|
},
|
|
@@ -13284,7 +13284,7 @@
|
|
|
13284
13284
|
"surface": "builders-hall",
|
|
13285
13285
|
"text": "Your verdict on a review is recorded from the review itself — open it to dismiss it, note what you saw, or file the follow-up.",
|
|
13286
13286
|
"file": "modules/hall-ui/public/studio.js",
|
|
13287
|
-
"line":
|
|
13287
|
+
"line": 173,
|
|
13288
13288
|
"origin": "js-markup",
|
|
13289
13289
|
"confidence": "certain"
|
|
13290
13290
|
},
|
|
@@ -13482,7 +13482,7 @@
|
|
|
13482
13482
|
"surface": "builders-hall",
|
|
13483
13483
|
"text": "and {…} more waiting{…}",
|
|
13484
13484
|
"file": "modules/hall-ui/public/studio.js",
|
|
13485
|
-
"line":
|
|
13485
|
+
"line": 291,
|
|
13486
13486
|
"origin": "js-markup",
|
|
13487
13487
|
"confidence": "certain"
|
|
13488
13488
|
},
|
|
@@ -15300,7 +15300,7 @@
|
|
|
15300
15300
|
"surface": "builders-hall",
|
|
15301
15301
|
"text": "to tend now · {…}",
|
|
15302
15302
|
"file": "modules/hall-ui/public/studio.js",
|
|
15303
|
-
"line":
|
|
15303
|
+
"line": 218,
|
|
15304
15304
|
"origin": "js-markup",
|
|
15305
15305
|
"confidence": "certain"
|
|
15306
15306
|
},
|
|
@@ -15309,7 +15309,7 @@
|
|
|
15309
15309
|
"surface": "builders-hall",
|
|
15310
15310
|
"text": "to tend now · {…}",
|
|
15311
15311
|
"file": "modules/hall-ui/public/studio.js",
|
|
15312
|
-
"line":
|
|
15312
|
+
"line": 233,
|
|
15313
15313
|
"origin": "js-markup",
|
|
15314
15314
|
"confidence": "certain"
|
|
15315
15315
|
},
|
|
@@ -16299,7 +16299,7 @@
|
|
|
16299
16299
|
"surface": "builders-hall",
|
|
16300
16300
|
"text": "— your words, in your voice. Needed for a note or a follow-up.",
|
|
16301
16301
|
"file": "modules/hall-ui/public/studio.js",
|
|
16302
|
-
"line":
|
|
16302
|
+
"line": 176,
|
|
16303
16303
|
"origin": "js-markup",
|
|
16304
16304
|
"confidence": "certain"
|
|
16305
16305
|
},
|
|
@@ -2617,5 +2617,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2617
2617
|
landed since 1.19.1063 with no explicit bump. run 36441707814. (task 1002620)
|
|
2618
2618
|
1.19.1065 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2619
2619
|
landed since 1.19.1064 with no explicit bump. run 36451089716. (task 1002620)
|
|
2620
|
+
1.19.1066 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2621
|
+
landed since 1.19.1065 with no explicit bump. run 36454504693. (task 1002620)
|
|
2622
|
+
1.19.1067 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2623
|
+
landed since 1.19.1066 with no explicit bump. run 36458843914. (task 1002620)
|
|
2620
2624
|
---------------------------------------------------------------------------
|
|
2621
2625
|
```
|
package/docs/page-readings.json
CHANGED
|
@@ -2651,7 +2651,7 @@
|
|
|
2651
2651
|
"surface": "builders",
|
|
2652
2652
|
"title": "Studio",
|
|
2653
2653
|
"states_read": ["focus","out","full","full-back","approvals","approvals-before","approvals-phone","approvals-note","approved","sent-back"],
|
|
2654
|
-
"files_hash": "
|
|
2654
|
+
"files_hash": "30f4407e6abacbb0",
|
|
2655
2655
|
"reading_hash": "e52bb7163191d85a",
|
|
2656
2656
|
"counts": {"lines":45,"placed":23,"shared":5,"unplaced":17},
|
|
2657
2657
|
"omitted": {"data":7},
|
|
@@ -2667,18 +2667,18 @@
|
|
|
2667
2667
|
{"key":"L0008","section":"Good morning, {…}","text":"Approval queue","placement":"placed","file":"modules/hall-ui/public/studio.html","line":55,"string_id":"20c98a4b630f"},
|
|
2668
2668
|
{"key":"L0009","section":"Good morning, {…}","text":"1 page applied, waiting for you","placement":"unplaced","state":"approved"},
|
|
2669
2669
|
{"key":"L0010","section":"Good morning, {…}","text":"2 pages applied, waiting for you","placement":"unplaced"},
|
|
2670
|
-
{"key":"L0011","section":"Good morning, {…}","text":"to tend now · {…}","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2670
|
+
{"key":"L0011","section":"Good morning, {…}","text":"to tend now · {…}","placement":"placed","file":"modules/hall-ui/public/studio.js","line":218,"string_id":"1b88ce51fd84"},
|
|
2671
2671
|
{"key":"L0012","section":"The copy and visuals that {…} in task #1899","text":"The copy and visuals that {…} in task #1899","placement":"unplaced"},
|
|
2672
|
-
{"key":"L0013","section":"The copy and visuals that {…} in task #1899","text":"It shipped and it is live. Say what you see — your review coaches the grader and never blocks what shipped.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2673
|
-
{"key":"L0014","section":"The copy and visuals that {…} in task #1899","text":"What you saw","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2674
|
-
{"key":"L0015","section":"The copy and visuals that {…} in task #1899","text":"— your words, in your voice. Needed for a note or a follow-up.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2675
|
-
{"key":"L0016","section":"The copy and visuals that {…} in task #1899","text":"The headline lands, but the sub-line reads like a brochure.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2676
|
-
{"key":"L0017","section":"The copy and visuals that {…} in task #1899","text":"Looks good","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2677
|
-
{"key":"L0018","section":"The copy and visuals that {…} in task #1899","text":"Note it","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2678
|
-
{"key":"L0019","section":"The copy and visuals that {…} in task #1899","text":"Needs work","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2679
|
-
{"key":"L0020","section":"The copy and visuals that {…} in task #1899","text":"Open this review","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2680
|
-
{"key":"L0021","section":"The copy and visuals that {…} in task #1899","text":"Let it be for now","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2681
|
-
{"key":"L0022","section":"The copy and visuals that {…} in task #1899","text":"and {…} more waiting{…}","placement":"placed","file":"modules/hall-ui/public/studio.js","line":
|
|
2672
|
+
{"key":"L0013","section":"The copy and visuals that {…} in task #1899","text":"It shipped and it is live. Say what you see — your review coaches the grader and never blocks what shipped.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":216,"string_id":"a28aa368453f"},
|
|
2673
|
+
{"key":"L0014","section":"The copy and visuals that {…} in task #1899","text":"What you saw","placement":"placed","file":"modules/hall-ui/public/studio.js","line":176,"string_id":"1d5bfd09068c"},
|
|
2674
|
+
{"key":"L0015","section":"The copy and visuals that {…} in task #1899","text":"— your words, in your voice. Needed for a note or a follow-up.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":176,"string_id":"d3afa6d6dd9e"},
|
|
2675
|
+
{"key":"L0016","section":"The copy and visuals that {…} in task #1899","text":"The headline lands, but the sub-line reads like a brochure.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":176,"string_id":"027e9420daa2","attr":"placeholder"},
|
|
2676
|
+
{"key":"L0017","section":"The copy and visuals that {…} in task #1899","text":"Looks good","placement":"placed","file":"modules/hall-ui/public/studio.js","line":176,"string_id":"73677b6839d7"},
|
|
2677
|
+
{"key":"L0018","section":"The copy and visuals that {…} in task #1899","text":"Note it","placement":"placed","file":"modules/hall-ui/public/studio.js","line":176,"string_id":"73c72974f4f9"},
|
|
2678
|
+
{"key":"L0019","section":"The copy and visuals that {…} in task #1899","text":"Needs work","placement":"placed","file":"modules/hall-ui/public/studio.js","line":176,"string_id":"3970d299c95a"},
|
|
2679
|
+
{"key":"L0020","section":"The copy and visuals that {…} in task #1899","text":"Open this review","placement":"placed","file":"modules/hall-ui/public/studio.js","line":218,"string_id":"1cb80282de09"},
|
|
2680
|
+
{"key":"L0021","section":"The copy and visuals that {…} in task #1899","text":"Let it be for now","placement":"placed","file":"modules/hall-ui/public/studio.js","line":218,"string_id":"d6a78b9e5368"},
|
|
2681
|
+
{"key":"L0022","section":"The copy and visuals that {…} in task #1899","text":"and {…} more waiting{…}","placement":"placed","file":"modules/hall-ui/public/studio.js","line":291,"string_id":"d86265f99668"},
|
|
2682
2682
|
{"key":"L0023","section":"The copy and visuals that {…} in task #1899","text":"The copy desk — every flagged string","placement":"placed","file":"modules/hall-ui/public/studio.html","line":76,"string_id":"2dc061096c48"},
|
|
2683
2683
|
{"key":"L0024","section":"The copy and visuals that {…} in task #1899","text":"The task board — all work","placement":"placed","file":"modules/hall-ui/public/studio.html","line":77,"string_id":"599fd0e82d1c"},
|
|
2684
2684
|
{"key":"L0025","section":"footer","text":"Sign out","placement":"shared","file":"modules/hall-ui/public/shell.js","line":473,"string_id":"1883ad7f07fc"},
|
|
@@ -36,8 +36,10 @@ const pages = require('./pages');
|
|
|
36
36
|
|
|
37
37
|
const TERMINAL = new Set(['shipped', 'abandoned']);
|
|
38
38
|
|
|
39
|
-
// The credit reason ADR 0341 D10 books an approved page under.
|
|
40
|
-
//
|
|
39
|
+
// The credit reason ADR 0341 D10 books an approved page under. The economy
|
|
40
|
+
// module writes it at the land (credits.js awardArtistPageCredit, task 1004324,
|
|
41
|
+
// its ARTIST_PAGE_REASON_PREFIX); restated here because a module cannot require
|
|
42
|
+
// another, and tests/artist_page_credit.mjs holds the two strings together.
|
|
41
43
|
const TALLY_REASON_PREFIX = 'tweak.page_approved:';
|
|
42
44
|
const WEEK_MS = 7 * 24 * 60 * 60 * 1000;
|
|
43
45
|
|
|
@@ -361,8 +361,9 @@ function pageReadsOrFail(res) {
|
|
|
361
361
|
}
|
|
362
362
|
|
|
363
363
|
// Every `tweak.page_approved:` credit row the caller has, through the reward
|
|
364
|
-
// port (credit_log is economy's table). No reward port, or no
|
|
365
|
-
//
|
|
364
|
+
// port (credit_log is economy's table). No reward port, or no approved page
|
|
365
|
+
// landed yet (economy books one row per landed round, task 1004324), reads as
|
|
366
|
+
// none: a tally of 0 is the truth then.
|
|
366
367
|
//
|
|
367
368
|
// ONE bounded query. An approved page books one row, so the cap is thousands of
|
|
368
369
|
// pages for one artist; past it the tally says `truncated` (creditLedger's
|
|
@@ -1174,6 +1174,80 @@ async function sumSessionEarnings(executor, builderId, taskIds, sessionId) {
|
|
|
1174
1174
|
return rows[0] ? rows[0].total : 0;
|
|
1175
1175
|
}
|
|
1176
1176
|
|
|
1177
|
+
// =========================================================================
|
|
1178
|
+
// The ARTIST credit lane (task 1004324 / BV2.TW13, ADR 0341 D10).
|
|
1179
|
+
// =========================================================================
|
|
1180
|
+
// Tweak Mode replaced the per-ship artist review with an approved page, and the
|
|
1181
|
+
// owner's rule is the same payouts. A review paid its PRICED value,
|
|
1182
|
+
// credits_reward x kind multiplier, as the per-task estimate, which cost-plus-only
|
|
1183
|
+
// withholds, so paid literally a studio artist would earn nothing on this
|
|
1184
|
+
// instance. So an approved page pays that priced value (30 for a feature round
|
|
1185
|
+
// at 30) on its own lane, `artistCredit`, which cost-plus-only does not touch:
|
|
1186
|
+
// the ideator lane's precedent (ADR 0172). The lifecycle calls this at the land
|
|
1187
|
+
// INSTEAD of the shipper's per-task estimate, so the total is conserved in both
|
|
1188
|
+
// modes, and the applier keeps its cost-plus session reward, which is booked
|
|
1189
|
+
// elsewhere and is untouched here.
|
|
1190
|
+
//
|
|
1191
|
+
// The reason prefix is the one copy-desk's tally already sums
|
|
1192
|
+
// (modules/copy-desk/page-status.js TALLY_REASON_PREFIX, restated there because
|
|
1193
|
+
// a module cannot require another; tests/artist_page_credit.mjs holds the two
|
|
1194
|
+
// strings together).
|
|
1195
|
+
const ARTIST_PAGE_REASON_PREFIX = 'tweak.page_approved:';
|
|
1196
|
+
const PAGE_TWEAK_SOURCE = 'page-tweak';
|
|
1197
|
+
|
|
1198
|
+
// Everything is read from the ledger inside the caller's transaction, never
|
|
1199
|
+
// taken from the caller (ADR 0185): the task's own source, status and priced
|
|
1200
|
+
// value, and the payee, the builder of the round's LATEST WEB claim (both
|
|
1201
|
+
// worktree_name and creator_session_id null), the claim the submit released.
|
|
1202
|
+
// That is the TW05 reads' artist rule (modules/lifecycle/page-tweak-reads.js),
|
|
1203
|
+
// so the changelog's artist and the paid artist are the same person.
|
|
1204
|
+
//
|
|
1205
|
+
// NEVER PAID UNLESS SHIPPED. The row must read `shipped` in this transaction, so
|
|
1206
|
+
// a round that was sent back, abandoned or is still waiting pays nothing, even
|
|
1207
|
+
// if a caller reaches this early.
|
|
1208
|
+
//
|
|
1209
|
+
// ONE PAYMENT PER ROUND. The NOT EXISTS keys on (task_id, reason), served by
|
|
1210
|
+
// idx_credit_log_task. That is stricter than ADR 0341's "(builder, reason)": a
|
|
1211
|
+
// round has one payee, so keying on the round alone also refuses a second row
|
|
1212
|
+
// should the payee ever read differently on a re-sweep, and a self-applied round
|
|
1213
|
+
// (the artist also ran /tweak) is still one artist row, never two.
|
|
1214
|
+
//
|
|
1215
|
+
// Returns { credited, reason, artistId, delta } with a reason on every path:
|
|
1216
|
+
// 'paid' · 'already_paid' · 'artist_lane_off' · 'not_found' · 'not_a_page_tweak'
|
|
1217
|
+
// · 'not_shipped' · 'no_artist' · 'zero_value'.
|
|
1218
|
+
async function awardArtistPageCredit(client, { taskId, config = rewardConfig() } = {}) {
|
|
1219
|
+
if (config && config.artistCredit === false) return { credited: 0, reason: 'artist_lane_off' };
|
|
1220
|
+
const { rows } = await client.query(
|
|
1221
|
+
`SELECT t.source, t.status, t.credits_reward, t.kind,
|
|
1222
|
+
(SELECT c.builder_id FROM claims c
|
|
1223
|
+
WHERE c.task_id = t.id AND c.worktree_name IS NULL AND c.creator_session_id IS NULL
|
|
1224
|
+
ORDER BY c.claimed_at DESC, c.id DESC
|
|
1225
|
+
LIMIT 1) AS artist_id
|
|
1226
|
+
FROM tasks t
|
|
1227
|
+
WHERE t.id = $1`,
|
|
1228
|
+
[taskId]
|
|
1229
|
+
);
|
|
1230
|
+
const t = rows[0];
|
|
1231
|
+
if (!t) return { credited: 0, reason: 'not_found' };
|
|
1232
|
+
if (t.source !== PAGE_TWEAK_SOURCE) return { credited: 0, reason: 'not_a_page_tweak' };
|
|
1233
|
+
if (t.status !== 'shipped') return { credited: 0, reason: 'not_shipped' };
|
|
1234
|
+
if (t.artist_id == null) return { credited: 0, reason: 'no_artist' };
|
|
1235
|
+
// The review's priced value, by the one multiplier rule (rounded once, there).
|
|
1236
|
+
const priced = applyKindMultiplier(t.credits_reward, t.kind);
|
|
1237
|
+
if (priced.effective <= 0) return { credited: 0, reason: 'zero_value', artistId: t.artist_id };
|
|
1238
|
+
const reason = `${ARTIST_PAGE_REASON_PREFIX}${taskId}`;
|
|
1239
|
+
const { rowCount } = await client.query(
|
|
1240
|
+
`INSERT INTO credit_log (builder_id, task_id, delta, reason, description)
|
|
1241
|
+
SELECT $1, $2, $3, $4, $5
|
|
1242
|
+
WHERE NOT EXISTS (SELECT 1 FROM credit_log WHERE task_id = $2 AND reason = $4)`,
|
|
1243
|
+
[t.artist_id, taskId, priced.effective, reason,
|
|
1244
|
+
`Approved page tweak, task #${taskId}: ${priced.description} to its artist (artist lane, ADR 0341 D10)`]
|
|
1245
|
+
);
|
|
1246
|
+
return rowCount > 0
|
|
1247
|
+
? { credited: priced.effective, reason: 'paid', artistId: t.artist_id, delta: priced.effective }
|
|
1248
|
+
: { credited: 0, reason: 'already_paid', artistId: t.artist_id, delta: priced.effective };
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1177
1251
|
// The three ideator streams (ADR 0172) each book under a reason key that EMBEDS
|
|
1178
1252
|
// the idea (and, for stream 1, the task) — that string IS the idempotency
|
|
1179
1253
|
// predicate, which is why it can't be a bare constant:
|
|
@@ -1294,4 +1368,7 @@ module.exports = {
|
|
|
1294
1368
|
// the ledger read surface (task 1003484, blocker 1000127)
|
|
1295
1369
|
creditLedger,
|
|
1296
1370
|
IDEA_STREAM_REASON_PREFIXES,
|
|
1371
|
+
// the artist lane (task 1004324 / BV2.TW13, ADR 0341 D10)
|
|
1372
|
+
awardArtistPageCredit,
|
|
1373
|
+
ARTIST_PAGE_REASON_PREFIX,
|
|
1297
1374
|
};
|
|
@@ -61,6 +61,12 @@ function rewardPolicy(rawReward) {
|
|
|
61
61
|
const perTaskCredit = mode !== REWARD_MODE_COST_PLUS_ONLY;
|
|
62
62
|
// Default-on, opt-out-only: only an explicit `false` withholds the ideator lane.
|
|
63
63
|
const ideatorCredit = r.ideatorCredit !== false;
|
|
64
|
+
// The ARTIST lane (task 1004324 / BV2.TW13, ADR 0341 D10): an approved page
|
|
65
|
+
// pays its artist on its own lane, the ideator lane's precedent exactly. Not
|
|
66
|
+
// derived from `mode`, so cost-plus-only does not withhold it: a studio artist
|
|
67
|
+
// runs no session, so the cost-plus reward can never reach them. Default-on,
|
|
68
|
+
// opt-out-only, the same rule as ideatorCredit.
|
|
69
|
+
const artistCredit = r.artistCredit !== false;
|
|
64
70
|
// Validated to [0, 1): see IDEA_DESCENT_DECAY above — a rate of 1 or more does
|
|
65
71
|
// not converge, and a negative one would pay a descent backwards.
|
|
66
72
|
// ABSENT IS THE DEFAULT, NOT ZERO — and Number(null) is 0, which is a legal
|
|
@@ -71,7 +77,7 @@ function rewardPolicy(rawReward) {
|
|
|
71
77
|
const ideaDescentDecay = Number.isFinite(rawDecay) && rawDecay >= 0 && rawDecay < 1
|
|
72
78
|
? rawDecay
|
|
73
79
|
: IDEA_DESCENT_DECAY;
|
|
74
|
-
return { marginPct, usdPeg, mode, perTaskCredit, ideatorCredit, ideaDescentDecay };
|
|
80
|
+
return { marginPct, usdPeg, mode, perTaskCredit, ideatorCredit, artistCredit, ideaDescentDecay };
|
|
75
81
|
}
|
|
76
82
|
|
|
77
83
|
module.exports = {
|
|
@@ -40,6 +40,10 @@ module.exports = {
|
|
|
40
40
|
// `client` (docs/specs/board-room-pass-event-contract.md) — the port is how
|
|
41
41
|
// money crosses the wall; the `board.item.passed` event never carries a payment.
|
|
42
42
|
awardIdeaGovernancePassCredit: (...a) => credits.awardIdeaGovernancePassCredit(...a),
|
|
43
|
+
// BV2.TW13 / ADR 0341 D10 — the artist lane: an approved page, at its land,
|
|
44
|
+
// pays its artist the review's priced value. The lifecycle's landing hook calls
|
|
45
|
+
// it INSTEAD of the per-task estimate on a page tweak; the payee is read here.
|
|
46
|
+
awardArtistPageCredit: (...a) => credits.awardArtistPageCredit(...a),
|
|
43
47
|
awardNetNegativeBonus: (...a) => credits.awardNetNegativeBonus(...a),
|
|
44
48
|
awardSessionTokenReward: (...a) => credits.awardSessionTokenReward(...a),
|
|
45
49
|
// gamification hooks the lifecycle fires at claim/ship
|
|
@@ -97,6 +97,6 @@
|
|
|
97
97
|
studio.js mounts it with its own WRITE_ROUTES. -->
|
|
98
98
|
<script src="/builders/approval-queue-lib.js"></script>
|
|
99
99
|
<script src="/builders/approval-queue.js"></script>
|
|
100
|
-
<script src="/builders/studio.js?v=2026-09-28-
|
|
100
|
+
<script src="/builders/studio.js?v=2026-09-28-tw14"></script>
|
|
101
101
|
</body>
|
|
102
102
|
</html>
|
|
@@ -8,10 +8,13 @@
|
|
|
8
8
|
// So this is NOT a queue table. It aggregates the artist's real work — the two
|
|
9
9
|
// surfaces the rest of goal 1000074 built — and presents it ONE PIECE AT A TIME,
|
|
10
10
|
// a stone to tend in a calm garden, with the rest waiting quietly:
|
|
11
|
-
// 1. REVIEW REQUESTS (R04, cascade.js) —
|
|
12
|
-
// artist review at `backlog`, discipline
|
|
13
|
-
//
|
|
14
|
-
//
|
|
11
|
+
// 1. REVIEW REQUESTS (R04, cascade.js) — RETIRED, draining. A copy/visual
|
|
12
|
+
// ship used to file a two-step artist review at `backlog`, discipline
|
|
13
|
+
// 'artist', source 'cascade'. Tweak Mode removed that rule (task 1004325 /
|
|
14
|
+
// BV2.TW14, ADR 0341 D9), so no new reviews arrive; the ones already filed
|
|
15
|
+
// still show here so they can be answered (they may still hold a deploy
|
|
16
|
+
// under the strict artist gate, ADR 0241). TW16 rebuilds this room as the
|
|
17
|
+
// Tweak Mode home, and this queue goes with it once it is empty.
|
|
15
18
|
// 2. FLAGGED COPY (R02, copy-desk) — open flags over the words the product
|
|
16
19
|
// shows people. Best-effort: an instance without the copy-desk module has
|
|
17
20
|
// no queue, and the room degrades to reviews alone rather than erroring.
|
|
@@ -46,9 +49,9 @@
|
|
|
46
49
|
let busy = false; // a verdict is in flight — one at a time, so a double-click cannot file twice
|
|
47
50
|
let tended = false; // at least one verdict landed this sitting, so an emptied garden reads as finished
|
|
48
51
|
|
|
49
|
-
// Bound the reviews read. cascade.js
|
|
50
|
-
//
|
|
51
|
-
// so this queue
|
|
52
|
+
// Bound the reviews read. cascade.js USED to file a review per qualifying ship
|
|
53
|
+
// (no longer, since TW14: the queue only drains now), and they sit at backlog
|
|
54
|
+
// until claimed or dismissed, so this queue could grow without bound — the unbounded-read
|
|
52
55
|
// shape modules/hall-ui/CLAUDE.md flags as a repeat bug (the Work board's backlog,
|
|
53
56
|
// Home's next-up card, the Goals rollup all had it). 50 is far more than a focus
|
|
54
57
|
// queue tends at once; the footer links to the copy desk and board are the
|
|
@@ -240,8 +243,8 @@
|
|
|
240
243
|
function emptyCard(done) {
|
|
241
244
|
const heading = done ? 'You have tended everything waiting' : 'Nothing waits right now';
|
|
242
245
|
const body = done
|
|
243
|
-
? 'That is the whole garden. Come back when
|
|
244
|
-
: 'A quiet moment
|
|
246
|
+
? 'That is the whole garden. Come back when someone flags a line, or start again from the top.'
|
|
247
|
+
: 'A quiet moment. When someone flags a line of copy, it waits here for you.';
|
|
245
248
|
const restart = done
|
|
246
249
|
? '<div class="studio-card__actions studio-empty__actions"><button type="button" class="btn-ghost" data-restart>Start over</button></div>'
|
|
247
250
|
: '';
|