@bongos/core 1.19.1076 → 1.19.1078
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 +48 -28
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +6 -0
- package/clients/bongos-client/index.cjs +6 -0
- package/clients/bongos-client/index.d.ts +7 -0
- package/clients/bongos-client/index.mjs +6 -0
- package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +7 -0
- package/docs/api/openapi.json +116 -3
- package/docs/api-reference.md +6 -3
- package/docs/architecture.md +16 -0
- package/docs/module-api-changelog.md +4 -0
- package/migrations/core_259_module_entitlements.sql +58 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/src/bongos/auth.js +8 -1
- package/src/bongos/middleware/rate-limit.js +1 -1
- package/src/bongos/module-entitlements.js +127 -0
- package/src/bongos/routes/auth.js +271 -73
- package/src/bongos/routes/modules.js +29 -0
- package/src/module-api.js +1 -1
- package/tests/hub_cookie_host_only.mjs +279 -0
- package/tests/landing_page.mjs +4 -1
- package/tests/module_entitlements.mjs +204 -0
- package/tests/session_rename_fallback.mjs +19 -11
- package/tests/subdomain_auth.mjs +17 -15
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.1078",
|
|
6
|
+
"core_contract": "1.19.1078",
|
|
7
|
+
"source_commit": "411c9ed509c000585d51b84c04a797ec9b15f67d",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-29T16:46:58.351Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 550,
|
|
13
13
|
"agent_docs_stubbed": 25,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2533,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 3109,
|
|
20
|
+
"tree_sha256": "391c5cd61e61bb87908e73e23c99d7e86ea0f2467f47dfd2a63ebb2b475f435b",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -322,12 +322,12 @@
|
|
|
322
322
|
{
|
|
323
323
|
"path": "clients/bongos-client/README.md",
|
|
324
324
|
"mode": "0000644",
|
|
325
|
-
"sha256": "
|
|
325
|
+
"sha256": "aa2d78e23e985228caf64e4b9bdacc0caa55f07f1b0d883520b5a97e112427b2"
|
|
326
326
|
},
|
|
327
327
|
{
|
|
328
328
|
"path": "clients/bongos-client/bongos-client.global.js",
|
|
329
329
|
"mode": "0000644",
|
|
330
|
-
"sha256": "
|
|
330
|
+
"sha256": "1267fb539bb527d61edc8b3372eca5f4e9b478b8bf2f23c5aed3760ad4d1d09c"
|
|
331
331
|
},
|
|
332
332
|
{
|
|
333
333
|
"path": "clients/bongos-client/examples/hello-world.mjs",
|
|
@@ -337,17 +337,17 @@
|
|
|
337
337
|
{
|
|
338
338
|
"path": "clients/bongos-client/index.cjs",
|
|
339
339
|
"mode": "0000644",
|
|
340
|
-
"sha256": "
|
|
340
|
+
"sha256": "4a5ca3b3f81ecc0d068f4456662342c2be6c609668c730bf8b90eb255ac6590f"
|
|
341
341
|
},
|
|
342
342
|
{
|
|
343
343
|
"path": "clients/bongos-client/index.d.ts",
|
|
344
344
|
"mode": "0000644",
|
|
345
|
-
"sha256": "
|
|
345
|
+
"sha256": "3f262f4b629221e5ac75344d23d2b07d51a8003b91567f1a7e96f6b354695e46"
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
"path": "clients/bongos-client/index.mjs",
|
|
349
349
|
"mode": "0000644",
|
|
350
|
-
"sha256": "
|
|
350
|
+
"sha256": "aa9e5ed9bf436f0e0eb28eb6a14a394668f614c5d30bdb31eb7bcd92335ff456"
|
|
351
351
|
},
|
|
352
352
|
{
|
|
353
353
|
"path": "clients/bongos-client/package.json",
|
|
@@ -1167,7 +1167,7 @@
|
|
|
1167
1167
|
{
|
|
1168
1168
|
"path": "docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md",
|
|
1169
1169
|
"mode": "0000644",
|
|
1170
|
-
"sha256": "
|
|
1170
|
+
"sha256": "7735acb6a10465a34e9c1b8ce75f045256ef0ed92bd94a5f383ddf7020afee82"
|
|
1171
1171
|
},
|
|
1172
1172
|
{
|
|
1173
1173
|
"path": "docs/adr/0146-configurable-reward-mode-cost-plus-only.md",
|
|
@@ -2207,17 +2207,17 @@
|
|
|
2207
2207
|
{
|
|
2208
2208
|
"path": "docs/api-reference.md",
|
|
2209
2209
|
"mode": "0000644",
|
|
2210
|
-
"sha256": "
|
|
2210
|
+
"sha256": "4cbfdf33670b1e7cfa9e361ef7209af719da5440fee486f2634a00ab2d8ded64"
|
|
2211
2211
|
},
|
|
2212
2212
|
{
|
|
2213
2213
|
"path": "docs/api/openapi.json",
|
|
2214
2214
|
"mode": "0000644",
|
|
2215
|
-
"sha256": "
|
|
2215
|
+
"sha256": "ee67c19d724bde053b4dbcb711c05cf8d1d14cb3b6ff15c198739fd368c8356d"
|
|
2216
2216
|
},
|
|
2217
2217
|
{
|
|
2218
2218
|
"path": "docs/architecture.md",
|
|
2219
2219
|
"mode": "0000644",
|
|
2220
|
-
"sha256": "
|
|
2220
|
+
"sha256": "c806ee6970ef09f4ee4da68b11b38e9e80bf6c37a71e63833ef3a491b9d1afde"
|
|
2221
2221
|
},
|
|
2222
2222
|
{
|
|
2223
2223
|
"path": "docs/branding-contract.md",
|
|
@@ -2742,7 +2742,7 @@
|
|
|
2742
2742
|
{
|
|
2743
2743
|
"path": "docs/module-api-changelog.md",
|
|
2744
2744
|
"mode": "0000644",
|
|
2745
|
-
"sha256": "
|
|
2745
|
+
"sha256": "e366a77119b50c3c36bfb3219a3cd873b1e36f735b7a150a199cab20ac40fc65"
|
|
2746
2746
|
},
|
|
2747
2747
|
{
|
|
2748
2748
|
"path": "docs/modules-contract.md",
|
|
@@ -3889,6 +3889,11 @@
|
|
|
3889
3889
|
"mode": "0000644",
|
|
3890
3890
|
"sha256": "6591b63dc385fd1d3a69b2729ef16141bdd6017bf3442cac1642403332edc601"
|
|
3891
3891
|
},
|
|
3892
|
+
{
|
|
3893
|
+
"path": "migrations/core_259_module_entitlements.sql",
|
|
3894
|
+
"mode": "0000644",
|
|
3895
|
+
"sha256": "496e1605d0bcac75631217e55ff87d707971332c25fab0730a592eed5d7da8b9"
|
|
3896
|
+
},
|
|
3892
3897
|
{
|
|
3893
3898
|
"path": "modules/agents/CLAUDE.md",
|
|
3894
3899
|
"mode": "0000644",
|
|
@@ -8597,12 +8602,12 @@
|
|
|
8597
8602
|
{
|
|
8598
8603
|
"path": "package-lock.json",
|
|
8599
8604
|
"mode": "0000644",
|
|
8600
|
-
"sha256": "
|
|
8605
|
+
"sha256": "3e6637987df0fac5b562427c291eb8b9ee03af1b4d84bdc96845fdc3f0616198"
|
|
8601
8606
|
},
|
|
8602
8607
|
{
|
|
8603
8608
|
"path": "package.json",
|
|
8604
8609
|
"mode": "0000644",
|
|
8605
|
-
"sha256": "
|
|
8610
|
+
"sha256": "6cfe5fc0e9b764a9e597bb45806a6f5876dd340c3dbedf3101ec20609546bd26"
|
|
8606
8611
|
},
|
|
8607
8612
|
{
|
|
8608
8613
|
"path": "public-docs/index.html",
|
|
@@ -8622,7 +8627,7 @@
|
|
|
8622
8627
|
{
|
|
8623
8628
|
"path": "release-notes.json",
|
|
8624
8629
|
"mode": "0000644",
|
|
8625
|
-
"sha256": "
|
|
8630
|
+
"sha256": "6c995cf2f60c9bca1bf378e3687ada8fe7963c5b18bf45b78bd92e0ee414c88b"
|
|
8626
8631
|
},
|
|
8627
8632
|
{
|
|
8628
8633
|
"path": "scripts/bongos-mcp.js",
|
|
@@ -10392,7 +10397,7 @@
|
|
|
10392
10397
|
{
|
|
10393
10398
|
"path": "src/bongos/auth.js",
|
|
10394
10399
|
"mode": "0000644",
|
|
10395
|
-
"sha256": "
|
|
10400
|
+
"sha256": "a46826214509f317fbe982265c0045edf9c3aa4c94bd2fa54232af51cbc51573"
|
|
10396
10401
|
},
|
|
10397
10402
|
{
|
|
10398
10403
|
"path": "src/bongos/cascade-dispatch.js",
|
|
@@ -10472,7 +10477,12 @@
|
|
|
10472
10477
|
{
|
|
10473
10478
|
"path": "src/bongos/middleware/rate-limit.js",
|
|
10474
10479
|
"mode": "0000644",
|
|
10475
|
-
"sha256": "
|
|
10480
|
+
"sha256": "efe34f92930419444ec31d84c7787488db4984ea761d1bb77d5375388758e68c"
|
|
10481
|
+
},
|
|
10482
|
+
{
|
|
10483
|
+
"path": "src/bongos/module-entitlements.js",
|
|
10484
|
+
"mode": "0000644",
|
|
10485
|
+
"sha256": "917f364b804f25437dea7fe507abe50e9b64cac79b6cc29ac786de0e24350d33"
|
|
10476
10486
|
},
|
|
10477
10487
|
{
|
|
10478
10488
|
"path": "src/bongos/module-overrides.js",
|
|
@@ -10572,7 +10582,7 @@
|
|
|
10572
10582
|
{
|
|
10573
10583
|
"path": "src/bongos/routes/auth.js",
|
|
10574
10584
|
"mode": "0000644",
|
|
10575
|
-
"sha256": "
|
|
10585
|
+
"sha256": "951276d7d3bd022cd9250fe8cd7bd141278d46c4bc6bc06463867f2889e52bc3"
|
|
10576
10586
|
},
|
|
10577
10587
|
{
|
|
10578
10588
|
"path": "src/bongos/routes/backup.js",
|
|
@@ -10622,7 +10632,7 @@
|
|
|
10622
10632
|
{
|
|
10623
10633
|
"path": "src/bongos/routes/modules.js",
|
|
10624
10634
|
"mode": "0000644",
|
|
10625
|
-
"sha256": "
|
|
10635
|
+
"sha256": "e349115a6adea7e97eaf91d2a5fde6d17c90ac80d8f4be579c890ce4a593ef66"
|
|
10626
10636
|
},
|
|
10627
10637
|
{
|
|
10628
10638
|
"path": "src/bongos/routes/my-sessions.js",
|
|
@@ -10692,7 +10702,7 @@
|
|
|
10692
10702
|
{
|
|
10693
10703
|
"path": "src/module-api.js",
|
|
10694
10704
|
"mode": "0000644",
|
|
10695
|
-
"sha256": "
|
|
10705
|
+
"sha256": "28d2a831a69f59cc426c1e318991e4ab0755abd3303cc5786e88b72988e97a5c"
|
|
10696
10706
|
},
|
|
10697
10707
|
{
|
|
10698
10708
|
"path": "src/module-loader/catalog.js",
|
|
@@ -12894,6 +12904,11 @@
|
|
|
12894
12904
|
"mode": "0000644",
|
|
12895
12905
|
"sha256": "5281b73558af27b1be5a839718d845ef47190734d248a3edb5d547c92621f432"
|
|
12896
12906
|
},
|
|
12907
|
+
{
|
|
12908
|
+
"path": "tests/hub_cookie_host_only.mjs",
|
|
12909
|
+
"mode": "0000644",
|
|
12910
|
+
"sha256": "96698c6be76c8c6d6cc5f09522d110514c420cb1a7279ca86871a034892c7328"
|
|
12911
|
+
},
|
|
12897
12912
|
{
|
|
12898
12913
|
"path": "tests/hub_disconnect_ui.mjs",
|
|
12899
12914
|
"mode": "0000644",
|
|
@@ -13267,7 +13282,7 @@
|
|
|
13267
13282
|
{
|
|
13268
13283
|
"path": "tests/landing_page.mjs",
|
|
13269
13284
|
"mode": "0000644",
|
|
13270
|
-
"sha256": "
|
|
13285
|
+
"sha256": "cb0dbcf0f4cc6fc67f7eeda609b2ea4c879bd8ad9efea7556fcbb8c7afe85bd4"
|
|
13271
13286
|
},
|
|
13272
13287
|
{
|
|
13273
13288
|
"path": "tests/leak_scan_allowlist.mjs",
|
|
@@ -13534,6 +13549,11 @@
|
|
|
13534
13549
|
"mode": "0000644",
|
|
13535
13550
|
"sha256": "02862e4df8c3df0f6e255c8ad8108b518de7a665881f744eb3e59537193f4587"
|
|
13536
13551
|
},
|
|
13552
|
+
{
|
|
13553
|
+
"path": "tests/module_entitlements.mjs",
|
|
13554
|
+
"mode": "0000644",
|
|
13555
|
+
"sha256": "50e4d45bf544efe755dda538a93eafc40dcd9caa071e987d8833d97ecf1b7e0f"
|
|
13556
|
+
},
|
|
13537
13557
|
{
|
|
13538
13558
|
"path": "tests/module_exports_unique_keys.mjs",
|
|
13539
13559
|
"mode": "0000644",
|
|
@@ -14692,7 +14712,7 @@
|
|
|
14692
14712
|
{
|
|
14693
14713
|
"path": "tests/session_rename_fallback.mjs",
|
|
14694
14714
|
"mode": "0000644",
|
|
14695
|
-
"sha256": "
|
|
14715
|
+
"sha256": "9d6964a9df8051430d7cf495ca1fa93c22a60b9cf6c90174da209255ff3e551d"
|
|
14696
14716
|
},
|
|
14697
14717
|
{
|
|
14698
14718
|
"path": "tests/session_reward_on_land.mjs",
|
|
@@ -15122,7 +15142,7 @@
|
|
|
15122
15142
|
{
|
|
15123
15143
|
"path": "tests/subdomain_auth.mjs",
|
|
15124
15144
|
"mode": "0000644",
|
|
15125
|
-
"sha256": "
|
|
15145
|
+
"sha256": "a9f2b527557bdd86ccabb6c7aff779a235cdd20374f278232cfe7451d9f22d9b"
|
|
15126
15146
|
},
|
|
15127
15147
|
{
|
|
15128
15148
|
"path": "tests/sweep_app_account.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
|
+
- 436 operations across 67 resource groups
|
|
9
9
|
|
|
10
10
|
## Use it from your project
|
|
11
11
|
|
|
@@ -163,6 +163,8 @@ function createClient(opts = {}) {
|
|
|
163
163
|
getAuthWebAdmissionStatus: (args) => request("GET", "/auth/web/admission-status", { hasBody: false }, args),
|
|
164
164
|
// GET /auth/web/callback — rank: public — GET /auth/web/callback
|
|
165
165
|
getAuthWebCallback: (args) => request("GET", "/auth/web/callback", { hasBody: false }, args),
|
|
166
|
+
// GET /auth/web/handoff — rank: public — GET /auth/web/handoff
|
|
167
|
+
getAuthWebHandoff: (args) => request("GET", "/auth/web/handoff", { hasBody: false }, args),
|
|
166
168
|
// GET /auth/web/start — rank: public — GET /auth/web/start
|
|
167
169
|
getAuthWebStart: (args) => request("GET", "/auth/web/start", { hasBody: false }, args),
|
|
168
170
|
},
|
|
@@ -969,6 +971,10 @@ function createClient(opts = {}) {
|
|
|
969
971
|
postSsoToken: (args) => request("POST", "/sso/token", { hasBody: true }, args),
|
|
970
972
|
},
|
|
971
973
|
"store": {
|
|
974
|
+
// GET /store/entitlements — rank: any-builder — GET /store/entitlements
|
|
975
|
+
getStoreEntitlements: (args) => request("GET", "/store/entitlements", { hasBody: false }, args),
|
|
976
|
+
// GET /store/modules/{key}/entitlement — rank: any-builder — GET /store/modules/:key/entitlement
|
|
977
|
+
getStoreModulesKeyEntitlement: (args) => request("GET", "/store/modules/{key}/entitlement", { hasBody: false }, args),
|
|
972
978
|
// POST /store/modules/{key}/versions — rank: metic+archon — POST /store/modules/:key/versions
|
|
973
979
|
postStoreModulesKeyVersions: (args) => request("POST", "/store/modules/{key}/versions", { hasBody: true }, args),
|
|
974
980
|
},
|
|
@@ -162,6 +162,8 @@ function createClient(opts = {}) {
|
|
|
162
162
|
getAuthWebAdmissionStatus: (args) => request("GET", "/auth/web/admission-status", { hasBody: false }, args),
|
|
163
163
|
// GET /auth/web/callback — rank: public — GET /auth/web/callback
|
|
164
164
|
getAuthWebCallback: (args) => request("GET", "/auth/web/callback", { hasBody: false }, args),
|
|
165
|
+
// GET /auth/web/handoff — rank: public — GET /auth/web/handoff
|
|
166
|
+
getAuthWebHandoff: (args) => request("GET", "/auth/web/handoff", { hasBody: false }, args),
|
|
165
167
|
// GET /auth/web/start — rank: public — GET /auth/web/start
|
|
166
168
|
getAuthWebStart: (args) => request("GET", "/auth/web/start", { hasBody: false }, args),
|
|
167
169
|
},
|
|
@@ -968,6 +970,10 @@ function createClient(opts = {}) {
|
|
|
968
970
|
postSsoToken: (args) => request("POST", "/sso/token", { hasBody: true }, args),
|
|
969
971
|
},
|
|
970
972
|
"store": {
|
|
973
|
+
// GET /store/entitlements — rank: any-builder — GET /store/entitlements
|
|
974
|
+
getStoreEntitlements: (args) => request("GET", "/store/entitlements", { hasBody: false }, args),
|
|
975
|
+
// GET /store/modules/{key}/entitlement — rank: any-builder — GET /store/modules/:key/entitlement
|
|
976
|
+
getStoreModulesKeyEntitlement: (args) => request("GET", "/store/modules/{key}/entitlement", { hasBody: false }, args),
|
|
971
977
|
// POST /store/modules/{key}/versions — rank: metic+archon — POST /store/modules/:key/versions
|
|
972
978
|
postStoreModulesKeyVersions: (args) => request("POST", "/store/modules/{key}/versions", { hasBody: true }, args),
|
|
973
979
|
},
|
|
@@ -157,6 +157,7 @@ export interface GetSpecialitiesIdResponse { speciality: unknown }
|
|
|
157
157
|
export interface GetSpecialitiesOfferedResponse { suggestions: unknown }
|
|
158
158
|
export interface GetSpecialitiesResponse { specialities: unknown }
|
|
159
159
|
export interface GetSsoPubkeyResponse { alg: unknown; format: unknown; public_key_b64: unknown }
|
|
160
|
+
export interface GetStoreEntitlementsResponse { entitlements: unknown }
|
|
160
161
|
export interface GetTaskRecommendationsForMeResponse { recommendations: unknown; count: unknown }
|
|
161
162
|
export interface GetTaskRecommendationsMineResponse { recommendations: unknown; count: unknown }
|
|
162
163
|
export interface GetTasksClaimableResponse { claimable: unknown; claimable_total: unknown; active_claims: unknown }
|
|
@@ -562,6 +563,8 @@ export interface BongosClient {
|
|
|
562
563
|
getAuthWebAdmissionStatus(args?: RequestArgs): Promise<GetAuthWebAdmissionStatusResponse>;
|
|
563
564
|
/** GET /auth/web/callback — rank: public */
|
|
564
565
|
getAuthWebCallback(args?: RequestArgs): Promise<ApiResponse>;
|
|
566
|
+
/** GET /auth/web/handoff — rank: public */
|
|
567
|
+
getAuthWebHandoff(args?: RequestArgs): Promise<ApiResponse>;
|
|
565
568
|
/** GET /auth/web/start — rank: public */
|
|
566
569
|
getAuthWebStart(args?: RequestArgs): Promise<ApiResponse>;
|
|
567
570
|
};
|
|
@@ -1368,6 +1371,10 @@ export interface BongosClient {
|
|
|
1368
1371
|
postSsoToken(args: RequestArgs & { body: PostSsoTokenRequest }): Promise<PostSsoTokenResponse>;
|
|
1369
1372
|
};
|
|
1370
1373
|
"store": {
|
|
1374
|
+
/** GET /store/entitlements — rank: any-builder */
|
|
1375
|
+
getStoreEntitlements(args?: RequestArgs): Promise<GetStoreEntitlementsResponse>;
|
|
1376
|
+
/** GET /store/modules/{key}/entitlement — rank: any-builder */
|
|
1377
|
+
getStoreModulesKeyEntitlement(args?: RequestArgs): Promise<ApiResponse>;
|
|
1371
1378
|
/** POST /store/modules/{key}/versions — rank: metic+archon */
|
|
1372
1379
|
postStoreModulesKeyVersions(args?: RequestArgs): Promise<PostStoreModulesKeyVersionsResponse>;
|
|
1373
1380
|
};
|
|
@@ -159,6 +159,8 @@ export function createClient(opts = {}) {
|
|
|
159
159
|
getAuthWebAdmissionStatus: (args) => request("GET", "/auth/web/admission-status", { hasBody: false }, args),
|
|
160
160
|
// GET /auth/web/callback — rank: public — GET /auth/web/callback
|
|
161
161
|
getAuthWebCallback: (args) => request("GET", "/auth/web/callback", { hasBody: false }, args),
|
|
162
|
+
// GET /auth/web/handoff — rank: public — GET /auth/web/handoff
|
|
163
|
+
getAuthWebHandoff: (args) => request("GET", "/auth/web/handoff", { hasBody: false }, args),
|
|
162
164
|
// GET /auth/web/start — rank: public — GET /auth/web/start
|
|
163
165
|
getAuthWebStart: (args) => request("GET", "/auth/web/start", { hasBody: false }, args),
|
|
164
166
|
},
|
|
@@ -965,6 +967,10 @@ export function createClient(opts = {}) {
|
|
|
965
967
|
postSsoToken: (args) => request("POST", "/sso/token", { hasBody: true }, args),
|
|
966
968
|
},
|
|
967
969
|
"store": {
|
|
970
|
+
// GET /store/entitlements — rank: any-builder — GET /store/entitlements
|
|
971
|
+
getStoreEntitlements: (args) => request("GET", "/store/entitlements", { hasBody: false }, args),
|
|
972
|
+
// GET /store/modules/{key}/entitlement — rank: any-builder — GET /store/modules/:key/entitlement
|
|
973
|
+
getStoreModulesKeyEntitlement: (args) => request("GET", "/store/modules/{key}/entitlement", { hasBody: false }, args),
|
|
968
974
|
// POST /store/modules/{key}/versions — rank: metic+archon — POST /store/modules/:key/versions
|
|
969
975
|
postStoreModulesKeyVersions: (args) => request("POST", "/store/modules/{key}/versions", { hasBody: true }, args),
|
|
970
976
|
},
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# 0145 — A free "own-repo" hosted project tier needs domain separation + per-project isolation (not a bare cloudbongos.com subdomain)
|
|
2
2
|
|
|
3
|
+
- **Status update 2026-09-29 — Finding 1 is FIXED by host-only hub cookies ([task 1004357](https://cloudbongos.com/builders#/task/1004357); build sequence step 1, the cookie half).** Option A was chosen over a separate registrable domain for halls: it needs no new domain, no DNS or TLS work and no change to any project's address, and it closes the hole for every hall already live. What changed, all in `src/bongos/routes/auth.js`:
|
|
4
|
+
- **Nothing the hub sets carries a `Domain` attribute any more.** The session is `__Host-bongos_session` over https (a browser only accepts a `__Host-` cookie that is Secure, `Path=/` and host-only), plain `bongos_session` on local http. The OAuth and Discord handshake cookies are host-only too.
|
|
5
|
+
- **`builders.` / `status.` / `www.` get the session through a one-time handoff.** A sign-in begun on one of them restarts on the canonical host (the only host the GitHub callback reaches). The canonical host then redirects back with a single-use, 60-second code bound to that one host, and `GET /auth/web/handoff` trades it for that host's own host-only copy of the same token. A builder already signed in on the apex who opens `builders.` skips GitHub entirely. A code is only ever minted for one of the hub's four hosts, never a hall.
|
|
6
|
+
- **Existing browsers are moved over.** Every hub API request that carries a pre-fix session cookie and no `__Host-` one re-issues the same token host-only and expires the apex-scoped copy.
|
|
7
|
+
- **Proof:** `tests/hub_cookie_host_only.mjs` runs the real router through an RFC 6265 cookie jar and asserts a hall at `<handle>.<apex>` receives no hub cookie after the full flow.
|
|
8
|
+
- **Still open from step 1:** CSRF tokens on state-changing hub endpoints. `SameSite=Lax` does not separate a hall from the hub, because they are the same site. The legacy session names are still ACCEPTED on read (so nobody was signed out at deploy), which leaves a hall able to plant a cookie under an old name. Retiring those names (task 1003706's Part 4) closes that. A token copied by a hall BEFORE this shipped stays valid until it expires or its builder signs out.
|
|
9
|
+
|
|
3
10
|
- **Status update 2026-09-28 — Finding 1 is OPEN again, and permanently ([ADR 0345](0345-we-host-every-projects-hall-and-its-app-deploys-where-the-owner-chooses.md) decision 6).** Project halls now stay hosted on our box, so ADR 0323's "closed by removing its precondition" below no longer holds. Measured: the hub still sets `Domain=.cloudbongos.com`, and a hall loads modules from its own repository, so a hall at one of our addresses can read a visiting hub builder's session. The sign-in hardening is a **blocking prerequisite again** for any new hall at one of our addresses, filed as [task 1004357](https://cloudbongos.com/builders#/task/1004357). A hall on the owner's own domain is not exposed.
|
|
4
11
|
- **Status:** **Superseded in part by [ADR 0323](0323-hosting-is-three-shapes-and-we-are-not-the-landlord.md)** (2026-09-21). Three of this ADR's decisions are replaced: the free tier becomes a **capped trial**, not all-free; customer projects leave the shared box for a managed platform, so **container isolation on our own box is no longer the plan**; and **Finding 1 is closed by removing its precondition** — with no customer code on a `cloudbongos.com` subdomain there is no tenant to receive the hub session cookie, so the sign-in hardening in the build sequence below is no longer a blocking prerequisite (it remains worth doing on its own merits). The two security FINDINGS below stand as analysis and are the reason the new direction is safe.
|
|
5
12
|
- **Status:** Accepted — owner decided 2026-07-15: **keep `cloudbongos.com`** (no separate domain), **container** isolation, **all-free** for now. Choosing the literal same domain makes hardening core sign-in a required prerequisite (see "Decisions" + "Required build sequence"). Build unblocked ([task 1002251](https://cloudbongos.com/builders#/task/1002251)); blocker 1000080 resolved.
|
package/docs/api/openapi.json
CHANGED
|
@@ -1662,6 +1662,27 @@
|
|
|
1662
1662
|
"security": []
|
|
1663
1663
|
}
|
|
1664
1664
|
},
|
|
1665
|
+
"/auth/web/handoff": {
|
|
1666
|
+
"get": {
|
|
1667
|
+
"operationId": "get_auth_web_handoff",
|
|
1668
|
+
"tags": [
|
|
1669
|
+
"auth"
|
|
1670
|
+
],
|
|
1671
|
+
"summary": "GET /auth/web/handoff",
|
|
1672
|
+
"description": "GET /auth/web/handoff?code=&return= — the far side of the one-time session handoff (task 1004357). The canonical host minted `code` for THIS host after a sign-in (or for a builder already signed in there); trading it sets this host's own host-only copy of the session, then lands on `return` — a relative path only, so the handoff can never become an open redirect. rank: public — auth establishment; the one-time code is the bearer, bound to this exact host, single-use and alive for HANDOFF_TTL_MS.\n\n**Rank:** `public` — No authentication — any caller.",
|
|
1673
|
+
"x-rank": "public",
|
|
1674
|
+
"x-source": "src/bongos/routes/auth.js",
|
|
1675
|
+
"responses": {
|
|
1676
|
+
"200": {
|
|
1677
|
+
"description": "Success."
|
|
1678
|
+
},
|
|
1679
|
+
"400": {
|
|
1680
|
+
"$ref": "#/components/responses/BadRequest"
|
|
1681
|
+
}
|
|
1682
|
+
},
|
|
1683
|
+
"security": []
|
|
1684
|
+
}
|
|
1685
|
+
},
|
|
1665
1686
|
"/auth/web/start": {
|
|
1666
1687
|
"get": {
|
|
1667
1688
|
"operationId": "get_auth_web_start",
|
|
@@ -17691,6 +17712,89 @@
|
|
|
17691
17712
|
"security": []
|
|
17692
17713
|
}
|
|
17693
17714
|
},
|
|
17715
|
+
"/store/entitlements": {
|
|
17716
|
+
"get": {
|
|
17717
|
+
"operationId": "get_store_entitlements",
|
|
17718
|
+
"tags": [
|
|
17719
|
+
"store"
|
|
17720
|
+
],
|
|
17721
|
+
"summary": "GET /store/entitlements",
|
|
17722
|
+
"description": "GET /api/bongos/store/entitlements and /store/modules/:key/entitlement — the read side of the entitlement record (task 1003813, ADR 0338 D1). Own-scoped like /me/sessions: the holder is ALWAYS the caller (holder_kind 'builder', holder_ref = req.builder.id), never named in the query or path, so requireBuilder alone is the gate and one builder cannot read another's holdings. Granting has no route yet: install (task 1003785) grants a free module, area 8's buy action grants a paid one — both through src/bongos/module-entitlements.js.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
17723
|
+
"x-rank": "any-builder",
|
|
17724
|
+
"x-source": "src/bongos/routes/modules.js",
|
|
17725
|
+
"responses": {
|
|
17726
|
+
"200": {
|
|
17727
|
+
"description": "Success.",
|
|
17728
|
+
"content": {
|
|
17729
|
+
"application/json": {
|
|
17730
|
+
"schema": {
|
|
17731
|
+
"$ref": "#/components/schemas/GetStoreEntitlementsResponse"
|
|
17732
|
+
}
|
|
17733
|
+
}
|
|
17734
|
+
}
|
|
17735
|
+
},
|
|
17736
|
+
"400": {
|
|
17737
|
+
"$ref": "#/components/responses/BadRequest"
|
|
17738
|
+
},
|
|
17739
|
+
"401": {
|
|
17740
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
17741
|
+
},
|
|
17742
|
+
"403": {
|
|
17743
|
+
"$ref": "#/components/responses/Forbidden"
|
|
17744
|
+
}
|
|
17745
|
+
},
|
|
17746
|
+
"security": [
|
|
17747
|
+
{
|
|
17748
|
+
"builderSession": []
|
|
17749
|
+
}
|
|
17750
|
+
]
|
|
17751
|
+
}
|
|
17752
|
+
},
|
|
17753
|
+
"/store/modules/{key}/entitlement": {
|
|
17754
|
+
"get": {
|
|
17755
|
+
"operationId": "get_store_modules_key_entitlement",
|
|
17756
|
+
"tags": [
|
|
17757
|
+
"store"
|
|
17758
|
+
],
|
|
17759
|
+
"summary": "GET /store/modules/:key/entitlement",
|
|
17760
|
+
"description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
17761
|
+
"x-rank": "any-builder",
|
|
17762
|
+
"x-source": "src/bongos/routes/modules.js",
|
|
17763
|
+
"parameters": [
|
|
17764
|
+
{
|
|
17765
|
+
"name": "key",
|
|
17766
|
+
"in": "path",
|
|
17767
|
+
"required": true,
|
|
17768
|
+
"schema": {
|
|
17769
|
+
"type": "string"
|
|
17770
|
+
},
|
|
17771
|
+
"description": "Path parameter `key`."
|
|
17772
|
+
}
|
|
17773
|
+
],
|
|
17774
|
+
"responses": {
|
|
17775
|
+
"200": {
|
|
17776
|
+
"description": "Success."
|
|
17777
|
+
},
|
|
17778
|
+
"400": {
|
|
17779
|
+
"$ref": "#/components/responses/BadRequest"
|
|
17780
|
+
},
|
|
17781
|
+
"401": {
|
|
17782
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
17783
|
+
},
|
|
17784
|
+
"403": {
|
|
17785
|
+
"$ref": "#/components/responses/Forbidden"
|
|
17786
|
+
},
|
|
17787
|
+
"404": {
|
|
17788
|
+
"$ref": "#/components/responses/NotFound"
|
|
17789
|
+
}
|
|
17790
|
+
},
|
|
17791
|
+
"security": [
|
|
17792
|
+
{
|
|
17793
|
+
"builderSession": []
|
|
17794
|
+
}
|
|
17795
|
+
]
|
|
17796
|
+
}
|
|
17797
|
+
},
|
|
17694
17798
|
"/store/modules/{key}/versions": {
|
|
17695
17799
|
"post": {
|
|
17696
17800
|
"operationId": "post_store_modules_key_versions",
|
|
@@ -22320,6 +22424,15 @@
|
|
|
22320
22424
|
"public_key_b64"
|
|
22321
22425
|
]
|
|
22322
22426
|
},
|
|
22427
|
+
"GetStoreEntitlementsResponse": {
|
|
22428
|
+
"type": "object",
|
|
22429
|
+
"properties": {
|
|
22430
|
+
"entitlements": {}
|
|
22431
|
+
},
|
|
22432
|
+
"required": [
|
|
22433
|
+
"entitlements"
|
|
22434
|
+
]
|
|
22435
|
+
},
|
|
22323
22436
|
"GetTaskRecommendationsForMeResponse": {
|
|
22324
22437
|
"type": "object",
|
|
22325
22438
|
"properties": {
|
|
@@ -27716,9 +27829,9 @@
|
|
|
27716
27829
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
27717
27830
|
}
|
|
27718
27831
|
},
|
|
27719
|
-
"x-endpoint-count":
|
|
27720
|
-
"x-schema-count":
|
|
27832
|
+
"x-endpoint-count": 436,
|
|
27833
|
+
"x-schema-count": 467,
|
|
27721
27834
|
"x-undocumented-bodies": 11,
|
|
27722
|
-
"x-response-schemas":
|
|
27835
|
+
"x-response-schemas": 320,
|
|
27723
27836
|
"x-generated-by": "scripts/gds/gen-api-docs.js"
|
|
27724
27837
|
}
|
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. 436 endpoints across 75 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`.
|
|
@@ -61,7 +61,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
61
61
|
|---|---|---|---|---|
|
|
62
62
|
| GET | `/api/bongos/audit-log` | `metic+archon` | — | GET /api/bongos/audit-log?limit=&offset=&builder_id=&method= Paginated, newest-first. |
|
|
63
63
|
|
|
64
|
-
## `auth` (
|
|
64
|
+
## `auth` (15)
|
|
65
65
|
|
|
66
66
|
| Method | Path | Rank | Body | Description |
|
|
67
67
|
|---|---|---|---|---|
|
|
@@ -78,6 +78,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
78
78
|
| POST | `/api/bongos/auth/revoke-all` | `archon` | `builder_id` | POST /auth/revoke-all — V3.R38 / task 259. |
|
|
79
79
|
| GET | `/api/bongos/auth/web/admission-status` | `public` | — | GET /auth/web/admission-status?login=X — the probe renderAccessPendingPage polls (task 1002097). |
|
|
80
80
|
| GET | `/api/bongos/auth/web/callback` | `public` | — | OAuth callback; the state cookie + code are the bearer. |
|
|
81
|
+
| GET | `/api/bongos/auth/web/handoff` | `public` | — | GET /auth/web/handoff?code=&return= — the far side of the one-time session handoff (task 1004357). |
|
|
81
82
|
| GET | `/api/bongos/auth/web/start` | `public` | — | /auth/web — browser flow (used by the /builders page). |
|
|
82
83
|
|
|
83
84
|
## `autonomy` (8)
|
|
@@ -693,10 +694,12 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
693
694
|
| GET | `/api/bongos/sso/pubkey` | `public` | — | GET /sso/pubkey — the hub's Ed25519 assertion-verification key (public). |
|
|
694
695
|
| POST | `/api/bongos/sso/token` | `public` | `client_id`, `client_secret`, `code`, `redirect_uri` | POST /sso/token — server-to-server code redemption. |
|
|
695
696
|
|
|
696
|
-
## `store` (
|
|
697
|
+
## `store` (3)
|
|
697
698
|
|
|
698
699
|
| Method | Path | Rank | Body | Description |
|
|
699
700
|
|---|---|---|---|---|
|
|
701
|
+
| GET | `/api/bongos/store/entitlements` | `any-builder` | — | GET /api/bongos/store/entitlements and /store/modules/:key/entitlement — the read side of the entitlement record (task 1003813, ADR 0338 … |
|
|
702
|
+
| GET | `/api/bongos/store/modules/:key/entitlement` | `any-builder` | — | |
|
|
700
703
|
| 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). |
|
|
701
704
|
|
|
702
705
|
## `task-recommendations` (4)
|
package/docs/architecture.md
CHANGED
|
@@ -233,6 +233,22 @@ store_module_prices(id, module_key, price_cents, price_credits, set_by, set_at)
|
|
|
233
233
|
-- in that currency, at least one must be set.
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
+
Module entitlements (migration `core_259`, task 1003813 — who holds which module, at which version; the record install, update and the telemetry signals consult; it records ownership, never payment — area 8 owns money):
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
module_entitlements(id, module_key, holder_kind IN (builder|instance), holder_ref,
|
|
240
|
+
source IN (free|core|grant|purchase), payment_ref (opaque, area 8's),
|
|
241
|
+
version exact X.Y.Z | NULL, acquired_at, granted_by, granted_at,
|
|
242
|
+
revoked_at, revoked_reason, UNIQUE(module_key, holder_kind, holder_ref))
|
|
243
|
+
-- module_key is NOT an FK: a core-bundled module has no store row and
|
|
244
|
+
-- holds an entitlement like any other. Ownership is per module; an update
|
|
245
|
+
-- moves `version` forward, never asks for a second purchase. A delist never
|
|
246
|
+
-- touches it (ADR 0338 D2); only revoke (refund, task 1003789) ends a hold,
|
|
247
|
+
-- keeping the row.
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Code: `src/bongos/module-entitlements.js` (`grantEntitlement`, `recordAcquired`, `revokeEntitlement`, `checkEntitlement`, `listEntitlements`). Read routes (own-scoped, `requireBuilder`): `GET /store/entitlements`, `GET /store/modules/:key/entitlement`. No grant route yet: install (task 1003785) grants a free module, the buy action (area 8) a paid one.
|
|
251
|
+
|
|
236
252
|
Bongos views: `claimable_tasks` (rebuilt in 006 to use SELECT t.*; rebuilt again in 014 so the new `discipline` column flows through), `version_progress` (rebuilt in 006 to count only leaf tasks for forward-compat with task hierarchy), `tasks_session_fit` (new in 006: derives `fits_session_modes[]` and `credits_per_minute`; rebuilt in 014 for the same SELECT t.* refresh), `task_grades_with_context` (new in 016: joins task_grades × tasks × builders × cost_log so the V4 optimizer has quality-per-dollar in one read).
|
|
237
253
|
|
|
238
254
|
**Bongos API (`/api/bongos/*`, mounted in the same Node process):**
|
|
@@ -2643,5 +2643,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2643
2643
|
the doorway loses nothing inside 1.x; it goes at the next MAJOR.
|
|
2644
2644
|
1.19.1076 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2645
2645
|
landed since 1.19.1075 with no explicit bump. run 36523068301. (task 1002620)
|
|
2646
|
+
1.19.1077 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2647
|
+
landed since 1.19.1076 with no explicit bump. run 36558431394. (task 1002620)
|
|
2648
|
+
1.19.1078 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2649
|
+
landed since 1.19.1077 with no explicit bump. run 36600137276. (task 1002620)
|
|
2646
2650
|
---------------------------------------------------------------------------
|
|
2647
2651
|
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
-- core_259_module_entitlements.sql — who holds which module, and at which version.
|
|
2
|
+
--
|
|
3
|
+
-- task 1003813 (goal 1000091, working area 5). ADR 0338 D1: the store checks an
|
|
4
|
+
-- entitlement before it serves a tarball, and install (1003785), update (1003786)
|
|
5
|
+
-- and the install/reliability signals (1003793) all read it. This is the durable
|
|
6
|
+
-- meaning of "bought" — and deliberately NOT the act of paying. Granting an
|
|
7
|
+
-- entitlement is area 5's; taking money, balances and payout are area 8's (goal
|
|
8
|
+
-- 1000092) and are not modelled here. The one seam is `payment_ref`: an opaque
|
|
9
|
+
-- text pointer area 8 can fill when it wires the buy action, never read by us.
|
|
10
|
+
--
|
|
11
|
+
-- module_entitlements one row per (module, holder). The holder is a builder or
|
|
12
|
+
-- an instance, named by (holder_kind, holder_ref).
|
|
13
|
+
-- `source` says how it came to be held: 'free' (a zero-price
|
|
14
|
+
-- store module), 'core' (bundled with core), 'grant' (a
|
|
15
|
+
-- person gave it, no payment), 'purchase' (area 8 will
|
|
16
|
+
-- write this). Every source is the same row, so free and
|
|
17
|
+
-- core modules go through exactly the record a paid one does.
|
|
18
|
+
-- `version` is the exact X.Y.Z the holder last acquired —
|
|
19
|
+
-- NULL until the first acquisition. Ownership is per MODULE:
|
|
20
|
+
-- an update moves `version` forward and never asks for a
|
|
21
|
+
-- second purchase (task 1003786).
|
|
22
|
+
--
|
|
23
|
+
-- module_key is deliberately NOT a foreign key to store_modules: a core-bundled
|
|
24
|
+
-- module has no store row, and it must hold an entitlement like any other.
|
|
25
|
+
-- A delist never touches this table (ADR 0338 D2: an entitlement is never revoked
|
|
26
|
+
-- by a delist); the only thing that ends one is `revoked_at`, set by the refund
|
|
27
|
+
-- path (task 1003789). A revoked row is kept, not deleted, so history stays
|
|
28
|
+
-- answerable, and a re-grant clears `revoked_at` on the same row.
|
|
29
|
+
--
|
|
30
|
+
-- Additive only (a new table), so forward-safe. Idempotent: safe to re-run.
|
|
31
|
+
|
|
32
|
+
CREATE TABLE IF NOT EXISTS module_entitlements (
|
|
33
|
+
id bigserial PRIMARY KEY,
|
|
34
|
+
module_key text NOT NULL
|
|
35
|
+
CHECK (module_key ~ '^[a-z][a-z0-9-]*$'),
|
|
36
|
+
holder_kind text NOT NULL
|
|
37
|
+
CHECK (holder_kind IN ('builder', 'instance')),
|
|
38
|
+
holder_ref text NOT NULL CHECK (length(holder_ref) > 0),
|
|
39
|
+
source text NOT NULL
|
|
40
|
+
CHECK (source IN ('free', 'core', 'grant', 'purchase')),
|
|
41
|
+
payment_ref text,
|
|
42
|
+
version text
|
|
43
|
+
CHECK (version IS NULL OR version ~ '^[0-9]+\.[0-9]+\.[0-9]+$'),
|
|
44
|
+
acquired_at timestamptz,
|
|
45
|
+
granted_by bigint REFERENCES builders(id),
|
|
46
|
+
granted_at timestamptz NOT NULL DEFAULT now(),
|
|
47
|
+
revoked_at timestamptz,
|
|
48
|
+
revoked_reason text,
|
|
49
|
+
UNIQUE (module_key, holder_kind, holder_ref),
|
|
50
|
+
CHECK ((version IS NULL) = (acquired_at IS NULL)),
|
|
51
|
+
CHECK ((revoked_at IS NULL) = (revoked_reason IS NULL))
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
CREATE INDEX IF NOT EXISTS idx_module_entitlements_holder
|
|
55
|
+
ON module_entitlements (holder_kind, holder_ref);
|
|
56
|
+
|
|
57
|
+
INSERT INTO schema_migrations (version) VALUES ('core_259_module_entitlements')
|
|
58
|
+
ON CONFLICT (version) DO NOTHING;
|