@bongos/core 1.23.5 → 1.23.6
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 +51 -36
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +2 -0
- package/clients/bongos-client/index.cjs +2 -0
- package/clients/bongos-client/index.d.ts +4 -0
- package/clients/bongos-client/index.mjs +2 -0
- package/docs/adr/0356-a-recruit-invite-expires-30-days-after-it-is-sent-read-time.md +2 -1
- package/docs/api/openapi.json +96 -5
- package/docs/api-reference.md +3 -2
- package/docs/module-api-changelog.md +2 -0
- package/docs/modules-contract.md +1 -0
- package/modules/onboarding/routes/access-requests.js +10 -9
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +10 -0
- package/scripts/bongos/login.js +13 -14
- package/scripts/bongos/module-store-cli.js +182 -0
- package/scripts/bongos/module.js +36 -129
- package/scripts/gds/module-store-cli.js +6 -0
- package/src/bongos/auth-admission.js +3 -3
- package/src/bongos/middleware/rate-limit.js +1 -1
- package/src/bongos/module-listing.js +12 -2
- package/src/bongos/module-store.js +49 -1
- package/src/bongos/route-rank-check.js +3 -0
- package/src/bongos/routes/auth.js +7 -11
- package/src/bongos/routes/modules.js +32 -1
- package/src/module-api.js +1 -1
- package/tests/account_existence_rate_limit.mjs +7 -3
- package/tests/application_lifecycle.mjs +4 -3
- package/tests/bongos_login.mjs +15 -4
- package/tests/invite_expiry_db.mjs +1 -1
- package/tests/module_store_cli.mjs +1 -1
- package/tests/module_store_price.mjs +207 -0
package/.bongos-core.json
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/bongos/package-core.js",
|
|
5
|
-
"core_version": "1.23.
|
|
6
|
-
"core_contract": "1.23.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.23.6",
|
|
6
|
+
"core_contract": "1.23.6",
|
|
7
|
+
"source_commit": "05ce1a9370fbfc0af9f835a707c5c9ee9988be52",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-10-26T23:
|
|
9
|
+
"built_at": "2026-10-26T23:35:18.876Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 616,
|
|
13
13
|
"agent_docs_stubbed": 29,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 3557,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 4203,
|
|
20
|
+
"tree_sha256": "4f3b55cbbaaa3543f5aff4f5f6e26626e2fb433745b649921fcea34837f302f2",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -317,12 +317,12 @@
|
|
|
317
317
|
{
|
|
318
318
|
"path": "clients/bongos-client/README.md",
|
|
319
319
|
"mode": "0000644",
|
|
320
|
-
"sha256": "
|
|
320
|
+
"sha256": "627dcf2fadbf1ab61e7c6efcf6d343b8b6bdb99864dfb39e5941b3ebcb1cb03a"
|
|
321
321
|
},
|
|
322
322
|
{
|
|
323
323
|
"path": "clients/bongos-client/bongos-client.global.js",
|
|
324
324
|
"mode": "0000644",
|
|
325
|
-
"sha256": "
|
|
325
|
+
"sha256": "0741b0ffb53b7b7622370f516588ee2dc0977b242e86caf403c63d26b8d122d7"
|
|
326
326
|
},
|
|
327
327
|
{
|
|
328
328
|
"path": "clients/bongos-client/examples/hello-world.mjs",
|
|
@@ -332,17 +332,17 @@
|
|
|
332
332
|
{
|
|
333
333
|
"path": "clients/bongos-client/index.cjs",
|
|
334
334
|
"mode": "0000644",
|
|
335
|
-
"sha256": "
|
|
335
|
+
"sha256": "6db6d05c604d48c3afa2915a30156dc48763795f4498467a75d026e49f1f407e"
|
|
336
336
|
},
|
|
337
337
|
{
|
|
338
338
|
"path": "clients/bongos-client/index.d.ts",
|
|
339
339
|
"mode": "0000644",
|
|
340
|
-
"sha256": "
|
|
340
|
+
"sha256": "433a4ae717283cb60453bb10c34b1626fc9f0cc696a81ab7b6a884b2708a7e15"
|
|
341
341
|
},
|
|
342
342
|
{
|
|
343
343
|
"path": "clients/bongos-client/index.mjs",
|
|
344
344
|
"mode": "0000644",
|
|
345
|
-
"sha256": "
|
|
345
|
+
"sha256": "3cb6d90344a0642f3be6ceb3385be63e71c8f7e0174bf3dbfc1d2196fac101ac"
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
"path": "clients/bongos-client/package.json",
|
|
@@ -2242,7 +2242,7 @@
|
|
|
2242
2242
|
{
|
|
2243
2243
|
"path": "docs/adr/0356-a-recruit-invite-expires-30-days-after-it-is-sent-read-time.md",
|
|
2244
2244
|
"mode": "0000644",
|
|
2245
|
-
"sha256": "
|
|
2245
|
+
"sha256": "c9bffb1cc48a4f34a20571be61916a5d13f6f1d8bdb50c3c5071eb6ced68efba"
|
|
2246
2246
|
},
|
|
2247
2247
|
{
|
|
2248
2248
|
"path": "docs/adr/0357-the-update-rule-set-on-deploy-is-the-one-the-sweep-follows.md",
|
|
@@ -2392,12 +2392,12 @@
|
|
|
2392
2392
|
{
|
|
2393
2393
|
"path": "docs/api-reference.md",
|
|
2394
2394
|
"mode": "0000644",
|
|
2395
|
-
"sha256": "
|
|
2395
|
+
"sha256": "4d024afe3537d84fede274feebe91e6d4c8cb668ae5bfbc6788dfdd9bede3f1f"
|
|
2396
2396
|
},
|
|
2397
2397
|
{
|
|
2398
2398
|
"path": "docs/api/openapi.json",
|
|
2399
2399
|
"mode": "0000644",
|
|
2400
|
-
"sha256": "
|
|
2400
|
+
"sha256": "c94977d1c916fc4e57bd0647463a431f2d5f7ef595803442475ce108c79841c3"
|
|
2401
2401
|
},
|
|
2402
2402
|
{
|
|
2403
2403
|
"path": "docs/architecture.md",
|
|
@@ -2937,12 +2937,12 @@
|
|
|
2937
2937
|
{
|
|
2938
2938
|
"path": "docs/module-api-changelog.md",
|
|
2939
2939
|
"mode": "0000644",
|
|
2940
|
-
"sha256": "
|
|
2940
|
+
"sha256": "8d3fd9e42419ebfcd1642f42725dd24c60efc03a8aafc88c9f022ab90c0152d6"
|
|
2941
2941
|
},
|
|
2942
2942
|
{
|
|
2943
2943
|
"path": "docs/modules-contract.md",
|
|
2944
2944
|
"mode": "0000644",
|
|
2945
|
-
"sha256": "
|
|
2945
|
+
"sha256": "a54fc56cc901d2580c71138906b4b27eb16529438dbfc3b293a1242cab783477"
|
|
2946
2946
|
},
|
|
2947
2947
|
{
|
|
2948
2948
|
"path": "docs/onboarding/diagrams/01-task-lifecycle.mmd",
|
|
@@ -8212,7 +8212,7 @@
|
|
|
8212
8212
|
{
|
|
8213
8213
|
"path": "modules/onboarding/routes/access-requests.js",
|
|
8214
8214
|
"mode": "0000644",
|
|
8215
|
-
"sha256": "
|
|
8215
|
+
"sha256": "c472b5060dfd0143275ff6769daac986a6cd46c7d722186653f9adaf641a83be"
|
|
8216
8216
|
},
|
|
8217
8217
|
{
|
|
8218
8218
|
"path": "modules/onboarding/routes/onboarding.js",
|
|
@@ -10837,12 +10837,12 @@
|
|
|
10837
10837
|
{
|
|
10838
10838
|
"path": "package-lock.json",
|
|
10839
10839
|
"mode": "0000644",
|
|
10840
|
-
"sha256": "
|
|
10840
|
+
"sha256": "d399eed08dca874f7e3a4f6daecaeebbff9d9d7d99896cfbc23c992786d0b9f5"
|
|
10841
10841
|
},
|
|
10842
10842
|
{
|
|
10843
10843
|
"path": "package.json",
|
|
10844
10844
|
"mode": "0000644",
|
|
10845
|
-
"sha256": "
|
|
10845
|
+
"sha256": "91e4472ae55582eec26d9e0c1264e8fd5c4132441fb6bffdf10a3b90c1ddcdbb"
|
|
10846
10846
|
},
|
|
10847
10847
|
{
|
|
10848
10848
|
"path": "public-docs/index.html",
|
|
@@ -10862,7 +10862,7 @@
|
|
|
10862
10862
|
{
|
|
10863
10863
|
"path": "release-notes.json",
|
|
10864
10864
|
"mode": "0000644",
|
|
10865
|
-
"sha256": "
|
|
10865
|
+
"sha256": "20ffa719f32b7a90a464a880922c08e19de95ebee64d5703168ff7d2aa9db69c"
|
|
10866
10866
|
},
|
|
10867
10867
|
{
|
|
10868
10868
|
"path": "scripts/bongos/CLAUDE.md",
|
|
@@ -11657,7 +11657,7 @@
|
|
|
11657
11657
|
{
|
|
11658
11658
|
"path": "scripts/bongos/login.js",
|
|
11659
11659
|
"mode": "0000644",
|
|
11660
|
-
"sha256": "
|
|
11660
|
+
"sha256": "0a13005b8a73dd31b46bdb6f7762f483654e85e060f37eb8e78d9a6088f7245c"
|
|
11661
11661
|
},
|
|
11662
11662
|
{
|
|
11663
11663
|
"path": "scripts/bongos/main-audit.js",
|
|
@@ -11734,6 +11734,11 @@
|
|
|
11734
11734
|
"mode": "0000644",
|
|
11735
11735
|
"sha256": "0334f9d2e31559bbc661ae0be5404499719d76e670560fa5f4ba72d7c14d0ac7"
|
|
11736
11736
|
},
|
|
11737
|
+
{
|
|
11738
|
+
"path": "scripts/bongos/module-store-cli.js",
|
|
11739
|
+
"mode": "0000644",
|
|
11740
|
+
"sha256": "9634332ab9995fbb906d856fbf575cad3ad83923e4e724e888af5fd25d82b047"
|
|
11741
|
+
},
|
|
11737
11742
|
{
|
|
11738
11743
|
"path": "scripts/bongos/module-test-runner.js",
|
|
11739
11744
|
"mode": "0000644",
|
|
@@ -11752,7 +11757,7 @@
|
|
|
11752
11757
|
{
|
|
11753
11758
|
"path": "scripts/bongos/module.js",
|
|
11754
11759
|
"mode": "0000644",
|
|
11755
|
-
"sha256": "
|
|
11760
|
+
"sha256": "f771cd502f959a281f4aaf60b65b19c240c5a5f7828a030001f7f01fcc75b222"
|
|
11756
11761
|
},
|
|
11757
11762
|
{
|
|
11758
11763
|
"path": "scripts/bongos/move-escalation.js",
|
|
@@ -13399,6 +13404,11 @@
|
|
|
13399
13404
|
"mode": "0000644",
|
|
13400
13405
|
"sha256": "053d6df274f015359f4eb52361aae55857f643672fc3746c941bfed348092b21"
|
|
13401
13406
|
},
|
|
13407
|
+
{
|
|
13408
|
+
"path": "scripts/gds/module-store-cli.js",
|
|
13409
|
+
"mode": "0000644",
|
|
13410
|
+
"sha256": "f7060060ae2ad7f74d3ee43ae3ac7bffe45de976c2ccfbf3ca5e91aecb896b8f"
|
|
13411
|
+
},
|
|
13402
13412
|
{
|
|
13403
13413
|
"path": "scripts/gds/module-test-runner.js",
|
|
13404
13414
|
"mode": "0000644",
|
|
@@ -14302,7 +14312,7 @@
|
|
|
14302
14312
|
{
|
|
14303
14313
|
"path": "src/bongos/auth-admission.js",
|
|
14304
14314
|
"mode": "0000644",
|
|
14305
|
-
"sha256": "
|
|
14315
|
+
"sha256": "1f60d40b8157a9dcc9fcff239123955553ddfe11bb671386f0a0ec4f8ae0ee75"
|
|
14306
14316
|
},
|
|
14307
14317
|
{
|
|
14308
14318
|
"path": "src/bongos/auth-config.js",
|
|
@@ -14422,7 +14432,7 @@
|
|
|
14422
14432
|
{
|
|
14423
14433
|
"path": "src/bongos/middleware/rate-limit.js",
|
|
14424
14434
|
"mode": "0000644",
|
|
14425
|
-
"sha256": "
|
|
14435
|
+
"sha256": "8191011bfa63fcfa1a77383fbab08abdfa4a4584ac641fdf382af5423b06b087"
|
|
14426
14436
|
},
|
|
14427
14437
|
{
|
|
14428
14438
|
"path": "src/bongos/module-entitlements.js",
|
|
@@ -14432,7 +14442,7 @@
|
|
|
14432
14442
|
{
|
|
14433
14443
|
"path": "src/bongos/module-listing.js",
|
|
14434
14444
|
"mode": "0000644",
|
|
14435
|
-
"sha256": "
|
|
14445
|
+
"sha256": "ef63c8be3af54a23b36647b2402517fe2fca4c6c1b0ba5a75d07a85cd39abc92"
|
|
14436
14446
|
},
|
|
14437
14447
|
{
|
|
14438
14448
|
"path": "src/bongos/module-overrides.js",
|
|
@@ -14457,7 +14467,7 @@
|
|
|
14457
14467
|
{
|
|
14458
14468
|
"path": "src/bongos/module-store.js",
|
|
14459
14469
|
"mode": "0000644",
|
|
14460
|
-
"sha256": "
|
|
14470
|
+
"sha256": "75c7e86fc1c0c9d6cffaa63a4c6654fe5191dab919dd988dc04903ca84c84382"
|
|
14461
14471
|
},
|
|
14462
14472
|
{
|
|
14463
14473
|
"path": "src/bongos/module-subcategories.js",
|
|
@@ -14542,7 +14552,7 @@
|
|
|
14542
14552
|
{
|
|
14543
14553
|
"path": "src/bongos/route-rank-check.js",
|
|
14544
14554
|
"mode": "0000644",
|
|
14545
|
-
"sha256": "
|
|
14555
|
+
"sha256": "456217f8086f0748d4bf64536cc304b0124dd4d94783b627cfc5d9ed25e3d8b4"
|
|
14546
14556
|
},
|
|
14547
14557
|
{
|
|
14548
14558
|
"path": "src/bongos/routes.js",
|
|
@@ -14567,7 +14577,7 @@
|
|
|
14567
14577
|
{
|
|
14568
14578
|
"path": "src/bongos/routes/auth.js",
|
|
14569
14579
|
"mode": "0000644",
|
|
14570
|
-
"sha256": "
|
|
14580
|
+
"sha256": "d5ad4455493abf3777e51b6d82a186b810275ab05f8959a7fc13213dcebe9c3a"
|
|
14571
14581
|
},
|
|
14572
14582
|
{
|
|
14573
14583
|
"path": "src/bongos/routes/backup.js",
|
|
@@ -14627,7 +14637,7 @@
|
|
|
14627
14637
|
{
|
|
14628
14638
|
"path": "src/bongos/routes/modules.js",
|
|
14629
14639
|
"mode": "0000644",
|
|
14630
|
-
"sha256": "
|
|
14640
|
+
"sha256": "e7e9c57d4b5c1513425c9349d477e5b1b07c5538cabc74f30d9f899c7962384e"
|
|
14631
14641
|
},
|
|
14632
14642
|
{
|
|
14633
14643
|
"path": "src/bongos/routes/my-passkeys.js",
|
|
@@ -14717,7 +14727,7 @@
|
|
|
14717
14727
|
{
|
|
14718
14728
|
"path": "src/module-api.js",
|
|
14719
14729
|
"mode": "0000644",
|
|
14720
|
-
"sha256": "
|
|
14730
|
+
"sha256": "9c9c3ae365588e980585b171efb35ea63dcad8d21c8a6b8e3e5a9bf140d7dd34"
|
|
14721
14731
|
},
|
|
14722
14732
|
{
|
|
14723
14733
|
"path": "src/module-loader/catalog.js",
|
|
@@ -14822,7 +14832,7 @@
|
|
|
14822
14832
|
{
|
|
14823
14833
|
"path": "tests/account_existence_rate_limit.mjs",
|
|
14824
14834
|
"mode": "0000644",
|
|
14825
|
-
"sha256": "
|
|
14835
|
+
"sha256": "41b8175653a86b79a5dae1e0be041eb4a286720cb41cbcd069afe9bc78b172ac"
|
|
14826
14836
|
},
|
|
14827
14837
|
{
|
|
14828
14838
|
"path": "tests/account_privacy_flags.mjs",
|
|
@@ -15037,7 +15047,7 @@
|
|
|
15037
15047
|
{
|
|
15038
15048
|
"path": "tests/application_lifecycle.mjs",
|
|
15039
15049
|
"mode": "0000644",
|
|
15040
|
-
"sha256": "
|
|
15050
|
+
"sha256": "42a2fb6dae46ffc7b41ffca65be0014be65b46d73c5167b7299543f59387ee6a"
|
|
15041
15051
|
},
|
|
15042
15052
|
{
|
|
15043
15053
|
"path": "tests/architect.mjs",
|
|
@@ -15402,7 +15412,7 @@
|
|
|
15402
15412
|
{
|
|
15403
15413
|
"path": "tests/bongos_login.mjs",
|
|
15404
15414
|
"mode": "0000644",
|
|
15405
|
-
"sha256": "
|
|
15415
|
+
"sha256": "468694776fb15978ac7f716b7c7d434085a5da2331ffa28e274310195cf1e7a2"
|
|
15406
15416
|
},
|
|
15407
15417
|
{
|
|
15408
15418
|
"path": "tests/branding.mjs",
|
|
@@ -17997,7 +18007,7 @@
|
|
|
17997
18007
|
{
|
|
17998
18008
|
"path": "tests/invite_expiry_db.mjs",
|
|
17999
18009
|
"mode": "0000644",
|
|
18000
|
-
"sha256": "
|
|
18010
|
+
"sha256": "711b2f2fdf012b9583edbac35f9bf8eac38425bfe794d8253871d2f2d3bfa034"
|
|
18001
18011
|
},
|
|
18002
18012
|
{
|
|
18003
18013
|
"path": "tests/join_application_note.mjs",
|
|
@@ -18492,7 +18502,7 @@
|
|
|
18492
18502
|
{
|
|
18493
18503
|
"path": "tests/module_store_cli.mjs",
|
|
18494
18504
|
"mode": "0000644",
|
|
18495
|
-
"sha256": "
|
|
18505
|
+
"sha256": "7b57aafabc5d9c3fa568c88157e3049befde2abaa1d54c69ac69520d6cea6efd"
|
|
18496
18506
|
},
|
|
18497
18507
|
{
|
|
18498
18508
|
"path": "tests/module_store_delist.mjs",
|
|
@@ -18514,6 +18524,11 @@
|
|
|
18514
18524
|
"mode": "0000644",
|
|
18515
18525
|
"sha256": "5f0cb9cb6e3faf90d342e1d9e1767699b677b8630d874f1c2af9cb7f713ef530"
|
|
18516
18526
|
},
|
|
18527
|
+
{
|
|
18528
|
+
"path": "tests/module_store_price.mjs",
|
|
18529
|
+
"mode": "0000644",
|
|
18530
|
+
"sha256": "52fe692c1991fa33388b15ff5622f5207b5314fb05d0aa474543d888bda36e66"
|
|
18531
|
+
},
|
|
18517
18532
|
{
|
|
18518
18533
|
"path": "tests/module_store_publish.mjs",
|
|
18519
18534
|
"mode": "0000644",
|
|
@@ -5,7 +5,7 @@ A **generated**, zero-dependency typed client for the Bongos API — produced fr
|
|
|
5
5
|
by hand; it regenerates when the spec changes, so it can never drift from the routes.
|
|
6
6
|
|
|
7
7
|
- API version: **v1** (served at `/api/bongos/v1`)
|
|
8
|
-
-
|
|
8
|
+
- 584 operations across 76 resource groups
|
|
9
9
|
|
|
10
10
|
## Use it from your project
|
|
11
11
|
|
|
@@ -1251,6 +1251,8 @@ function createClient(opts = {}) {
|
|
|
1251
1251
|
getStoreModulesKeyEntitlement: (args) => request("GET", "/store/modules/{key}/entitlement", { hasBody: false }, args),
|
|
1252
1252
|
// GET /store/modules/{key}/listing — rank: any-builder — GET /store/modules/:key/listing
|
|
1253
1253
|
getStoreModulesKeyListing: (args) => request("GET", "/store/modules/{key}/listing", { hasBody: false }, args),
|
|
1254
|
+
// POST /store/modules/{key}/price — rank: metic+archon — POST /store/modules/:key/price
|
|
1255
|
+
postStoreModulesKeyPrice: (args) => request("POST", "/store/modules/{key}/price", { hasBody: true }, args),
|
|
1254
1256
|
// POST /store/modules/{key}/versions — rank: metic+archon — POST /store/modules/:key/versions
|
|
1255
1257
|
postStoreModulesKeyVersions: (args) => request("POST", "/store/modules/{key}/versions", { hasBody: true }, args),
|
|
1256
1258
|
// GET /store/modules/{key}/versions/{version}/channel — rank: any-builder — GET /store/modules/:key/versions/:version/channel
|
|
@@ -1250,6 +1250,8 @@ function createClient(opts = {}) {
|
|
|
1250
1250
|
getStoreModulesKeyEntitlement: (args) => request("GET", "/store/modules/{key}/entitlement", { hasBody: false }, args),
|
|
1251
1251
|
// GET /store/modules/{key}/listing — rank: any-builder — GET /store/modules/:key/listing
|
|
1252
1252
|
getStoreModulesKeyListing: (args) => request("GET", "/store/modules/{key}/listing", { hasBody: false }, args),
|
|
1253
|
+
// POST /store/modules/{key}/price — rank: metic+archon — POST /store/modules/:key/price
|
|
1254
|
+
postStoreModulesKeyPrice: (args) => request("POST", "/store/modules/{key}/price", { hasBody: true }, args),
|
|
1253
1255
|
// POST /store/modules/{key}/versions — rank: metic+archon — POST /store/modules/:key/versions
|
|
1254
1256
|
postStoreModulesKeyVersions: (args) => request("POST", "/store/modules/{key}/versions", { hasBody: true }, args),
|
|
1255
1257
|
// GET /store/modules/{key}/versions/{version}/channel — rank: any-builder — GET /store/modules/:key/versions/:version/channel
|
|
@@ -562,6 +562,8 @@ export interface PostStoreModulesKeyAcquiredRequest { version: string }
|
|
|
562
562
|
export interface PostStoreModulesKeyAcquiredResponse { ok: boolean; entitlement: unknown }
|
|
563
563
|
export interface PostStoreModulesKeyDelistRequest { reason?: string }
|
|
564
564
|
export interface PostStoreModulesKeyDelistResponse { ok: boolean; module_key: unknown; status: unknown; delisted_at: unknown }
|
|
565
|
+
export interface PostStoreModulesKeyPriceRequest { cents?: unknown; credits?: unknown }
|
|
566
|
+
export interface PostStoreModulesKeyPriceResponse { ok: boolean; module_key: unknown; previous: unknown; price: unknown }
|
|
565
567
|
export interface PostStoreModulesKeyVersionsResponse { ok: boolean; created_module: unknown; version: unknown; channel: unknown; category: unknown }
|
|
566
568
|
export interface PostStoreModulesKeyVersionsVersionErrorCountRequest { day: string; count: number }
|
|
567
569
|
export interface PostStoreModulesKeyVersionsVersionInstallReportRequest { ok: boolean; error_code?: string }
|
|
@@ -1810,6 +1812,8 @@ export interface BongosClient {
|
|
|
1810
1812
|
getStoreModulesKeyEntitlement(args?: RequestArgs): Promise<ApiResponse>;
|
|
1811
1813
|
/** GET /store/modules/{key}/listing — rank: any-builder */
|
|
1812
1814
|
getStoreModulesKeyListing(args?: RequestArgs): Promise<ApiResponse>;
|
|
1815
|
+
/** POST /store/modules/{key}/price — rank: metic+archon */
|
|
1816
|
+
postStoreModulesKeyPrice(args?: RequestArgs & { body?: PostStoreModulesKeyPriceRequest }): Promise<PostStoreModulesKeyPriceResponse>;
|
|
1813
1817
|
/** POST /store/modules/{key}/versions — rank: metic+archon */
|
|
1814
1818
|
postStoreModulesKeyVersions(args?: RequestArgs): Promise<PostStoreModulesKeyVersionsResponse>;
|
|
1815
1819
|
/** GET /store/modules/{key}/versions/{version}/channel — rank: any-builder */
|
|
@@ -1247,6 +1247,8 @@ export function createClient(opts = {}) {
|
|
|
1247
1247
|
getStoreModulesKeyEntitlement: (args) => request("GET", "/store/modules/{key}/entitlement", { hasBody: false }, args),
|
|
1248
1248
|
// GET /store/modules/{key}/listing — rank: any-builder — GET /store/modules/:key/listing
|
|
1249
1249
|
getStoreModulesKeyListing: (args) => request("GET", "/store/modules/{key}/listing", { hasBody: false }, args),
|
|
1250
|
+
// POST /store/modules/{key}/price — rank: metic+archon — POST /store/modules/:key/price
|
|
1251
|
+
postStoreModulesKeyPrice: (args) => request("POST", "/store/modules/{key}/price", { hasBody: true }, args),
|
|
1250
1252
|
// POST /store/modules/{key}/versions — rank: metic+archon — POST /store/modules/:key/versions
|
|
1251
1253
|
postStoreModulesKeyVersions: (args) => request("POST", "/store/modules/{key}/versions", { hasBody: true }, args),
|
|
1252
1254
|
// GET /store/modules/{key}/versions/{version}/channel — rank: any-builder — GET /store/modules/:key/versions/:version/channel
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
- **Task:** [task 1002969](https://cloudbongos.com/builders#/task/1002969) (goal 1000110)
|
|
6
6
|
- **Builds on:** privacy spec D4 (`docs/specs/<redacted>.md`; the owner signed the 30 days), [ADR 0335](0335-an-invite-is-a-pre-approved-row-on-the-projects-own-instance.md) D2 (an invite is a `kind='invite'` row on the project's own instance), [ADR 0353](0353-a-hub-invite-is-a-notice-of-the-projects-own-invite.md) (the hub's `pending` row is a notice of that invite)
|
|
7
7
|
- **Amends:** ADR 0335 D2.5 ("no admission path reads `kind`")
|
|
8
|
+
- **Amended by:** [ADR 0217](0217-rank-gates-inviting-not-viewing.md) D4, as built in [task 1003359](https://cloudbongos.com/builders#/task/1003359) — the public status probe answers `not_admitted`, not `expired`, for a lapsed invite, and `bongos login` no longer stops on it. In practice the CLI never saw `expired`: it files a request first, and that newer pending row is what the probe read.
|
|
8
9
|
- **Decided with:** the owner split the original task on 2026-09-30. `seen_at` is [task 1004443](https://cloudbongos.com/builders#/task/1004443); the decline relay is [task 1004444](https://cloudbongos.com/builders#/task/1004444).
|
|
9
10
|
|
|
10
11
|
## Context
|
|
@@ -23,7 +24,7 @@ An invite writes an `invited` row, and the sign-in gate admits any login holding
|
|
|
23
24
|
- The gate refuses it. The public "already approved?" check and the standing-invite probe no longer count it, so the invitee may apply and the recruiter can re-invite.
|
|
24
25
|
- A re-invite writes a fresh row, which opens a fresh door. The expired row stays as history.
|
|
25
26
|
- The queue marks it `expired` with `expires_at`. The outstanding-invite list keeps it so the sender knows to invite again, and drops it once a newer invite for that login is live. The hall's queue shows "Invite expired" and offers no rescind.
|
|
26
|
-
- The public status probe answers `expired` (`admitted: false`), and `bongos login` stops waiting on it. An older CLI treats an unknown status as "wait" and times out, which is no worse than before.
|
|
27
|
+
- The public status probe answers `expired` (`admitted: false`), and `bongos login` stops waiting on it. An older CLI treats an unknown status as "wait" and times out, which is no worse than before. *(Superseded: it now answers `not_admitted` — see "Amended by" above.)*
|
|
27
28
|
- A rescind that leaves only expired rows clears the hub notice.
|
|
28
29
|
|
|
29
30
|
**D5 — The hub's notice follows the door.** `listPendingInvitesForAccount` hides a `pending` notice older than the same 30 days (its `joined_at` is when the project sent the notice). `inviteToProject` restamps `joined_at` only on a `pending` row that is already past the window, so a re-invite shows again. A re-send while the invite is live changes nothing, and a real membership is never touched.
|
package/docs/api/openapi.json
CHANGED
|
@@ -505,7 +505,7 @@
|
|
|
505
505
|
"access-requests"
|
|
506
506
|
],
|
|
507
507
|
"summary": "GET /access-requests/status",
|
|
508
|
-
"description": "GET /access-requests/status?github_login=X — PUBLIC. The `bongos login` CLI polls this after filing a request: the device flow's not_approved is TERMINAL (the device_code is spent), so the CLI can't re-poll the flow — it polls this instead, then restarts sign-in once admitted. Exposes nothing the public POST above doesn't already reveal through its 409s (already_member / already_approved). status ∈ member | invited |
|
|
508
|
+
"description": "GET /access-requests/status?github_login=X — PUBLIC. The `bongos login` CLI polls this after filing a request: the device flow's not_approved is TERMINAL (the device_code is spent), so the CLI can't re-poll the flow — it polls this instead, then restarts sign-in once admitted. Exposes nothing the public POST above doesn't already reveal through its 409s (already_member / already_approved). status ∈ member | invited | not_admitted; admitted = member||invited (ADR 0217 D4, task 1003359). `not_admitted` covers pending, declined, a lapsed invite and no request at all, so a caller who is not the subject cannot learn that someone applied here or was turned down. It does NOT close the membership oracle — `admitted` still answers that, and the limiter below is what bounds enumeration. A lapsed invite answering `not_admitted` rather than `expired` amends ADR 0356 D4. rank: public — a would-be builder is by definition outside the system. Declared BEFORE `GET /access-requests` so the literal `/status` path is matched as its own route (not swallowed as a query on the list route). RATE-LIMITED (task 1003339 / ADR 0209). Public + unthrottled, this was a login→membership oracle an attacker could script at line rate to learn who builds here. accountExistenceReadRateLimit is the doorway's SHARED 120/60s per-IP budget: core's GET /auth/web/admission-status (the boolean twin of this answer) mounts the very same instance, so the two cannot be alternated for double the rate. The limiter runs before the queries, so a refused probe costs no DB work.\n\n**Rank:** `public` — No authentication — any caller.",
|
|
509
509
|
"x-rank": "public",
|
|
510
510
|
"x-source": "modules/onboarding/routes/access-requests.js",
|
|
511
511
|
"responses": {
|
|
@@ -1656,7 +1656,7 @@
|
|
|
1656
1656
|
"auth"
|
|
1657
1657
|
],
|
|
1658
1658
|
"summary": "GET /auth/web/admission-status",
|
|
1659
|
-
"description": "GET /auth/web/admission-status?login=X — the probe renderAccessPendingPage polls (task 1002097). Answers ONE question: would this login be admitted right now? It mirrors the real gate via auth.webAdmissionStatus so the page can never invite someone in the gate would refuse. rank: public — it must be reachable by a visitor with no session (that is the entire situation it exists for). It grants nothing: admission still runs through the normal sign-in, and this only reads state. WHAT IT LEAKS, stated plainly (task 1002430 — an earlier version of this comment claimed the opposite and was wrong). Returning only a boolean does NOT make it non-enumerable: with open enrollment off, and for any login that is not the configured firstAdmin, `admitted:true` means that login is a member or has been invited. That reveals account existence to an unauthenticated caller. IT IS NOW THROTTLED (task 1003339 / ADR 0209). It used to say \"NOT throttled\" here, and that was true: rateLimitMiddleware returns early for non-write methods, so GETs bypassed it entirely and the page's 3s poll bounded the honest client, not an attacker. accountExistenceReadRateLimit below is the ceiling — 120 reads/60s per IP, and the SAME instance is mounted on the onboarding module's GET /access-requests/status, which is this route's strictly richer twin (member|invited|
|
|
1659
|
+
"description": "GET /auth/web/admission-status?login=X — the probe renderAccessPendingPage polls (task 1002097). Answers ONE question: would this login be admitted right now? It mirrors the real gate via auth.webAdmissionStatus so the page can never invite someone in the gate would refuse. rank: public — it must be reachable by a visitor with no session (that is the entire situation it exists for). It grants nothing: admission still runs through the normal sign-in, and this only reads state. WHAT IT LEAKS, stated plainly (task 1002430 — an earlier version of this comment claimed the opposite and was wrong). Returning only a boolean does NOT make it non-enumerable: with open enrollment off, and for any login that is not the configured firstAdmin, `admitted:true` means that login is a member or has been invited. That reveals account existence to an unauthenticated caller. IT IS NOW THROTTLED (task 1003339 / ADR 0209). It used to say \"NOT throttled\" here, and that was true: rateLimitMiddleware returns early for non-write methods, so GETs bypassed it entirely and the page's 3s poll bounded the honest client, not an attacker. accountExistenceReadRateLimit below is the ceiling — 120 reads/60s per IP, and the SAME instance is mounted on the onboarding module's GET /access-requests/status, which is this route's strictly richer twin (member|invited|not_admitted plus its own `admitted`). One budget across both, because they are one oracle: hardening either alone would accomplish nothing, and giving each its own budget would just let an enumerator alternate for double the rate. That twin once told pending/declined/none apart too; it collapsed to `not_admitted` on the owner's call (ADR 0217 D4, task 1003359). That endpoint is also why this one exists: it models neither the firstAdmin bypass nor open enrollment, so it reports the OWNER as 'not_admitted' forever — the exact case this page has to resolve.\n\n**Rank:** `public` — No authentication — any caller.",
|
|
1660
1660
|
"x-rank": "public",
|
|
1661
1661
|
"x-source": "src/bongos/routes/auth.js",
|
|
1662
1662
|
"responses": {
|
|
@@ -23827,6 +23827,72 @@
|
|
|
23827
23827
|
]
|
|
23828
23828
|
}
|
|
23829
23829
|
},
|
|
23830
|
+
"/store/modules/{key}/price": {
|
|
23831
|
+
"post": {
|
|
23832
|
+
"operationId": "post_store_modules_key_price",
|
|
23833
|
+
"tags": [
|
|
23834
|
+
"store"
|
|
23835
|
+
],
|
|
23836
|
+
"summary": "POST /store/modules/:key/price",
|
|
23837
|
+
"description": "POST /api/bongos/store/modules/:key/price — the module's author sets its price (task 1004894, criterion wa5-module-economy). Body: { cents?, credits? }, each a whole number of 0 or more, or null for \"not offered in that currency\"; at least one is given, and 0 in either is free. Appends a row to the price history; the newest is what the catalog shows and what acquire charges. A paid price may be set before buying exists (owner, 2026-10-26): the catalog marks it not yet buyable. Price never moves the score (ADR 0343 D6). The audit middleware records who changed it and to what. rank: metic+archon — the same gate as publishing (module.submit), plus the author check inside setPrice: only the person who published the module prices it.\n\n**Rank:** `metic+archon` — Metic or Archon rank (review/triage powers).\n\n**Permissions:** `module.submit` (all required).",
|
|
23838
|
+
"x-rank": "metic+archon",
|
|
23839
|
+
"x-source": "src/bongos/routes/modules.js",
|
|
23840
|
+
"x-permissions": [
|
|
23841
|
+
"module.submit"
|
|
23842
|
+
],
|
|
23843
|
+
"parameters": [
|
|
23844
|
+
{
|
|
23845
|
+
"name": "key",
|
|
23846
|
+
"in": "path",
|
|
23847
|
+
"required": true,
|
|
23848
|
+
"schema": {
|
|
23849
|
+
"type": "string"
|
|
23850
|
+
},
|
|
23851
|
+
"description": "Path parameter `key`."
|
|
23852
|
+
}
|
|
23853
|
+
],
|
|
23854
|
+
"requestBody": {
|
|
23855
|
+
"required": false,
|
|
23856
|
+
"content": {
|
|
23857
|
+
"application/json": {
|
|
23858
|
+
"schema": {
|
|
23859
|
+
"$ref": "#/components/schemas/PostStoreModulesKeyPriceRequest"
|
|
23860
|
+
}
|
|
23861
|
+
}
|
|
23862
|
+
},
|
|
23863
|
+
"x-validated": true
|
|
23864
|
+
},
|
|
23865
|
+
"responses": {
|
|
23866
|
+
"200": {
|
|
23867
|
+
"description": "Success.",
|
|
23868
|
+
"content": {
|
|
23869
|
+
"application/json": {
|
|
23870
|
+
"schema": {
|
|
23871
|
+
"$ref": "#/components/schemas/PostStoreModulesKeyPriceResponse"
|
|
23872
|
+
}
|
|
23873
|
+
}
|
|
23874
|
+
}
|
|
23875
|
+
},
|
|
23876
|
+
"400": {
|
|
23877
|
+
"$ref": "#/components/responses/ValidationFailed"
|
|
23878
|
+
},
|
|
23879
|
+
"401": {
|
|
23880
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
23881
|
+
},
|
|
23882
|
+
"403": {
|
|
23883
|
+
"$ref": "#/components/responses/Forbidden"
|
|
23884
|
+
},
|
|
23885
|
+
"404": {
|
|
23886
|
+
"$ref": "#/components/responses/NotFound"
|
|
23887
|
+
}
|
|
23888
|
+
},
|
|
23889
|
+
"security": [
|
|
23890
|
+
{
|
|
23891
|
+
"builderSession": []
|
|
23892
|
+
}
|
|
23893
|
+
]
|
|
23894
|
+
}
|
|
23895
|
+
},
|
|
23830
23896
|
"/store/modules/{key}/versions": {
|
|
23831
23897
|
"post": {
|
|
23832
23898
|
"operationId": "post_store_modules_key_versions",
|
|
@@ -36055,6 +36121,31 @@
|
|
|
36055
36121
|
"delisted_at"
|
|
36056
36122
|
]
|
|
36057
36123
|
},
|
|
36124
|
+
"PostStoreModulesKeyPriceRequest": {
|
|
36125
|
+
"type": "object",
|
|
36126
|
+
"properties": {
|
|
36127
|
+
"cents": {},
|
|
36128
|
+
"credits": {}
|
|
36129
|
+
},
|
|
36130
|
+
"additionalProperties": false
|
|
36131
|
+
},
|
|
36132
|
+
"PostStoreModulesKeyPriceResponse": {
|
|
36133
|
+
"type": "object",
|
|
36134
|
+
"properties": {
|
|
36135
|
+
"ok": {
|
|
36136
|
+
"type": "boolean"
|
|
36137
|
+
},
|
|
36138
|
+
"module_key": {},
|
|
36139
|
+
"previous": {},
|
|
36140
|
+
"price": {}
|
|
36141
|
+
},
|
|
36142
|
+
"required": [
|
|
36143
|
+
"ok",
|
|
36144
|
+
"module_key",
|
|
36145
|
+
"previous",
|
|
36146
|
+
"price"
|
|
36147
|
+
]
|
|
36148
|
+
},
|
|
36058
36149
|
"PostStoreModulesKeyVersionsResponse": {
|
|
36059
36150
|
"type": "object",
|
|
36060
36151
|
"properties": {
|
|
@@ -37292,9 +37383,9 @@
|
|
|
37292
37383
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
37293
37384
|
}
|
|
37294
37385
|
},
|
|
37295
|
-
"x-endpoint-count":
|
|
37296
|
-
"x-schema-count":
|
|
37386
|
+
"x-endpoint-count": 584,
|
|
37387
|
+
"x-schema-count": 628,
|
|
37297
37388
|
"x-undocumented-bodies": 12,
|
|
37298
|
-
"x-response-schemas":
|
|
37389
|
+
"x-response-schemas": 406,
|
|
37299
37390
|
"x-generated-by": "scripts/bongos/gen-api-docs.js"
|
|
37300
37391
|
}
|
package/docs/api-reference.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Bongos API reference
|
|
4
4
|
|
|
5
|
-
> **Generated from the live route files** — the route file is authoritative.
|
|
5
|
+
> **Generated from the live route files** — the route file is authoritative. 584 endpoints across 98 route files.
|
|
6
6
|
> Machine-readable spec: [`docs/api/openapi.json`](api/openapi.json) (OpenAPI 3.1). Rendered docs site: **`/docs`** (e.g. `cloudbongos.com/docs`).
|
|
7
7
|
|
|
8
8
|
Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust-boundary-server-enforced-permissions.md)): `public` < `any-builder` < `metic+archon` < `archon`.
|
|
@@ -863,7 +863,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
863
863
|
| GET | `/api/bongos/sso/pubkey` | `public` | — | GET /sso/pubkey — the hub's Ed25519 assertion-verification key (public). |
|
|
864
864
|
| POST | `/api/bongos/sso/token` | `public` | `client_id`, `client_secret`, `code`, `redirect_uri` | POST /sso/token — server-to-server code redemption. |
|
|
865
865
|
|
|
866
|
-
## `store` (
|
|
866
|
+
## `store` (24)
|
|
867
867
|
|
|
868
868
|
| Method | Path | Rank | Body | Description |
|
|
869
869
|
|---|---|---|---|---|
|
|
@@ -874,6 +874,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
874
874
|
| POST | `/api/bongos/store/modules/:key/delist` | `metic+archon` | `reason` | POST /api/bongos/store/modules/:key/delist — a Metic+ person takes a module out of the store (task 1003797, ADR 0338 D2). |
|
|
875
875
|
| GET | `/api/bongos/store/modules/:key/entitlement` | `any-builder` | — | |
|
|
876
876
|
| GET | `/api/bongos/store/modules/:key/listing` | `any-builder` | — | GET /api/bongos/store/modules/:key/listing — whether one module is in the catalog and why (task 1003810): the reason in a sentence, what … |
|
|
877
|
+
| POST | `/api/bongos/store/modules/:key/price` | `metic+archon` | `cents`, `credits` | POST /api/bongos/store/modules/:key/price — the module's author sets its price (task 1004894, criterion wa5-module-economy). |
|
|
877
878
|
| POST | `/api/bongos/store/modules/:key/versions` | `metic+archon` | _undocumented_ | POST /api/bongos/store/modules/:key/versions — publish one module version to the store (task 1004271, ADR 0338 D1). |
|
|
878
879
|
| GET | `/api/bongos/store/modules/:key/versions/:version/channel` | `any-builder` | — | GET /api/bongos/store/modules/:key/versions/:version/channel — where a version stands on the promotion gate (task 1003804, ADR 0344 D3): … |
|
|
879
880
|
| POST | `/api/bongos/store/modules/:key/versions/:version/error-count` | `any-builder` | `day`, `count` | |
|
|
@@ -3227,5 +3227,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
3227
3227
|
landed since 1.23.3 with no explicit bump. run 40406624494. (task 1002620)
|
|
3228
3228
|
1.23.5 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
3229
3229
|
landed since 1.23.4 with no explicit bump. run 40417462733. (task 1002620)
|
|
3230
|
+
1.23.6 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
3231
|
+
landed since 1.23.5 with no explicit bump. run 40420658396. (task 1002620)
|
|
3230
3232
|
---------------------------------------------------------------------------
|
|
3231
3233
|
```
|
package/docs/modules-contract.md
CHANGED
|
@@ -400,6 +400,7 @@ Run `bongos upgrade` to confirm coreVersion compatibility, then `node scripts/bo
|
|
|
400
400
|
- **Tester feedback** (task 1003806, ADR 0344 D5). While a version is on the tester channel, what tester projects report about it becomes its Tester feedback part: the share of testers whose install worked and who hit no runtime errors, blended with ten neutral testers so a small sample cannot score high — `round(100 × (went well + 5) / (testers + 10))`. Reports from after the version left the tester channel, and the author's own, never count; under 3 testers it is not scored yet. The rule is `assessTesterFeedback` in `scripts/bongos/module-assess-installs.js`.
|
|
401
401
|
- **What a module is strong and weak at** (task 1003799, ADR 0343 D4). Each catalog entry also carries `parts` (the current result of Tests, Clean installs, Reliability, Tester feedback and How-to) and a reading of them: `strengths` (a part scored **80 or more**), `weaknesses` (a part scored **below the floor**) and `unmeasured` (a part with no score yet, which is never counted as weak). Each strength and weakness has a one-sentence `detail` saying what the number rests on. Security is not among them: every listed version has passed it. The reading is `readParts` in `src/bongos/module-listing.js`; the hall's Modules tab shows it in its "In the store" group, so two modules with the same overall score can be told apart.
|
|
402
402
|
- **Sorting by a part** (task 1003800). `GET /store/modules?sort=<part>` orders the listed modules by one part a buyer cares about: `tests`, `install`, `reliability`, `tester_feedback` or `docs` (the response lists them as `sort_parts`, and says which one it applied as `sort`). Modules with a score for that part come first, highest first; a tie goes to the higher overall score, then the module key. A module with no score for that part goes last, so missing data never wins or loses a place on its own. New modules are not sorted: they are never ranked. Any other `sort` value is refused with a 400. Without `sort`, the listed modules are in the ranking below; New stays in key order. The rule is `sortByPart` in `src/bongos/module-listing.js`.
|
|
403
|
+
- **Setting a price** (task 1004894). A module's author sets its price with `bongos module price <key> [--cents N] [--credits N]` (or the same two flags on `bongos module publish`, which sets the price right after the upload), or `POST /store/modules/:key/price { cents?, credits? }` (the `module.submit` permission, the same one that publishes, and only the author passes; a delisted module takes no new price). Each amount is a whole number of 0 or more, or null for "not offered in that currency"; at least one is given, and 0 in either makes the module free. Every change appends a row to the price history (in one transaction, the module row locked) naming who set it and when, so the history is the audit of what each price replaced, and the newest is current: it is what the catalog shows and what acquire charges. A paid price may be set before buying exists (owner, 2026-10-26): the catalog lists the module with its price and `buyable: false`, `bongos module store` prints it as not yet buyable, and acquire keeps refusing it without an entitlement. When buying ships (task 1003788), `BUYING_OPEN` in `src/bongos/module-listing.js` is the one switch to flip. Price is never an input to the score (ADR 0343 D6).
|
|
403
404
|
- **The ranking, and a maximum price** (task 1003808, owner decision 2026-10-23). Without `sort`, listed modules are ranked **quality first**: highest overall score first; between equal scores, free modules first, then the lowest cash price, then the lowest credit price, then the module key. Price never buys a better place, it only orders modules the score could not tell apart (and it is never an input to the score, ADR 0343 D6). The response states the rule as `ranking`, and each entry carries its current `price` (`cents`, `credits`, `free`). A buyer may add `?max_cents=` and/or `?max_credits=` (whole numbers, 0 or more): modules that cost more are left out of both lists, free modules always stay, and a priced module stays when it is offered at or under a cap the buyer set. The applied caps come back as `max_price`. The rules are `rankListed` and `withinMaxPrice` in `src/bongos/module-listing.js`.
|
|
404
405
|
- **The cap: at most ten per sub-category** (task 1003809, [ADR 0342](adr/0342-module-categories-are-eight-parents-with-approved-sub-categories.md) D2). Above the floor, at most **ten** modules are listed in each approved sub-category: the first ten in the ranking above, so a buyer's `sort` or maximum price reorders or narrows those ten but never lets the eleventh in. The cap is never applied to a parent. A module whose sub-category is only proposed is listed under its parent and counts toward no cap, and a New module is not ranked, so it neither takes a slot nor is held by one. The catalog returns the cap as `cap`. The rule is `applyCap` in `src/bongos/module-listing.js`.
|
|
405
406
|
- **Why a module is not listed** (task 1003810). `GET /store/modules/:key/listing` says where one module stands, judging the same newest version the catalog does: `listed` (true or false), a `reason` (`not_assessed`, `security_not_passed`, `no_score`, `below_floor`, `delisted`, `no_version`, `over_cap`, `new` or `at_or_above_floor`), `why` in a sentence and `next_step` saying what would change it. A failed Security gate is told apart from one that has not finished, and names what it found to the module's author only (to anyone else it would point at a weakness not fixed yet); below the floor names the score, the floor and the weakest parts. It carries the same `parts`, `strengths`, `weaknesses` and `unmeasured` as the catalog, plus `security`. Any signed-in builder can read it. Past the cap it is `over_cap`, which names the score, the module's place in its sub-category and the cap, so an author can tell being eleventh apart from being below the floor. Both responses carry the module's `category` (`parent`, `parent_title`, and `sub` and `label` once its sub-category is approved). The rule is `explainPlacement` in `src/bongos/module-listing.js`.
|