@bongos/core 1.19.374 → 1.19.375
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 +72 -42
- 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/0194-joinability-one-door-decision.md +42 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +85 -3
- package/docs/api-reference.md +3 -2
- package/docs/copy-inventory.md +249 -233
- package/docs/copy-registry.json +475 -300
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +2 -0
- package/modules/government/catalog.js +1 -1
- package/modules/hall-ui/public/builders.js +5 -3
- package/modules/hall-ui/public/hall-render.js +63 -22
- package/modules/hall-ui/public/my-projects.js +6 -1
- package/modules/hall-ui/public/watch.css +8 -0
- package/modules/hall-ui/public/watch.js +56 -3
- package/modules/onboarding/module.json +1 -1
- package/modules/onboarding/routes/access-requests.js +87 -1
- package/modules/platform-identity/routes/my-projects.js +35 -9
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/projects.html +169 -3
- package/scripts/gds/login.js +24 -3
- package/src/bongos/auth-admission.js +50 -5
- package/src/bongos/auth.js +2 -1
- package/src/bongos/routes/auth.js +15 -0
- package/src/branding.js +3 -2
- package/src/module-api.js +20 -1
- package/tests/access_requests_invite.mjs +165 -0
- package/tests/auth_admission_gate.mjs +42 -0
- package/tests/join_relay_outcome.mjs +61 -0
- package/tests/joinability_apply.mjs +72 -0
- package/tests/joinability_invite_only.mjs +192 -0
- package/tests/joinability_open.mjs +89 -0
- package/tests/module_api.mjs +1 -0
- package/tests/projects_hub.mjs +76 -2
- package/tests/projects_hub_pre_uat.mjs +4 -2
- package/tests/public_landing_projects.mjs +10 -3
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.375",
|
|
6
|
+
"core_contract": "1.19.375",
|
|
7
|
+
"source_commit": "75b8de1c408ddd51e9e44d88a1fab7eee51cf017",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-
|
|
9
|
+
"built_at": "2026-08-25T23:12:43.870Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
|
-
"docs_redacted":
|
|
12
|
+
"docs_redacted": 335,
|
|
13
13
|
"agent_docs_stubbed": 22,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 1554,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 1911,
|
|
20
|
+
"tree_sha256": "6f58b38b0e6751d8cbf0fbaecae632da6dd95061c28e22fd950e182471f7ea57",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -347,12 +347,12 @@
|
|
|
347
347
|
{
|
|
348
348
|
"path": "clients/bongos-client/README.md",
|
|
349
349
|
"mode": "0000644",
|
|
350
|
-
"sha256": "
|
|
350
|
+
"sha256": "663c0e020d58d131bd1311d3cee1ee2b09b27287f59f0f301f89ecac3452a9dd"
|
|
351
351
|
},
|
|
352
352
|
{
|
|
353
353
|
"path": "clients/bongos-client/bongos-client.global.js",
|
|
354
354
|
"mode": "0000644",
|
|
355
|
-
"sha256": "
|
|
355
|
+
"sha256": "e2454e2affc5a2f9203d7dacbe10423264e2c3ff1a45f4d8d5c3bf805c658484"
|
|
356
356
|
},
|
|
357
357
|
{
|
|
358
358
|
"path": "clients/bongos-client/examples/hello-world.mjs",
|
|
@@ -362,17 +362,17 @@
|
|
|
362
362
|
{
|
|
363
363
|
"path": "clients/bongos-client/index.cjs",
|
|
364
364
|
"mode": "0000644",
|
|
365
|
-
"sha256": "
|
|
365
|
+
"sha256": "2c353c9b91dcb8c0afbc961e5b5f383aee69569c05cf7a03fabac02b34d06760"
|
|
366
366
|
},
|
|
367
367
|
{
|
|
368
368
|
"path": "clients/bongos-client/index.d.ts",
|
|
369
369
|
"mode": "0000644",
|
|
370
|
-
"sha256": "
|
|
370
|
+
"sha256": "b19f0435cf2a0124d9e568ad6daac87b54220ea3f170f65fda54ed391058f480"
|
|
371
371
|
},
|
|
372
372
|
{
|
|
373
373
|
"path": "clients/bongos-client/index.mjs",
|
|
374
374
|
"mode": "0000644",
|
|
375
|
-
"sha256": "
|
|
375
|
+
"sha256": "f6d8b1a0ba6b2868204aabda309594e3c25f092611972dbd32753a257a095bd3"
|
|
376
376
|
},
|
|
377
377
|
{
|
|
378
378
|
"path": "clients/bongos-client/package.json",
|
|
@@ -1464,20 +1464,25 @@
|
|
|
1464
1464
|
"mode": "0000644",
|
|
1465
1465
|
"sha256": "38af373e191ebf9d9788884315f90d439ec5a719f08afc596039d722153c8396"
|
|
1466
1466
|
},
|
|
1467
|
+
{
|
|
1468
|
+
"path": "docs/adr/0194-joinability-one-door-decision.md",
|
|
1469
|
+
"mode": "0000644",
|
|
1470
|
+
"sha256": "65bd3a60b8d313af7ea69acf7fe9a522a15a144c4395b3788bd3f82cc20e8351"
|
|
1471
|
+
},
|
|
1467
1472
|
{
|
|
1468
1473
|
"path": "docs/adr/README.md",
|
|
1469
1474
|
"mode": "0000644",
|
|
1470
|
-
"sha256": "
|
|
1475
|
+
"sha256": "7f7354c2597bd982d92e0008595e05642c8ccc05c1e9446388c304e80b142626"
|
|
1471
1476
|
},
|
|
1472
1477
|
{
|
|
1473
1478
|
"path": "docs/api-reference.md",
|
|
1474
1479
|
"mode": "0000644",
|
|
1475
|
-
"sha256": "
|
|
1480
|
+
"sha256": "3fca3c9ed9fe092266ac1b4c721094cd0d50792e1b17a0821f7135d65fb89a57"
|
|
1476
1481
|
},
|
|
1477
1482
|
{
|
|
1478
1483
|
"path": "docs/api/openapi.json",
|
|
1479
1484
|
"mode": "0000644",
|
|
1480
|
-
"sha256": "
|
|
1485
|
+
"sha256": "72f2236c4123dd96be29c778df0b6b2b8531923cd394f193cf80b221b9bb8bdb"
|
|
1481
1486
|
},
|
|
1482
1487
|
{
|
|
1483
1488
|
"path": "docs/architecture.md",
|
|
@@ -1502,12 +1507,12 @@
|
|
|
1502
1507
|
{
|
|
1503
1508
|
"path": "docs/copy-inventory.md",
|
|
1504
1509
|
"mode": "0000644",
|
|
1505
|
-
"sha256": "
|
|
1510
|
+
"sha256": "fd5277bcf4ea80591a81d0b321d67f51380e0db35d0c08e237d95477f02d93b3"
|
|
1506
1511
|
},
|
|
1507
1512
|
{
|
|
1508
1513
|
"path": "docs/copy-registry.json",
|
|
1509
1514
|
"mode": "0000644",
|
|
1510
|
-
"sha256": "
|
|
1515
|
+
"sha256": "24955cb19ef7ef3b24783f58e9a8b403bdd43c8845b4a800b992191d6872dc01"
|
|
1511
1516
|
},
|
|
1512
1517
|
{
|
|
1513
1518
|
"path": "docs/design-contract.md",
|
|
@@ -2912,7 +2917,7 @@
|
|
|
2912
2917
|
{
|
|
2913
2918
|
"path": "modules/dev-box/app/src/vendor/bongos-client.cjs",
|
|
2914
2919
|
"mode": "0000644",
|
|
2915
|
-
"sha256": "
|
|
2920
|
+
"sha256": "2c353c9b91dcb8c0afbc961e5b5f383aee69569c05cf7a03fabac02b34d06760"
|
|
2916
2921
|
},
|
|
2917
2922
|
{
|
|
2918
2923
|
"path": "modules/dev-box/app/test/unit.mjs",
|
|
@@ -3147,7 +3152,7 @@
|
|
|
3147
3152
|
{
|
|
3148
3153
|
"path": "modules/government/catalog.js",
|
|
3149
3154
|
"mode": "0000644",
|
|
3150
|
-
"sha256": "
|
|
3155
|
+
"sha256": "89c03f4af6b1a2bfef8c6820621b977d4872cd7fd4432e4f5ab506063c9acf96"
|
|
3151
3156
|
},
|
|
3152
3157
|
{
|
|
3153
3158
|
"path": "modules/government/config.js",
|
|
@@ -3442,7 +3447,7 @@
|
|
|
3442
3447
|
{
|
|
3443
3448
|
"path": "modules/hall-ui/public/builders.js",
|
|
3444
3449
|
"mode": "0000644",
|
|
3445
|
-
"sha256": "
|
|
3450
|
+
"sha256": "22f1d7714524e07397354507df61ccd4bcaf7c1779317945d1ba4cb45fca7042"
|
|
3446
3451
|
},
|
|
3447
3452
|
{
|
|
3448
3453
|
"path": "modules/hall-ui/public/chime.wav",
|
|
@@ -3617,7 +3622,7 @@
|
|
|
3617
3622
|
{
|
|
3618
3623
|
"path": "modules/hall-ui/public/hall-render.js",
|
|
3619
3624
|
"mode": "0000644",
|
|
3620
|
-
"sha256": "
|
|
3625
|
+
"sha256": "5a09364d61b41b2cf7e970370ee993e41bbe85d0dbf5be89e979d436ac1e48a1"
|
|
3621
3626
|
},
|
|
3622
3627
|
{
|
|
3623
3628
|
"path": "modules/hall-ui/public/hall-widgets.js",
|
|
@@ -3707,7 +3712,7 @@
|
|
|
3707
3712
|
{
|
|
3708
3713
|
"path": "modules/hall-ui/public/my-projects.js",
|
|
3709
3714
|
"mode": "0000644",
|
|
3710
|
-
"sha256": "
|
|
3715
|
+
"sha256": "25195cabf71890f93f065e2aa15e899d51c251807e59ba14a147150c5b6228a3"
|
|
3711
3716
|
},
|
|
3712
3717
|
{
|
|
3713
3718
|
"path": "modules/hall-ui/public/not-ready.html",
|
|
@@ -3882,7 +3887,7 @@
|
|
|
3882
3887
|
{
|
|
3883
3888
|
"path": "modules/hall-ui/public/watch.css",
|
|
3884
3889
|
"mode": "0000644",
|
|
3885
|
-
"sha256": "
|
|
3890
|
+
"sha256": "bc89cba0af3e580f56425b5ecb83389ead0246e7240b08c2280671f2184025ad"
|
|
3886
3891
|
},
|
|
3887
3892
|
{
|
|
3888
3893
|
"path": "modules/hall-ui/public/watch.html",
|
|
@@ -3892,7 +3897,7 @@
|
|
|
3892
3897
|
{
|
|
3893
3898
|
"path": "modules/hall-ui/public/watch.js",
|
|
3894
3899
|
"mode": "0000644",
|
|
3895
|
-
"sha256": "
|
|
3900
|
+
"sha256": "122f76452956180e3c3aff6b5d5bcddd5866131e37b244bb36b0efda25b35bd8"
|
|
3896
3901
|
},
|
|
3897
3902
|
{
|
|
3898
3903
|
"path": "modules/hall-ui/public/work.css",
|
|
@@ -4372,7 +4377,7 @@
|
|
|
4372
4377
|
{
|
|
4373
4378
|
"path": "modules/onboarding/module.json",
|
|
4374
4379
|
"mode": "0000644",
|
|
4375
|
-
"sha256": "
|
|
4380
|
+
"sha256": "36800847c9cc9d239bb4d0ec910b35b547f8c67e5db5cb1cd5aa63d801e4bf02"
|
|
4376
4381
|
},
|
|
4377
4382
|
{
|
|
4378
4383
|
"path": "modules/onboarding/newcomer-restock.js",
|
|
@@ -4397,7 +4402,7 @@
|
|
|
4397
4402
|
{
|
|
4398
4403
|
"path": "modules/onboarding/routes/access-requests.js",
|
|
4399
4404
|
"mode": "0000644",
|
|
4400
|
-
"sha256": "
|
|
4405
|
+
"sha256": "060e8c33c5182c3d11b2b39b721f485deecc07b51f735b98f97aafbcc7e7657a"
|
|
4401
4406
|
},
|
|
4402
4407
|
{
|
|
4403
4408
|
"path": "modules/onboarding/routes/onboarding.js",
|
|
@@ -4492,7 +4497,7 @@
|
|
|
4492
4497
|
{
|
|
4493
4498
|
"path": "modules/platform-identity/routes/my-projects.js",
|
|
4494
4499
|
"mode": "0000644",
|
|
4495
|
-
"sha256": "
|
|
4500
|
+
"sha256": "4fadf91c0d40f3e5dd5d53f9ebe3ec825fd16a13aab41a76e8af25c911e11edf"
|
|
4496
4501
|
},
|
|
4497
4502
|
{
|
|
4498
4503
|
"path": "modules/platform-identity/routes/profile.js",
|
|
@@ -4912,12 +4917,12 @@
|
|
|
4912
4917
|
{
|
|
4913
4918
|
"path": "package-lock.json",
|
|
4914
4919
|
"mode": "0000644",
|
|
4915
|
-
"sha256": "
|
|
4920
|
+
"sha256": "63450349ce8f5c64c960a3f83c7f217324c1a7ee61f28e5ff06e8972021b53d3"
|
|
4916
4921
|
},
|
|
4917
4922
|
{
|
|
4918
4923
|
"path": "package.json",
|
|
4919
4924
|
"mode": "0000644",
|
|
4920
|
-
"sha256": "
|
|
4925
|
+
"sha256": "e7deabfda7d0840b92653973c68e280bbe64ded769d1dd8fa94db95a21cc0ba6"
|
|
4921
4926
|
},
|
|
4922
4927
|
{
|
|
4923
4928
|
"path": "public-docs/index.html",
|
|
@@ -5177,7 +5182,7 @@
|
|
|
5177
5182
|
{
|
|
5178
5183
|
"path": "public-landing/projects.html",
|
|
5179
5184
|
"mode": "0000644",
|
|
5180
|
-
"sha256": "
|
|
5185
|
+
"sha256": "f4818358fb126ccef093b6193b743aab73fe7598c13c685485651f6d6ad63921"
|
|
5181
5186
|
},
|
|
5182
5187
|
{
|
|
5183
5188
|
"path": "public-landing/world/assets/clouds/cloud-island-large.png",
|
|
@@ -5802,7 +5807,7 @@
|
|
|
5802
5807
|
{
|
|
5803
5808
|
"path": "scripts/gds/login.js",
|
|
5804
5809
|
"mode": "0000644",
|
|
5805
|
-
"sha256": "
|
|
5810
|
+
"sha256": "f16497d7eae23657e83f631b420f82a55ed8216480f3cd5488609d3b93274dee"
|
|
5806
5811
|
},
|
|
5807
5812
|
{
|
|
5808
5813
|
"path": "scripts/gds/main-audit.js",
|
|
@@ -6527,7 +6532,7 @@
|
|
|
6527
6532
|
{
|
|
6528
6533
|
"path": "src/bongos/auth-admission.js",
|
|
6529
6534
|
"mode": "0000644",
|
|
6530
|
-
"sha256": "
|
|
6535
|
+
"sha256": "0d2e4aaf4b99ac4b1122c182f279ae622f53d8896baa31d796c5bb0f4ef6532c"
|
|
6531
6536
|
},
|
|
6532
6537
|
{
|
|
6533
6538
|
"path": "src/bongos/auth-config.js",
|
|
@@ -6552,7 +6557,7 @@
|
|
|
6552
6557
|
{
|
|
6553
6558
|
"path": "src/bongos/auth.js",
|
|
6554
6559
|
"mode": "0000644",
|
|
6555
|
-
"sha256": "
|
|
6560
|
+
"sha256": "6e9c3e0116fa0e2a62b6fc67db1c4a37020491e7f659f1193a4e71fae1be8b26"
|
|
6556
6561
|
},
|
|
6557
6562
|
{
|
|
6558
6563
|
"path": "src/bongos/cascade-dispatch.js",
|
|
@@ -6692,7 +6697,7 @@
|
|
|
6692
6697
|
{
|
|
6693
6698
|
"path": "src/bongos/routes/auth.js",
|
|
6694
6699
|
"mode": "0000644",
|
|
6695
|
-
"sha256": "
|
|
6700
|
+
"sha256": "d4dc490ccf82f56d66f4d17e64f514632171480f22175bfa682dea9eb0e2e44a"
|
|
6696
6701
|
},
|
|
6697
6702
|
{
|
|
6698
6703
|
"path": "src/bongos/routes/backup.js",
|
|
@@ -6782,7 +6787,7 @@
|
|
|
6782
6787
|
{
|
|
6783
6788
|
"path": "src/branding.js",
|
|
6784
6789
|
"mode": "0000644",
|
|
6785
|
-
"sha256": "
|
|
6790
|
+
"sha256": "51d70cad3ef6955a0648f4467dd3e0ffa54d747d93b7a30301dce3c8afdbe1cb"
|
|
6786
6791
|
},
|
|
6787
6792
|
{
|
|
6788
6793
|
"path": "src/build-info.js",
|
|
@@ -6802,7 +6807,7 @@
|
|
|
6802
6807
|
{
|
|
6803
6808
|
"path": "src/module-api.js",
|
|
6804
6809
|
"mode": "0000644",
|
|
6805
|
-
"sha256": "
|
|
6810
|
+
"sha256": "8d822b226b35e7226e3678e7e1e53e0c4da9d27be845bfe69d6832c976d2ffcb"
|
|
6806
6811
|
},
|
|
6807
6812
|
{
|
|
6808
6813
|
"path": "src/module-loader/catalog.js",
|
|
@@ -6859,6 +6864,11 @@
|
|
|
6859
6864
|
"mode": "0000644",
|
|
6860
6865
|
"sha256": "031b75aeb83322055c4d69ab5481b220a7a41ccbe950129b84f8bc80d7c75a40"
|
|
6861
6866
|
},
|
|
6867
|
+
{
|
|
6868
|
+
"path": "tests/access_requests_invite.mjs",
|
|
6869
|
+
"mode": "0000644",
|
|
6870
|
+
"sha256": "4d8435e7f8b949715ee40843beddc1868105edd9c67b269cfa8f510a192e9212"
|
|
6871
|
+
},
|
|
6862
6872
|
{
|
|
6863
6873
|
"path": "tests/achievements_reconcile.mjs",
|
|
6864
6874
|
"mode": "0000644",
|
|
@@ -6977,7 +6987,7 @@
|
|
|
6977
6987
|
{
|
|
6978
6988
|
"path": "tests/auth_admission_gate.mjs",
|
|
6979
6989
|
"mode": "0000644",
|
|
6980
|
-
"sha256": "
|
|
6990
|
+
"sha256": "2acde0caeab2acba0e3d52a7605bf1017b95d2eab0358972a58d691a43f5dfc6"
|
|
6981
6991
|
},
|
|
6982
6992
|
{
|
|
6983
6993
|
"path": "tests/auth_anthropic_identity.mjs",
|
|
@@ -8319,6 +8329,26 @@
|
|
|
8319
8329
|
"mode": "0000644",
|
|
8320
8330
|
"sha256": "d00e82184fbf7aab49c9b6efe5709b14f300ca0cea277a0eb140f073ded7ff50"
|
|
8321
8331
|
},
|
|
8332
|
+
{
|
|
8333
|
+
"path": "tests/join_relay_outcome.mjs",
|
|
8334
|
+
"mode": "0000644",
|
|
8335
|
+
"sha256": "d3cb9fcd89fe88cfa5b1578cb9e2fc48d762227ee99b807006047e58ba9133b0"
|
|
8336
|
+
},
|
|
8337
|
+
{
|
|
8338
|
+
"path": "tests/joinability_apply.mjs",
|
|
8339
|
+
"mode": "0000644",
|
|
8340
|
+
"sha256": "18e67c48f3fb400ed69bcef5e7b706d19f1779c4751c091e72edb57040ca65e6"
|
|
8341
|
+
},
|
|
8342
|
+
{
|
|
8343
|
+
"path": "tests/joinability_invite_only.mjs",
|
|
8344
|
+
"mode": "0000644",
|
|
8345
|
+
"sha256": "082693b5e07c1c25cec17cde7f93a8716aafa94ead9b1cee76b1643f30edff79"
|
|
8346
|
+
},
|
|
8347
|
+
{
|
|
8348
|
+
"path": "tests/joinability_open.mjs",
|
|
8349
|
+
"mode": "0000644",
|
|
8350
|
+
"sha256": "c26fa3ccb97861370c08ebcc1ab4e7706f90b7cf427efd1a29db456ea82fbfa8"
|
|
8351
|
+
},
|
|
8322
8352
|
{
|
|
8323
8353
|
"path": "tests/key-card.mjs",
|
|
8324
8354
|
"mode": "0000644",
|
|
@@ -8497,7 +8527,7 @@
|
|
|
8497
8527
|
{
|
|
8498
8528
|
"path": "tests/module_api.mjs",
|
|
8499
8529
|
"mode": "0000644",
|
|
8500
|
-
"sha256": "
|
|
8530
|
+
"sha256": "e5bb1ae80c818eec08f3f06999037b61d176afecb850fe65e4eab6c34e97b6b1"
|
|
8501
8531
|
},
|
|
8502
8532
|
{
|
|
8503
8533
|
"path": "tests/module_catalog.mjs",
|
|
@@ -8742,12 +8772,12 @@
|
|
|
8742
8772
|
{
|
|
8743
8773
|
"path": "tests/projects_hub.mjs",
|
|
8744
8774
|
"mode": "0000644",
|
|
8745
|
-
"sha256": "
|
|
8775
|
+
"sha256": "9aa24895829edb4896c48258c974802f835b6b391db8b8e765cbdceb272738a9"
|
|
8746
8776
|
},
|
|
8747
8777
|
{
|
|
8748
8778
|
"path": "tests/projects_hub_pre_uat.mjs",
|
|
8749
8779
|
"mode": "0000644",
|
|
8750
|
-
"sha256": "
|
|
8780
|
+
"sha256": "a6669ad211a98454a17330756ae8a36d6c853a3688d284c1487dc7b2f6a21dbc"
|
|
8751
8781
|
},
|
|
8752
8782
|
{
|
|
8753
8783
|
"path": "tests/promote_goal_id.mjs",
|
|
@@ -8827,7 +8857,7 @@
|
|
|
8827
8857
|
{
|
|
8828
8858
|
"path": "tests/public_landing_projects.mjs",
|
|
8829
8859
|
"mode": "0000644",
|
|
8830
|
-
"sha256": "
|
|
8860
|
+
"sha256": "232ac3f8206850957852c5d855f72cfc94f272ef8e0493410376903e2ae06176"
|
|
8831
8861
|
},
|
|
8832
8862
|
{
|
|
8833
8863
|
"path": "tests/public_mirror_export.mjs",
|
|
@@ -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
|
+
- 321 operations across 52 resource groups
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -91,6 +91,8 @@ function createClient(opts = {}) {
|
|
|
91
91
|
postAccessRequests: (args) => request("POST", "/access-requests", { hasBody: true }, args),
|
|
92
92
|
// PATCH /access-requests/{id} — rank: archon — PATCH /access-requests/:id
|
|
93
93
|
patchAccessRequestsId: (args) => request("PATCH", "/access-requests/{id}", { hasBody: true }, args),
|
|
94
|
+
// POST /access-requests/invite — rank: archon — POST /access-requests/invite
|
|
95
|
+
postAccessRequestsInvite: (args) => request("POST", "/access-requests/invite", { hasBody: true }, args),
|
|
94
96
|
// GET /access-requests/status — rank: public — GET /access-requests/status
|
|
95
97
|
getAccessRequestsStatus: (args) => request("GET", "/access-requests/status", { hasBody: false }, args),
|
|
96
98
|
},
|
|
@@ -90,6 +90,8 @@ function createClient(opts = {}) {
|
|
|
90
90
|
postAccessRequests: (args) => request("POST", "/access-requests", { hasBody: true }, args),
|
|
91
91
|
// PATCH /access-requests/{id} — rank: archon — PATCH /access-requests/:id
|
|
92
92
|
patchAccessRequestsId: (args) => request("PATCH", "/access-requests/{id}", { hasBody: true }, args),
|
|
93
|
+
// POST /access-requests/invite — rank: archon — POST /access-requests/invite
|
|
94
|
+
postAccessRequestsInvite: (args) => request("POST", "/access-requests/invite", { hasBody: true }, args),
|
|
93
95
|
// GET /access-requests/status — rank: public — GET /access-requests/status
|
|
94
96
|
getAccessRequestsStatus: (args) => request("GET", "/access-requests/status", { hasBody: false }, args),
|
|
95
97
|
},
|
|
@@ -163,6 +163,8 @@ export interface PatchProvisioningInstancesIdSettingsResponse { ok: boolean; sav
|
|
|
163
163
|
export interface PatchTaskRecommendationsIdRequest { status: "declined" | "withdrawn" }
|
|
164
164
|
export interface PatchTaskRecommendationsIdResponse { ok: boolean; recommendation: unknown }
|
|
165
165
|
export interface PatchTasksIdRequest { kind?: string; discipline?: string; requires_rank?: string; module_key?: string; goal_id?: number; parent_task_id?: StringifiableId; parallel_safe?: unknown; newcomer_friendly?: boolean; xenos_claimable?: boolean; security_sensitive?: boolean; automation_tag?: string; needs_migration?: boolean; description?: string; status?: unknown }
|
|
166
|
+
export interface PostAccessRequestsInviteRequest { github_login: string }
|
|
167
|
+
export interface PostAccessRequestsInviteResponse { ok: boolean; already_invited?: boolean; github_login?: unknown; request?: unknown }
|
|
166
168
|
export interface PostAccessRequestsRequest { github_login: string; display_name?: string; note?: string }
|
|
167
169
|
export interface PostAccessRequestsResponse { ok: boolean; request?: unknown; already_pending?: boolean }
|
|
168
170
|
export interface PostAuthAppPairApproveRequest { pair_code: string }
|
|
@@ -377,6 +379,8 @@ export interface BongosClient {
|
|
|
377
379
|
postAccessRequests(args: RequestArgs & { body: PostAccessRequestsRequest }): Promise<PostAccessRequestsResponse>;
|
|
378
380
|
/** PATCH /access-requests/{id} — rank: archon */
|
|
379
381
|
patchAccessRequestsId(args: RequestArgs & { body: PatchAccessRequestsIdRequest }): Promise<PatchAccessRequestsIdResponse>;
|
|
382
|
+
/** POST /access-requests/invite — rank: archon */
|
|
383
|
+
postAccessRequestsInvite(args: RequestArgs & { body: PostAccessRequestsInviteRequest }): Promise<PostAccessRequestsInviteResponse>;
|
|
380
384
|
/** GET /access-requests/status — rank: public */
|
|
381
385
|
getAccessRequestsStatus(args?: RequestArgs): Promise<GetAccessRequestsStatusResponse>;
|
|
382
386
|
};
|
|
@@ -87,6 +87,8 @@ export function createClient(opts = {}) {
|
|
|
87
87
|
postAccessRequests: (args) => request("POST", "/access-requests", { hasBody: true }, args),
|
|
88
88
|
// PATCH /access-requests/{id} — rank: archon — PATCH /access-requests/:id
|
|
89
89
|
patchAccessRequestsId: (args) => request("PATCH", "/access-requests/{id}", { hasBody: true }, args),
|
|
90
|
+
// POST /access-requests/invite — rank: archon — POST /access-requests/invite
|
|
91
|
+
postAccessRequestsInvite: (args) => request("POST", "/access-requests/invite", { hasBody: true }, args),
|
|
90
92
|
// GET /access-requests/status — rank: public — GET /access-requests/status
|
|
91
93
|
getAccessRequestsStatus: (args) => request("GET", "/access-requests/status", { hasBody: false }, args),
|
|
92
94
|
},
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# ADR 0194 — A project's membership door is one decision, answered the same way everywhere a stranger meets it
|
|
2
|
+
|
|
3
|
+
- **Status:** accepted
|
|
4
|
+
- **Date:** 2026-08-25
|
|
5
|
+
- **Task:** [task 1003044](https://cloudbongos.com/builders#/task/1003044) (goal 1000058 — the non-cloudbongos project lifecycle)
|
|
6
|
+
- **Relates to:** ADR 0050 (invite-gated by default; the `OPEN_XENOS_ENROLLMENT` escape hatch), ADR 0190 (the settings channel: `brand.project` as the read-back), ADR 0192 (the platform-visibility member door — this setting's sibling), ADR 0116 (the error envelope), ADR 0083 (the module doorway), ADR 0161 (a MINOR is a human edit), task 1003040 (the settings row), task 1003043 (the manage-page section shape)
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
The owner decided on 2026-08-16 that a project chooses how people join it — **open** (whoever signs in is in), **apply** (a stranger files an access request, an Archon invites; today's behaviour), or **invite only** (no applications; only an Archon's invite admits). Task 1003040 stored the choice on the platform's settings row, 1003139/1003140 pushed it into the instance's environment, and `branding().project.joinability` resolved it — enforced by nothing, and the manage page said so.
|
|
11
|
+
|
|
12
|
+
Admission on an instance is decided in one place already: `firstTimeAdmissionBlocked` (SR-19 — one pure decision both sign-in flows call, so they cannot drift), fed by `openEnrollmentEnabled()`, which read only the legacy env flag. Four sign-in paths call it (the GitHub web and device flows, and their federated twins). Beside it sit the onboarding module's public `POST /access-requests` (the one unauthenticated write), the Archon's `PATCH … invited`, the hall's landing page with its request form, the web sign-in's 403 page, the CLI's stranger path, and the hub's join relay — each of which tells a stranger what to do next.
|
|
13
|
+
|
|
14
|
+
## Decision
|
|
15
|
+
|
|
16
|
+
1. **One reader, and open enrolment follows it.** `joinabilityMode()` (`src/bongos/auth-admission.js`) is the project's effective door: `branding().project.joinability` when it says `open` or `invite_only`; otherwise `apply` — **unless** the legacy `OPEN_XENOS_ENROLLMENT` flag is set, which still turns an *apply* project into an open one. `openEnrollmentEnabled()` becomes `joinabilityMode() === 'open'`, so the four sign-in call sites, `webAdmissionStatus`, and the manifest's `admission.policy` follow without being touched. Why the flag keeps its power on `apply` only: a self-hosted instance that set it (ADR 0050) must keep its open door across the upgrade — the neutral pack defaults to `apply`, so "flag ignored" would have silently closed those doors; and an explicit `invite_only` is the stricter, newer choice, which the flag must not reopen. Why the flag is not folded into `branding()`: the pack is memoized for the process while the flag is read per call (and toggled by the existing tests), and the manifest's `brand.project.joinability` must stay the *pushed* value the hub reads back. The one case where the two disagree — a self-hosted instance carrying the flag — is never platform-managed: its hall landing offers the request form (the injected pack says `apply`), and the form collapses into "no request needed — sign in" on the door's own 409; an owner who wants the hall to say so up front sets `<PREFIX>_JOINABILITY=open`. The flag is kept only so nothing changes on upgrade.
|
|
17
|
+
|
|
18
|
+
2. **An unreadable pack, or a value this core cannot read, fails closed: `invite_only`.** When the door's policy is unknown — the pack will not load, or it says `invite-only` with a hyphen, or a truncated write — the widest door is never the fallback, the same rule the visibility gate applies (ADR 0192 §2). Only an absent value or `apply` reaches the legacy-flag branch. Logged through the kernel logger, an unknown value once per process.
|
|
19
|
+
|
|
20
|
+
3. **The public `POST /access-requests` answers the door first** — before validating the body and before any lookup. On `invite_only` it refuses `403 invite_only`; on `open` it refuses `409 open_enrollment` ("no request needed — sign in"). Both are plain sentences in the ADR 0116 envelope. Answering first costs no query, reveals nothing about who already exists (the account-existence oracle ADR 0192 §3 deferred does not widen), and keeps the refusal DB-free — which is what lets the real booted app prove it. A non-2xx for `open` rather than a friendly 200: an older `bongos login` would otherwise print "✓ Requested access" and wait thirty minutes for an approval that never comes; a refusal it does not recognise prints its status and stops, which is honest.
|
|
21
|
+
|
|
22
|
+
4. **An Archon's invite is the same row the gate already reads.** `POST /access-requests/invite { github_login }` (rank archon — the gate that resolves a request) writes an `access_requests` row at `'invited'` — resolving a pending one in place, or inserting one. `hasInvitedAccessRequest` admits it at sign-in with nothing new consulted. No second table, no token, no expiry: an invite here is exactly what the `PATCH … invited` has meant since ADR 0050, created before the request instead of after. It reaches the hall as an "Invite by GitHub username" form in the Watch page's Access-requests section, whose one-line explanation names the door the project runs.
|
|
23
|
+
|
|
24
|
+
5. **The door is said in every place a stranger meets it, in the project's own words.** The hall landing renders one door per mode from the pack the server injects (`window.__BRANDING__.project` — no fetch, no flash); its request form collapses into "sign in" on the door's own refusal codes. The web sign-in's 403 page names the invite-only door and the one way in instead of sending a stranger to a form the project refuses. The CLI says invite-only and stops instead of collecting a username. The hub's join relay names the door in the hub's own words (`joinRelayOutcome`, pure) — a registered project is trusted to build, not to write prose into the platform's UI — rather than painting a refusal as "requested", or as "could not be reached", which a 403 used to become; a 401 (the project's member-only door, ADR 0192, refusing the ask itself) is said as such, and the hub's join box keeps the typed address and does not repaint as if a request went out. Someone who applied before a project switched to invite-only stays in the queue — the Archon can still invite or dismiss them from the Watch page, and the manage fold says so.
|
|
25
|
+
|
|
26
|
+
6. **The manifest's `admission.policy` stays binary.** It is a pinned public field derived from `openEnrollmentEnabled()`, so it agrees with the new decision for free (`open` → `open`, else `invite-only`, which is true of both `apply` and `invite_only`: you need an invite). The three-valued truth is `brand.project.joinability`, which the hub's "runs as" line already reads.
|
|
27
|
+
|
|
28
|
+
7. **`joinabilityMode` joins the doorway — and rides the next CI patch, not a hand-bumped 1.20.0.** The onboarding module must refuse with the *same* decision the sign-in gate makes; re-deriving it from `api.branding()` would copy the flag rule and the fail-closed default into a second place — the drift SR-19 exists to prevent. An added export is a statement about the doorway surface, which ADR 0161 §2 reserves as a human MINOR (the 1.19.0 precedent). This task tried exactly that, and the publish lane refused it: `tests/bump_version.mjs`'s LIVE test asserts HEAD's version is one the lane's own carrier commits announced, so a branch declaring `1.20.0` fails the `unit` check by construction (1.19.0 was "bumped and never packaged" for the same reason). Landing hands-free on CI (ADR 0162) outranks expressing the MINOR in the number: the version stays the carrier's, the changelog says why, `modules/onboarding/module.json` floors at `^1.19.374`, and the contradiction between ADR 0161 §2's promise and the lane's test is filed as an idea for the owner.
|
|
29
|
+
|
|
30
|
+
8. **The hub's section clones `#mVisibility`'s shape rather than extracting a factory.** Task 1003043's tests pin that block's text function by function; two settings sharing `visPushOpen()` is tolerable duplication. A third setting is the point at which a factory — and one manifest read serving every key — pays for itself.
|
|
31
|
+
|
|
32
|
+
## What was deliberately not built
|
|
33
|
+
|
|
34
|
+
- No change to the Discord `#member-approvals` broadcast (an invite-only project simply never posts one, because nothing is filed).
|
|
35
|
+
- No widening of `admission.policy`; no projection of the manifest (idea 1000845); no throttling of the admission-status lookup (ADR 0192 §3).
|
|
36
|
+
- No invite expiry, revocation, or token. An Archon can dismiss nothing they created here — the row is the audit trail, as it is for a resolved request.
|
|
37
|
+
|
|
38
|
+
## Consequences
|
|
39
|
+
|
|
40
|
+
- A project's door is enforced server-side wherever admission is decided, from one reader, and every surface that speaks to a stranger says which door it is.
|
|
41
|
+
- The hall's `postJSON` now reads the envelope (`error.code` / `error.message`); its already-a-member branch had silently never fired since the envelope landed, and the new refusal codes needed the same read.
|
|
42
|
+
- A self-hosted instance on the legacy flag is unchanged. A platform project defaults to `apply`, unchanged. Only a pushed `open` or `invite_only` changes behaviour, and only after the restart the runner performs (ADR 0190).
|
package/docs/adr/README.md
CHANGED
|
@@ -271,5 +271,6 @@ This keeps the decision history honest and traceable.
|
|
|
271
271
|
| 0192 | [**A gated project refuses strangers at the app's front door, and the hub reads what the project runs from the project itself** ([task 1003043](https://cloudbongos.com/builders#/task/1003043), goal 1000058). Task 1003040 gave every project a `platform_visibility` setting and 1003139/1003140 carried it into the instance's `branding().project.platformVisibility` — resolved, enforced by nothing. Decision: ONE app-level middleware (`src/bongos/platform-visibility-gate.js`), mounted beside the pre-launch gate ahead of every human and public-read surface — the landing, the hub pages, the status host, the hall shell, `/public/*` and every module's `rank: public` route — rather than per-surface wiring, which misses the next surface nobody told it about. "Member" is a live, non-deactivated session on this instance, the same `resolveSession` lookup `requireBuilder` uses, per request, no cache; a lookup that throws fails CLOSED. The exempt list is the door, the manifest and the probes and nothing wider: `/api/*/auth/*` (a door that cannot be opened locks the members out too), `/api/*/instance` (what a stranger reads to learn how to sign in AND what the runner reads after a settings restart to learn whether the value was consumed — including the push that turns this gate on), `/healthz`, `/version`, `/metrics`; the pre-launch gate's blanket `/api/` exemption is deliberately not copied. A refused page gets a self-contained 401 door (no stylesheet, no branding bundle, no script) with one control — Sign in, returning (relatively) to the page knocked on; a refused API call gets `res.fail('unauthenticated', 401)`, exactly requireBuilder's envelope, which is why it mounts after `attachFail`. A member's answer leaves marked `private, no-store` whatever the route said — the public read API sends `public, max-age`, and a CDN edge would otherwise serve a member's copy to the next stranger. The exempt list covers every API prefix (the versioned contract too), `/downloads/*` and Caddy's TLS ask; a request's session is resolved once (`resolveSession` memoizes per request). The hub's manage page shows the CHOICE from the platform's row and what the project RUNS from the project's own public manifest (`brand.project`), and never confuses the two: `push.message` is rendered verbatim, `saved` moves only the radio, the "runs" line is written only from the manifest and says "doesn't report this setting yet" for a core that predates the channel. Rejected: per-surface wiring; a 302 into OAuth for a refused page (sends assets and crawlers to GitHub); copying the `/api/` exemption; painting the radio from the manifest or the runs line from `saved`; reusing the pre-launch gate.](<redacted>.md) | instance / project visibility |
|
|
272
272
|
| 0192 | [**A work category orients a human and authorises nothing** ([task 1003275](https://cloudbongos.com/builders#/task/1003275), goal 1000072, criterion `legibility-categories`). A goal gains a human CATEGORY from an owner-named set of eight (Builders Hall, Context Management, Government (Decision Making), Modules, Security, Economics, Legal, User/ABI Experience) so a person scanning the board can tell at a glance which goals are about money, which about the walls, which about the hall — today each goal's own words say so, but only if you read all thirty-eight. The DECISION is the constraint, not the feature: the owner said twice that this organisation has no hierarchical purpose and no effect on the agentic management of the work, and the system ALREADY has a load-bearing hierarchy (ADR 0086 — the scope_modules wall, rank floors, goal membership). The goal's own prose predicts the failure: a second thing that looks like a hierarchy gets mistaken for one within a release, and the mistake arrives as ONE plausible line in a gate ('skip Legal goals in the feed'), after which work is refused because of a label nobody meant as a permission. So: no authority, claim-eligibility, feed or dependency surface may read a category — enforced by the `scripts/gds/category-advisory-guard.js` fitness check, which scans every decision surface with comments stripped (a gate may CITE the rule, never branch on it) AND asserts the feature still exists, so a renamed-away subject fails loudly instead of passing vacuously (the ADR 0022 assurance-of-assurance finding). Uncategorised is LEGAL — nullable, no default, required by no write — because the criterion is explicit that Claude failing to place a goal is a designed prompt, not an error. A task stores no category and INHERITS its goal's through `tasks.goal_id`; a stored copy would be a second answer to one question. The set is a table, not an enum (runtime-extensible without a migration per addition) and retiring is `active = false`, never a DELETE, so a goal keeps rendering a label someone tidied away. The three route-rank pins are a tripwire: if one ever needs a WIDER gate than its neighbours, the label has grown into a permission. Deliberately NOT built: a per-category page or filtered navigation view — a chip is a label, a drill-down destination is a tier. Making a category gate anything is an owner decision and needs its own ADR first.](<redacted>.md) | GDS / goals |
|
|
273
273
|
| 0193 | [**Pause task-scoped box slices: a box serves its rank scope (the full repo for Metic+)** ([task 1003285](https://cloudbongos.com/builders#/task/1003285), owner decision from the 2026-08-25 dev-box efficiency review). Pauses, does not repeal, ADR 0148 / goal 1000051: `routes/box.js` skips the lifecycle-port `scopeKeys` resolution unless `BOX_TASK_SCOPE=on`, so `decideSourceAccess` takes its documented rank fallback — full repo for Metic+, starter surface below. WHY: the slice was defense-in-depth git cannot hard-enforce (ADR 0031 §6's honest limit) while its costs were real on the live fleet — sessions on a box that cannot see a module (or its nested CLAUDE.md) misdiagnose themselves as stuck, the scope machinery kept failing in the field (task 1002729's base-slice collapse), and every live box user is Metic+ anyway, so the slice narrowed trusted builders while newcomers were already gated by rank. UNCHANGED: live-rank allow/deny per request (ADR 0016), the provision floor and demotion clawback, the read-only per-request credential (ADR 0055 — push still 403s, re-verified on hardware in task 1003253), and sub-Metic starter boxes. `GET /box/scope` now reports `task_scoping_paused` so the hall/app can say why `task_scope` is false; the app task-picker's "scoped to `<modules>` and nothing else" copy overstates while paused (cosmetic). Revert = set the env flag; make-permanent = delete the resolution + a follow-up ADR.](<redacted>.md) | dev-box |
|
|
274
|
+
| 0194 | [**A project's membership door is one decision, answered the same way everywhere a stranger meets it** ([task 1003044](https://cloudbongos.com/builders#/task/1003044), goal 1000058). The owner's 2026-08-16 joinability setting — open / apply / invite_only — was stored (1003040), pushed (1003139/1003140) and resolved into `branding().project.joinability`, enforced by nothing. Decision: ONE reader, `joinabilityMode()` in `auth-admission.js`, and `openEnrollmentEnabled()` becomes `mode === 'open'`, so the four sign-in call sites, `webAdmissionStatus` and the manifest's `admission.policy` follow untouched (SR-19: one gate, no drift). The legacy `OPEN_XENOS_ENROLLMENT` flag still opens an APPLY project — a self-hosted instance that set it keeps its door across the upgrade — but never reopens an explicit invite_only; an unreadable pack or a value this core cannot read fails CLOSED (invite_only), the ADR 0192 rule. The public `POST /access-requests` answers the door FIRST — before validation, before any lookup — `403 invite_only` / `409 open_enrollment` with plain sentences: no query, nothing revealed about who exists, and DB-free enough for the real booted app to prove. An Archon's invite is the row the gate already reads: `POST /access-requests/invite` writes `access_requests` at 'invited' (resolving a pending one in place), so sign-in consults nothing new — surfaced as "Invite by GitHub username" on the Watch page. The door is SAID wherever a stranger meets it, in the project's words: the hall landing renders one door per mode from the injected pack, the web 403 names the invite-only door and the way in, the CLI stops instead of filing, the hub's join relay names the door in the hub's own words (a project is trusted to build, not to write prose into the platform's UI) instead of painting a refusal as "requested" or "unreachable". `admission.policy` stays binary (pinned; agrees for free); `joinabilityMode` joins the doorway — a human MINOR by ADR 0161 §2, which the publish lane's LIVE test refused (HEAD's version must be a CI carrier's), so it rides the next CI patch and the contradiction is filed as an idea. The hub's `#mJoinability` clones `#mVisibility` rather than a factory — a third setting is where a factory pays. Rejected: folding the flag into `branding()` (memoized vs per-call; the manifest must stay the pushed value); a 200 for the open door (an older CLI would wait thirty minutes for an approval); re-deriving the mode inside the module; a second invite table.](<redacted>.md) | instance / project joinability |
|
|
274
275
|
|
|
275
276
|
> ⚠️ **Numbering collision (known):** two ADRs share `0008`. The numbers were assigned in parallel sessions before the lock could be enforced. The files are kept under their existing filenames to preserve git history, but the table disambiguates them as `0008-a` / `0008-b`. New ADRs should resume at `0040` to avoid further collisions. (`0024` is also a real on-disk duplicate: the cloneable-repo/local-first-memory ADR and the multi-agent-system-architecture ADR were both numbered `0024` in parallel; both keep their filenames, disambiguated as `0024-a` / `0024-b` like `0008`. Likewise `0025` ended up with two on-disk files — the offsite-backup ADR and the structured-criterion↔task-link ADR — both kept under their existing filenames and disambiguated as `0025-a` / `0025-b`; separately, the BFG ADR had also claimed `0025` on 2026-05-30 and yielded to `0026`. A third happened 2026-06-06: `0036` was claimed in parallel by the builders-subdomain ADR ([#726](https://example.com/builders#/task/726)) and this Discord-channels ADR ([#727](https://example.com/builders#/task/727)); the Discord-channels ADR yielded to `0037`. A fourth landed 2026-06-10: `0044` was claimed in parallel by the palette-replacement ADR and the per-box game-preview ADR ([#897](https://example.com/builders#/task/897)); both keep their filenames, disambiguated as `0044-a` / `0044-b` like `0008`. A fifth was caught pre-land 2026-06-13: `0050` was claimed in parallel by the device-flow-admission ADR ([#1000](https://example.com/builders#/task/1000)) and the sandbox-for-everyone ADR ([#1001](https://example.com/builders#/task/1001)); the latter yielded to `0052` before merging, so there is no `0050` duplicate. A sixth was caught pre-land 2026-06-21: the tool-agnostic-design-layer ADR ([#1375](https://example.com/builders#/task/1375)) first collided at `0079` with the value-gated-autonomous-engagement ADR, then at `0080` with the llm-cache-api-transport ADR (both part of the 0075–0080 LLM-cost-reduction series, landed on `main` in parallel); it yielded to `0081` before merging, so there is no `0079`/`0080` design-layer duplicate. A seventh landed 2026-06-23: `0084` was claimed in parallel by the auto-derived-per-task-rank-floor ADR and the remove-default-spend-cap ADR (task 1499); the rank-floor ADR landed on `main` first, so the spend-cap ADR yielded to `0085`, leaving no `0084` duplicate. An eighth landed 2026-06-27: `0095` was claimed in parallel by the borrowed-memory-and-retrieval-concepts ADR (PR #459, landed first) and the cross-agent-context-management ADR ([#1651](https://example.com/builders#/task/1651), PR #460); both keep their filenames, disambiguated as `0095-a` / `0095-b` like `0008`. These two are companions — `0095-a` adopts the memory/retrieval concepts and explicitly defers the grep-vs-semantic question to `0095-b`.)
|
package/docs/api/openapi.json
CHANGED
|
@@ -309,6 +309,58 @@
|
|
|
309
309
|
"security": []
|
|
310
310
|
}
|
|
311
311
|
},
|
|
312
|
+
"/access-requests/invite": {
|
|
313
|
+
"post": {
|
|
314
|
+
"operationId": "post_access_requests_invite",
|
|
315
|
+
"tags": [
|
|
316
|
+
"access-requests"
|
|
317
|
+
],
|
|
318
|
+
"summary": "POST /access-requests/invite",
|
|
319
|
+
"description": "POST /access-requests/invite — an Archon admits a GitHub username BEFORE any request exists (task 1003044): the only way in on an invite-only project, where the public POST refuses, and a shortcut on an apply one. It writes the same access_request row the sign-in gate reads (status 'invited' — hasInvitedAccessRequest), so nothing new is consulted at sign-in; a pending request for that login is resolved in place rather than duplicated. Two Archons inviting the same login at once can each insert a row (the unique index covers pending only): harmless — the gate reads \"any invited row\" — and it shows as two lines in the invited history, so no lock is taken. body: { github_login }. 201 with a new row; 200 with the row when a pending request was resolved; 200 already_invited when an invite already stands; 409 already_member when they have an account. rank: archon — the same gate as resolving a request.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `access_request.review` (all required).",
|
|
320
|
+
"x-rank": "archon",
|
|
321
|
+
"x-source": "modules/onboarding/routes/access-requests.js",
|
|
322
|
+
"x-permissions": [
|
|
323
|
+
"access_request.review"
|
|
324
|
+
],
|
|
325
|
+
"requestBody": {
|
|
326
|
+
"required": true,
|
|
327
|
+
"content": {
|
|
328
|
+
"application/json": {
|
|
329
|
+
"schema": {
|
|
330
|
+
"$ref": "#/components/schemas/PostAccessRequestsInviteRequest"
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
"x-validated": true
|
|
335
|
+
},
|
|
336
|
+
"responses": {
|
|
337
|
+
"200": {
|
|
338
|
+
"description": "Success.",
|
|
339
|
+
"content": {
|
|
340
|
+
"application/json": {
|
|
341
|
+
"schema": {
|
|
342
|
+
"$ref": "#/components/schemas/PostAccessRequestsInviteResponse"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
"400": {
|
|
348
|
+
"$ref": "#/components/responses/ValidationFailed"
|
|
349
|
+
},
|
|
350
|
+
"401": {
|
|
351
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
352
|
+
},
|
|
353
|
+
"403": {
|
|
354
|
+
"$ref": "#/components/responses/Forbidden"
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
"security": [
|
|
358
|
+
{
|
|
359
|
+
"builderSession": []
|
|
360
|
+
}
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
},
|
|
312
364
|
"/access-requests/status": {
|
|
313
365
|
"get": {
|
|
314
366
|
"operationId": "get_access_requests_status",
|
|
@@ -16635,6 +16687,36 @@
|
|
|
16635
16687
|
},
|
|
16636
16688
|
"additionalProperties": false
|
|
16637
16689
|
},
|
|
16690
|
+
"PostAccessRequestsInviteRequest": {
|
|
16691
|
+
"type": "object",
|
|
16692
|
+
"properties": {
|
|
16693
|
+
"github_login": {
|
|
16694
|
+
"type": "string",
|
|
16695
|
+
"minLength": 1,
|
|
16696
|
+
"maxLength": 60
|
|
16697
|
+
}
|
|
16698
|
+
},
|
|
16699
|
+
"required": [
|
|
16700
|
+
"github_login"
|
|
16701
|
+
],
|
|
16702
|
+
"additionalProperties": false
|
|
16703
|
+
},
|
|
16704
|
+
"PostAccessRequestsInviteResponse": {
|
|
16705
|
+
"type": "object",
|
|
16706
|
+
"properties": {
|
|
16707
|
+
"ok": {
|
|
16708
|
+
"type": "boolean"
|
|
16709
|
+
},
|
|
16710
|
+
"already_invited": {
|
|
16711
|
+
"type": "boolean"
|
|
16712
|
+
},
|
|
16713
|
+
"github_login": {},
|
|
16714
|
+
"request": {}
|
|
16715
|
+
},
|
|
16716
|
+
"required": [
|
|
16717
|
+
"ok"
|
|
16718
|
+
]
|
|
16719
|
+
},
|
|
16638
16720
|
"PostAccessRequestsRequest": {
|
|
16639
16721
|
"type": "object",
|
|
16640
16722
|
"properties": {
|
|
@@ -20152,9 +20234,9 @@
|
|
|
20152
20234
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
20153
20235
|
}
|
|
20154
20236
|
},
|
|
20155
|
-
"x-endpoint-count":
|
|
20156
|
-
"x-schema-count":
|
|
20237
|
+
"x-endpoint-count": 321,
|
|
20238
|
+
"x-schema-count": 355,
|
|
20157
20239
|
"x-undocumented-bodies": 9,
|
|
20158
|
-
"x-response-schemas":
|
|
20240
|
+
"x-response-schemas": 238,
|
|
20159
20241
|
"x-generated-by": "scripts/gds/gen-api-docs.js"
|
|
20160
20242
|
}
|
package/docs/api-reference.md
CHANGED
|
@@ -2,18 +2,19 @@
|
|
|
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. 321 endpoints across 52 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/<redacted>.md)): `public` < `any-builder` < `metic+archon` < `archon`.
|
|
9
9
|
|
|
10
|
-
## `access-requests` (
|
|
10
|
+
## `access-requests` (5)
|
|
11
11
|
|
|
12
12
|
| Method | Path | Rank | Body | Description |
|
|
13
13
|
|---|---|---|---|---|
|
|
14
14
|
| GET | `/api/bongos/access-requests` | `archon` | — | GET /access-requests?status=pending — Archon queue. |
|
|
15
15
|
| POST | `/api/bongos/access-requests` | `public` | `github_login`, `display_name`, `note` | POST /access-requests — PUBLIC. |
|
|
16
16
|
| PATCH | `/api/bongos/access-requests/:id` | `archon` | `status` | PATCH /access-requests/:id — Archon resolves a request. |
|
|
17
|
+
| POST | `/api/bongos/access-requests/invite` | `archon` | `github_login` | POST /access-requests/invite — an Archon admits a GitHub username BEFORE any request exists (task 1003044): the only way in on an invite-… |
|
|
17
18
|
| GET | `/api/bongos/access-requests/status` | `public` | — | GET /access-requests/status?github_login=X — PUBLIC. |
|
|
18
19
|
|
|
19
20
|
## `achievements` (1)
|