@bongos/core 1.24.17 → 1.24.18
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 +44 -24
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +4 -0
- package/clients/bongos-client/index.cjs +4 -0
- package/clients/bongos-client/index.d.ts +6 -0
- package/clients/bongos-client/index.mjs +4 -0
- package/docs/api/openapi.json +116 -3
- package/docs/api-reference.md +4 -2
- package/docs/architecture.md +15 -0
- package/docs/module-api-changelog.md +2 -0
- package/migrations/core_290_builder_payouts.sql +86 -0
- package/modules/economy/module.json +1 -1
- package/modules/economy/routes/project-account.js +10 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +6 -0
- package/scripts/bongos/run-unit-tests.js +4 -0
- package/src/bongos/builder-payouts.js +264 -0
- package/src/bongos/routes/payout-approvals.js +41 -1
- package/src/module-api.js +1 -1
- package/tests/builder_payouts.mjs +295 -0
- package/tests/builder_payouts_db.mjs +109 -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.24.
|
|
6
|
-
"core_contract": "1.24.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.24.18",
|
|
6
|
+
"core_contract": "1.24.18",
|
|
7
|
+
"source_commit": "0ebf219ad01de6b8e9ed1b617c4fcf6857ebabbf",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-10-30T21:
|
|
9
|
+
"built_at": "2026-10-30T21:27:32.715Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 632,
|
|
13
13
|
"agent_docs_stubbed": 32,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 3802,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 4467,
|
|
20
|
+
"tree_sha256": "c5ec1713b059cfb62f825c5ff39b3ebf934db4b9ef6bee93c174a99da1c999f1",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -332,12 +332,12 @@
|
|
|
332
332
|
{
|
|
333
333
|
"path": "clients/bongos-client/README.md",
|
|
334
334
|
"mode": "0000644",
|
|
335
|
-
"sha256": "
|
|
335
|
+
"sha256": "93014d9ba68f4a28c1c23ca623762df541883df9201aad5ffdfd53bee22a0b8d"
|
|
336
336
|
},
|
|
337
337
|
{
|
|
338
338
|
"path": "clients/bongos-client/bongos-client.global.js",
|
|
339
339
|
"mode": "0000644",
|
|
340
|
-
"sha256": "
|
|
340
|
+
"sha256": "f4ef4c8a0d192356bcbf81a20d793ad368506a245f9b392d4654776fde6539f0"
|
|
341
341
|
},
|
|
342
342
|
{
|
|
343
343
|
"path": "clients/bongos-client/examples/hello-world.mjs",
|
|
@@ -347,17 +347,17 @@
|
|
|
347
347
|
{
|
|
348
348
|
"path": "clients/bongos-client/index.cjs",
|
|
349
349
|
"mode": "0000644",
|
|
350
|
-
"sha256": "
|
|
350
|
+
"sha256": "fafbd80941536f67f85b55c5c250df1ed152398f30ebec2820d431c99676ffb3"
|
|
351
351
|
},
|
|
352
352
|
{
|
|
353
353
|
"path": "clients/bongos-client/index.d.ts",
|
|
354
354
|
"mode": "0000644",
|
|
355
|
-
"sha256": "
|
|
355
|
+
"sha256": "0e60eb71a4c912b79c2cac3bc338403883667da5c6f871ed811f21dec58d33f9"
|
|
356
356
|
},
|
|
357
357
|
{
|
|
358
358
|
"path": "clients/bongos-client/index.mjs",
|
|
359
359
|
"mode": "0000644",
|
|
360
|
-
"sha256": "
|
|
360
|
+
"sha256": "68e375e1c32558fc6e442849bac87b2a82433d333bee255d3aeb0904b9c3f5a1"
|
|
361
361
|
},
|
|
362
362
|
{
|
|
363
363
|
"path": "clients/bongos-client/package.json",
|
|
@@ -2457,17 +2457,17 @@
|
|
|
2457
2457
|
{
|
|
2458
2458
|
"path": "docs/api-reference.md",
|
|
2459
2459
|
"mode": "0000644",
|
|
2460
|
-
"sha256": "
|
|
2460
|
+
"sha256": "57e77a6ffdbe2d558c088fce69e154b3b595b4d6d10b5053ad4ba0043cb00c46"
|
|
2461
2461
|
},
|
|
2462
2462
|
{
|
|
2463
2463
|
"path": "docs/api/openapi.json",
|
|
2464
2464
|
"mode": "0000644",
|
|
2465
|
-
"sha256": "
|
|
2465
|
+
"sha256": "d2e12182597058030c086d3283f652f8d8e2b2e62900c9babed2eba71a97996a"
|
|
2466
2466
|
},
|
|
2467
2467
|
{
|
|
2468
2468
|
"path": "docs/architecture.md",
|
|
2469
2469
|
"mode": "0000644",
|
|
2470
|
-
"sha256": "
|
|
2470
|
+
"sha256": "ac90efe1fecf89564c59896f69f6131923dfbfdc480f514af9e86802eb1041de"
|
|
2471
2471
|
},
|
|
2472
2472
|
{
|
|
2473
2473
|
"path": "docs/branding-contract.md",
|
|
@@ -3002,7 +3002,7 @@
|
|
|
3002
3002
|
{
|
|
3003
3003
|
"path": "docs/module-api-changelog.md",
|
|
3004
3004
|
"mode": "0000644",
|
|
3005
|
-
"sha256": "
|
|
3005
|
+
"sha256": "f452287804538b6969ab460071c916397ba3ec34aa53231b18f30d52d3d00b7a"
|
|
3006
3006
|
},
|
|
3007
3007
|
{
|
|
3008
3008
|
"path": "docs/modules-contract.md",
|
|
@@ -4309,6 +4309,11 @@
|
|
|
4309
4309
|
"mode": "0000644",
|
|
4310
4310
|
"sha256": "e7be74430d0d9349b4f9820ff3f202ef03d8c28363fecbaa532c4b9c119e77ec"
|
|
4311
4311
|
},
|
|
4312
|
+
{
|
|
4313
|
+
"path": "migrations/core_290_builder_payouts.sql",
|
|
4314
|
+
"mode": "0000644",
|
|
4315
|
+
"sha256": "6a8ca9343a4e7d9657baaadb89f42fe76f9354ce739d09ea51569d12e01d8706"
|
|
4316
|
+
},
|
|
4312
4317
|
{
|
|
4313
4318
|
"path": "modules/agents/CLAUDE.md",
|
|
4314
4319
|
"mode": "0000644",
|
|
@@ -5242,7 +5247,7 @@
|
|
|
5242
5247
|
{
|
|
5243
5248
|
"path": "modules/economy/module.json",
|
|
5244
5249
|
"mode": "0000644",
|
|
5245
|
-
"sha256": "
|
|
5250
|
+
"sha256": "0c1dd2a3a6f467697bdd72443d05cc3f99ec51b2b4e6d2efdd2e0f57a03cf6c9"
|
|
5246
5251
|
},
|
|
5247
5252
|
{
|
|
5248
5253
|
"path": "modules/economy/policy.js",
|
|
@@ -5287,7 +5292,7 @@
|
|
|
5287
5292
|
{
|
|
5288
5293
|
"path": "modules/economy/routes/project-account.js",
|
|
5289
5294
|
"mode": "0000644",
|
|
5290
|
-
"sha256": "
|
|
5295
|
+
"sha256": "1e61263bf8b0aaf2ad0e677fb4a57ab2c02888c296de4ca8fc76ccd2c135f235"
|
|
5291
5296
|
},
|
|
5292
5297
|
{
|
|
5293
5298
|
"path": "modules/economy/routes/reward.js",
|
|
@@ -11692,12 +11697,12 @@
|
|
|
11692
11697
|
{
|
|
11693
11698
|
"path": "package-lock.json",
|
|
11694
11699
|
"mode": "0000644",
|
|
11695
|
-
"sha256": "
|
|
11700
|
+
"sha256": "575055f35b185145ffef2a3568a1ac4547fb6fa2379d6e130d70563660fb25b8"
|
|
11696
11701
|
},
|
|
11697
11702
|
{
|
|
11698
11703
|
"path": "package.json",
|
|
11699
11704
|
"mode": "0000644",
|
|
11700
|
-
"sha256": "
|
|
11705
|
+
"sha256": "121c3e8f9ea0d45d23fcb52d5791b7e6524aac3ae9898f922d0c7b259e945b35"
|
|
11701
11706
|
},
|
|
11702
11707
|
{
|
|
11703
11708
|
"path": "public-docs/index.html",
|
|
@@ -11717,7 +11722,7 @@
|
|
|
11717
11722
|
{
|
|
11718
11723
|
"path": "release-notes.json",
|
|
11719
11724
|
"mode": "0000644",
|
|
11720
|
-
"sha256": "
|
|
11725
|
+
"sha256": "00b08004177af637f2afa9c9eb567146deaf53ad93d975965eeb99f86d3024d2"
|
|
11721
11726
|
},
|
|
11722
11727
|
{
|
|
11723
11728
|
"path": "scripts/bongos/CLAUDE.md",
|
|
@@ -12947,7 +12952,7 @@
|
|
|
12947
12952
|
{
|
|
12948
12953
|
"path": "scripts/bongos/run-unit-tests.js",
|
|
12949
12954
|
"mode": "0000644",
|
|
12950
|
-
"sha256": "
|
|
12955
|
+
"sha256": "52b452c7f022282371d0583561498737716103358ed8e010eb9734efe77f2e89"
|
|
12951
12956
|
},
|
|
12952
12957
|
{
|
|
12953
12958
|
"path": "scripts/bongos/runner-drift.js",
|
|
@@ -15139,6 +15144,11 @@
|
|
|
15139
15144
|
"mode": "0000644",
|
|
15140
15145
|
"sha256": "f09f297371563a361002d1443414aa5ab65da36ad5e68bfadb634c659aeda6f3"
|
|
15141
15146
|
},
|
|
15147
|
+
{
|
|
15148
|
+
"path": "src/bongos/builder-payouts.js",
|
|
15149
|
+
"mode": "0000644",
|
|
15150
|
+
"sha256": "b84ffb276778a5ddf018618c689b656c2d5d3a810af9e829dcb5fd20e6d6e81f"
|
|
15151
|
+
},
|
|
15142
15152
|
{
|
|
15143
15153
|
"path": "src/bongos/cascade-dispatch.js",
|
|
15144
15154
|
"mode": "0000644",
|
|
@@ -15492,7 +15502,7 @@
|
|
|
15492
15502
|
{
|
|
15493
15503
|
"path": "src/bongos/routes/payout-approvals.js",
|
|
15494
15504
|
"mode": "0000644",
|
|
15495
|
-
"sha256": "
|
|
15505
|
+
"sha256": "5575f0616b45c78f57a8fa237ead916f3b04e4eae394f807603d7bf6cb53a912"
|
|
15496
15506
|
},
|
|
15497
15507
|
{
|
|
15498
15508
|
"path": "src/bongos/routes/payout-gates.js",
|
|
@@ -15582,7 +15592,7 @@
|
|
|
15582
15592
|
{
|
|
15583
15593
|
"path": "src/module-api.js",
|
|
15584
15594
|
"mode": "0000644",
|
|
15585
|
-
"sha256": "
|
|
15595
|
+
"sha256": "8db80ccb2a1b60d7c647717b445dafeb381b0473e21b64da3ae780124f9afe4d"
|
|
15586
15596
|
},
|
|
15587
15597
|
{
|
|
15588
15598
|
"path": "src/module-loader/catalog.js",
|
|
@@ -16399,6 +16409,16 @@
|
|
|
16399
16409
|
"mode": "0000644",
|
|
16400
16410
|
"sha256": "2eecaaa02ad5d2cd8e25449d66dc86aa1884278dbf72656c0d9401129034e247"
|
|
16401
16411
|
},
|
|
16412
|
+
{
|
|
16413
|
+
"path": "tests/builder_payouts.mjs",
|
|
16414
|
+
"mode": "0000644",
|
|
16415
|
+
"sha256": "45d49e84f826115c43bf9f01a42eae4ee70ffe26fdc02acf303b345c9850d397"
|
|
16416
|
+
},
|
|
16417
|
+
{
|
|
16418
|
+
"path": "tests/builder_payouts_db.mjs",
|
|
16419
|
+
"mode": "0000644",
|
|
16420
|
+
"sha256": "1676f0b2452e0d834df2b49974d4699f918e223e56d2f4193ffe87339b6f1f4a"
|
|
16421
|
+
},
|
|
16402
16422
|
{
|
|
16403
16423
|
"path": "tests/builder_tester_tag.mjs",
|
|
16404
16424
|
"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
|
+
- 659 operations across 83 resource groups
|
|
9
9
|
|
|
10
10
|
## Use it from your project
|
|
11
11
|
|
|
@@ -1037,6 +1037,10 @@ function createClient(opts = {}) {
|
|
|
1037
1037
|
getPayoutsApprovals: (args) => request("GET", "/payouts/approvals", { hasBody: false }, args),
|
|
1038
1038
|
// POST /payouts/approve — rank: archon — POST /payouts/approve
|
|
1039
1039
|
postPayoutsApprove: (args) => request("POST", "/payouts/approve", { hasBody: true }, args),
|
|
1040
|
+
// GET /payouts/builder-payouts — rank: archon — GET /payouts/builder-payouts
|
|
1041
|
+
getPayoutsBuilderPayouts: (args) => request("GET", "/payouts/builder-payouts", { hasBody: false }, args),
|
|
1042
|
+
// POST /payouts/builder-payouts — rank: archon — POST /payouts/builder-payouts
|
|
1043
|
+
postPayoutsBuilderPayouts: (args) => request("POST", "/payouts/builder-payouts", { hasBody: true }, args),
|
|
1040
1044
|
// POST /payouts/contracts — rank: archon — POST /payouts/contracts
|
|
1041
1045
|
postPayoutsContracts: (args) => request("POST", "/payouts/contracts", { hasBody: true }, args),
|
|
1042
1046
|
// POST /payouts/freezes — rank: archon — POST /payouts/freezes
|
|
@@ -1036,6 +1036,10 @@ function createClient(opts = {}) {
|
|
|
1036
1036
|
getPayoutsApprovals: (args) => request("GET", "/payouts/approvals", { hasBody: false }, args),
|
|
1037
1037
|
// POST /payouts/approve — rank: archon — POST /payouts/approve
|
|
1038
1038
|
postPayoutsApprove: (args) => request("POST", "/payouts/approve", { hasBody: true }, args),
|
|
1039
|
+
// GET /payouts/builder-payouts — rank: archon — GET /payouts/builder-payouts
|
|
1040
|
+
getPayoutsBuilderPayouts: (args) => request("GET", "/payouts/builder-payouts", { hasBody: false }, args),
|
|
1041
|
+
// POST /payouts/builder-payouts — rank: archon — POST /payouts/builder-payouts
|
|
1042
|
+
postPayoutsBuilderPayouts: (args) => request("POST", "/payouts/builder-payouts", { hasBody: true }, args),
|
|
1039
1043
|
// POST /payouts/contracts — rank: archon — POST /payouts/contracts
|
|
1040
1044
|
postPayoutsContracts: (args) => request("POST", "/payouts/contracts", { hasBody: true }, args),
|
|
1041
1045
|
// POST /payouts/freezes — rank: archon — POST /payouts/freezes
|
|
@@ -144,6 +144,7 @@ export interface GetPageNotesSiteResponse { notes: unknown }
|
|
|
144
144
|
export interface GetPayTermsResponse { pay_terms: unknown }
|
|
145
145
|
export interface GetPayTypeGatesResponse { gates: unknown }
|
|
146
146
|
export interface GetPayoutsApprovalsResponse { approvals: unknown }
|
|
147
|
+
export interface GetPayoutsBuilderPayoutsResponse { payouts: unknown; page: PageInfo }
|
|
147
148
|
export interface GetPayoutsGatesBuilderIdResponse { gate: unknown }
|
|
148
149
|
export interface GetPayoutsRulesResponse { rules: unknown }
|
|
149
150
|
export interface GetProfilesHandleResponse { account: unknown; cross_project: unknown }
|
|
@@ -534,6 +535,7 @@ export interface PostPayoutsAgeRecordsRequest { builder_id: StringifiableId; tie
|
|
|
534
535
|
export interface PostPayoutsAgeRecordsResponse { record: unknown }
|
|
535
536
|
export interface PostPayoutsApproveRequest { recipient_id?: StringifiableId; amount_cents?: unknown; currency?: unknown; note?: unknown }
|
|
536
537
|
export interface PostPayoutsApproveResponse { approval: unknown }
|
|
538
|
+
export interface PostPayoutsBuilderPayoutsRequest { approval_id: StringifiableId; task_id: StringifiableId }
|
|
537
539
|
export interface PostPayoutsFreezesIdDecideRequest { decision: unknown; statement: unknown }
|
|
538
540
|
export interface PostPayoutsFreezesIdDecideResponse { event: unknown }
|
|
539
541
|
export interface PostPayoutsFreezesRequest { builder_id: StringifiableId; notice_text: unknown; owed_cents?: unknown }
|
|
@@ -1675,6 +1677,10 @@ export interface BongosClient {
|
|
|
1675
1677
|
getPayoutsApprovals(args?: RequestArgs): Promise<GetPayoutsApprovalsResponse>;
|
|
1676
1678
|
/** POST /payouts/approve — rank: archon */
|
|
1677
1679
|
postPayoutsApprove(args?: RequestArgs & { body?: PostPayoutsApproveRequest }): Promise<PostPayoutsApproveResponse>;
|
|
1680
|
+
/** GET /payouts/builder-payouts — rank: archon */
|
|
1681
|
+
getPayoutsBuilderPayouts(args?: RequestArgs): Promise<GetPayoutsBuilderPayoutsResponse>;
|
|
1682
|
+
/** POST /payouts/builder-payouts — rank: archon */
|
|
1683
|
+
postPayoutsBuilderPayouts(args: RequestArgs & { body: PostPayoutsBuilderPayoutsRequest }): Promise<ApiResponse>;
|
|
1678
1684
|
/** POST /payouts/contracts — rank: archon */
|
|
1679
1685
|
postPayoutsContracts(args?: RequestArgs): Promise<ApiResponse>;
|
|
1680
1686
|
/** POST /payouts/freezes — rank: archon */
|
|
@@ -1033,6 +1033,10 @@ export function createClient(opts = {}) {
|
|
|
1033
1033
|
getPayoutsApprovals: (args) => request("GET", "/payouts/approvals", { hasBody: false }, args),
|
|
1034
1034
|
// POST /payouts/approve — rank: archon — POST /payouts/approve
|
|
1035
1035
|
postPayoutsApprove: (args) => request("POST", "/payouts/approve", { hasBody: true }, args),
|
|
1036
|
+
// GET /payouts/builder-payouts — rank: archon — GET /payouts/builder-payouts
|
|
1037
|
+
getPayoutsBuilderPayouts: (args) => request("GET", "/payouts/builder-payouts", { hasBody: false }, args),
|
|
1038
|
+
// POST /payouts/builder-payouts — rank: archon — POST /payouts/builder-payouts
|
|
1039
|
+
postPayoutsBuilderPayouts: (args) => request("POST", "/payouts/builder-payouts", { hasBody: true }, args),
|
|
1036
1040
|
// POST /payouts/contracts — rank: archon — POST /payouts/contracts
|
|
1037
1041
|
postPayoutsContracts: (args) => request("POST", "/payouts/contracts", { hasBody: true }, args),
|
|
1038
1042
|
// POST /payouts/freezes — rank: archon — POST /payouts/freezes
|
package/docs/api/openapi.json
CHANGED
|
@@ -19595,6 +19595,90 @@
|
|
|
19595
19595
|
]
|
|
19596
19596
|
}
|
|
19597
19597
|
},
|
|
19598
|
+
"/payouts/builder-payouts": {
|
|
19599
|
+
"get": {
|
|
19600
|
+
"operationId": "get_payouts_builder_payouts",
|
|
19601
|
+
"tags": [
|
|
19602
|
+
"payouts"
|
|
19603
|
+
],
|
|
19604
|
+
"summary": "GET /payouts/builder-payouts",
|
|
19605
|
+
"description": "GET /api/bongos/payouts/builder-payouts — every builder payout and where it stands (task 1003183, M04): paid, or owed with its latest try and the reason in words.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `payout.approve` (all required).",
|
|
19606
|
+
"x-rank": "archon",
|
|
19607
|
+
"x-source": "src/bongos/routes/payout-approvals.js",
|
|
19608
|
+
"x-permissions": [
|
|
19609
|
+
"payout.approve"
|
|
19610
|
+
],
|
|
19611
|
+
"responses": {
|
|
19612
|
+
"200": {
|
|
19613
|
+
"description": "Success.",
|
|
19614
|
+
"content": {
|
|
19615
|
+
"application/json": {
|
|
19616
|
+
"schema": {
|
|
19617
|
+
"$ref": "#/components/schemas/GetPayoutsBuilderPayoutsResponse"
|
|
19618
|
+
}
|
|
19619
|
+
}
|
|
19620
|
+
}
|
|
19621
|
+
},
|
|
19622
|
+
"400": {
|
|
19623
|
+
"$ref": "#/components/responses/BadRequest"
|
|
19624
|
+
},
|
|
19625
|
+
"401": {
|
|
19626
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
19627
|
+
},
|
|
19628
|
+
"403": {
|
|
19629
|
+
"$ref": "#/components/responses/Forbidden"
|
|
19630
|
+
}
|
|
19631
|
+
},
|
|
19632
|
+
"security": [
|
|
19633
|
+
{
|
|
19634
|
+
"builderSession": []
|
|
19635
|
+
}
|
|
19636
|
+
]
|
|
19637
|
+
},
|
|
19638
|
+
"post": {
|
|
19639
|
+
"operationId": "post_payouts_builder_payouts",
|
|
19640
|
+
"tags": [
|
|
19641
|
+
"payouts"
|
|
19642
|
+
],
|
|
19643
|
+
"summary": "POST /payouts/builder-payouts",
|
|
19644
|
+
"description": "POST /api/bongos/payouts/builder-payouts — send ONE approved payout for ONE task (task 1003183, M04). Body: { approval_id, task_id }. The person and the amount come from the approval, never the body. A person presses it on the website: the approval says what may be paid, and this is the person sending it (Art. I). Pressing again is safe: a paid task answers paid, an owed one retries with the same processor key.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `payout.approve` (all required).",
|
|
19645
|
+
"x-rank": "archon",
|
|
19646
|
+
"x-source": "src/bongos/routes/payout-approvals.js",
|
|
19647
|
+
"x-permissions": [
|
|
19648
|
+
"payout.approve"
|
|
19649
|
+
],
|
|
19650
|
+
"requestBody": {
|
|
19651
|
+
"required": true,
|
|
19652
|
+
"content": {
|
|
19653
|
+
"application/json": {
|
|
19654
|
+
"schema": {
|
|
19655
|
+
"$ref": "#/components/schemas/PostPayoutsBuilderPayoutsRequest"
|
|
19656
|
+
}
|
|
19657
|
+
}
|
|
19658
|
+
},
|
|
19659
|
+
"x-validated": true
|
|
19660
|
+
},
|
|
19661
|
+
"responses": {
|
|
19662
|
+
"200": {
|
|
19663
|
+
"description": "Success."
|
|
19664
|
+
},
|
|
19665
|
+
"400": {
|
|
19666
|
+
"$ref": "#/components/responses/ValidationFailed"
|
|
19667
|
+
},
|
|
19668
|
+
"401": {
|
|
19669
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
19670
|
+
},
|
|
19671
|
+
"403": {
|
|
19672
|
+
"$ref": "#/components/responses/Forbidden"
|
|
19673
|
+
}
|
|
19674
|
+
},
|
|
19675
|
+
"security": [
|
|
19676
|
+
{
|
|
19677
|
+
"builderSession": []
|
|
19678
|
+
}
|
|
19679
|
+
]
|
|
19680
|
+
}
|
|
19681
|
+
},
|
|
19598
19682
|
"/payouts/contracts": {
|
|
19599
19683
|
"post": {
|
|
19600
19684
|
"operationId": "post_payouts_contracts",
|
|
@@ -32569,6 +32653,19 @@
|
|
|
32569
32653
|
"approvals"
|
|
32570
32654
|
]
|
|
32571
32655
|
},
|
|
32656
|
+
"GetPayoutsBuilderPayoutsResponse": {
|
|
32657
|
+
"type": "object",
|
|
32658
|
+
"properties": {
|
|
32659
|
+
"payouts": {},
|
|
32660
|
+
"page": {
|
|
32661
|
+
"$ref": "#/components/schemas/PageInfo"
|
|
32662
|
+
}
|
|
32663
|
+
},
|
|
32664
|
+
"required": [
|
|
32665
|
+
"payouts",
|
|
32666
|
+
"page"
|
|
32667
|
+
]
|
|
32668
|
+
},
|
|
32572
32669
|
"GetPayoutsGatesBuilderIdResponse": {
|
|
32573
32670
|
"type": "object",
|
|
32574
32671
|
"properties": {
|
|
@@ -38572,6 +38669,22 @@
|
|
|
38572
38669
|
"approval"
|
|
38573
38670
|
]
|
|
38574
38671
|
},
|
|
38672
|
+
"PostPayoutsBuilderPayoutsRequest": {
|
|
38673
|
+
"type": "object",
|
|
38674
|
+
"properties": {
|
|
38675
|
+
"approval_id": {
|
|
38676
|
+
"$ref": "#/components/schemas/StringifiableId"
|
|
38677
|
+
},
|
|
38678
|
+
"task_id": {
|
|
38679
|
+
"$ref": "#/components/schemas/StringifiableId"
|
|
38680
|
+
}
|
|
38681
|
+
},
|
|
38682
|
+
"required": [
|
|
38683
|
+
"approval_id",
|
|
38684
|
+
"task_id"
|
|
38685
|
+
],
|
|
38686
|
+
"additionalProperties": false
|
|
38687
|
+
},
|
|
38575
38688
|
"PostPayoutsFreezesIdDecideRequest": {
|
|
38576
38689
|
"type": "object",
|
|
38577
38690
|
"properties": {
|
|
@@ -41644,9 +41757,9 @@
|
|
|
41644
41757
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
41645
41758
|
}
|
|
41646
41759
|
},
|
|
41647
|
-
"x-endpoint-count":
|
|
41648
|
-
"x-schema-count":
|
|
41760
|
+
"x-endpoint-count": 659,
|
|
41761
|
+
"x-schema-count": 707,
|
|
41649
41762
|
"x-undocumented-bodies": 12,
|
|
41650
|
-
"x-response-schemas":
|
|
41763
|
+
"x-response-schemas": 452,
|
|
41651
41764
|
"x-generated-by": "scripts/bongos/gen-api-docs.js"
|
|
41652
41765
|
}
|
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. 659 endpoints across 111 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`.
|
|
@@ -708,13 +708,15 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
708
708
|
| GET | `/api/bongos/pay-type-gates` | `any-builder` | — | for met/missing (the same pay information `GET /pay-terms` shows, no person's money); the evidence references and who cleared each requir… |
|
|
709
709
|
| PUT | `/api/bongos/pay-type-gates/:payType/:requirement` | `archon` | `state`, `evidence_ref`, `acknowledged` | .approve (archon floor). |
|
|
710
710
|
|
|
711
|
-
## `payouts` (
|
|
711
|
+
## `payouts` (18)
|
|
712
712
|
|
|
713
713
|
| Method | Path | Rank | Body | Description |
|
|
714
714
|
|---|---|---|---|---|
|
|
715
715
|
| POST | `/api/bongos/payouts/age-records` | `archon` | `builder_id`, `tier` | POST /api/bongos/payouts/age-records — record a builder's age tier, verified by a person. |
|
|
716
716
|
| GET | `/api/bongos/payouts/approvals` | `archon` | — | GET /api/bongos/payouts/approvals — the log, newest first. |
|
|
717
717
|
| POST | `/api/bongos/payouts/approve` | `archon` | `recipient_id`, `amount_cents`, `currency`, `note` | POST /api/bongos/payouts/approve — approve ONE payout. |
|
|
718
|
+
| GET | `/api/bongos/payouts/builder-payouts` | `archon` | — | GET /api/bongos/payouts/builder-payouts — every builder payout and where it stands (task 1003183, M04): paid, or owed with its latest try… |
|
|
719
|
+
| POST | `/api/bongos/payouts/builder-payouts` | `archon` | `approval_id`, `task_id` | POST /api/bongos/payouts/builder-payouts — send ONE approved payout for ONE task (task 1003183, M04). |
|
|
718
720
|
| POST | `/api/bongos/payouts/contracts` | `archon` | — | POST /api/bongos/payouts/contracts — sign ONE contract. |
|
|
719
721
|
| POST | `/api/bongos/payouts/freezes` | `archon` | `builder_id`, `notice_text`, `owed_cents` | POST /api/bongos/payouts/freezes — a person freezes a builder's payouts by hand. |
|
|
720
722
|
| POST | `/api/bongos/payouts/freezes/:id/decide` | `archon` | `decision`, `statement` | POST /api/bongos/payouts/freezes/:id/decide — uphold or lift a freeze, with the reason the person will read. |
|
package/docs/architecture.md
CHANGED
|
@@ -308,6 +308,21 @@ payout_guardian_cosigns(id, builder_id, guardian_id, approval_id | rule_id+run_k
|
|
|
308
308
|
-- and a co-signature by anyone but the current guardian.
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
+
Builder payouts (migration `core_290`, task 1003183, [ADR 0397](adr/0397-the-payment-rail-is-stripe-connect-with-one-connected-account-per-project.md) D7 — a builder is paid for a task exactly once; `src/bongos/builder-payouts.js`, routes `GET`/`POST /payouts/builder-payouts` gated `payout.approve` plus the person's own web session for the POST; the `payout` movement is booked through the economy module's `economy.account` port in the same transaction. No processor adapter exists yet, so every payout is recorded owed and held `no_processor`):
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
builder_payouts_owed(id, builder_id FK, task_id FK, approval_id FK payout_approvals,
|
|
315
|
+
amount_cents, currency, recorded_by FK, created_at)
|
|
316
|
+
-- written BEFORE anything is sent; UNIQUE (builder_id, task_id) and UNIQUE
|
|
317
|
+
-- (approval_id): a task is paid once, an approval pays one task.
|
|
318
|
+
builder_payout_attempts(id, owed_id FK, outcome sent|failed|held, processor_ref, reason,
|
|
319
|
+
actor_id, created_at)
|
|
320
|
+
-- at most one `sent` per debt (partial UNIQUE); sent needs processor_ref,
|
|
321
|
+
-- failed/held need a reason. BOTH APPEND-ONLY by trigger. The processor is
|
|
322
|
+
-- called with idempotency key `bongos-payout-<owed id>`, so a retry after an
|
|
323
|
+
-- unknown outcome gets the same transfer back.
|
|
324
|
+
```
|
|
325
|
+
|
|
311
326
|
Store sub-categories (migration `core_280`, task 1004355, [ADR 0342](adr/0342-module-categories-are-eight-parents-with-approved-sub-categories.md) D3 — an author proposes one at publish, a Metic+ person approves, renames or merges it; `src/bongos/module-subcategories.js`):
|
|
312
327
|
|
|
313
328
|
```
|
|
@@ -3290,5 +3290,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
3290
3290
|
landed since 1.24.15 with no explicit bump. run 41124515103. (task 1002620)
|
|
3291
3291
|
1.24.17 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
3292
3292
|
landed since 1.24.16 with no explicit bump. run 41129472650. (task 1002620)
|
|
3293
|
+
1.24.18 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
3294
|
+
landed since 1.24.17 with no explicit bump. run 41131020363. (task 1002620)
|
|
3293
3295
|
---------------------------------------------------------------------------
|
|
3294
3296
|
```
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
-- core_290_builder_payouts.sql — a builder is paid for a task, exactly once, and a payout
|
|
2
|
+
-- that did not go through still says it is owed (task 1003183, goal 1000092 M04;
|
|
3
|
+
-- ADR 0385 decisions 1 and 4, ADR 0397 decisions 2, 5 and 7).
|
|
4
|
+
--
|
|
5
|
+
-- TWO TABLES, BOTH APPEND-ONLY.
|
|
6
|
+
--
|
|
7
|
+
-- builder_payouts_owed one row per (builder, task): what is owed, and the
|
|
8
|
+
-- personal approval that authorises it. Written BEFORE
|
|
9
|
+
-- the processor is asked to move anything, in its own
|
|
10
|
+
-- committed step, so a crash, a refusal or a timeout
|
|
11
|
+
-- afterwards still leaves the debt on record. The failure
|
|
12
|
+
-- this exists to prevent is a builder who was silently
|
|
13
|
+
-- never paid, with no trace anything was due.
|
|
14
|
+
-- builder_payout_attempts every try at paying one owed row: sent (with the
|
|
15
|
+
-- processor's transfer reference), failed (with the
|
|
16
|
+
-- reason), or held (not sent, with the reason: a gate,
|
|
17
|
+
-- no processor connected, a missing approval).
|
|
18
|
+
--
|
|
19
|
+
-- EXACTLY ONCE is three rules, each enforced here, not only by the code:
|
|
20
|
+
-- * one owed row per (builder, task), and one per approval (an approval pays one
|
|
21
|
+
-- thing, never two tasks);
|
|
22
|
+
-- * at most one `sent` attempt per owed row;
|
|
23
|
+
-- * the processor is called with an idempotency key derived from the owed row's id,
|
|
24
|
+
-- so a retry after an unknown outcome is answered by the processor with the same
|
|
25
|
+
-- transfer, not a second one.
|
|
26
|
+
--
|
|
27
|
+
-- Amounts are integer cents, as the approval that authorises them is. The money
|
|
28
|
+
-- itself is held by the processor (ADR 0397); the matching `payout` movement is booked
|
|
29
|
+
-- through the economy module's `economy.account` port, in micro-dollars, in the same step as `sent`.
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS builder_payouts_owed (
|
|
32
|
+
id BIGSERIAL PRIMARY KEY,
|
|
33
|
+
builder_id BIGINT NOT NULL REFERENCES builders(id),
|
|
34
|
+
task_id BIGINT NOT NULL REFERENCES tasks(id),
|
|
35
|
+
approval_id BIGINT NOT NULL REFERENCES payout_approvals(id),
|
|
36
|
+
amount_cents BIGINT NOT NULL,
|
|
37
|
+
currency TEXT NOT NULL,
|
|
38
|
+
recorded_by BIGINT NOT NULL REFERENCES builders(id),
|
|
39
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
40
|
+
CONSTRAINT builder_payouts_owed_amount_chk CHECK (amount_cents > 0),
|
|
41
|
+
CONSTRAINT builder_payouts_owed_currency_chk CHECK (currency ~ '^[A-Z]{3}$')
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
-- one payout per builder per task, and one task per approval
|
|
45
|
+
CREATE UNIQUE INDEX IF NOT EXISTS builder_payouts_owed_one_per_task
|
|
46
|
+
ON builder_payouts_owed (builder_id, task_id);
|
|
47
|
+
CREATE UNIQUE INDEX IF NOT EXISTS builder_payouts_owed_one_per_approval
|
|
48
|
+
ON builder_payouts_owed (approval_id);
|
|
49
|
+
CREATE INDEX IF NOT EXISTS builder_payouts_owed_by_time ON builder_payouts_owed (created_at DESC, id DESC);
|
|
50
|
+
|
|
51
|
+
CREATE TABLE IF NOT EXISTS builder_payout_attempts (
|
|
52
|
+
id BIGSERIAL PRIMARY KEY,
|
|
53
|
+
owed_id BIGINT NOT NULL REFERENCES builder_payouts_owed(id),
|
|
54
|
+
outcome TEXT NOT NULL,
|
|
55
|
+
processor_ref TEXT,
|
|
56
|
+
reason TEXT,
|
|
57
|
+
actor_id BIGINT REFERENCES builders(id),
|
|
58
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
59
|
+
CONSTRAINT builder_payout_attempts_outcome_chk CHECK (outcome IN ('sent', 'failed', 'held')),
|
|
60
|
+
CONSTRAINT builder_payout_attempts_reason_len_chk CHECK (reason IS NULL OR length(reason) <= 300),
|
|
61
|
+
-- a sent attempt names the processor transfer; a failed or held one says why
|
|
62
|
+
CONSTRAINT builder_payout_attempts_cause_chk CHECK (
|
|
63
|
+
(outcome = 'sent' AND processor_ref IS NOT NULL) OR
|
|
64
|
+
(outcome IN ('failed', 'held') AND reason IS NOT NULL AND length(reason) > 0))
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
-- paid at most once
|
|
68
|
+
CREATE UNIQUE INDEX IF NOT EXISTS builder_payout_attempts_one_sent
|
|
69
|
+
ON builder_payout_attempts (owed_id) WHERE outcome = 'sent';
|
|
70
|
+
CREATE INDEX IF NOT EXISTS builder_payout_attempts_by_owed ON builder_payout_attempts (owed_id, id DESC);
|
|
71
|
+
|
|
72
|
+
CREATE OR REPLACE FUNCTION builder_payouts_append_only() RETURNS trigger AS $$
|
|
73
|
+
BEGIN
|
|
74
|
+
RAISE EXCEPTION '% is append-only: a payout is never edited or deleted, a new attempt is recorded instead', TG_TABLE_NAME;
|
|
75
|
+
END;
|
|
76
|
+
$$ LANGUAGE plpgsql;
|
|
77
|
+
|
|
78
|
+
DROP TRIGGER IF EXISTS builder_payouts_owed_no_rewrite ON builder_payouts_owed;
|
|
79
|
+
CREATE TRIGGER builder_payouts_owed_no_rewrite BEFORE UPDATE OR DELETE ON builder_payouts_owed
|
|
80
|
+
FOR EACH ROW EXECUTE FUNCTION builder_payouts_append_only();
|
|
81
|
+
DROP TRIGGER IF EXISTS builder_payout_attempts_no_rewrite ON builder_payout_attempts;
|
|
82
|
+
CREATE TRIGGER builder_payout_attempts_no_rewrite BEFORE UPDATE OR DELETE ON builder_payout_attempts
|
|
83
|
+
FOR EACH ROW EXECUTE FUNCTION builder_payouts_append_only();
|
|
84
|
+
|
|
85
|
+
INSERT INTO schema_migrations (version) VALUES ('core_290_builder_payouts')
|
|
86
|
+
ON CONFLICT DO NOTHING;
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
"default": true,
|
|
9
9
|
"maintenance": { "status": "core-maintained" },
|
|
10
10
|
"contributes": { "migrations": true, "routes": ["cost", "credits", "earnings", "leaderboard", "project-account", "reward"] },
|
|
11
|
-
"provides": ["reward"],
|
|
11
|
+
"provides": ["reward", "economy.account"],
|
|
12
12
|
"consumes": []
|
|
13
13
|
}
|
|
@@ -15,11 +15,20 @@
|
|
|
15
15
|
|
|
16
16
|
const express = require('express');
|
|
17
17
|
const api = require('../../../src/module-api');
|
|
18
|
-
const { readAccount } = require('../project-account');
|
|
18
|
+
const { readAccount, recordMovement } = require('../project-account');
|
|
19
19
|
|
|
20
20
|
const log = api.logger('economy');
|
|
21
21
|
|
|
22
|
+
// The `economy.account` PORT (task 1003183): core's payout path (src/bongos/builder-payouts.js)
|
|
23
|
+
// books its `payout` movement through this, inside its own transaction, without importing the
|
|
24
|
+
// module. Registered here for the reason routes/reward.js gives: the loader runs this factory in
|
|
25
|
+
// the live server and whenever a test rebuilds the router. hasProvider-guarded for re-runs.
|
|
26
|
+
function registerSeams() {
|
|
27
|
+
if (!api.hasProvider('economy.account')) api.registerProvider('economy.account', { recordMovement });
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
module.exports = function buildProjectAccountRouter({ processor = null } = {}) {
|
|
31
|
+
registerSeams();
|
|
23
32
|
const router = express.Router();
|
|
24
33
|
|
|
25
34
|
// rank: payout.approve (archon floor) — the owner. The account's balance and who was paid what
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.18",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.24.
|
|
9
|
+
"version": "1.24.18",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.18",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
package/release-notes.json
CHANGED
|
@@ -10987,5 +10987,11 @@
|
|
|
10987
10987
|
"id": "1005029",
|
|
10988
10988
|
"text": "Artists with both an OpenRouter and a Gemini key saved can now choose which one runs their AI request."
|
|
10989
10989
|
}
|
|
10990
|
+
],
|
|
10991
|
+
"1.24.18": [
|
|
10992
|
+
{
|
|
10993
|
+
"id": "1003183",
|
|
10994
|
+
"text": "Builders can now be paid for a task, and never twice. Each payment is written down as owed before anything is sent, so a failed payment still leaves a record. No money moves yet: the Stripe connection comes next."
|
|
10995
|
+
}
|
|
10990
10996
|
]
|
|
10991
10997
|
}
|